【PyTorch】现代卷积神经网络

文章目录

  • 1. 理论介绍
    • 1.1. 深度卷积神经网络(AlexNet)
      • 1.1.1. 概述
      • 1.1.2. 模型设计
    • 1.2. 使用块的网络(VGG)
    • 1.3. 网络中的网络(NiN)
    • 1.4. 含并行连结的网络(GoogLeNet)
  • 2. 实例解析
    • 2.1. 实例描述
    • 2.2. 代码实现
      • 2.2.1. 在FashionMNIST数据集上训练AlexNet
        • 2.2.1.1. 主要代码
        • 2.2.1.2. 完整代码
        • 2.2.1.3. 输出结果
      • 2.2.2. 在FashionMNIST数据集上训练VGG-11
        • 2.2.2.1. 主要代码
        • 2.2.2.2. 完整代码
        • 2.2.2.3. 输出结果
      • 2.2.3. 在FashionMNIST数据集上训练NiN
        • 2.2.3.1. 主要代码
        • 2.2.3.2. 完整代码
        • 2.2.3.3. 输出结果
      • 2.2.4. 在FashionMNIST数据集上训练GoogLeNet
        • 2.2.4.1. 主要代码
        • 2.2.4.2. 完整代码
        • 2.2.4.3. 输出结果

1. 理论介绍

1.1. 深度卷积神经网络(AlexNet)

1.1.1. 概述

  • 特征本身应该被学习,而且在合理地复杂性前提下,特征应该由多个共同学习的神经网络层组成,每个层都有可学习的参数。在机器视觉中,最底层可能检测边缘、颜色和纹理,更高层建立在这些底层表示的基础上,以表示更大的特征。
  • 包含许多特征的深度模型需要大量的有标签数据,才能显著优于基于凸优化的传统方法(如线性方法和核方法)。ImageNet挑战赛为研究人员提高超大规模的数据集。
  • 深度学习对计算资源要求很高,训练可能需要数百个迭代轮数,每次迭代都需要通过代价高昂的许多线性代数层传递数据。用GPU训练神经网络大大提高了训练速度,相比于CPU,GPU由100~1000个小的处理单元(核心)组成,庞大的核心数量使GPU比CPU快几个数量级;GPU核心更简单,功耗更低;GPU拥有更高的内存带宽;卷积和矩阵乘法,都是可以在GPU上并行化的操作。
  • AlexNet首次证明了学习到的特征可以超越手工设计的特征。

1.1.2. 模型设计

模型设计

  • AlexNet使用ReLU而不是sigmoid作为其激活函数。
  • 在最后一个卷积层后有两个全连接层,分别有4096个输出。 这两个巨大的全连接层拥有将近1GB的模型参数。 由于早期GPU显存有限,原版的AlexNet采用了双数据流设计,使得每个GPU只负责存储和计算模型的一半参数。
  • AlexNet通过暂退法控制全连接层的模型复杂度。
  • 为了进一步扩充数据,AlexNet在训练时增加了大量的图像增强数据,如翻转、裁切和变色。 这使得模型更健壮,更大的样本量有效地减少了过拟合。

1.2. 使用块的网络(VGG)

  • 经典卷积神经网络的基本组成部分
    • 带填充以保持分辨率的卷积层
    • 非线性激活函数
    • 池化层
  • VGG块由一系列卷积层组成,后面再加上用于空间下采样的最大池化层。深层且窄的卷积(即 3 × 3 3\times3 3×3)比较浅层且宽的卷积更有效。不同的VGG模型可通过每个VGG块中卷积层数量和输出通道数量的差异来定义。
  • VGG网络由几个VGG块和全连接层组成。超参数变量conv_arch指定了每个VGG块里卷积层个数和输出通道数。全连接模块则与AlexNet中的相同。
  • VGG-11有5个VGG块,其中前两个块各有一个卷积层,后三个块各包含两个卷积层,共8个卷积层。 第一个模块有64个输出通道,每个后续模块将输出通道数量翻倍,直到该数字达到512。

