ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

深度学习笔记020 LeNet

2022-02-07 23:31:08  阅读:249  来源: 互联网

标签:nn iter 笔记 train 020 LeNet device net d2l


LeNet卷积神经网络

所谓卷积Net,就是将空间信息不停地压缩,压缩,在压缩,最后将特征变得很小很小,通道数变得越来越多,最后甚至特征会变成1,通道数会变成上千,最后做全连接输出,这便是卷积神经网络的内核。

feature map:输出

LeNet:

 

 输入是一个32x32的图,第一层卷积,大概是用的3x3的核,所以输出的形状是28x28,多通道将输出改为6通道;随后将这6个通道分别做池化操作,池化将输入大小减半;随后又是一层5x5的卷积层,将输出结果变为16层的10x10的图;随后又是一层大小减半的池化;最后输入到三个全连接层,在这之前,将16通道的结果拉成一个向量,最后用Softmax得到一个概率。

总结:

  LeNet是早期的成功的神经网络;

  先用卷积层学习图片空间信息,然后用池化降低空间位置敏感度,最后用全连接层来转换到类别空间。

 

pytorch中view和reshape的区别:https://www.cnblogs.com/regain/p/14499449.html

 

用这个卷积神经网络跑了一下d2l里面那个fashion_mnist数据集,结果如下:

 

跑50次,可以达到90%:

 

 

 准确率达到了81%,loss降低到了0.475,准确度不是很高,在之前MLP中,精度也是80多,但是明显看到在MLP中有一定的过拟合,因为MLP的模型复杂度更大一些,所以过拟合现象比较明显,如下:

深度学习笔记008MultilayerPerceptron多层感知机AssertionError:https://www.cnblogs.com/loveandninenine/p/15810917.html

 

 

沐神:一般没有过拟合的模型,都是欠拟合了。

 

这个网络是神经网络中唯一一个能在CPU上跑的代码了……

因为这个网络是80年代的网络了,当年都是超级计算机跑的,要10w美金的那种计算机才能跑得动;但是现在,沐神只用了10秒钟就跑完了,而我在google平台上用GPU跑了1分钟左右;而在我可怜巴巴的thinkpad用CPU跑了5min,结果如下:

 

 所以,后面的学习基本用不到我的pycharm了……

 

Q&A:

1、通常输入的高宽减半的时候,通道数会翻倍,相当于把多个模式分散放入了其他的通道中。当然了,信息在本质上一直在损失。

2、LeNet中的6和16这个参数很奇特,没有理论依据。比如,改成5和15,模型变小了,所以更不该出现过拟合,但是,沐神跑了一下,过拟合了,模型大的时候没有过拟合,模型小了反而过拟合了,神用自己的实际行动证明了炼丹这种事情是没有理论依据的。

3、用Max只关心最大的信号量,在实际中max比avg更好用一些。

 

 

代码:

import torch
from torch import nn
from d2l import torch as d2l

class Reshape(torch.nn.Module):
    def forward(self,x):
        return x.view(-1,1,28,28)   #-1代表自适应,也就是样本数不变;通道数改为1,宽高为28

'''
view 函数只能用于 contiguous 后的 tensor 上,也就是只能用于内存中连续存储的 tensor。
如果对 tensor 调用过 transpose, permute 等操作的话会使该 tensor 在内存中变得不再连续,此时就不能再调用 view 函数。
因此,需要先使用 contiguous 来返回一个 contiguous copy。    
reshape 则不需要依赖目标 tensor 是否在内存中是连续的。
总结:reshape Yes!
'''


net = nn.Sequential(
    Reshape(),
    nn.Conv2d(1, 6, kernel_size=5, padding=2), #输入是1,输出是6,上下填了两个空,因为原始输入是32x32,当时在边上pad了两列两行.
    # 这里也因为不加padding的话,边边的像素信息就会减少
    nn.Sigmoid(),   # 为了非线性性,加入sigmoid
    nn.AvgPool2d(kernel_size=2, stride=2),  # 步长为2、大小为2x2的pool
    nn.Conv2d(6, 16, kernel_size=5),
    nn.Sigmoid(),
    nn.AvgPool2d(kernel_size=2, stride=2),
    nn.Flatten(),   # 将输出拉成一个向量,输入到后面的感知机中。第一维度批量保持住,后面的都拉成一个向量
    nn.Linear(16 * 5 * 5, 120), nn.Sigmoid(),
    nn.Linear(120, 84), nn.Sigmoid(),
    nn.Linear(84, 10))

X = torch.rand(size=(1, 1, 28, 28), dtype=torch.float32)
for layer in net:
    X = layer(X)
    print(layer.__class__.__name__,'output shape: \t',X.shape)




batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size=batch_size)

def evaluate_accuracy_gpu(net, data_iter, device=None):
    """使用GPU计算模型在数据集上的精度"""
    if isinstance(net, nn.Module):
        net.eval()  # 设置为评估模式
        if not device:
            device = next(iter(net.parameters())).device
    # 正确预测的数量,总预测的数量
    metric = d2l.Accumulator(2)
    with torch.no_grad():
        for X, y in data_iter:
            if isinstance(X, list):
                # BERT微调所需的(之后将介绍)
                X = [x.to(device) for x in X]
            else:
                X = X.to(device)
            y = y.to(device)
            metric.add(d2l.accuracy(net(X), y), y.numel())
    return metric[0] / metric[1]


def train_ch6(net, train_iter, test_iter, num_epochs, lr, device):
    """用GPU训练模型(在第六章定义)"""
    def init_weights(m):
        if type(m) == nn.Linear or type(m) == nn.Conv2d:
            nn.init.xavier_uniform_(m.weight)
    net.apply(init_weights)
    print('training on', device)
    net.to(device)
    optimizer = torch.optim.SGD(net.parameters(), lr=lr)
    loss = nn.CrossEntropyLoss()
    animator = d2l.Animator(xlabel='epoch', xlim=[1, num_epochs],
                            legend=['train loss', 'train acc', 'test acc'])
    timer, num_batches = d2l.Timer(), len(train_iter)
    for epoch in range(num_epochs):
        # 训练损失之和,训练准确率之和,样本数
        metric = d2l.Accumulator(3)
        net.train()
        for i, (X, y) in enumerate(train_iter):
            timer.start()
            optimizer.zero_grad()
            X, y = X.to(device), y.to(device)
            y_hat = net(X)
            l = loss(y_hat, y)
            l.backward()
            optimizer.step()
            with torch.no_grad():
                metric.add(l * X.shape[0], d2l.accuracy(y_hat, y), X.shape[0])
            timer.stop()
            train_l = metric[0] / metric[2]
            train_acc = metric[1] / metric[2]
            if (i + 1) % (num_batches // 5) == 0 or i == num_batches - 1:
                animator.add(epoch + (i + 1) / num_batches,
                             (train_l, train_acc, None))
        test_acc = evaluate_accuracy_gpu(net, test_iter)
        animator.add(epoch + 1, (None, None, test_acc))
    print(f'loss {train_l:.3f}, train acc {train_acc:.3f}, '
          f'test acc {test_acc:.3f}')
    print(f'{metric[2] * num_epochs / timer.sum():.1f} examples/sec '
          f'on {str(device)}')
    d2l.plt.show()

lr, num_epochs = 0.9, 10
train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())

 

标签:nn,iter,笔记,train,020,LeNet,device,net,d2l
来源: https://www.cnblogs.com/loveandninenine/p/15869815.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有