〇、
文章总是改来改去,其实也是各个地方找到,看到的东西拿过来拼拼凑凑,主要还是给自己看的吧。
第一部分 主要的算法解读
第二部分 Python 代码的实现
第三部分 对代码和细节的解读
一、模型构建
softmax 函数(归一化指数函数),能将任意一个含有任意实数的 K 维向量 z 投射到另一个 K 维实向量 σ(z) 中,使得每一个元素的范围都在 (0, 1) 之间,并且所有元素的和为1。
$$
\sigma(\mathbf{z})j = \frac{e^{z_j}}{\sum{k=1}^{K}e^{z_k}},\quad j=1,\dots,K
$$
MNIST中的每一张 28*28 的图片都表示一个手写数字,从0到9,为了得到给定图片代表每个数字的概率,我们使用 softmax 回归(softmax regression),为每个不同的对象(数字)分配概率。
对图片像素值进行加权求和。如果这个像素具有很强的证据说明这张图片不属于该类,那么相应的权值为负数,相反如果这个像素拥有有利的证据支持这张图片属于这个类,那么权值是正数。
图为,对每个数字图片上的像素点进行学习,得到每个像素对于特定数字类的权值。红色代表负数权值,蓝色代表正数权值。
此外,还要添加一个偏置量(bias),b,来排除输入数据中的干扰量。
$$
evidence_i = \sum_j \mathbf{W}_{i,j}x_j+b_i
$$
然后用 softmax 函数将其转换为概率:
$$
y = softmax(evidence)
$$
二、Python实现
作为数据集数据文件本身没有使用标准的图片格式存储,因此需要使用输入数据的代码(在这里下载)来手动解压。
训练和验证的 python 代码如下(TensorFlow中文社区)
1 | import input_data |
三、一点解读
从公式到 Tensorflow 的“翻译”:
loss function,Loss 越小表示模型行的分类结果与真实值的偏差越小,即模型越精准。这里使用了交叉熵 Cross-entropy 作为 loss function,其公式如下。
\begin{equation}
H_{y’}(y)=- \sum_iy’_i log(y_i)
\end{equation}
这里的 y’ 是输入的真实 label,在代码中定义一个 placeholder,label 是用 one-hot 编码的,因此我们将检查输入数据的格式是否为“[None, 10]”,10 维向量。求和为 tf.reduce_sum,“翻译”成 Python 代码为:
1 | # 计算交叉熵 |
定义优化算法,使用随机梯度下降 SGD(Stochastic Gradient Descent),此时,前面构建的公式自动构成了计算图,tensorflow根据此计算图进行自动求导,通过反向传播算法(back propagation)进行训练,通过减少 loss 来更新模型的参数。
1 | # 反向传播算法 (backpropagation algorithm) |
最后迭代的执行训练操作 train_step。此处用从训练集抽取的 100 条样本构成 batch,feed 给前面预留的输入 placeholder,进行训练。此方法可以减少计算量,避免不容易跳出局部最优的现象,收敛速度也比全样本训练要快很多。
1 | batch_xs, batch_ys = mnist.train.next_batch(100) |
完成训练,对模型的准确率进行验证,使用 tf.argmax() ,它的第一个参数是 tensor,第二个参数是 axis,即“寻找的方向”,一维向量则为0。此函数在这里的作用是寻找 tensor 中最大值的索引号,对于 y 来说,就是预测的结果中可能性最大的那个分类结果。然后用 tf.equal 来判断是否和正确的类型相同。以此来评价算法的准确率。
(argmax(f(x)) 函数的含义是使 f(x) 取得最大值的自变量 x 的值。)
回忆一下上面的步骤,利用 Tensorflow 实现机器学习算法的一般步骤如下:
(1)定义算法公式;
(2)定义 loss function,选择优化器,指定优化器来优化 loss;
(3)迭代地对数据进行训练;
(4)在测试集或验证集上对准确率进行评价。