1.3. 网络中的网络(NiN)

  • 网络中的网络(NiN)在每个像素的通道上分别使用多层感知机
  • NiN块以一个普通卷积层开始,后面是两个 1 × 1 1\times1 1×1的卷积层。这两个 1 × 1 1\times1 1×1卷积层充当带有ReLU激活函数的逐像素全连接层。
  • NiN网络使用窗口形状为 11 × 11 11\times11 11×11 5 × 5 5\times5 5×5 3 × 3 3\times3 3×3的卷积层,输出通道数量与AlexNet中的相同。 每个NiN块后有一个最大池化层,池化窗口形状为 3 × 3 3\times3 3×3,步幅为2。 NiN和AlexNet之间的一个显著区别是NiN完全取消了全连接层。NiN使用一个NiN块,其输出通道数等于标签类别的数量。最后放一个全局平均池化层,生成一个对数几率 (logits)。
  • 移除全连接层可减少过拟合,同时显著减少NiN的参数。

1.4. 含并行连结的网络(GoogLeNet)

  • 使用不同大小的卷积核组合是有利的,因为可以有效地识别不同范围的图像细节。
  • Inception块由四条并行路径组成。四条路径都使用合适的填充来使输入与输出的高和宽一致。超参数是每层输出通道数
    Inception
  • GoogLeNet一共使用9个Inception块和全局平均汇聚层的堆叠来生成其估计值。Inception块之间的最大汇聚层可降低维度。
    GoogLeNet

2. 实例解析

2.1. 实例描述

  • 在FashionMNIST数据集上训练AlexNet。注:输入图像调整到 224 × 224 224\times224 224×224,不使用跨GPU分解模型。
  • 在FashionMNIST数据集上训练VGG-11。注:输入图像调整到 224 × 224 224\times224 224×224,可以按比例缩小通道数以减少参数量,学习率可以设置得略高。
  • 在FashionMNIST数据集上训练NiN。注:输入图像调整到 224 × 224 224\times224 224×224
  • 在FashionMNIST数据集上训练GoogLeNet。注:输入图像调整到 96 × 96 96\times96 96×96

2.2. 代码实现

2.2.1. 在FashionMNIST数据集上训练AlexNet

