自己做好网站,青岛网页设计公司,seo公司网站推广,韩国世界杯出线条件目录 1. Inception块3. GoogLeNet模型3. 训练模型 GoogLeNet吸收了NiN中串联网络的思想#xff0c;并在此基础上做了改进#xff0c;并且在2014年的ImageNet图像识别挑战赛中获得了不错的效果。
1. Inception块
GoogLeNet论文解决了多大的卷积核最合适的问题。 Inception块… 目录 1. Inception块3. GoogLeNet模型3. 训练模型 GoogLeNet吸收了NiN中串联网络的思想并在此基础上做了改进并且在2014年的ImageNet图像识别挑战赛中获得了不错的效果。
1. Inception块
GoogLeNet论文解决了多大的卷积核最合适的问题。 Inception块可以说是“集百家之长”它由四条并行路径组成不同的路径提取不同的信息在通道合并层进行合并。
Inception块有两种主要架构 这里我们采取第二种架构
第一条路径1x1卷积层提取信息第二条路径1x1卷积层减少通道数3x3卷积层提取信息第三条路径1x1卷积层减少通道数5x5卷积层提取信息第四条路径3x3最大汇聚层提取信息1x1卷积层改变通道数
在Inception块中通常调整的超参数是每层输出通道数。 将Inception想象成滤波器的组合不同尺寸的滤波器可以有效识别不同范围的图像细节。
import torch
from torch import nn
from torch.nn import functional as F
from d2l import torch as d2lclass Inception(nn.Module):# c1--c4是每条路径的输出通道数def __init__(self, in_channels, c1, c2, c3, c4, **kwargs):super(Inception, self).__init__(**kwargs)# 路径1单1×1卷积层self.p1_1 nn.Conv2d(in_channels, c1, kernel_size1)# 路径21×1卷积层后接3×3卷积层self.p2_1 nn.Conv2d(in_channels, c2[0], kernel_size1)self.p2_2 nn.Conv2d(c2[0], c2[1], kernel_size3, padding1)# 路径31×1卷积层后接5×5卷积层self.p3_1 nn.Conv2d(in_channels, c3[0], kernel_size1)self.p3_2 nn.Conv2d(c3[0], c3[1], kernel_size5, padding2)# 路径43×3最大汇聚层后接1×1卷积层self.p4_1 nn.MaxPool2d(kernel_size3, stride1, padding1)self.p4_2 nn.Conv2d(in_channels, c4, kernel_size1)def forward(self, x):p1 F.relu(self.p1_1(x))p2 F.relu(self.p2_2(F.relu(self.p2_1(x))))p3 F.relu(self.p3_2(F.relu(self.p3_1(x))))p4 F.relu(self.p4_2(F.relu(self.p4_1(x))))# 在通道维度上连接输出return torch.cat((p1, p2, p3, p4), dim1)3. GoogLeNet模型
GoogLeNet一共使用9个Inception块和全局平均汇聚层的堆叠来生成其估计值Inception块之间的最大汇聚层可降低维度。 现在逐一实现GoogLeNet的每个模块 第一个模块
# GoogLeNet一共使用9个Inception块和平均汇聚层的堆叠
# 第一个模块使用64个通道、7×7卷积层
b1 nn.Sequential(nn.Conv2d(1, 64, kernel_size7, stride2, padding3),nn.ReLU(),nn.MaxPool2d(kernel_size3, stride2, padding1))第二个模块
第二个模块第一个卷积层64个通道、1×1卷积层第二个卷积层通道数增加为3倍的3×3卷积层b2 nn.Sequential(nn.Conv2d(64, 64, kernel_size1),nn.ReLU(),nn.Conv2d(64, 192, kernel_size3),nn.ReLU(),nn.MaxPool2d(kernel_size3, stride2, padding1))第三个模块
第三个模块串联2个Inception块第一个Inception块通道数641283232256第二个Inception块通道数1281929664480其中第一路径64--128第二路径96--128--192 96/192 1/2第三路径16--32--96 16/192 1/12第四路径32--64
# Inception(in_channels, c1, c2, c3, c4)
# c1c2c3c4是每条路径的输出通道数
b3 nn.Sequential(Inception(192, 64, (96, 128), (16, 32), 32),Inception(256, 128, (128, 192), (32, 96), 64),nn.MaxPool2d(kernel_size3, stride2, padding1))第四个模块
第四个模块串联5个Inception块 第二、第三条路径按比例减少通道数第一个Inception块通道数1922084864512第二个Inception块通道数1602246464512第三个Inception块通道数1282566464512第四个Inception块通道数1122886464528第五个Inception块通道数256320128128832其中第一路径192--160--128--112--256第二路径96--208--224--256--144--288--160--320第三路径16--48--24--64--24--64--32--64--32--128第四路径64--64--64--64--128
b4 nn.Sequential(Inception(480, 192, (96, 208), (16, 48), 64),Inception(512, 160, (112, 224), (24, 64), 64),Inception(512, 128, (128, 256), (24, 64), 64),Inception(512, 112, (144, 288), (32, 64), 64),Inception(528, 256, (160, 320), (32, 128), 128),nn.MaxPool2d(kernel_size3, stride2, padding1))第五个模块
第五个模块串联2个Inception块 ,后紧跟输出层第一个Inception块通道数256320128128832第二个Inception块通道数3843841281281024其中第一路径256--384第二路径160--320--192--384第三路径32--128--48--128第四路径128--128
b5 nn.Sequential(Inception(832, 256, (160, 320), (32, 128), 128),Inception(832, 384, (192, 384), (48, 128), 128),# 使用全局平均汇聚层将每个通道的高度和宽度变成1nn.AdaptiveAvgPool2d((1, 1)),# 将输出变成二维数组nn.Flatten())# 连接一个输出个数为标签类别数的全连接层
net nn.Sequential(b1, b2, b3, b4, b5, nn.Linear(1024, 10))演示各个模块的输出形状变化
# 为了更好的训练Fashion-MNIST将输入的高度和宽度从224降到96
# 演示各个模块的输出形状变化
# size (batch_size, in_channels, height, weight)
X torch.rand(size(1, 1, 96, 96))
for layer in net:X layer(X)print(layer.__class__.__name__,output shape:\t, X.shape)3. 训练模型
定义精度评估函数
定义精度评估函数1、将数据集复制到显存中2、通过调用accuracy计算数据集的精度def evaluate_accuracy_gpu(net, data_iter, deviceNone): #save# 判断net是否属于torch.nn.Module类if isinstance(net, nn.Module):net.eval()# 如果不在参数选定的设备将其传输到设备中if not device:device next(iter(net.parameters())).device# Accumulator是累加器定义两个变量正确预测的数量总预测的数量。metric d2l.Accumulator(2)with torch.no_grad():for X, y in data_iter:# 将X, y复制到设备中if isinstance(X, list):# BERT微调所需的之后将介绍X [x.to(device) for x in X]else:X X.to(device)y y.to(device)# 计算正确预测的数量总预测的数量并存储到metric中metric.add(d2l.accuracy(net(X), y), y.numel())return metric[0] / metric[1]定义GPU训练函数
定义GPU训练函数1、为了使用gpu首先需要将每一小批量数据移动到指定的设备例如GPU上2、使用Xavier随机初始化模型参数3、使用交叉熵损失函数和小批量随机梯度下降。#save
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)# 在设备device上进行训练print(training on, device)net.to(device)# 优化器随机梯度下降optimizer torch.optim.SGD(net.parameters(), lrlr)# 损失函数交叉熵损失函数loss nn.CrossEntropyLoss()# Animator为绘图函数animator d2l.Animator(xlabelepoch, xlim[1, num_epochs],legend[train loss, train acc, test acc])# 调用Timer函数统计时间timer, num_batches d2l.Timer(), len(train_iter)for epoch in range(num_epochs):# Accumulator(3)定义3个变量损失值正确预测的数量总预测的数量metric d2l.Accumulator(3)net.train()# enumerate() 函数用于将一个可遍历的数据对象for i, (X, y) in enumerate(train_iter):timer.start() # 进行计时optimizer.zero_grad() # 梯度清零X, y X.to(device), y.to(device) # 将特征和标签转移到devicey_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(floss {train_l:.3f}, train acc {train_acc:.3f},ftest acc {test_acc:.3f})# 设备的计算能力print(f{metric[2] * num_epochs / timer.sum():.1f} examples/secfon {str(device)})进行训练
# 训练将图像转为96像素×96像素
lr, num_epochs, batch_size 0.1, 10, 128
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())