AI智能
改变未来

卷积神经网络中nn.Conv2d()和nn.MaxPool2d()以及卷积神经网络实现minist数据集分类


卷积神经网络中nn.Conv2d()和nn.MaxPool2d()

卷积神经网络之Pythorch实现:

nn.Conv2d()

就是PyTorch中的卷积模块

参数列表| 参数 | 作用 || ———— | ——————————————— || in_channels | 输入数据体的深度 || out_channels | 输出数 据体的深度 || kernel_size | 滤波器(卷积核)的大小 注1 || stride | 滑动的步长 || padding | 零填充的圈数 注2 || bias | 是否启用偏置,默认是True,代表启用 || groups | 输出数据体深度上和输入数 据体深度上的联系 注3 || dilation | 卷积对于输入数据体的空间间隔 注4 |

注:1. 可以使用一 个数字来表示高和宽相同的卷积核,比如 kernel_size=3,也可以使用 不同的数字来表示高和宽不同的卷积核,比如 kernel_size=(3, 2);

  1. padding=0表示四周不进行零填充,而 padding=1表示四周进行1个像素点的零填充;

  2. groups表示输出数据体深度上和输入数 据体深度上的联系,默认 groups=1,也就是所有的输出和输入都是相 关联的,如果 groups=2,这表示输入的深度被分割成两份,输出的深 度也被分割成两份,它们之间分别对应起来,所以要求输出和输入都 必须要能被 groups整除。

  3. 默认dilation=1详情见 nn.Conv2d()中dilation参数的作用或者CSDN

nn.MaxPool2d()

表示网络中的最大值池化

参数列表:

参数 作用
kernel_size 与上面

nn.Conv2d()

相同

stride 与上面

nn.Conv2d()

相同

padding 与上面

nn.Conv2d()

相同

dilation 与上面

nn.Conv2d()

相同

return_indices 表示是否返回最大值所处的下标,默认 return_indices=False
ceil_mode 表示使用一些方格代替层结构,默认 ceil_mode=False

注:一般不会去设置

return_indices

ceil_mode

参数

import torch.nn as nnclass SimpleCNN(nn.Module):def __init__(self):super(SimpleCNN, self).__init__()layer1 = nn.Sequential()# 把一个三通道的照片RGB三个使用32组卷积核卷积,每组三个卷积核,组内卷积后相加得出32组输出layer1.add_module(\'conv1\', nn.Conv2d(3, 32, (3, 3), (1, 1), padding=1))layer1.add_module(\'relu1\', nn.ReLU(True))layer1.add_module(\'pool1\', nn.MaxPool2d(2, 2))self.layer1 = layer1layer2 = nn.Sequential()layer2.add_module(\'conv2\', nn.Conv2d(32, 64, (3, 3), (1, 1), padding=1))layer2.add_module(\'relu2\', nn.ReLU(True))layer2.add_module(\'pool2\', nn.MaxPool2d(2, 2))self.layer2 = layer2layer3 = nn.Sequential()layer3.add_module(\'conv3\', nn.Conv2d(64, 128, (3, 3), (1, 1), padding=1))layer3.add_module(\'relu3\', nn.ReLU(True))layer3.add_module(\'pool3\', nn.MaxPool2d(2, 2))self.layer3 = layer3layer4 = nn.Sequential()layer4.add_module(\'fc1\', nn.Linear(2048, 512))layer4.add_module(\'fc_relu1\', nn.ReLU(True))layer4.add_module(\'fc2\', nn.Linear(512, 64))layer4.add_module(\'fc_relu2\', nn.ReLU(True))layer4.add_module(\'f3\', nn.Linear(64, 10))self.layer4 = layer4def forward(self, x):conv1 = self.layer1(x)conv2 = self.layer2(conv1)conv3 = self.layer3(conv2)fc_input = conv3.view(conv3.size(0), -1)fc_out = self.layer4(fc_input)return fc_outmodel = SimpleCNN()print(model)

输出

SimpleCNN((layer1): Sequential((conv1): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(relu1): ReLU(inplace=True)(pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False))(layer2): Sequential((conv2): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1))(relu2): ReLU(inplace=True)(pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False))(layer3): Sequential((conv3): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(relu3): ReLU(inplace=True)(pool3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False))(layer4): Sequential((fc1): Linear(in_features=2048, out_features=512, bias=True)(fc_relu1): ReLU(inplace=True)(fc2): Linear(in_features=512, out_features=64, bias=True)(fc_relu2): ReLU(inplace=True)(f3): Linear(in_features=64, out_features=10, bias=True)))

提取模型的层级结构

提取层级结构可以使用以下几个

nn.Model

的属性,第一个是

children()

属性,它会返回下一级模块的迭代器,在上面这个模型中,它会返回在self.layer1,self.layer2,self.layer4上的迭代器而不会返回它们内部的东西;

modules()

会返回模型中所有的模块的迭代器,这样它就能访问到最内层,比如self.layer1.conv1这个模块;还有一个与它们相对应的是

name_children()

属性以及

named_modules()

