完整演示代码请见本书GitHub上的15-1.py。
1.数据清洗与特征提取
我们依然使用MNIST数据集合,使用TensorFlow的softmax回归算法,MNIST详细介绍请参考第3章中的介绍。唯一不同的地方是我们使用one-hot编码处理标记数据,原有的标记数据使用长度为1的向量标记结果,取值范围为0~9,one-hot编码又称一位有效编码,其方法是使用N位状态寄存器来对N个状态进行编码,每个状态都有其独立的寄存器位,并且在任意时刻,其中只有一位有效。使用one-hot编码后,使用一个长度为10的向量标记结果,转换的函数实现为:
def get_one_hot(x,size=10): v=[] for x1 in x: x2=[0]*size x2[(x1-1)]=1 v.append(x2) return v
我们使用离线版的MNIST文件,下载链接为:
http://www.iro.umontreal.ca/~lisa/deep/data/mnist/mnist.pkl.gz
文件读取方式为:
import pickle import gzip def load_data(): with gzip.open('./mnist.pkl.gz') as fp: training_data, valid_data, test_data = pickle.load(fp) return training_data, valid_data, test_data
其中各个返回集合分别为:
·training_data,训练数据集合;
·valid_data,校验数据集合;
·test_data,测试数据集合。
加载数据,并针对标记数据转换成one-hot编码。
training_data, valid_data, test_dat=load_data() x_training_data,y_training_data=training_data x1,y1=test_dat y_training_data=get_one_hot(y_training_data) y1=get_one_hot(y1)
2.训练
我们使用经典的softmax回归算法来处理,如图15-9所示。
softmax算法的数学化的表现为:y=softmax(Wx+b)
使用TensorFlow的计算模型展现处理过程,如图15-10所示。
图15-9 TensorFlow官网对softmax算法的图解
图15-10 TensorFlow计算模型示例图
使用placeholder函数设置占位符,用于定义整个数据流的输入和输出。在这个例子中x和_y都是这种情况,其中,x对应整个系统输入,是一个维度为784的向量集合,且长度不限制;_y是整个系统的输出,对应一个维度为10的向量集合,两者的特征数据类型都是浮点型:
x = tf.placeholder("float", [None, 784]) y_ = tf.placeholder("float", [None,10])
定义整个系统中的变量,包括W、b,初始化均为0。整个系统的操作为y=softmax(Wx+b),x的维度为784,所以W为一个784乘以10的数组,b是一个维度为10的向量:
W = tf.Variable(tf.zeros([784,10])) b = tf.Variable(tf.zeros([10]))
定义整个系统的操作函数:
y = tf.nn.softmax(tf.matmul(x,W) + b)
定义衰减函数,这里的衰减函数使用交叉熵来衡量,通过梯度下降算法以0.01的学习速率最小化交叉熵:
cross_entropy = -tf.reduce_sum(y_*tf.log(y)) train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
初始化全部变量并定义会话,在TensorFlow中每个会话都是独立的,相互不干扰。
init = tf.initialize_all_variables() sess = tf.Session() sess.run(init)
在理想情况下,我们希望用所有的数据来进行每一步的训练,因为这能给我们更好的训练结果,但显然这需要很大的计算开销。所以,每一次训练我们可以使用不同的数据子集,这样做既可以减少计算开销,又可以最大化地学习到数据集的总体特性。我们定义每次训练的数据子集的个数:
batch_size=100
每次我们都顺序取出100个数据用于训练,便于梯度下降算法快速收敛,整个训练次数取决于整个数据集合的长度以及每次训练的数据个数:
for i in range(int(len(x_training_data)/batch_size)): batch_xs=x_training_data[(i*batch_size):((i+1)*batch_size)] batch_ys=y_training_data[(i*batch_size):((i+1)*batch_size)] sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})
3.验证
TensorFlow的数据验证非常简单,使用自带的API即可:
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) print(sess.run(accuracy, feed_dict={x: x1, y_: y1}))
运行结果如下,准确率约为90%:
can't determine number of CPU cores: assuming 4 I tensorflow/core/common_runtime/local_device.cc:25] Local device intra op parallelism threads: 4 can't determine number of CPU cores: assuming 4 I tensorflow/core/common_runtime/local_session.cc:45] Local session inter op parallelism threads: 4 0.9097