关键字:tensorflow、cnn、mnist、神经网络、卷积、验证码、识别
时间:2017年5月

目录

前言
CNN介绍
Tensorflow介绍
MNIST介绍
定义网络结构及参数
代码及说明
注意事项

前言

工作原因需要抓取一个网站的数据,但这个网站有验证码,很自然的想到了验证码识别。起初通过使用了一些常规的验证码识别的方法,但到了分割字符这一步是,发现非常困难。通过搜索发现了卷积神经网络可以很简单的完成识别工作,于是开始了卷积神经网络的学习。
继续向下阅读需要你对神经网络的基本概念有所认识。

CNN介绍

卷积神经网络(CNN),完全可以按字面去理解它,就是神经网络,并在网络中引入了卷积算法。CNN目前已经在图像识别上取得了广泛的应用。

Tensorflow介绍

Tensorflow是Google开源的一个神经网络框架,支持Python语言,是主流神经网络框架之一。

MNIST介绍

MNIST是一个非常好的分类算法研究的样本库。它由0~9的手写数字灰度图片构成,6万个训练样本,1万个测试样本。

定义网络结构及参数

这里采用了2层卷积和2层全连接构建网络结构。这是一个比较通用的层数,完全可以用于任意位数的验证码识别。但用于多位验证码图片识别时,需要调整输入层和输出层。

输入层(reshape) 输入节点: 784 输出节点: 28*28
隐层1(卷积) 输入节点: 28*28 输出节点: 32*14*14
隐层2(卷积) 输入节点: 32*14*14 输出节点: 64*7*7
隐层3(全连接) 输入节点: 64*7*7 输出节点: 1024
隐层4(全连接) 输入节点: 1024 输出节点: 10
输出层(Softmax) 输入节点: 10 输出节点: 10

代码及说明

tensor,是tensorflow的核心,tf.Variable()、tf.reshape()、tf.nn.relu()、tf.matmul()、tf.nn.softmax()、tf.reduce_mean()等,几乎所有函数的输入输出都是tensor,因此他们之间可以任意连接,构造网络。
reshape中的-1,对矩阵数据进行形状变换时,可以在一个维度上使用-1代替。例如:把一个[1,2,3,4,5,6,7,8,9,0]变成[[1,2,3,4,5],[6,7,8,9,0]],可以使用reshape(x,[2,5])或reshape(x,[-1,5])。

# -*- coding:utf-8 -*-
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

X = tf.placeholder(tf.float32, [None, 784]) # 图片分辨率为28x28,但样本是
Y = tf.placeholder(tf.float32, [None, 10])
# placeholder(),占位函数,session.run的参数feed_dict={X: , Y:}中的X和Y对应的就是它。

inputs = tf.reshape(X,[-1,28,28,1])
# 样本是n个长度为784的1维向量,把它转成n个高28x宽28x通道数1的矩阵

#
# 第一层,卷积层
#
l1_weights = tf.Variable(tf.truncated_normal([5,5,1,32], stddev=0.1))
l1_biases = tf.Variable(tf.constant(0.1, shape=[32]))
# 卷积核[5,5],输入1张28x28图片,输出32张28x28特征图片

l1 = tf.nn.conv2d(inputs, l1_weights, strides=[1,1,1,1], padding='SAME') + l1_biases
# strides=[1,1,1,1],所有方向步进为1进行卷积
# padding='SAME',输出大小和输入大小相同28x28

l1 = tf.nn.relu(l1)
# 激活函数,例如:relu([0.5,-0.3,-0.13,1.2,-0.7] = [0.5,0,0,1.2,0]

