快速上手大模型:深度学习9(池化层、卷积神经网络1)

ModelEngine·创作计划征文活动 10w+人浏览 1.4k人参与

目录

1 作用

2 代码

2.1 最大/平均池化层

2.2 填充和步幅

2.3 多个通道

3 卷积神经网络算法

3.1 背景

3.2 LeNet

3.3 AlexNet

3.3.1 AlexNet架构

3.3.2 代码

3.4 VGG

3.4.1 VGG块

3.4.2 VGG架构

3.4.3 代码

3.5 NiN

3.5.1 特点

3.5.2 架构

3.5.3 代码

4 电脑配置查询

4.1 CPU

4.2 内存

4.3 GPU

4.4 所有硬件信息


注意:

本章开始需要进行模型复现,硬件设备尤其是GPU性能要求变高,如在复现时出现out of memory(OOM)报错可以采用降低模型参数、使用云服务器、使用CPU训练等方法,详情https://blog.youkuaiyun.com/weixin_45728280/article/details/155074452?sharetype=blogdetail&sharerId=155074452&sharerefer=PC&sharesource=weixin_45728280&spm=1011.2480.3001.8118,同时电脑配置查询方法详见本章4。

1 作用

(1)降采样,降低计算量、减少参数;

(2)扩大感受野,捕捉更大结构;

(3)平移不变性,稳定性强;

(4)特征筛选,去噪、保留关键特征。

       有最大池化、平均池化,最大池化最常用、保留了区域内最强特征;平均池化会使图像更加柔和。

2 代码

2.1 最大/平均池化层
import torch
from torch import nn
from d2l import torch as d2l

def pool2d(X, pool_size, mode='max'):
    p_h, p_w = pool_size
    Y = torch.zeros((X.shape[0] - p_h + 1, X.shape[1] - p_w + 1))
    for i in range(Y.shape[0]):
        for j in range(Y.shape[1]):
            if mode == 'max':
                Y[i, j] = X[i: i + p_h, j: j + p_w].max()
            elif mode == 'avg':
                Y[i, j] = X[i: i + p_h, j: j + p_w].mean()
    return Y

X = torch.tensor([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]])
pool2d(X, (2, 2))

pool2d(X, (2, 2), 'avg')

同卷积层类似。

2.2 填充和步幅
X = torch.arange(16, dtype=torch.float32).reshape((1, 1, 4, 4))
X

pool2d = nn.MaxPool2d(3)
pool2d(X)

pool2d = nn.MaxPool2d(3, padding=1, stride=2)
pool2d(X)

pool2d = nn.MaxPool2d((2, 3), stride=(2, 3), padding=(0, 1))
pool2d(X)

2.3 多个通道
X = torch.cat((X, X + 1), 1)
X

pool2d = nn.MaxPool2d(3, padding=1, stride=2)
pool2d(X)

3 卷积神经网络算法

其他卷积神经网络见:https://blog.youkuaiyun.com/weixin_45728280/article/details/155074452?sharetype=blogdetail&sharerId=155074452&sharerefer=PC&sharesource=weixin_45728280&spm=1011.2480.3001.8118

3.1 背景

(1)硬件发展

(2)数据集的扩充

3.2 LeNet

神经网络起始,有兴趣,详见:https://www.bilibili.com/video/BV1t44y1r7ct/?spm_id_from=333.1387.collection.video_card.click&vd_source=182193abde263463fca6d383cebdbc35

3.3 AlexNet

2012年,引起深度学习热潮。本质是更深、更大的LeNet,改进点:丢弃法、ReLu、MaxPooling,其使得计算机视觉方法论改变。左图为标准机器学习处理方案、右图为深度学习处理方案。

3.3.1 AlexNet架构

                   

右图为LeNet、左图为AlexNet,更多细节:

(1)激活函数从sigmoid变到ReLu(减缓梯度消失);

(2)隐藏全链接层后加入丢弃层;

(3)数据增强。

3.3.2 代码

(1)容量控制及预处理

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

net = nn.Sequential(
    #大卷积+大步幅=快速拉开不同物体的空间差异
    # 这里使用一个11*11的更大窗口来捕捉对象。
    # 同时,步幅为4,以减少输出的高度和宽度。
    # 另外,输出通道的数目远大于LeNet
    nn.Conv2d(1, 96, kernel_size=11, stride=4, padding=1), nn.ReLU(),
    nn.MaxPool2d(kernel_size=3, stride=2),
    #提取中层图像特征,如边缘组合、纹理
    # 减小卷积窗口,使用填充为2来使得输入与输出的高和宽一致,且增大输出通道数
    nn.Conv2d(96, 256, kernel_size=5, padding=2), nn.ReLU(),
    nn.MaxPool2d(kernel_size=3, stride=2),
    #提取高层抽象特征,如脸部结构、物体部件、类别相关形状
    # 使用三个连续的卷积层和较小的卷积窗口。
    # 除了最后的卷积层,输出通道的数量进一步增加。
    # 在前两个卷积层之后,汇聚层不用于减少输入的高度和宽度
    nn.Conv2d(256, 384, kernel_size=3, padding=1), nn.ReLU(),
    nn.Conv2d(384, 384, kernel_size=3, padding=1), nn.ReLU(),
    nn.Conv2d(384, 256, kernel_size=3, padding=1), nn.ReLU(),
    nn.MaxPool2d(kernel_size=3, stride=2),
    #将多通道卷积特征展开为一维向量
    nn.Flatten(),
    # 这里,全连接层的输出数量是LeNet中的好几倍。使用dropout层来减轻过拟合
    nn.Linear(6400, 4096), nn.ReLU(),
    nn.Dropout(p=0.5),
    nn.Linear(4096, 4096), nn.ReLU(),
    nn.Dropout(p=0.5),
    # 最后是输出层。由于这里使用Fashion-MNIST,所以用类别数为10,而非论文中的1000
    nn.Linear(4096, 10))