2.2.1.1. 主要代码
AlexNet = nn.Sequential(nn.Conv2d(1, 96, kernel_size=11, stride=4, padding=1), nn.ReLU(),nn.MaxPool2d(kernel_size=3, stride=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(),nn.Linear(6400, 4096), nn.ReLU(),nn.Dropout(p=0.5),nn.Linear(4096, 4096), nn.ReLU(),nn.Dropout(p=0.5),nn.Linear(4096, 10)
).to(device, non_blocking=True)
2.2.1.2. 完整代码
import os, torch
from tensorboardX import SummaryWriter
from rich.progress import track
from torchvision.datasets import FashionMNIST
from torchvision.transforms import Compose, ToTensor, Resize
from torch.utils.data import DataLoader
from torch import nn, optimdef load_dataset():"""加载数据集"""root = "./dataset"transform = Compose([Resize(224), ToTensor()])mnist_train = FashionMNIST(root, True, transform, download=True)mnist_test = FashionMNIST(root, False, transform, download=True)dataloader_train = DataLoader(mnist_train, batch_size, shuffle=True, num_workers=num_workers, pin_memory=True,)dataloader_test = DataLoader(mnist_test, batch_size, shuffle=False,num_workers=num_workers, pin_memory=True,)return dataloader_train, dataloader_testif __name__ == "__main__":# 全局参数设置num_epochs = 10batch_size = 128num_workers = 3lr = 0.01device = torch.device('cuda')# 创建记录器def log_dir():root = "runs"if not os.path.exists(root):os.mkdir(root)order = len(os.listdir(root)) + 1return f'{root}/exp{order}'writer = SummaryWriter(log_dir=log_dir())# 数据集配置dataloader_train, dataloader_test = load_dataset()# 模型配置AlexNet = nn.Sequential(nn.Conv2d(1, 96, kernel_size=11, stride=4, padding=1), nn.ReLU(),nn.MaxPool2d(kernel_size=3, stride=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(),nn.Linear(6400, 4096), nn.ReLU(),nn.Dropout(p=0.5),nn.Linear(4096, 4096), nn.ReLU(),nn.Dropout(p=0.5),nn.Linear(4096, 10)).to(device, non_blocking=True)criterion = nn.CrossEntropyLoss(reduction='none')optimizer = optim.SGD(AlexNet.parameters(), lr=lr)# 训练循环metrics_train = torch.zeros(3, device=device)  # 训练损失、训练准确度、样本数metrics_test = torch.zeros(2, device=device)   # 测试准确度、样本数for epoch in track(range(num_epochs), description='AlexNet'):AlexNet.train()for X, y in dataloader_train:X, y = X.to(device, non_blocking=True), y.to(device, non_blocking=True)loss = criterion(AlexNet(X), y)optimizer.zero_grad()loss.mean().backward()optimizer.step()AlexNet.eval()with torch.no_grad():metrics_train.zero_()for X, y in dataloader_train:X, y = X.to(device, non_blocking=True), y.to(device, non_blocking=True)y_hat = AlexNet(X)loss = criterion(y_hat, y)metrics_train[0] += loss.sum()metrics_train[1] += (y_hat.argmax(dim=1) == y).sum()metrics_train[2] += y.numel()metrics_train[0] /= metrics_train[2]metrics_train[1] /= metrics_train[2]metrics_test.zero_()for X, y in dataloader_test:X, y = X.to(device, non_blocking=True), y.to(device, non_blocking=True)y_hat = AlexNet(X)metrics_test[0] += (y_hat.argmax(dim=1) == y).sum()metrics_test[1] += y.numel()metrics_test[0] /= metrics_test[1]_metrics_train = metrics_train.cpu().numpy()_metrics_test = metrics_test.cpu().numpy()writer.add_scalars('metrics', {'train_loss': _metrics_train[0],'train_acc': _metrics_train[1],'test_acc': _metrics_test[0]}, epoch)writer.close()
2.2.1.3. 输出结果

AlexNet

2.2.2. 在FashionMNIST数据集上训练VGG-11

2.2.2.1. 主要代码
def vgg_block(num_convs, in_channels, out_channels):"""定义VGG块"""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_channelslayers.append(nn.MaxPool2d(kernel_size=2, stride=2))return nn.Sequential(*layers)def vgg(conv_arch):"""定义VGG网络"""vgg_blocks = []in_channels = 1out_channels = 0for num_convs, out_channels in conv_arch:vgg_blocks.append(vgg_block(num_convs, in_channels, out_channels))in_channels = out_channelsreturn nn.Sequential(*vgg_blocks, nn.Flatten(),nn.Linear(out_channels * 7 * 7, 4096), nn.ReLU(),nn.Dropout(p=0.5),nn.Linear(4096, 4096), nn.ReLU(),nn.Dropout(p=0.5),nn.Linear(4096, 10),)
2.2.2.2. 完整代码
import os
from tensorboardX import SummaryWriter
from rich.progress import track
import torch
from torch import nn, optim
from torch.utils.data import DataLoader
from torchvision.transforms import Compose, Resize, ToTensor
from torchvision.datasets import FashionMNISTdef load_dataset():"""加载数据集"""root = "./dataset"transform = Compose([Resize(224), ToTensor()])mnist_train = FashionMNIST(root, True, transform, download=True)mnist_test = FashionMNIST(root, False, transform, download=True)dataloader_train = DataLoader(mnist_train, batch_size, shuffle=True, num_workers=num_workers, pin_memory=True,)dataloader_test = DataLoader(mnist_test, batch_size, shuffle=False,num_workers=num_workers, pin_memory=True,)return dataloader_train, dataloader_testdef vgg_block(num_convs, in_channels, out_channels):"""定义VGG块"""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_channelslayers.append(nn.MaxPool2d(kernel_size=2, stride=2))return nn.Sequential(*layers)def vgg(conv_arch):"""定义VGG网络"""vgg_blocks = []in_channels = 1out_channels = 0for num_convs, out_channels in conv_arch:vgg_blocks.append(vgg_block(num_convs, in_channels, out_channels))in_channels = out_channelsreturn nn.Sequential(*vgg_blocks, nn.Flatten(),nn.Linear(out_channels * 7 * 7, 4096), nn.ReLU(),nn.Dropout(p=0.5),nn.Linear(4096, 4096), nn.ReLU(),nn.Dropout(p=0.5),nn.Linear(4096, 10),)if __name__ == '__main__':# 全局参数配置num_epochs = 10batch_size = 128num_workers = 3lr = 0.05device = torch.device('cuda')# 记录器配置def log_dir():root = "runs"if not os.path.exists(root):os.mkdir(root)order = len(os.listdir(root)) + 1return f'{root}/exp{order}'writer = SummaryWriter(log_dir=log_dir())# 数据集配置dataloader_train, dataloader_test = load_dataset()# 模型配置ratio = 4conv_arch = ((1, 64), (1, 128), (2, 256), (2, 512), (2, 512))small_conv_arch =  [(pair[0], pair[1] // ratio) for pair in conv_arch]net = vgg(small_conv_arch).to(device, non_blocking=True)criterion = nn.CrossEntropyLoss(reduction='none')optimizer = optim.SGD(net.parameters(), lr=lr)# 训练循环metrics_train = torch.zeros(3, device=device)  # 训练损失、训练准确度、样本数metrics_test = torch.zeros(2, device=device)   # 测试准确度、样本数for epoch in track(range(num_epochs), description='VGG'):net.train()for X, y in dataloader_train:X, y = X.to(device, non_blocking=True), y.to(device, non_blocking=True)loss = criterion(net(X), y)optimizer.zero_grad()loss.mean().backward()optimizer.step()net.eval()with torch.no_grad():metrics_train.zero_()for X, y in dataloader_train:X, y = X.to(device, non_blocking=True), y.to(device, non_blocking=True)y_hat = net(X)loss = criterion(y_hat, y)metrics_train[0] += loss.sum()metrics_train[1] += (y_hat.argmax(dim=1) == y).sum()metrics_train[2] += y.numel()metrics_train[0] /= metrics_train[2]metrics_train[1] /= metrics_train[2]metrics_test.zero_()for X, y in dataloader_test:X, y = X.to(device, non_blocking=True), y.to(device, non_blocking=True)y_hat = net(X)metrics_test[0] += (y_hat.argmax(dim=1) == y).sum()metrics_test[1] += y.numel()metrics_test[0] /= metrics_test[1]_metrics_train = metrics_train.cpu().numpy()_metrics_test = metrics_test.cpu().numpy()writer.add_scalars('metrics', {'train_loss': _metrics_train[0],'train_acc': _metrics_train[1],'test_acc': _metrics_test[0]}, epoch)writer.close()
2.2.2.3. 输出结果

VGG

2.2.3. 在FashionMNIST数据集上训练NiN

2.2.3.1. 主要代码
def nin_block(in_channels, out_channels, kernel_size, strides, padding):"""定义NiN块"""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())
net = nn.Sequential(nin_block(1, 96, kernel_size=11, strides=4, padding=0),nn.MaxPool2d(kernel_size=3, stride=2),nin_block(96, 256, kernel_size=5, strides=1, padding=2),nn.MaxPool2d(kernel_size=3, stride=2),nin_block(256, 384, kernel_size=3, strides=1, padding=1),nn.MaxPool2d(kernel_size=3, stride=2),nn.Dropout(0.5),nin_block(384, 10, kernel_size=3, strides=1, padding=1),nn.AdaptiveAvgPool2d((1, 1)),nn.Flatten()
).to(device, non_blocking=True)
2.2.3.2. 完整代码
import os
from tensorboardX import SummaryWriter
from alive_progress import alive_bar
import torch
from torch import nn, optim
from torch.utils.data import DataLoader
from torchvision.transforms import Compose, ToTensor, Resize
from torchvision.datasets import FashionMNISTdef load_dataset():"""加载数据集"""root = "./dataset"transform = Compose([Resize(224), ToTensor()])mnist_train = FashionMNIST(root, True, transform, download=True)mnist_test = FashionMNIST(root, False, transform, download=True)dataloader_train = DataLoader(mnist_train, batch_size, shuffle=True, num_workers=num_workers, pin_memory=True,)dataloader_test = DataLoader(mnist_test, batch_size, shuffle=False,num_workers=num_workers, pin_memory=True,)return dataloader_train, dataloader_testdef train_on_FashionMNIST(title):"""在FashionMNIST数据集上训练指定模型"""# 创建记录器def log_dir():root = "runs"if not os.path.exists(root):os.mkdir(root)order = len(os.listdir(root)) + 1return f'{root}/exp{order}'writer = SummaryWriter(log_dir=log_dir())# 数据集配置dataloader_train, dataloader_test = load_dataset()# 模型配置criterion = nn.CrossEntropyLoss(reduction='none')optimizer = optim.SGD(net.parameters(), lr=lr)# 训练循环metrics_train = torch.zeros(3, device=device)  # 训练损失、训练准确度、样本数metrics_test = torch.zeros(2, device=device)   # 测试准确度、样本数with alive_bar(num_epochs, theme='classic', title=title) as bar:for epoch in range(num_epochs):net.train()for X, y in dataloader_train:X, y = X.to(device, non_blocking=True), y.to(device, non_blocking=True)loss = criterion(net(X), y)optimizer.zero_grad()loss.mean().backward()optimizer.step()net.eval()with torch.no_grad():metrics_train.zero_()for X, y in dataloader_train:X, y = X.to(device, non_blocking=True), y.to(device, non_blocking=True)y_hat = net(X)loss = criterion(y_hat, y)metrics_train[0] += loss.sum()metrics_train[1] += (y_hat.argmax(dim=1) == y).sum()metrics_train[2] += y.numel()metrics_train[0] /= metrics_train[2]metrics_train[1] /= metrics_train[2]metrics_test.zero_()for X, y in dataloader_test:X, y = X.to(device, non_blocking=True), y.to(device, non_blocking=True)y_hat = net(X)metrics_test[0] += (y_hat.argmax(dim=1) == y).sum()metrics_test[1] += y.numel()metrics_test[0] /= metrics_test[1]_metrics_train = metrics_train.cpu().numpy()_metrics_test = metrics_test.cpu().numpy()writer.add_scalars('metrics', {'train_loss': _metrics_train[0],'train_acc': _metrics_train[1],'test_acc': _metrics_test[0]}, epoch)bar()writer.close()if __name__ == '__main__':# 全局参数配置num_epochs = 10batch_size = 128num_workers = 3lr = 0.1device = torch.device('cuda')# 模型配置def nin_block(in_channels, out_channels, kernel_size, strides, padding):"""定义NiN块"""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())net = nn.Sequential(nin_block(1, 96, kernel_size=11, strides=4, padding=0),nn.MaxPool2d(kernel_size=3, stride=2),nin_block(96, 256, kernel_size=5, strides=1, padding=2),nn.MaxPool2d(kernel_size=3, stride=2),nin_block(256, 384, kernel_size=3, strides=1, padding=1),nn.MaxPool2d(kernel_size=3, stride=2),nn.Dropout(0.5),nin_block(384, 10, kernel_size=3, strides=1, padding=1),nn.AdaptiveAvgPool2d((1, 1)),nn.Flatten()).to(device, non_blocking=True)def init_weights(m):if type(m) in [nn.Linear, nn.Conv2d]:nn.init.xavier_uniform_(m.weight)nn.init.zeros_(m.bias)net.apply(init_weights)# 在FashionMNIST数据集上训练模型train_on_FashionMNIST('NiN')
2.2.3.3. 输出结果