l1 = tf.nn.max_pool(l1, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')
# 池化,strides=[1,2,2,1]使得输出为14x14

#
# 第二层,卷积层,与第一层类似
#
l2_weights = tf.Variable(tf.truncated_normal([5,5,32,64], stddev=0.1))
l2_biases = tf.Variable(tf.constant(0.1, shape=[64]))
# 卷积核[5,5],输入32张14x14图片,输出64张14x14特征图片

l2 = tf.nn.conv2d(l1, l2_weights, strides=[1,1,1,1], padding='SAME') + l2_biases
l2 = tf.nn.relu(l2)
l2 = tf.nn.max_pool(l2, ksize=[1,2,2,1], strides[1,2,2,1], padding='SAME')
# 池化,strides=[1,2,2,1]使得输出为7x7

#
# 第三层,全连接层
#
l3_weights = tf.Variable(tf.truncated_normal([7*7*64, 1024], stddev=0.1))
l3_biases = tf.Variable(tf.constant(0.1, shape=[1024]))
# 7*7*64个输入,1024个输出

l3 = tf.reshape(l2, [-1,7*7*64])
# 把64张7x7的特征转换成1维进行输入给全连接

l3 = tf.matmul(l3, l3_weights) + l3_biases
l3 = tf.nn.relu(l3)

#
#第四层,全连接层
#
l4_weights = tf.Variable(tf.truncated_normal([1024, 10], stddev=0.1))
l4_biases = tf.Variable(tf.constant(0.1, shape=[10]))
# 1024个输入,10个输出

l4 = tf.matmul(l3, l4_weights) + l4_biases # y = W * x + b

outputs = tf.nn.softmax(l4)
# softmax([1,2,2]) =  [1/(1+2+2),2/(1+2+2),2/(1+2+2)] = [0.2,0.4,0.4]

cross_entropy = -tf.reduce_sum(Y*tf.log(outputs)) # 计算交叉熵
train_op = tf.train.AdamOptimizer(0.0001).minimize(cross_entropy)

correct_prediction = tf.equal(tf.argmax(outputs, axis=1), tf.argmax(Y, axis=1))
# tf.argmax找某个轴上的最大值的位置,理解起来比较困难,简单理解就是把[1,0,0,0,0,0,0,0,0,0]转成[0],[0,1,0,0,0,0,0,0,0,0]转成[1],以此类推。
# tf.equal比较两个矩阵相同位置的值,相同为True,否则为False,例如:[[0,1],[1,0]]与[[0,0],[1,1]]比较,结果为[[True,False],[True,False]]

accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
# tf.cast()数据类型转换,True/False转成浮点1./0.

sess = tf.Session()
sess.run(tf.initialize_all_variables())

mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
# 加载MNIST库,本地没有则从网络下载,下载完成后在当前目录有个MNIST_data/目录

for i in range(1000):
# 训练1000次
    batch_xs, batch_ys = mnist.train.next_batch(100)
    # 100个样本一批,进行1次训练
    sess.run(train_op, feed_dict={X:batch_xs, Y:batch_ys})
    if i%50==0:
        print "step %d, accuracy %f"%(i, sess.run(accuracy, feed_dict={X:batch_xs,Y:batch_ys}))
        # 每50次训练,输出准确率

print "test accuracy: ",sess.run(accuracy, feed_dict{X:mnist.test.images, Y:mnist.test.labels})
# 使用测试集计算准确率

注意事项

mnist样本库文件大小约10MB,但下载比较慢。
为了代码简单,没有加入tf.nn.dropout()、tf.train.Saver()等函数。tf.nn.dropout(),可防止过拟合。tf.train.Saver(),可以保存或回复模型,主要用于暂停训练和恢复训练,以及训练好的模型直接加载使用。

关键字:mnist、python、格式、转换、显示
时间:2017年5月

前言

MNIST是一个手写数字样本库,它主要用于图像识别的研究。它的格式方便于程序使用,但不能直接显示,如果需要显示必须进行转换。
OpenCV是使用最多的图像处理库,它实现了矩阵和图片之间的无缝转换。

MNIST数据格式

图片

图片10万张28×28图片->10万条长度为784的一维数组->长度为78400000的一维数组->按顺序写入数据文件

标签编码

0 => [1,0,0,0,0,0,0,0,0,0]
1 => [0,1,0,0,0,0,0,0,0,0]
2 => [0,0,1,0,0,0,0,0,0,0]
3 => [0,0,0,1,0,0,0,0,0,0]
4 => [0,0,0,0,1,0,0,0,0,0]
5 => [0,0,0,0,0,1,0,0,0,0]
6 => [0,0,0,0,0,0,1,0,0,0]
7 => [0,0,0,0,0,0,0,1,0,0]
8 => [0,0,0,0,0,0,0,0,1,0]
9 => [0,0,0,0,0,0,0,0,0,1]
注:这种编码格式,通俗的英文叫法是“one hot”。

代码

import cv2
import numpy as np
from matplotlib import pyplot as plt
from tensorflow.examples.turorials.mnist import input_data

convert = [[0],[1],[2],[3],[4],[5],[6],[7],[8],[9]] # 标签编码还原矩阵

mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
for i in range(10):                                # 取10张图片数据
    batch_xs, batch_ys = mnist.train.next_batch(1) # 从训练集中取1条数据
    img = np.reshape(batch_xs, [28,28])            # 把1维数据还原成2维28x28的图片格式
    if i==0:
        img2 = img.copy()                          # 用第1张图来初始化img2变量
    else:
        img2 = np.column_stack([img2,img])         # 矩阵水平拼接,相当于图片水平拼接
    print np.dot(batch_ys, convert)                # 通过矩阵乘法把编码的标签还原成数字

img2 = cv2.cvtColor(img2, cv2.COLOR_GRAY2BGR)      # 转换成灰度图片
plt.imshow(img2)
plt.show()

关键字:线性回归、股票、指标、股价、相关性
时间:2017年3月

目录

前言
数据格式
代码
结果

前言

本文主要是讲述线性回归分析相关性的方法。指标数据使用的是16年第三季度的财报数据(部分股票还未公布16年全年财报数据),股价使用的是17年3月29日数据。

数据格式

eps,navps,afps,udpps,ocfps,close
0.015,3.196,1.9056,0.3219,-0.0276,10.8
-0.148,1.8565,2.1732,-1.3452,-0.1338,9.22
1.16,10.6478,2.5714,6.4652,2.3885,52.55
...

注:eps,每股收益。navps,每股净资产。afps,每股公积金。udpps,每股未分配利润。ocfps,每股经营现金流。close,最新收盘价。

代码

import pandas as pd
from sklearn import linear_model

X_train = []
y_train = []

data = pd.read_csv('~/tmp/170329.csv', header=0)
for eps, navps, afps, udpps, ocfps, price in zip(data['eps'],data['navps'],data['afps'],data['udpps'],data['ocfps'],data['close']):
    X_train.append([float(eps),float(navps),float(afps),float(udpps),float(ocfps)])
    y_train.append(float(price))

#print X_train

lr = linear_model.LinearRegression()
lr.fit(X_train,y_train)

formula = 'price = '\
          + str(lr.coef_[0]) + ' * eps + '\
          + str(lr.coef_[1]) + ' * navps + ' \
          + str(lr.coef_[2]) + ' * afps + ' \
          + str(lr.coef_[3]) + ' * udpps + ' \
          + str(lr.coef_[4]) + ' * ocfps + ' \
          + str(lr.intercept_)
print formula
print 'R^2 = ',lr.score(X_train,y_train)

结论

输出结果

price = 22.180397822 * eps + -4.84933539669 * navps + 6.92859281574 * afps + 6.13493457791 * udpps + 0.0891737524391 * ocfps + 14.2736899403
R^2 =  0.475642112179

结论
股价与每股收益相关性最大,成正相关。
R^2不到0.5,回归效果很不理想。

关键字:线性回归、python、sklearn、linear、regression
时间:2017年3月

目录

前言
数据
代码

前言

以沪深股市每股收益与股价为案例,通过线性回归分析来预测每股收益合理的股价。

数据

eps.csv

eps,price
1.09,9.12
0.748,21.27
0.175,38.28
0.126,6.42
0.0848,8.5
0.0367,8.55
0.098,9.52
0.0268,6.9
-0.0121,16.19
0.34,11.26
-0.0869,18.19
-0.0184,4.48
0.0038,10.82
0.1785,10.45
-0.061,15.96
0.0159,23.17
0.2063,9.63
0.663,20.99
0.06,29.36
0.0882,50.07
0.2469,14.52
0.3375,6.97
1.993,74.7
0.4,8.61
0.04,8.28
0.1091,7.88
0.4231,8.27
-0.11,12.21
0.4804,40.25
-0.0898,16.27
-0.0393,12.65
-0.1,13.65
0.3593,9.13
0.6498,51.49
0.15,15.07
0.07,12.59
0.054,10.17
0.7337,11.7
0.07,11.23
0.1261,11.29
0.373,26.44
0.69,17.51
0.39,36.58
0.0203,10.9
-0.031,7.82
0.3555,7.29
0.397,24.13
0.1455,6.33
0.1388,7.74
0.1996,8.86
0.1849,9.27
0.2,16.38
0.1251,12.07
0.1259,3.63
2.159,29.1
0.2552,23.78
0.3198,17.15
-0.1,4.83
-0.046,11.9
0.0242,10.87
0.19,6.27
2,33.95
0.38,11.32
0.2426,17.88
-0.336,14.5
0.27,11.1
0.21,31.72
0.3237,10.28
0.3216,16.8
-1.04,11.4
0.2876,24.07
0.2,11.23
0.0185,10.7
0.2958,9.04
1.44,40.69
0.1529,8.42
0.0258,4.11
0.2253,8.78
0.02,6.82
1.8745,64.18
0.024,4.09
0.0811,8.62
-0.12,6.8
0.43,7.34
0.3007,12.8
0.74,12.2
0.2215,8.4
1.29,22.66
-0.1874,16.56
-0.0947,33.75
-0.0507,17.37
-0.21,11.08
0.007,10.52
0.1064,7.37
-0.0406,7.69
0.0296,10.76
-0.07,6.54
1.57,56.03
0.0129,9.93
0.0064,5.25
0.0101,8.11
0.045,16.9
-0.0032,8.08
0.2164,7.24
0.04,11.33
0.108,15.46
0.0669,18.9
0.0056,9.16
0.13,10.86
0.23,11.31
0.6307,11.4
0.0867,18.05
0.023,11.1
0.1397,15.19
0.5252,11.65
0.49,9.9
2.27,86.14
0.281,5.45
0.4413,6.78
0.2202,10.65
0.4316,6.9
0.43,19.98
0.049,6.69
0.375,13.27
0.12,9.94
1.27,28.38
0.15,11.13
0.0527,3.87
0.0063,11.85
0.1344,21.11
-0.0458,6.57
0.271,12.29
0.1183,16.08
0.1134,6.28
0.0094,8.53
0.124,12.92
0.0107,32.3
1.074,41
0.1,9.02
0.0794,7.93
0.1271,6.04
0.0383,8.67
-0.1603,17.77
1.3,23.1
0.408,18.15
-0.0268,8.02
0.014,19.3
0.66,15.51
0.009,6.26
0.0552,20.15
0.3387,14.37
0.011,6.37
0.015,10.63
1.16,52
0.25,5.84
0.12,8.23
0.917,9.48
0.4244,8.35
0.26,16.66
0.1643,20.73
0.0281,11.49
0.125,10.19
-0.45,7.95
0.4252,18.55
0.0071,14.69
0.036,10.19
-0.1249,13.74
-0.0173,5.03
-0.72,20.57
0.2528,12.43
0.08,7.75
-0.0446,9.06
1.4472,30.45
0.766,22.74
0.098,13.93
-0.1414,2.52
0.01,3.17
0.12,4.92
0.0031,8.77
-0.0957,11.45
0.136,26.6
0.12,10.63
0.065,8.01
0.027,13.5
0.26,22.8
0.22,6.88
1.87,30.8
0.0483,5.94
-0.24,9.17
0.2144,5.69
0.0351,14.43
-0.062,6.04
2.48,115.51
0.2422,19
0.03,14.92
0.37,14.9
0.6,23.27
0.1218,3.72
-0.27,21.45
...

代码

import matplotlib.pyplot as plt
import pandas as pd
from sklearn import linear_model

X_train = []
y_train = []

data = pd.read_csv('eps.csv', header=0)
for eps, price in zip(data['eps'],data['price']):
    X_train.append([float(eps)])
    y_train.append(float(price))

lr = linear_model.LinearRegression()
lr.fit(X_train,y_train)

formula = 'y = ' + str(lr.coef_[0]) + ' * x + ' + str(lr.intercept_)
print formula

plt.scatter(X_train,y_train,color='blue')
plt.plot(X_train,lr.predict(X_train),color='red')
plt.text(-2.5,140,formula)
plt.show()