【机器学习】029_SoftMax模型Part.4_Softmax模型简洁实现

一、数值稳定性问题

Softmax模型的计算公式: \widehat{y}_{j} = \frac{exp(o_{j})}{\sum_{k}^{}exp(o_{k})}

        · 当 o_{k} 中有一些数值特别大,那么分母的值可能超出数据类型所容许的最大数字,出现上溢

        · 这使得分母或分子变为inf无穷大,最后得到的预测值会出现错误:0、inf、nan(非数字)

解决方法:

        · 在继续softmax运算之前,先从所有 o_{k} 中减去 max(o_{k})

重新得到的计算公式: \widehat{y_{j}} = \frac{exp(o_{j}-max(o_{k}))}{\sum_{k}^{}exp(o_{k}-max(o_{k}))}

        · 但这样做之后,又可能有一些 o_{j} - max(o_{k}) 具有较大的负值,接近0,出现下溢

        · 这些接近0的值可能四舍五入为0,使预测值为0,并且使 log(\widehat{y_{j}}) 的值为-inf

尽管我们这里要计算指数函数,但是在交叉熵损失又要取对数。因此,通过将softmax和交叉熵结合在一起取对数,就能避免这样的问题,使得数值更稳定。

具体地,交叉熵损失函数和Softmax结合已经预设在了pytorch库里,可直接调用

二、代码及注释解析

import torch
from torch import nn
from d2l import torch as d2l
# 设置训练批量数据,并获取到图像数据集的训练、测试数据迭代器
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)

# Python不会隐式地调整输入的形状
# 因此,在线性层前要定义一个展平层(flatten)来调整神经网络形状
# 展平层只是一个桥梁,没有可学习的参数,只是将图像多维数据展平为一维
# Sequential是用来存放所有神经网络层的容器,它按照顺序组合网络层,并确保输入按照定义的顺序通过每一层。
net = nn.Sequential(nn.Flatten(), nn.Linear(784, 10))

# 初始化权重
# 当神经网络层为线性层时,m.weight权重矩阵将被初始化为正态分布(均值默认0,标准差0.01)
# apply()函数将权重值应用到net网络模型的每一层
def init_weights(m):
    if type(m) == nn.Linear:
        nn.init.normal_(m.weight, std=0.01)

net.apply(init_weights)

# 拿到损失函数
# CrossEntropyLoss为交叉熵损失类,函数内部通常会包含 softmax 操作,计算Softmax模型并得到损失
# reduction参数指定计算损失时如何处理损失值,这里'none'表示不进行处理
# 即对每个样本都计算一次损失值,而不对整个批次的损失值进行平均或求和
# 例如,如果有一个包含三个样本的批次,每个样本的损失分别是2、3、4,那么:
#
# 在 reduction='mean' 的情况下,平均损失是 (2 + 3 + 4) / 3 = 3。
# 在 reduction='sum' 的情况下,总和损失是 2 + 3 + 4 = 9。
# 在 reduction='none' 的情况下,得到的是一个包含每个样本损失的向量 [2, 3, 4]。
# 这种降维的操作是为了在反向传播中计算梯度和更新模型参数时更方便。
loss = nn.CrossEntropyLoss(reduction='none')
# 优化算法,使用学习率0.1的小批量随机梯度下降作为优化算法
# net.parameters() 是指定需要优化的参数,返回神经网络 net 中所有可学习参数的迭代器
# 优化器将通过梯度下降来更新这些参数,使得损失函数达到最小值
trainer = torch.optim.SGD(net.parameters(), lr=0.1)

# 设置训练执行10次
num_epochs = 10
# train_ch3是上节实现的训练函数,这里不再详细呈现
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值