AI智能
改变未来

飞桨百度架构师手把手带你零基础实践深度学习——手写数字识别损失函数的优化

我们上一节学的是将网络结构进行优化,接下来我们看是否能将损失函数进行优化
均方误差是我们在房价预测模型中使用的损失函数,显然适用于线性回归模型,实数输出与标签相减,而在分类问题中是不太合适的。
我们这个模型的期望输出是一个标签的概率。

SoftMax函数

所有输出和为1.
网络结构变化:单一输出(实数值)->每个分类一个输出(概率)
softmax(xi)=exi∑j=0Nejx,i=0,…,C−1softmax(x_i) = \\frac {e^{x_i}}{\\sum_{j=0}^N{e^x_j}}, i=0, …, C-1softmax(xi​)=∑j=0N​ejx​exi​​,i=0,…,C−1

为什么使用softmax折算概率?
若为二分类问题(两个标签),等价于单一输出接入sigmoid函数。z为1的概率为0.6,z为0的概率为0.4
在这种情况下,只有一层的模型为S(wTxi)S(w^{T}x_i)S(wTxi​),SSS为Sigmoid函数。模型预测为1的概率为S(wTxi)S(w^{T}x_i)S(wTxi​),模型预测为0的概率为1−S(wTxi)1-S(w^{T}x_i)1−S(wTxi​)。
提升边界区域的分辨率。

交叉熵

在模型输出为分类标签的概率时,直接以标签和概率做比较也不够合理,人们更习惯使用交叉熵误差作为分类问题的损失衡量。
最大似然思想
贝叶斯公式

P(h∣D)∝P(h)⋅P(D∣h)P(h|D) ∝ P(h) \\cdot P(D|h)P(h∣D)∝P(h)⋅P(D∣h)
D为数据,h为假设
若无假设偏好,去掉P(h)
依据贝叶斯公式,某二分类模型“生成”nnn个训练样本的概率:

P(x1)⋅S(wTx1)⋅P(x2)⋅(1−S(wTx2))⋅…⋅P(xn)⋅S(wTxn)P(x_1)\\cdot S(w^{T}x_1)\\cdot P(x_2)\\cdot(1-S(w^{T}x_2))\\cdot … \\cdot P(x_n)\\cdot S(w^{T}x_n)P(x1​)⋅S(wTx1​)⋅P(x2​)⋅(1−S(wTx2​))⋅…⋅P(xn​)⋅S(wTxn​)

对于二分类问题,模型为S(wTxi)S(w^{T}x_i)S(wTxi​),SSS为Sigmoid函数。当yiy_iyi​=1,概率为S(wTxi)S(w^{T}x_i)S(wTxi​);当yiy_iyi​=0,概率为1−S(wTxi)1-S(w^{T}x_i)1−S(wTxi​)。

经过公式推导,使得上述概率最大等价于最小化交叉熵,得到交叉熵的损失函数。交叉熵的公式如下:

L=−[∑k=1ntklog⁡yk+(1−tk)log⁡(1−yk)] L = -[\\sum_{k=1}^{n} t_k\\log y_k +(1- t_k)\\log(1-y_k)] L=−[k=1∑n​tk​logyk​+(1−tk​)log(1−yk​)]

其中,log⁡\\loglog表示以eee为底数的自然对数。yky_kyk​代表模型输出,tkt_ktk​代表各个标签。tkt_ktk​中只有正确解的标签为1,其余均为0(one-hot表示)。

因此,交叉熵只计算对应着“正确解”标签的输出的自然对数。比如,假设正确标签的索引是“2”,与之对应的神经网络的输出是0.6,则交叉熵误差是−log⁡0.6=0.51−\\log 0.6 = 0.51−log0.6=0.51;若“2”对应的输出是0.1,则交叉熵误差为−log⁡0.1=2.30−\\log 0.1 = 2.30−log0.1=2.30。由此可见,交叉熵误差的值是由正确标签所对应的输出结果决定的。

交叉熵的实现

更改label类型

label=np.reshape(labels[i],[1]).astype(\'int64\')

输出层修改为10个输出(标签),使用softmax函数处理

self.fc=Linear(input_dim=980,output_dim=10,act=\'softmax\')

损失函数由均方误差改为交叉熵

loss=fluid.layers.cross_entropy(predict,label)

**此时,loss值是离散的,无法进行训练,只能评价衡量模型好坏 **
由于我们修改了模型的输出格式,因此使用模型做预测时的代码也需要做相应的调整。从模型输出10个标签的概率中选择最大的,将其标签编号输出。
检验模型是否合理。

# 读取一张本地的样例图片,转变成模型输入的格式def load_image(img_path):# 从img_path中读取图像,并转为灰度图im = Image.open(img_path).convert(\'L\')im.show()im = im.resize((28, 28), Image.ANTIALIAS)im = np.array(im).reshape(1, 1, 28, 28).astype(np.float32)# 图像归一化im = 1.0 - im / 255.return im# 定义预测过程with fluid.dygraph.guard():model = MNIST()params_file_path = \'mnist\'img_path = \'./work/example_0.jpg\'# 加载模型参数model_dict, _ = fluid.load_dygraph(\"mnist\")model.load_dict(model_dict)model.eval()tensor_img = load_image(img_path)#模型反馈10个分类标签的对应概率results = model(fluid.dygraph.to_variable(tensor_img))#取概率最大的标签作为预测输出lab = np.argsort(results.numpy())  #概率排序print(\"本次预测的数字是: \", lab[0][-1])
赞(0) 打赏
未经允许不得转载:爱站程序员基地 » 飞桨百度架构师手把手带你零基础实践深度学习——手写数字识别损失函数的优化