pytorch_神经网络构建(数学原理),篇2

本文介绍了神经网络的深层结构、多分类问题、反向传播算法以及一系列优化算法,如动量算法、Adagrad、RMSProp和Adam等。通过MNIST手写识别案例展示了多分类网络的训练过程,并探讨了优化算法如何通过链式法则更新参数,以及这些算法在训练过程中如何影响损失函数和准确率。最后,比较了几种优化算法的性能表现。
摘要由CSDN通过智能技术生成

深层神经网络

分类基础理论:
交叉熵是信息论中用来衡量两个分布相似性的一种量化方式
之前讲述二分类的loss函数时我们使用公式-(y*log(y_)+(1-y)*log(1-y_)进行误差计算
y表示真实值,y_表示预测值

def binary_loss(y_pred, y):
    logits = (y * y_pred.clamp(1e-12).log() + (1 - y) * (1 - y_pred).clamp(1e-12).log()).mean()
    return -logits

交叉熵的一般公式为:
在这里插入图片描述
那么二分类时公式可以写作:
其中sigmoid(x)=y_
在这里插入图片描述
这就是二分类的loss函数,那么如果我们要进行多分类,比如三分类,十分类,参照此交叉熵方式改进是可行的
而pytorch已经为我们预设了此函数,它将根据我们神经网络输出的分类个数自动进行公式计算
其中每个分类的概率为:
对于输出层的每个输出x1,x2,x3,每个求指数e^x1等等,然后求和,再算出每个值大小占比,即其概率
在这里插入图片描述

多分类深层网络

我们可以举个例子,比如mnist手写识别案例,它有十个分类,据此实践交叉熵公式
其中网络的训练是类似的,不同的是loss函数

train_set=mnist.MNIST("./data",train=True,download=True)
test_set=mnist.MNIST('./data',train=False,download=True)
a_data, a_label = train_set[0]

从网络上下载mnist手写数据,然后将其类型转化为tensor类型
查看数据
在这里插入图片描述
每张图片28*28,可以看做一组784列的01数据,数据范围为0~255
将所有数据拉平并且标准化,方便输入

from torch.utils.data import DataLoader
def data_tf(x):
    x = np.array(x, dtype='float32') / 255
    x = (x - 0.5) / 0.5 # 标准化
    x = x.reshape((-1,)) # 拉平
    x = torch.from_numpy(x)
    return x
train_set = mnist.MNIST('./data', train=True, transform=data_tf, download=True) # 重新载入数据集,申明定义的数据变换
test_set = mnist.MNIST('./data', train=False, transform=data_tf, download=True)

当数据集巨大,不能一次导入内存时,往往采取划分迭代方式批次录入,使用数据迭代器

from torch.utils.data import DataLoader
# 数据迭代器
train_data = DataLoader(train_set, batch_size=64, shuffle=True)
test_data = DataLoader(test_set, batch_size=128, shuffle=False)
a, a_label = next(iter(train_data))

数据迭代器是一个对象,从其中取出数据需要使用迭代器,他没有下标
数据已经准备完毕
然后定义神经网络结构和参数,定义损失函数和wb参数优化器,然后进行迭代训练wb
pytroch已经预设了交叉熵函数

mnNet=nn.Sequential(
    nn.Linear(784,256),
    nn.ReLU(),
    nn.Linear(256, 128),
    nn.ReLU(),
    nn.Linear(128, 64),
    nn.ReLU(),
    nn.Linear(64, 20),
    nn.ReLU(),
    nn.Linear(20, 10)
    
)
losser=nn.CrossEntropyLoss()
optimizer=torch.optim.SGD(mnNet.parameters(),1e-1)

开始迭代训练,其中我们需要统计每个批次的准确率和loss值,方便我们直观的看到准确率和loss的变化
我们需要求出一次迭代数据集训练中所有批次的准确率之和,然后比批次的迭代次数
就得到了每个批次的平均准确率,来作为这一次训练迭代的准确率结果
不实时展示每个批次的准确率和loss是因为单个批次准确率波动范围大,不能准确显示一次迭代训练的效果
接下来我们对数据集进行20次迭代训练

训练和测试不同的地方在于,训练集不需要更新wb参数,也不需要loss进行反向传播

losses=[]
acces=[]
eval_losses=[]
eval_acces=[]
for e in range(20):
    train_loss=0
    train_acc=0
    mnNet.train()
    for im,label in train_data:
        im=Variable(im)
        label=Variable(label)
        out=mnNet(im)
        loss=losser(out,label)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        train_loss+=loss.item()
        _,pred=out.max(1)
        num_currect=(pred==label).sum()
        acc=num_currect/im.shape[0]
        train_acc+=acc
    losses.append(train_loss/len(train_data))
    acces.append(train_acc/len(train_data))
    eval_loss=0
    eva
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值