(2)观察每一层输出情况

X = torch.randn(1, 1, 224, 224)
for layer in net:
    X=layer(X)
    print(layer.__class__.__name__,'output shape:\t',X.shape)

(3)读取数据集

       AlexNet论文中使用ImageNet数据,量更大;此处用的是Fashion-MNIST(训练集6万张、测试集1万张),将其像素调整为和ImageNet一致224*224。

batch_size = 128
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=224)

(4)训练AlexNet

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

训练效果查看方法:

a.train loss越低越好,说明模型在训练集上拟合得越来越好;

                    

b.train acc越高越好,但不能比test acc高太多,正常情况是逐渐上升最终接近100%;

                                    

c.test.cc越高越好,表示泛化能力好。

3.4 VGG

更大更深的AlexNet。

3.4.1 VGG块

3.4.2 VGG架构

3.4.3 代码

(1)VGG块

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


def vgg_block(num_convs, in_channels, out_channels):
    layers = []
    for _ in range(num_convs):
        layers.append(nn.Conv2d(in_channels, out_channels,
                                kernel_size=3, padding=1))
        layers.append(nn.ReLU())
        in_channels = out_channels
    layers.append(nn.MaxPool2d(kernel_size=2,stride=2))
    return nn.Sequential(*layers)

(2)VGG网络

conv_arch = ((1, 64), (1, 128), (2, 256), (2, 512), (2, 512))

def vgg(conv_arch):
    conv_blks = []
    in_channels = 1
    # 卷积层部分
    for (num_convs, out_channels) in conv_arch:
        conv_blks.append(vgg_block(num_convs, in_channels, out_channels))
        in_channels = out_channels

    return nn.Sequential(
        *conv_blks, nn.Flatten(),
        # 全连接层部分
        nn.Linear(out_channels * 7 * 7, 4096), nn.ReLU(), nn.Dropout(0.5),
        nn.Linear(4096, 4096), nn.ReLU(), nn.Dropout(0.5),
        nn.Linear(4096, 10))

net = vgg(conv_arch)

X = torch.randn(size=(1, 1, 224, 224))
for blk in net:
    X = blk(X)
    print(blk.__class__.__name__,'output shape:\t',X.shape)

(3)模型训练

ratio = 4
small_conv_arch = [(pair[0], pair[1] // ratio) for pair in conv_arch]
net = vgg(small_conv_arch)

lr, num_epochs, batch_size = 0.05, 10, 8
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=224)
d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())
3.5 NiN

这个网络现在使用较少,了解思想即可。

3.5.1 特点

LeNet、AlexNet和VGG使用全连接层,可能会完全放弃表征的空间结构。 NiN提供了一个非常简单的解决方案,在每个像素的通道上分别使用多层感知机。

(1)NiN块使用卷积层+两个1x1卷积层,后者对每个像素增加了非线性

(2)NiN使用全局平均池化层替代VGG、AlexNet中全连接层,不易过拟合、更少的参数个数

3.5.2 架构

3.5.3 代码

(1)库

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


def nin_block(in_channels, out_channels, kernel_size, strides, padding):
    return nn.Sequential(
        nn.Conv2d(in_channels, out_channels, kernel_size, strides, padding),
        nn.ReLU(),
        nn.Conv2d(out_channels, out_channels, kernel_size=1), nn.ReLU(),
        nn.Conv2d(out_channels, out_channels, kernel_size=1), nn.ReLU())

(2)NIN模型

net = nn.Sequential(
    nin_block(1, 96, kernel_size=11, strides=4, padding=0),
    nn.MaxPool2d(3, stride=2),
    nin_block(96, 256, kernel_size=5, strides=1, padding=2),
    nn.MaxPool2d(3, stride=2),
    nin_block(256, 384, kernel_size=3, strides=1, padding=1),
    nn.MaxPool2d(3, stride=2),
    nn.Dropout(0.5),
    # 标签类别数是10
    nin_block(384, 10, kernel_size=3, strides=1, padding=1),
    nn.AdaptiveAvgPool2d((1, 1)),
    # 将四维的输出转成二维的输出,其形状为(批量大小,10)
    nn.Flatten())

#查看每层输出
X = torch.rand(size=(1, 1, 224, 224))
for layer in net:
    X = layer(X)
    print(layer.__class__.__name__,'output shape:\t', X.shape)

(3)训练模型

lr, num_epochs, batch_size = 0.1, 10, 128
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=224)
d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())

4 电脑配置查询

4.1 CPU
lscpu

4.2 内存
free -h

4.3 GPU
nvidia-smi

4.4 所有硬件信息
sudo lshw -short
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值