NiN

2.2.4. 在FashionMNIST数据集上训练GoogLeNet

2.2.4.1. 主要代码
class Inception(nn.Module):# c1--c4是每条路径的输出通道数def __init__(self, in_channels, c1, c2, c3, c4, **kwargs):super(Inception, self).__init__(**kwargs)# 线路1,单1x1卷积层self.p1_1 = nn.Conv2d(in_channels, c1, kernel_size=1)# 线路2,1x1卷积层后接3x3卷积层self.p2_1 = nn.Conv2d(in_channels, c2[0], kernel_size=1)self.p2_2 = nn.Conv2d(c2[0], c2[1], kernel_size=3, padding=1)# 线路3,1x1卷积层后接5x5卷积层self.p3_1 = nn.Conv2d(in_channels, c3[0], kernel_size=1)self.p3_2 = nn.Conv2d(c3[0], c3[1], kernel_size=5, padding=2)# 线路4,3x3最大汇聚层后接1x1卷积层self.p4_1 = nn.MaxPool2d(kernel_size=3, stride=1, padding=1)self.p4_2 = nn.Conv2d(in_channels, c4, kernel_size=1)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(self.p4_1(x)))# 在通道维度上连结输出return torch.cat((p1, p2, p3, p4), dim=1)
b1 = nn.Sequential(nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3),nn.ReLU(),nn.MaxPool2d(kernel_size=3, stride=2, padding=1))
b2 = nn.Sequential(nn.Conv2d(64, 64, kernel_size=1),nn.ReLU(),nn.Conv2d(64, 192, kernel_size=3, padding=1),nn.ReLU(),nn.MaxPool2d(kernel_size=3, stride=2, padding=1))
b3 = nn.Sequential(Inception(192, 64, (96, 128), (16, 32), 32),Inception(256, 128, (128, 192), (32, 96), 64),nn.MaxPool2d(kernel_size=3, stride=2, padding=1))
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_size=3, stride=2, padding=1))
b5 = nn.Sequential(Inception(832, 256, (160, 320), (32, 128), 128),Inception(832, 384, (192, 384), (48, 128), 128),nn.AdaptiveAvgPool2d((1,1)),nn.Flatten())net = nn.Sequential(b1, b2, b3, b4, b5, nn.Linear(1024, 10)).to(device, non_blocking=True)
2.2.4.2. 完整代码
import os
from tensorboardX import SummaryWriter
from alive_progress import alive_bar
import torch
from torch import nn, optim
from torch.nn import functional as F
from torch.utils.data import DataLoader
from torchvision.transforms import Compose, ToTensor, Resize
from torchvision.datasets import FashionMNISTdef load_dataset():"""加载数据集"""root = "./dataset"transform = Compose([Resize(96), ToTensor()])mnist_train = FashionMNIST(root, True, transform, download=True)mnist_test = FashionMNIST(root, False, transform, download=True)dataloader_train = DataLoader(mnist_train, batch_size, shuffle=True, num_workers=num_workers, pin_memory=True,)dataloader_test = DataLoader(mnist_test, batch_size, shuffle=False,num_workers=num_workers, pin_memory=True,)return dataloader_train, dataloader_testdef train_on_FashionMNIST(title):"""在FashionMNIST数据集上训练指定模型"""# 创建记录器def log_dir():root = "runs"if not os.path.exists(root):os.mkdir(root)order = len(os.listdir(root)) + 1return f'{root}/exp{order}'writer = SummaryWriter(log_dir=log_dir())# 数据集配置dataloader_train, dataloader_test = load_dataset()# 模型配置criterion = nn.CrossEntropyLoss(reduction='none')optimizer = optim.SGD(net.parameters(), lr=lr)# 训练循环metrics_train = torch.zeros(3, device=device)  # 训练损失、训练准确度、样本数metrics_test = torch.zeros(2, device=device)   # 测试准确度、样本数with alive_bar(num_epochs, theme='classic', title=title) as bar:for epoch in range(num_epochs):net.train()for X, y in dataloader_train:X, y = X.to(device, non_blocking=True), y.to(device, non_blocking=True)loss = criterion(net(X), y)optimizer.zero_grad()loss.mean().backward()optimizer.step()net.eval()with torch.no_grad():metrics_train.zero_()for X, y in dataloader_train:X, y = X.to(device, non_blocking=True), y.to(device, non_blocking=True)y_hat = net(X)loss = criterion(y_hat, y)metrics_train[0] += loss.sum()metrics_train[1] += (y_hat.argmax(dim=1) == y).sum()metrics_train[2] += y.numel()metrics_train[0] /= metrics_train[2]metrics_train[1] /= metrics_train[2]metrics_test.zero_()for X, y in dataloader_test:X, y = X.to(device, non_blocking=True), y.to(device, non_blocking=True)y_hat = net(X)metrics_test[0] += (y_hat.argmax(dim=1) == y).sum()metrics_test[1] += y.numel()metrics_test[0] /= metrics_test[1]_metrics_train = metrics_train.cpu().numpy()_metrics_test = metrics_test.cpu().numpy()writer.add_scalars('metrics', {'train_loss': _metrics_train[0],'train_acc': _metrics_train[1],'test_acc': _metrics_test[0]}, epoch)bar()writer.close()if __name__ == '__main__':# 全局参数配置num_epochs = 10batch_size = 128num_workers = 3lr = 0.1device = torch.device('cuda')# 模型配置class Inception(nn.Module):# c1--c4是每条路径的输出通道数def __init__(self, in_channels, c1, c2, c3, c4, **kwargs):super(Inception, self).__init__(**kwargs)# 线路1,单1x1卷积层self.p1_1 = nn.Conv2d(in_channels, c1, kernel_size=1)# 线路2,1x1卷积层后接3x3卷积层self.p2_1 = nn.Conv2d(in_channels, c2[0], kernel_size=1)self.p2_2 = nn.Conv2d(c2[0], c2[1], kernel_size=3, padding=1)# 线路3,1x1卷积层后接5x5卷积层self.p3_1 = nn.Conv2d(in_channels, c3[0], kernel_size=1)self.p3_2 = nn.Conv2d(c3[0], c3[1], kernel_size=5, padding=2)# 线路4,3x3最大汇聚层后接1x1卷积层self.p4_1 = nn.MaxPool2d(kernel_size=3, stride=1, padding=1)self.p4_2 = nn.Conv2d(in_channels, c4, kernel_size=1)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(self.p4_1(x)))# 在通道维度上连结输出return torch.cat((p1, p2, p3, p4), dim=1)b1 = nn.Sequential(nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3),nn.ReLU(),nn.MaxPool2d(kernel_size=3, stride=2, padding=1))b2 = nn.Sequential(nn.Conv2d(64, 64, kernel_size=1),nn.ReLU(),nn.Conv2d(64, 192, kernel_size=3, padding=1),nn.ReLU(),nn.MaxPool2d(kernel_size=3, stride=2, padding=1))b3 = nn.Sequential(Inception(192, 64, (96, 128), (16, 32), 32),Inception(256, 128, (128, 192), (32, 96), 64),nn.MaxPool2d(kernel_size=3, stride=2, padding=1))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_size=3, stride=2, padding=1))b5 = nn.Sequential(Inception(832, 256, (160, 320), (32, 128), 128),Inception(832, 384, (192, 384), (48, 128), 128),nn.AdaptiveAvgPool2d((1,1)),nn.Flatten())net = nn.Sequential(b1, b2, b3, b4, b5, nn.Linear(1024, 10)).to(device, non_blocking=True)def init_weights(m):if type(m) in [nn.Linear, nn.Conv2d]:nn.init.xavier_uniform_(m.weight)nn.init.zeros_(m.bias)net.apply(init_weights)# 在FashionMNIST数据集上训练模型train_on_FashionMNIST('GoogLeNet')
2.2.4.3. 输出结果

