卷积神经网络之LeNet(二)

训练器的改进

上篇文章对LeNet-5网络结构做了简单分析,并用pytorch搭建了该网络,同时实现了数据迭代器和一个简单的训练器对MNIST数据集做了简单训练,观察了训练过程中损失函数以及正确率的的变化情况,达到了预期效果。
本文将对上篇文章中的训练器稍作改进,希望在训练过程中可以观察损失函数值,以及模型在训练集和测试集上的正确率来判断神经网络的学习是否正常进行,模型是否出现过拟合。

1.改进前

def train(net,train_iter,test_iter,num_epochs,lr):
    def init(n):
        if type(n)==nn.Conv2d or type(n)==nn.Linear:
            nn.init.normal(n.weight.data)
    net.apply(init)
    optimizer =torch.optim.SGD(net.parameters(),lr=lr)
    loss=nn.CrossEntropyLoss()
    train_loss_list=[]
    train_acc_list=[]
    for i in range(num_epochs):
        for j,(X,y) in enumerate(train_iter):
            optimizer.zero_grad()
            Y=net(X)
            l=loss(Y,y)
            l.backward()
            optimizer.step()
            train_loss_list.append(l.data*X.shape[0]/X.shape[0])
            train_acc_list.append(accuracy(Y,y)/X.shape[0])

该训练器将每一个batch的正确率和学习时的损失函数都保存了下来:

for j,(X,y) in enumerate(train_iter):
            optimizer.zero_grad()
            Y=net(X)
            l=loss(Y,y)
            l.backward()
            optimizer.step()
            train_loss_list.append(l.data*X.shape[0]/X.shape[0])
            train_acc_list.append(accuracy(Y,y)/X.shape[0])

MNIST数据集而言,训练集共有加60000张图片,假如一个batch为100张照片,那么一个epoch共有60000/100=600个batch,训练一个epoch打印600组数据,完全没有必要。

2.改进后

for i in range(num_epochs):
        train_loss=0.0
        train_acc=0.0
        for j,(X,y) in enumerate(train_iter):
            optimizer.zero_grad()
            Y=net(X)
            l=loss(Y,y)
            l.backward()
            optimizer.step()
            train_loss+=l.item()
            train_acc+=accuracy(Y,y)/X.shape[0]
            if j%200==199:
                a=train_loss/200.0
                b=train_acc/200.0
                train_loss_list.append(a)
                train_acc_list.append(b)
                train_loss=0.0
                train_acc=0.0

                with torch.no_grad():#在测试数据集上测试
                    for m,(X_test,y_test) in enumerate(train_iter):
                        output=net(X_test)
                        acc=accuracy(output,y_test)/X.shape[0]
                        test_acc_list.append(acc)


                print(f'train_loss:{a:.3f},train_acc:{b:.3f},test_acc:{acc:.3f}')

改进后的训练器每训练200个batch才会计算这200个batch的损失函数和准确率的平均值:

train_loss+=l.item()
train_acc+=accuracy(Y,y)/X.shape[0]
if j%200==199:
   a=train_loss/200.0
   b=train_acc/200.0
   train_loss_list.append(a)
   train_acc_list.append(b)

同时还会计算在测试集上的准确率,用来判断模型是否过拟合(一般认为训练集上的准确率高而测试集上的准确率过低是模型过拟合):

with torch.no_grad():#在测试数据集上测试
     for m,(X_test,y_test) in enumerate(train_iter):
         output=net(X_test)
         acc=accuracy(output,y_test)/X.shape[0]
         test_acc_list.append(acc)

3.总结

本文对上篇文章中的训练器稍作改进,改进后的训练器每训练200个batch才会计算这200个batch的损失函数和准确率的平均值,当然也可以根据自己的需求调整batch个数,同时还计算在测试集上的准确率,用来判断模型是否过拟合。
最后将训练过程的损失函数值以及模型在测试集和训练集上的正确率都记录到了相应的列表里,用来画图,以便更加直观地观察数据随训练过程的变化。

(------纯属个人见解,欢迎交流不同意见------)

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值