,这两个不仅会返回模块的迭代器,还会返回网络层的名字。

提取出model中的前两层

nn.Sequential(*list(model.children())[:2])

输出:

Sequential((0): Sequential((conv1): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(relu1): ReLU(inplace=True)(pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False))(1): Sequential((conv2): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(relu2): ReLU(inplace=True)(pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)))

提取出model中的所有卷积层

conv_model = nn.Sequential()for layer in model.named_modules():if isinstance(layer[1], nn.Conv2d):conv_model.add_module(layer[0].split(\'.\')[1] ,layer[1])print(conv_model)

输出:

Sequential((conv1): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(conv2): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(conv3): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)))

提取网络参数并对其初始化

nn.Moudel

里面有两个特别重要的关于参数的属性,分别是

named_parameters()

parameters()

。前者会输出网络层的名字和参数的迭代器,后者会给出一个网络的全部参数的迭代器。

for param in model.named_parameters():print(param[0])# print(param[1])

输出:

layer1.conv1.weightlayer1.conv1.biaslayer2.conv2.weightlayer2.conv2.biaslayer3.conv3.weightlayer3.conv3.biaslayer4.fc1.weightlayer4.fc1.biaslayer4.fc2.weightlayer4.fc2.biaslayer4.f3.weightlayer4.f3.bias

主流神经网络案例分析

案例:使用卷积神经网络实现对Minist数据集的预测

import matplotlib.pyplot as pltimport torch.utils.dataimport torchvision.datasetsimport osimport torch.nn as nnfrom torchvision import transformsclass CNN(nn.Module):def __init__(self):super(CNN, self).__init__()self.layer1 = nn.Sequential(nn.Conv2d(1, 16, kernel_size=(3, 3)),nn.BatchNorm2d(16),nn.ReLU(inplace=True),)self.layer2 = nn.Sequential(nn.Conv2d(16, 32, kernel_size=(3, 3)),nn.BatchNorm2d(32),nn.ReLU(inplace=True),nn.MaxPool2d(kernel_size=2, stride=2),)self.layer3 = nn.Sequential(nn.Conv2d(32, 64, kernel_size=(3, 3)),nn.BatchNorm2d(64),nn.ReLU(inplace=True))self.layer4 = nn.Sequential(nn.Conv2d(64, 128, kernel_size=(3, 3)),nn.BatchNorm2d(128),nn.ReLU(inplace=True),nn.MaxPool2d(kernel_size=2, stride=2))self.fc = nn.Sequential(nn.Linear(128 * 4 * 4, 1024),nn.ReLU(inplace=True),nn.Linear(1024, 128),nn.Linear(128, 10))def forward(self, x):x = self.layer1(x)x = self.layer2(x)x = self.layer3(x)x = self.layer4(x)x = x.view(x.size(0), -1)x = self.fc(x)return xos.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"data_tf = transforms.Compose([transforms.ToTensor(),transforms.Normalize([0.5], [0.5])])train_dataset = torchvision.datasets.MNIST(root=\'F:/机器学习/pytorch/书/data/mnist\', train=True,transform=data_tf, download=True)test_dataset = torchvision.datasets.MNIST(root=\'F:/机器学习/pytorch/书/data/mnist\', train=False,transform=data_tf, download=True)batch_size = 100train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size)test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=batch_size)model = CNN()model = model.cuda()criterion = nn.CrossEntropyLoss()criterion = criterion.cuda()optimizer = torch.optim.Adam(model.parameters())# 节约时间,三次够了iter_step = 3loss1 = []loss2 = []for step in range(iter_step):loss1_count = 0loss2_count = 0for images, labels in train_loader:images = images.cuda()labels = labels.cuda()images = images.reshape(-1, 1, 28, 28)output = model(images)pred = output.squeeze()optimizer.zero_grad()loss = criterion(pred, labels)loss.backward()optimizer.step()_, pred = torch.max(pred, 1)loss1_count += int(torch.sum(pred == labels)) / 100# 测试else:test_loss = 0accuracy = 0with torch.no_grad():for images, labels in test_loader:images = images.cuda()labels = labels.cuda()pred = model(images.reshape(-1, 1, 28, 28))_, pred = torch.max(pred, 1)loss2_count += int(torch.sum(pred == labels)) / 100loss1.append(loss1_count / len(train_loader))loss2.append(loss2_count / len(test_loader))print(f\'第{step}次训练:训练准确率:{loss1[len(loss1)-1]},测试准确率:{loss2[len(loss2)-1]}\')plt.plot(loss1, label=\'Training loss\')plt.plot(loss2, label=\'Validation loss\')plt.legend()

输出:

第0次训练:训练准确率:0.9646166666666718,测试准确率:0.9868999999999996第1次训练:训练准确率:0.9865833333333389,测试准确率:0.9908999999999998第2次训练:训练准确率:0.9917000000000039,测试准确率:0.9879999999999994<matplotlib.legend.Legend at 0x21f03092fd0>

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » 卷积神经网络中nn.Conv2d()和nn.MaxPool2d()以及卷积神经网络实现minist数据集分类