GoogLeNet

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/215258.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

家具制造ERP软件包含哪些功能?家具制造业ERP系统哪个好

不同的家具有不同的用料、品质、制造工时、营销渠道等,而有些家具制造企业采用传统的管理方式在处理物料BOM、生产实际成本核算、库存盘点、供应商选择、班组计件核对、生产领用以及物料追溯等方面存在不少提升空间。 与此同时也有很多的皮具制造企业借助ERP软件优…

Linux16 ftp文件服务区、vsftpd文件系统服务安装、lftp客户端安装、NFS远程共享存储

目录 一、FTP基础ftp主动模式ftp被动模式 二、vsftpd配置共享目录编辑配置文件使用windows 访问 三、客户端安装 (lftp)匿名用户的一些操作(lftp {ip})ftp配置本地用户登录配置本地用户ftp配置文件 lftp操作 NFS远程共享存储安装n…

新的侧通道攻击可泄露处理器的 Root 密码

阿姆斯特丹自由大学的一组科学家开发了一种名为 SLAM(Spectre Linear Address Masking)的侧信道攻击。 该攻击利用旨在提高新型Intel、AMD 和 Arm 处理器安全性的硬件功能,从内核内存中提取根密码哈希。 重现 SLAM 攻击所需的代码和所有数据…

