网站后台演示地址,百度搜索推广收费标准,免费相册视频制作软件,如何运营一个网站动手学深度学习29 残差网络ResNet ResNet代码ReLU的两种调用1. 使用 torch.nn.ReLU 模块2. 使用 torch.nn.functional.relu 函数总结 QA29.2 ResNet 为什么能训练处1000层的模型ResNet的梯度计算怎么处理梯度消失的 QA ResNet 更复杂模型包含小模型#xff0c;不一定改进… 动手学深度学习29 残差网络ResNet ResNet代码ReLU的两种调用1. 使用 torch.nn.ReLU 模块2. 使用 torch.nn.functional.relu 函数总结 QA29.2 ResNet 为什么能训练处1000层的模型ResNet的梯度计算怎么处理梯度消失的 QA ResNet 更复杂模型包含小模型不一定改进但是加更深的层更复杂的模型至少不会变差。 复杂模型包含小模型当要新加的层没有学到任何东西的时候模型仍旧是可以学到前面层已经学到了的知识。可以认为是嵌入了小网络允许先学习小网络。 从vgg过来。1*1卷积是为了改变通道数和ResNet块输出的通道数保持一致这样能做对应位置元素加法。 核心加了一个加法。
152个卷积层。层数越高精度越高。34个卷积层用的比较多。刷榜经常用152【实际使用很少训练太贵】 ResNet的思想 Residual Connections残差连接当前经常使用例如 bert transformer。
不管再深总是先训练好小网络再往深层训练。
代码
用了比较大的输入。调优ResNet–把输入搞小或者调小config
import torch
from torch import nn
from torch.nn import functional as F
from d2l import torch as d2lclass Residual(nn.Module):def __init__(self, input_channels, num_channels, use_1x1convFalse, strides1):super().__init__()self.conv1 nn.Conv2d(input_channels, num_channels, kernel_size3, padding1, stridestrides)self.conv2 nn.Conv2d(num_channels, num_channels, kernel_size3, padding1)if use_1x1conv:self.conv3 nn.Conv2d(input_channels, num_channels, kernel_size1, stridestrides)else:self.conv3 Noneself.bn1 nn.BatchNorm2d(num_channels)self.bn2 nn.BatchNorm2d(num_channels)def forward(self, X):Y F.relu(self.bn1(self.conv1(X)))Y self.bn2(self.conv2(Y))if self.conv3:X self.conv3(X)Y Xreturn F.relu(Y)# 只传输入输出通道数 不设置使用残差连接 不改变高宽
blk Residual(3, 3)
X torch.rand(4, 3, 6, 6)
Y blk(X)
# stride 不传参 默认为1
print(Y.shape) # torch.Size([4, 3, 6, 6])# stride2 高宽减半 输出通道数加倍
blk Residual(3,6, use_1x1convTrue, strides2)
print(blk(X).shape) # torch.Size([4, 6, 3, 3])# 设置第一个网络块 7*7卷积 stride2 3*3池化层 stride2 高宽降低4倍
b1 nn.Sequential(nn.Conv2d(1, 64, kernel_size7, stride2, padding3), nn.BatchNorm2d(64), nn.ReLU(), nn.MaxPool2d(kernel_size3, stride2, padding1))# 残差块
def resnet_block(input_channels, num_channels, num_residuals, first_blockFalse):blk []for i in range(num_residuals):if i 0 and not first_block:blk.append(Residual(input_channels, num_channels, use_1x1convTrue, strides2))else:blk.append(Residual(num_channels, num_channels))return blkb2 nn.Sequential(*resnet_block(64, 64, 2, first_blockTrue))
b3 nn.Sequential(*resnet_block(64, 128, 2))
b4 nn.Sequential(*resnet_block(128, 256, 2))
b5 nn.Sequential(*resnet_block(256, 512, 2))net nn.Sequential(b1, b2, b3, b4, b5,nn.AdaptiveAvgPool2d((1,1)),nn.Flatten(), nn.Linear(512, 10))# 用了比较大的输入数据 高宽224 VGG用的是96高宽
X torch.rand(size(1, 1, 224, 224))
for layer in net:X layer(X)print(layer.__class__.__name__, output shape:\t, X.shape)lr, num_epochs, batch_size 0.05, 10, 256
train_iter, test_iter d2l.load_data_fashion_mnist(batch_size, resize96)
d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())torch.Size([4, 3, 6, 6])
torch.Size([4, 6, 3, 3])
Sequential output shape: torch.Size([1, 64, 56, 56])
Sequential output shape: torch.Size([1, 64, 56, 56])
Sequential output shape: torch.Size([1, 128, 28, 28])
Sequential output shape: torch.Size([1, 256, 14, 14])
Sequential output shape: torch.Size([1, 512, 7, 7])
AdaptiveAvgPool2d output shape: torch.Size([1, 512, 1, 1])
Flatten output shape: torch.Size([1, 512])
Linear output shape: torch.Size([1, 10])
loss 0.012, train acc 0.997, test acc 0.913
1557.1 examples/sec on cuda:0d2l.load_data_fashion_mnist(batch_size, resize224)loss 0.027, train acc 0.993, test acc 0.876
354.8 examples/sec on cuda:0ReLU的两种调用
在 PyTorch 中可以通过多种方式调用 ReLURectified Linear Unit激活函数。以下是几种常见的方法
1. 使用 torch.nn.ReLU 模块
torch.nn.ReLU 是一个 PyTorch 模块可以直接在模型中作为层来使用。
import torch
import torch.nn as nn# 创建一个 ReLU 模块实例
relu nn.ReLU()# 示例输入张量
input_tensor torch.tensor([-1.0, 0.0, 1.0, 2.0])# 应用 ReLU 激活函数
output_tensor relu(input_tensor)
print(output_tensor)2. 使用 torch.nn.functional.relu 函数
torch.nn.functional.relu 是一个函数可以直接应用于张量。这在编写自定义前向传播方法时非常有用。
import torch
import torch.nn.functional as F# 示例输入张量
input_tensor torch.tensor([-1.0, 0.0, 1.0, 2.0])# 应用 ReLU 激活函数
output_tensor F.relu(input_tensor)
print(output_tensor)总结
torch.nn.ReLU作为模块使用适合在构建模型时作为层的一部分。torch.nn.functional.relu作为函数使用适合在自定义的前向传播方法中调用。
QA
1 lenet batch_size 1000 大部分图片都是相似的影响收敛精度。 2 当f(x)xg(x)时如果x的效果已经很好那么g(x)训练可能拿不到梯度做梯度反传的时候梯度会是一个很小的值那么ResNet在做更深的网络的时候不会让模型变得更坏一般会变好。 3 绿色线-cos学习率 【效果挺好】 调参简单–调个最大值最小值。 4 残差怎么理解 layer2在layer1的基础上训练一些误差在layer1的基础上做叠加。底层网络没有fit好的东西加深的网络继续去fit。 5 * 解包裹传递参数 把list列表参数解包裹传参 6 两个BN有自己的参数要学 参数不一样 7 nn.ReLU(inplaceTrue) 原地更新参数 省一点内存 8 输入尺寸的确定是由数据和框架确定 9 当训练数据中加入了大量的噪音测试精度会大于训练精度在实际使用中 经常测试精度会大于训练精度。 达不到100%识别本身技术水平达不到数据集也会有标错的 10 不能假设数据集是完全正确的。还有数据人本身都无法分辨–hardcase。关心数据里面的误差。比较容易的case模型很容易训练好。
29.2 ResNet 为什么能训练处1000层的模型
https://www.bilibili.com/video/BV1554y157E3/?spm_id_fromautoNextvd_sourceeb04c9a33e87ceba9c9a2e5f09752ef8
ResNet的梯度计算
避免梯度消失把乘法变加法。
怎么处理梯度消失的
假设省略loss 希望偏y偏w不要很小学习的不要很慢。 把网络加深加一些层。 梯度怎么展开的–链式法则 导数和真实值预测值的区别是有一定关系的预测比较好的情况下导数会很小做乘法后整体梯度会比原来梯度小很多。 假设残差网络为y , 当g(x)的梯度很小的时候加和的梯度也会比原来很小。大数小数大数 大数*小数小数。当靠近底部的层梯度会很小避免梯度消失。 靠近数据端的w是很难训练的由于有跳转在训练一开始的时候靠近数据端的网络就会拿到比较大的梯度。
QA
1 在靠近输入的学习率设大一些 靠近输出的lr学习率设小一些 可以缓解梯度消失的问题但是调数比较难【设多大多小】。当超过浮点数的精度计算会出问题 小到很小梯度会为0 精度fp16问题更明显一些。残差连接不需要调太多的东西。 2 梯度是累乘的 深层的网络梯度值和误差值有关梯度回传越往网络底层会慢慢吸收掉误差误差会越小。