3.2Tensorflow实现Softmax Regression识别手写数字
首先记录一下除了书籍以外参考的博客:
- tensorflow入门-mnist手写数字识别(一,网络搭建)
- tensorflow入门-mnist手写数字识别(二,模型保存加载)
- tensorflow入门-mnist手写数字识别(三,可视化训练)
- tensorflow入门-mnist手写数字识别(四,h5py制作训练集)
先附上代码然后解析,代码已在Tensorflow-gpu1.9.0完成测试
#%%
# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
print(mnist.train.images.shape, mnist.train.labels.shape)
print(mnist.test.images.shape, mnist.test.labels.shape)
print(mnist.validation.images.shape, mnist.validation.labels.shape)
import tensorflow as tf
sess = tf.InteractiveSession()
x = tf.placeholder(tf.float32, [None, 784])
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))
y = tf.nn.softmax(tf.matmul(x, W) + b)
y_ = tf.placeholder(tf.float32, [None, 10])
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1]))
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
tf.global_variables_initializer().run()
for i in range(1000):
batch_xs, batch_ys = mnist.train.next_batch(100)
train_step.run({x: batch_xs, y_: batch_ys})
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print(accuracy.eval({x: mnist.test.images, y_: mnist.test.labels}))
前面的文章已经对数据集mnist进行了介绍:
每个图片都是28*28的灰度图,随机排列,0-9一共10类,
Training set images: train-images-idx3-ubyte.gz (9.9 MB, 解压后 47 MB, 包含 60,000 个样本)
Training set labels: train-labels-idx1-ubyte.gz (29 KB, 解压后 60 KB, 包含 60,000 个标签)
Test set images: t10k-images-idx3-ubyte.gz (1.6 MB, 解压后 7.8 MB, 包含 10,000 个样本)
Test set labels: t10k-labels-idx1-ubyte.gz (5KB, 解压后 10 KB, 包含 10,000 个标签)
这是2018.10.10之前的最新数据,和书中略微有点不同
在之前的博客中,我们已经尝试了CNN的入门:
- LeNet-5 研习 1
- LeNet-5 研习 2
- LeNet-5 研习 3 (进行C语言实现LeNet的前向传播的解读)
- LeNet-5 研习 4 (进行C语言实现LeNet的后向传播的解读)
- 梯度下降优化方法(SGD,Adagrad,Adadelta,Adam,Adamax,Nadam)
在解析这个网络之前,让我们学习下,前面没有讲过的东西
1.Sigmoid
例子:将28*28的灰度图像归一化到[0,1]之间,并将其展开成1维,即28*28=784维特征,丢弃了二维结构方面的信息,把一张图片变成一个很长的一维向量。展开成一维向量时,顺序并不重要,只要每一张图片都是用同样的顺序进行展开的就可以。
在三层BP反向传播网络中,输出层经过Sigmoid函数,得到输出值为[0.75136079 , 0.772928465]
假设输入是28*28=784个神经元+1个偏置项,输出是10个神经元
那么我们最后经过Sigmoid函数得到的输出值
[0(0.75136507),1(0.772928465),2(0.32),3(0.11),4(0.01),5(0.04),6(0.14),7(0.75),8(0.21),9(0.31)]
的最大值,就是当前图像在既定权重下的输出结果
2.Softmax Regression(Softmax回归)
参考:https://www.zhihu.com/question/23765351
Softmax函数将多个神经元的输出,映射到(0,1)区间内,可以看成概率来理解,从而来进行多分类!
假设未经过Softmax的值[3,1,-3]
经过Softmax函数,将较大的值变得更大,较小的值变得更小,然后进行标准化(让所有类别输出得概率值和为1)
那么我们最后经过Softmax函数得到的输出值
[0(0.88),1(0.12),2(0),3(0.11),4(0.01),5(0.04),6(0.14),7(0.75),8(0.21),9(0.31)]
的最大值,就是当前图像在既定权重下的输出结果
3.Sigmoid和Softmax的对比
不同点还有两个函数在反向传播时的区别,softmax的反向传播暂时我还没弄清楚,先放博客,留下以后解析:
详解softmax函数以及相关求导过程
https://zhuanlan.zhihu.com/p/25723112
4.one-hot编码
最简单的方式理解
0-9的10个数字,10种类别,进行one-hot编码
0的label为[1,0,0,0,0,0,0,0,0,0]
1的label为[0,1,0,0,0,0,0,0,0,0]
2的label为[0,0,1,0,0,0,0,0,0,0]
3的label为[0,0,0,1,0,0,0,0,0,0]
。。。。
5.损失函数cross-entropy
以前上课的时候,老师教三层BP反向传播网络时,损失函数使用的是
这里采用的是cross-entropy
上图公式中,y是预测的概率分布,y*是真实概率分布(即Label的one-hot编码)
假设最后经过Softmax函数得到的输出值
[0(0.88),1(0.12),2(0),3(0.11),4(0.01),5(0.04),6(0.14),7(0.75),8(0.21),9(0.31)]
Label为
[1,0,0,0,0,0,0,0,0,0]
那么当前损失函数值为:
如果是以前的方式,即为:
6.损失函数优化器
神经网络中我们降低损失函数使用的是梯度下降法,而原始的梯度下降法有很多缺点,现在有很多改进优化,比如常见的SGD随机梯度下降法
这里我们使用的代码是:
GradientDescentOptimizer百度了下,tensorflow中,这个优化器相当于SGD
随机梯度下降,每次使用一小部分样本进行训练,对于用一小部分训练的我们称为:mini-batch
当前和书中有些不同的是,博客:
https://www.cnblogs.com/ooon/p/5485231.html
https://blog.csdn.net/xiaotao_1/article/details/81031633
是这样介绍的
第一种:批量梯度下降法(Batch Gradient Descent)
数据集是60000,每次进入网络一个,将第一个数据进入,然后反向传播,接着进入第二个,然后反向传播,接着进入第三个,然后反向传播,
最后,进入数据集最后一个,然后反向传播,此为一个训练时代,接着再将第一个数据进入,开启第二个训练时代
第二种:随机梯度下降法(Stochastic Gradient Descent)
60000中随机选择600个样本,
每次进入网络一个,将第一个数据进入,然后反向传播,接着进入第二个,然后反向传播,接着进入第三个,然后反向传播,
最后,进入数据集最后一个,然后反向传播,此为一个训练时代,接着再将第一个数据进入,开启第二个训练时代
或者?(这块没理解)
每次进入网络一个,将第一个数据进入,然后反向传播,接着还是上一次进入的样本,然后反向传播,一个样本训练完500时代后,第二个样本进入,然后反向传播,接着第二个也500时代
最后,数据集最后一个进入,然后反向传播,训练500时代
假设训练的是500时代,那么,第一种是60000*500=3*10^7,第二种是600*500=3*10^5或1*500*600=3*10^5
第三种:小批量梯度下降法(Mini-batch Gradient Descen)
60000中随机选择n(n=500,迭代次数)组600个样本,
第一次进入的是第一组的600个样本,这里与上面第一种第二种不同的是,是第一组的600个都进入,每一个都进行了计算
在对某一个权值进行更新的时候
小批量梯度下降法的梯度计算是
然后进行第一次反向传播,接着进入第二组的600个样本,然后第二次反向传播,接着进入第三组,然后反向传播,
最后,每组600个样本的选择,是数据集中随机生成,我们可以理解他把一组进行的一次反向传播,作为一个训练时代,接着再将第二组数据进入,开启第二个训练时代
假设训练的是500时代,那么,第一种是60000*500=3*10^8,第二种是6000*500=3*10^6,第三种是1(600次前向)*500
通过别的博客又了解一些区别:
深度学习优化函数详解(2)-- SGD 随机梯度下降
https://blog.csdn.net/tsyccnh/article/details/76064087
深度学习优化函数详解(3)-- mini-batch SGD 小批量随机梯度下降
上面的博客很有用,我又重新理解了一下:
参考博文:
https://www.cnblogs.com/lliuye/p/9451903.html
。。。。。
有机会再写
经过前面的介绍我们已经把该了解的都了解了,