dockerfile:创建镜像的方式,船舰自定义的镜像

dockerfile:创建镜像的方式,船舰自定义的镜像 包括配置文件,挂载点,对外暴露的端口,设置环境变量 docker创建镜像的方式 1、基于已有镜像进行创建。 根据官方提供的镜像源,创建镜像,然后拉起…

IP与以太网的转发操作

TCP模块在执行连接、收发、断开等各阶段操作时,都需要委托IP模块将数据封装成包发送给通信对象。 网络中有路由器和集线器两种不同的转发设备,它们在传输网络包时有着各自的分工。 (1)路由器根据目标地址判断下一个路由器的位置 (2)集线器在子网中将网…

k8s pod日志写入ELK的具体实现

shigen坚持更新文章的博客写手,擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长,分享认知,留住感动。 在上一部分,shigen讲到了k8spod的日志写入ELK的三种技术方案,并在最后展示了一下我…

【USRP】LFTX / LFRX

LFTX/LFRX 设备概述 LFTX 子板利用两个高速运算放大器来允许 0-30 MHz 的传输。该板仅接受实模式信号。LFTX 非常适合 HF 频段的应用,或使用外部前端来上变频和放大中间信号的应用。LFTX 的输出可以独立处理,也可以作为单个 I/Q 对进行处理。 主要特征…

