From e337fef6a0f00a41e0d6c979e66b1d6e340312ed Mon Sep 17 00:00:00 2001 From: Lollipop-Wang <109408857+Lollipop-Wang@users.noreply.github.com> Date: Sun, 15 Dec 2024 18:26:18 +0800 Subject: [PATCH] Update image-augmentation.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit d2l中的residual存在问题。其使用了lazyconv2d会导致报错。报错提示如下: Attempted to use an uninitialized parameter in . This error happens when you are using a `LazyModule` or explicitly manipulating `torch.nn.parameter.UninitializedParameter` objects. When using LazyModules Call `forward` with a dummy batch to initialize the parameters before calling torch functions。 建议将lazyconv2d改为conv2d,就能正常运行 --- chapter_computer-vision/image-augmentation.md | 60 ++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/chapter_computer-vision/image-augmentation.md b/chapter_computer-vision/image-augmentation.md index dc343c3ce..af4c02945 100644 --- a/chapter_computer-vision/image-augmentation.md +++ b/chapter_computer-vision/image-augmentation.md @@ -23,6 +23,7 @@ npx.set_np() from d2l import torch as d2l import torch import torchvision +from torch.nn import functional as F from torch import nn ``` @@ -475,6 +476,63 @@ def train_ch13(net, train_iter, test_iter, loss, trainer, num_epochs, 现在,我们可以[**定义`train_with_data_aug`函数,使用图像增广来训练模型**]。该函数获取所有的GPU,并使用Adam作为训练的优化算法,将图像增广应用于训练集,最后调用刚刚定义的用于训练和评估模型的`train_ch13`函数。 +```{.python .input} +#@tab pytorch +class Residual(nn.Module): #@save + def __init__(self, input_channels, num_channels, + use_1x1conv=False, strides=1): + super().__init__() + self.conv1 = nn.Conv2d(input_channels, num_channels, + kernel_size=3, padding=1, stride=strides) + self.conv2 = nn.Conv2d(num_channels, num_channels, + kernel_size=3, padding=1) + if use_1x1conv: + self.conv3 = nn.Conv2d(input_channels, num_channels, + kernel_size=1, stride=strides) + else: + self.conv3 = None + self.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 += X + return F.relu(Y) + + + +def resnet18(num_classes, in_channels=1): + """稍加修改的ResNet-18模型""" + def resnet_block(in_channels, out_channels, num_residuals, + first_block=False): + blk = [] + for i in range(num_residuals): + if i == 0 and not first_block: + blk.append(Residual(in_channels, out_channels, + use_1x1conv=True, strides=2)) + else: + blk.append(Residual(out_channels, out_channels)) + return nn.Sequential(*blk) + + # 该模型使用了更小的卷积核、步长和填充,而且删除了最大汇聚层 + net = nn.Sequential( + nn.Conv2d(in_channels, 64, kernel_size=3, stride=1, padding=1), + nn.BatchNorm2d(64), + nn.ReLU()) + net.add_module("resnet_block1", resnet_block( + 64, 64, 2, first_block=True)) + net.add_module("resnet_block2", resnet_block(64, 128, 2)) + net.add_module("resnet_block3", resnet_block(128, 256, 2)) + net.add_module("resnet_block4", resnet_block(256, 512, 2)) + net.add_module("global_avg_pool", nn.AdaptiveAvgPool2d((1,1))) + net.add_module("fc", nn.Sequential(nn.Flatten(), + nn.Linear(512, num_classes))) + return net +``` + ```{.python .input} batch_size, devices, net = 256, d2l.try_all_gpus(), d2l.resnet18(10) net.initialize(init=init.Xavier(), ctx=devices) @@ -490,7 +548,7 @@ def train_with_data_aug(train_augs, test_augs, net, lr=0.001): ```{.python .input} #@tab pytorch -batch_size, devices, net = 256, d2l.try_all_gpus(), d2l.resnet18(10, 3) +batch_size, devices, net = 256, d2l.try_all_gpus(), resnet18(10, 3) def init_weights(m): if type(m) in [nn.Linear, nn.Conv2d]: