动手学深度学习25 VGG

1. VGG

vgg发现:模型用更深更窄,窗口更小,模型效果更好。
在这里插入图片描述
在这里插入图片描述

经典设置:把高宽减半,通道数翻倍。
在这里插入图片描述

vgg11=8层卷积+3层全连接。
在这里插入图片描述
在这里插入图片描述

https://cv.gluon.ai/model_zoo/classification.html
在这里插入图片描述

在这里插入图片描述

2. 代码

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) # 解包裹传递

# 卷积层数 输出通道数
conv_arch = ((1, 64), (1, 128), (2, 256), (2, 512), (2, 512))
def vgg(conv_arch):
  conv_blks = []  # vgg卷积块
  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  # 开始第一层网络输入通道是1, 后续网络输入通道数和输出通道数保持一致

  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)

ratio = 4
# 输出通道数减小4倍 计算减少16倍?
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, 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(0), './vgg.png')
# 因为是以块为单位追加到sequential的,所以是只显示块结构
Sequential output shape:	 torch.Size([1, 64, 112, 112])
Sequential output shape:	 torch.Size([1, 128, 56, 56])
Sequential output shape:	 torch.Size([1, 256, 28, 28])
Sequential output shape:	 torch.Size([1, 512, 14, 14])
Sequential output shape:	 torch.Size([1, 512, 7, 7])
Flatten output shape:	 torch.Size([1, 25088])
Linear output shape:	 torch.Size([1, 4096])
ReLU output shape:	 torch.Size([1, 4096])
Dropout output shape:	 torch.Size([1, 4096])
Linear output shape:	 torch.Size([1, 4096])
ReLU output shape:	 torch.Size([1, 4096])
Dropout output shape:	 torch.Size([1, 4096])
Linear output shape:	 torch.Size([1, 10])
training on cuda:0
<Figure size 350x250 with 1 Axes>
<Figure size 350x250 with 1 Axes>
<Figure size 350x250 with 1 Axes>
......
loss 0.180, train acc 0.933, test acc 0.924
1633.7 examples/sec on cuda:0

在这里插入图片描述

有更改的d2l代码

在linux机器上执行,无法像jupyter一样随时查看plt生成的图片,需要保存到一个文件中
修改代码:

查看d2l脚本位置 find查找一下 一般在py环境包里面
/***/miniconda_3/miniconda3/envs/py310/lib/python3.10/site-packages/d2l/torch.py

查找画图部分代码,增加保存图片功能

def add(self, x, y, save_path=None):
    # Add multiple data points into the figure
    if not hasattr(y, "__len__"):
        y = [y]
    n = len(y)
    if not hasattr(x, "__len__"):
        x = [x] * n
    if not self.X:
        self.X = [[] for _ in range(n)]
    if not self.Y:
        self.Y = [[] for _ in range(n)]
    for i, (a, b) in enumerate(zip(x, y)):
        if a is not None and b is not None:
            self.X[i].append(a)
            self.Y[i].append(b)
    self.axes[0].cla()
    for x, y, fmt in zip(self.X, self.Y, self.fmts):
        self.axes[0].plot(x, y, fmt)
    self.config_axes()
    display.display(self.fig)
    display.clear_output(wait=True)
    
    # Save the figure  增加保存图片功能
    if save_path:
        self.fig.savefig(save_path)

add脚本调用
可以通过在调用 add 方法时指定 save_path 来保存图片。例如:

animator = Animator()
animator.add(x, y, save_path='./figure.png')

如上,增加保存图片的调用传参

# d2l/torch.py train_ch6函数
# save_path 接收函数调用时传的参数
def train_ch6(net, train_iter, test_iter, num_epochs, lr, device, save_path):
# 调用 add 方法时指定 save_path 来保存图片
animator.add(epoch + (i + 1) / num_batches, (train_l, train_acc, None), save_path)

-------------------------

d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu(0), './vgg.png')
# d2l.try_gpu(0) 指定使用第0号gpu机器
# './vgg.png' 保存图片到当前路径

gou机器的使用函数 d2l.try_gpu(0)

# d2l/torch.py
def num_gpus():
    """Get the number of available GPUs.

    Defined in :numref:`sec_use_gpu`"""
    return torch.cuda.device_count()

def try_gpu(i=0):
    """Return gpu(i) if exists, otherwise return cpu().

    Defined in :numref:`sec_use_gpu`"""
    if num_gpus() >= i + 1:
        return gpu(i)
    return cpu()

3. QA

fancy 想法 novelty 新颖性

矩阵分解思想

尽量用简单的模型,后续可以重复使用。

最后一层全局池化层,输入通道数和要预测的类别数相同,max(所有通道)输出的通道就是对应的类别,做softmax就是输出概率。在每个通道上全局平均?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值