Python - 搭建 Flask 服务实现图像、视频修复需求

目录 一.引言 二.服务构建 1.主函数 upload_gif 2.文件接收 3.专属目录 4.图像修复 5.gif2mp4 6.mp42gif 7.图像返回 三.服务测试 1.服务启动 2.服务调用 四.总结 一.引言 前面我们介绍了如何使用 Real-ESRGAN 进行图像增强并在原始格式 jpeg、jpg、mp4 的基础上…

HeartBeat监控Redis状态

目录 一、概述 二、 安装部署 三、配置 四、启动服务 五、查看数据 一、概述 使用heartbeat可以实现在kibana界面对redis服务存活状态进行观察,如有必要,也可在服务宕机后立即向相关人员发送邮件通知 二、 安装部署 参照文章:HeartBeat监…

关于IDEA中maven的作用以及如何配置MAVEN

关于IDEA中maven的作用以及如何配置MAVEN 1、Maven是什么2、Idea中对于Maven的配置3、下载依赖时,Idea下方的显示3.1、Maven中央仓库的下载显示界面3.2、阿里云仓库的下载显示界面 4、Maven在Idea中的使用4.1、clean4.2、validate4.3、compile4.4、test(…

智能优化算法应用:基于人工蜂群算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于人工蜂群算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于人工蜂群算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.人工蜂群算法4.实验参数设定5.算法结果6.…

从零构建属于自己的GPT系列5:模型部署1(文本生成函数解读、模型本地化部署、文本生成文本网页展示、代码逐行解读)

🚩🚩🚩Hugging Face 实战系列 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在PyCharm中进行 本篇文章配套的代码资源已经上传 从零构建属于自己的GPT系列1:数据预处理 从零构建属于自己的GPT系列2:模型训…

2023年国赛高教杯数学建模A题定日镜场的优化设计解题全过程文档及程序

2023年国赛高教杯数学建模 A题 定日镜场的优化设计 原题再现 构建以新能源为主体的新型电力系统,是我国实现“碳达峰”“碳中和”目标的一项重要措施。塔式太阳能光热发电是一种低碳环保的新型清洁能源技术[1]。   定日镜是塔式太阳能光热发电站(以下…

【Fastadmin】根据Fieldlist键值组件做一个等级配置的完整示例

目录 1.效果展示: ​编辑 2.建表: 3.html页面 4.controller控制器 5.js 6.model 1.效果展示: 2.建表: 表名:fa_xxfb_config /*Navicat Premium Data TransferSource Server : rootSource Server Type …

深入Docker命令行:探索常用命令和实用技巧

Docker命令行界面是每个容器开发者的得力工具。在这篇文章中,将深入探讨一系列常用的Docker命令,以及一些实用技巧,通过更丰富的示例代码,帮助大家更全面地理解和运用Docker命令行工具。 1. Docker基本命令 1.1 镜像操作 深入了…

用 CSS 写一个渐变色边框的输入框

Using_CSS_gradients MDN 多渐变色输入框&#xff0c;群友问了下&#xff0c;就试着写了下&#xff0c;看了看 css 渐变色 MDN 文档&#xff0c;其实很简单&#xff0c;代码记录下&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta ch…

使用FFMPEG转码,转单声道,转标准WAV,转PCM

本文为使用FFMPEG命令行的方式处理音频&#xff0c;来获取想要得到的音频文件。 零、使用命令行查看编码封装信息 格式&#xff1a;ffprobe.exe -show_format inputfile 例子&#xff1a;ffprobe.exe -show_format .\stereo_44_16bit.wav 运行结果为下图&#xff1a; 如图可…

西南科技大学数字电子技术实验四(基本触发器逻辑功能测试及FPGA的实现)预习报告

一、计算/设计过程 说明:本实验是验证性实验,计算预测验证结果。是设计性实验一定要从系统指标计算出元件参数过程,越详细越好。用公式输入法完成相关公式内容,不得贴手写图片。(注意:从抽象公式直接得出结果,不得分,页数可根据内容调整) (1)D触发器 特征方程: Q…

ChatGPT/GPT4应用:文本、论文、编程、绘图等,提高工作效率及科研项目开发能力

2023年随着OpenAI开发者大会的召开&#xff0c;最重磅更新当属GPTs&#xff0c;多模态API&#xff0c;未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚于互联网和个人电脑的问世。360创始人周鸿祎认为未来各行各业如果不能搭上这班车…

排序-选择排序与堆排序

文章目录 一、选择排序二、堆排序三、时间复杂度四、稳定性 一、选择排序 思想&#xff1a; 将数组第一个元素作为min&#xff0c;然后进行遍历与其他元素对比&#xff0c;找到比min小的数就进行交换&#xff0c;直到最后一个元素就停止&#xff0c;然后再将第二个元素min&…