TensorFlow学习笔记【二】 手写数字识别入门

TensorFlow学习笔记【二】 手写数字识别入门

〇、

文章总是改来改去,其实也是各个地方找到,看到的东西拿过来拼拼凑凑,主要还是给自己看的吧。主要结构是酱的:
第一部分 主要的算法解读;
第二部分 Python 代码的实现;
第三部分 对代码和细节的解读。

一、模型构建

softmax 函数(归一化指数函数),能将任意一个含有任意实数的 K 维向量 z 投射到另一个 K 维实向量 σ(z) 中,使得每一个元素的范围都在 (0, 1) 之间,并且所有元素的和为1。

σ(z)j=ezjKk=1ezk,j=1,,K(12) (12) σ ( z ) j = e z j ∑ k = 1 K e z k , j = 1 , … , K

MNIST中的每一张 28*28 的图片都表示一个手写数字,从0到9,为了得到给定图片代表每个数字的概率,我们使用 softmax 回归(softmax regression),为每个不同的对象(数字)分配概率。

对图片像素值进行加权求和。如果这个像素具有很强的证据说明这张图片不属于该类,那么相应的权值为负数,相反如果这个像素拥有有利的证据支持这张图片属于这个类,那么权值是正数。

TensorFlow学习笔记【二】 手写数字识别入门_第1张图片

图为,对每个数字图片上的像素点进行学习,得到每个像素对于特定数字类的权值。红色代表负数权值,蓝色代表正数权值。

此外,还要添加一个偏置量(bias),b,来排除输入数据中的干扰量。

evidencei=jWi,jxj+bi(13) (13) e v i d e n c e i = ∑ j W i , j x j + b i

然后用 softmax 函数将其转换为概率:

y=softmax(evidence)(14) (14) y = s o f t m a x ( e v i d e n c e )

二、Python实现

作为数据集数据文件本身没有使用标准的图片格式存储,因此需要使用输入数据的代码(在这里下载)来手动解压。

训练和验证的 python 代码如下(TensorFlow中文社区)

import input_data
import tensorflow as tf

# 自动下载 MNIST 数据集, 表示为 one_hot 向量
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

# 任意数量的展平的图像张量作为输入值
x = tf.placeholder("float", [None, 784])

# weight 和 bias 的 Variable 对象,用来存储模型参数,在每轮迭代时被更新,初始化为 0,
# (在这个简单方法中初始值不太重要)
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))

# 建立 softmax 回归模型
y = tf.nn.softmax(tf.matmul(x,W) + b)

# 计算交叉熵的输入值
y_ = tf.placeholder("float", [None, 10])

# 计算交叉熵
cross_entropy = -tf.reduce_sum(y_*tf.log(y))

# 反向传播算法 (backpropagation algorithm)
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)


# 执行运行计算
init = tf.global_variables_initializer()

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

for i in range(1000):
    batch_xs, batch_ys = mnist.train.next_batch(100)
    sess.run(train_step, feed_dict={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, "float"))

print(sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}))

三、一点解读

从公式到 Tensorflow 的“翻译”:
loss function,Loss 越小表示模型行的分类结果与真实值的偏差越小,即模型越精准。这里使用了交叉熵 Cross-entropy 作为 loss function,其公式如下。

Hy(y)=iyilog(yi)(15) (15) H y ′ ( y ) = − ∑ i y i ′ l o g ( y i )

这里的 y’ 是输入的真实 label,在代码中定义一个 placeholder,label 是用 one-hot 编码的,因此我们将检查输入数据的格式是否为“[None, 10]”,10 维向量。求和为 tf.reduce_sum,“翻译”成 Python 代码为:

# 计算交叉熵
cross_entropy = -tf.reduce_sum(y_*tf.log(y))

定义优化算法,使用随机梯度下降 SGD(Stochastic Gradient Descent),此时,前面构建的公式自动构成了计算图,tensorflow根据此计算图进行自动求导,通过反向传播算法(back propagation)进行训练,通过减少 loss 来更新模型的参数。

# 反向传播算法 (backpropagation algorithm)
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

最后迭代的执行训练操作 train_step。此处用从训练集抽取的 100 条样本构成 batch,feed 给前面预留的输入 placeholder,进行训练。此方法可以减少计算量,避免不容易跳出局部最优的现象,收敛速度也比全样本训练要快很多。

batch_xs, batch_ys = mnist.train.next_batch(100)
sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})

完成训练,对模型的准确率进行验证,使用 tf.argmax() ,它的第一个参数是 tensor,第二个参数是 axis,即“寻找的方向”,一维向量则为0。此函数在这里的作用是寻找 tensor 中最大值的索引号,对于 y 来说,就是预测的结果中可能性最大的那个分类结果。然后用 tf.equal 来判断是否和正确的类型相同。以此来评价算法的准确率。
argmax(f(x)) 函数的含义是使 f(x) 取得最大值的自变量 x 的值。

回忆一下上面的步骤,利用 Tensorflow 实现机器学习算法的一般步骤如下:
(1)定义算法公式;
(2)定义 loss function,选择优化器,指定优化器来优化 loss;
(3)迭代地对数据进行训练;
(4)在测试集或验证集上对准确率进行评价。

你可能感兴趣的:(笔记)