CNN卷积神经网络,你知道多少?
举个例子,下面是一张图片以及假设对应的图片像素数值:
假设有有一张16x16x3的输入图像,其中32x32x3指图像的高度x宽度x通道数,通道数是RGB,也就是红色(Red)、绿色(Green)、蓝色(Blue)三个通道。下面进行图像卷积:
全连接层(Fully Connected Layer)是深度学习中一种基本的神经网络层,也称为密集层(Dense Layer)。全连接层的作用是将上一层的所有神经元都连接到当前层的每一个神经元上,从而实现输入与输出之间的全连接。
在全连接层中,每个输入神经元都与每个输出神经元相连接,每个连接都有一个可学习的权重和一个偏置项。这些权重和偏置项是需要通过反向传播算法进行学习的。全连接层的输出可以通过激活函数进行非线性变换,通常使用ReLU或sigmoid等激活函数。
全连接层的主要作用是将上一层的所有神经元都连接到当前层的每一个神经元上,从而实现输入与输出之间的全连接。在卷积神经网络中,全连接层通常用于将卷积层和池化层提取的特征进行压缩和分类。
# PyTorch的主要模块
import torch
# 用于构建神经网络的模块
import torch.nn as nn
# 用于定义优化器的模块
import torch.optim as optim
# 用于对图像进行变换的模块
import torchvision.transforms as transforms
# 包含了一些常见的数据集,例如MNIST、CIFAR-10等。
import torchvision.datasets as datasets
# ===定义卷积神经网络模型
# 定义了一个名为Net的类,继承自nn.Module类
class Net(nn.Module):
def __init__(self):
# 调用父级的初始化函数
super(Net, self).__init__()
# 定义了一个卷积层,输入通道数为1,输出通道数为32,卷积核大小为3x3。
self.conv1 = nn.Conv2d(1, 32, kernel_size=3)
# 定义了一个最大池化层,池化核大小为2x2,步长为2。
self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
# 定义了另一个卷积层,输入通道数为32,输出通道数为64,卷积核大小为3x3。
self.conv2 = nn.Conv2d(32, 64, kernel_size=3)
# 定义了一个全连接层,输入大小为64x5x5,输出大小为128。
self.fc1 = nn.Linear(64 * 5 * 5, 128)
# 定义了另一个全连接层,输入大小为128,输出大小为10。
self.fc2 = nn.Linear(128, 10)
# 定义了模型的前向传播函数,用于计算输入x的输出。
def forward(self, x):
# 先进行卷积操作,再进行ReLU激活操作,最后进行池化操作。
x = self.pool(nn.functional.relu(self.conv1(x)))
# 同上,再进行一次卷积操作、ReLU激活操作和池化操作。
x = self.pool(nn.functional.relu(self.conv2(x)))
# 将上一层的输出展平成一维向量。
x = x.view(-1, 64 * 5 * 5)
# 进行一次全连接操作,并进行ReLU激活操作。
x = nn.functional.relu(self.fc1(x))
# 进行另一次全连接操作,得到最终的输出。
x = self.fc2(x)
# 返回输出结果
return x
# 加载数据集
""""
加载MNIST数据集,并进行预处理,
将输入图像的像素值进行归一化处理,
然后将数据集转换为PyTorch的DataLoader对象,以便进行批量处理。
"""
# 定义了一个变换transform,先将图像转换为张量,然后对图像的像素值进行归一化处理,使得像素值的范围为[-1,1]。
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
# 定义了一个训练集train_set,使用MNIST数据集,
# 指定数据集存储的根目录为'./data',train=True表示使用训练集,
# download=True表示如果数据集不存在,则下载数据集,transform=transform表示对数据集进行预处理。
train_set = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
# 定义了一个测试集test_set,使用MNIST数据集,指定数据集存储的根目录为'./data',train=False表示使用测试集,
# download=True表示如果数据集不存在,则下载数据集,transform=transform表示对数据集进行预处理。
test_set = datasets.MNIST(root='./data', train=False, download=True, transform=transform)
# 定义了一个训练集的DataLoader对象train_loader,使用train_set作为数据源,batch_size=64表示每个批次的样本数为64,
# shuffle=True表示对数据进行随机打乱。
train_loader = torch.utils.data.DataLoader(train_set, batch_size=64, shuffle=True)
# 定义了一个测试集的DataLoader对象test_loader,使用test_set作为数据源,
# batch_size=64表示每个批次的样本数为64,shuffle=False表示不对数据进行随机打乱。
test_loader = torch.utils.data.DataLoader(test_set, batch_size=64, shuffle=False)
# 定义了一个卷积神经网络模型model,使用之前定义的Net类进行初始化。
model = Net()
# 定义了一个交叉熵损失函数criterion,用于计算模型输出与真实标签之间的损失。
criterion = nn.CrossEntropyLoss()
# 定义了一个随机梯度下降优化器optimizer,使用model.parameters()获取模型参数,
# lr=0.01表示学习率为0.01,momentum=0.9表示使用动量梯度下降法,
# 并设置动量参数为0.9。优化器的作用是根据损失函数计算的梯度来更新模型的参数,从而使模型的输出更接近真实标签。
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
# 进行10个epoch的训练
for epoch in range(10):
# 将running_loss置为0,用于记录每个epoch的累积损失。
running_loss = 0.0
# 遍历train_loader中的数据,使用enumerate函数获取数据的索引i和数据本身data。
for i, data in enumerate(train_loader, 0):
# 将data中的输入和标签分别赋值给inputs和labels。
labels = data
# 将优化器的梯度清零,避免梯度累加。
optimizer.zero_grad()
# 将输入数据输入到模型中进行前向传播,得到模型的输出。
outputs = model(inputs)
# 计算模型输出与真实标签之间的损失,使用之前定义的交叉熵损失函数criterion
loss = criterion(outputs, labels)
# 对损失进行反向传播,计算模型参数的梯度。
loss.backward()
# 使用优化器更新模型的参数,以减小损失
optimizer.step()
# 累加当前批次的损失到running_loss中。
running_loss += loss.item()
# 如果遍历了100个批次,则执行下面的代码。
if i % 100 == 99:
# 打印当前epoch和当前批次的平均损失。
%5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 100))
# 将running_loss置为0,用于记录下一个批次的累积损失。
running_loss = 0.0
# =====测试模型
# 将正确分类的样本数初始化为0。
correct = 0
# 将样本总数初始化为0。
total = 0
# 在测试过程中不需要计算梯度,因此使用torch.no_grad()上下文管理器禁用梯度计算。
with torch.no_grad():
# 遍历test_loader中的数据
for data in test_loader:
# 将data中的输入和标签分别赋值给images和labels。
labels = data
# 将输入数据输入到模型中进行前向传播,得到模型的输出。
outputs = model(images)
# 返回每个样本在输出中概率最大的类别,并将预测结果赋值给predicted。
predicted = torch.max(outputs.data, 1)
# 累加当前批次中的样本数到total中。
total += labels.size(0)
# 计算当前批次中预测正确的样本数,并累加到correct中。
correct += (predicted == labels).sum().item()
# 计算模型在测试集上的准确率,并将结果打印出来。
of the network on the 10000 test images: %d %%' % (100 * correct / total))
[1, 100] loss: 1.291
[1, 200] loss: 0.241
[1, 300] loss: 0.162
[1, 400] loss: 0.130
[1, 500] loss: 0.115
[1, 600] loss: 0.102
[1, 700] loss: 0.091
[1, 800] loss: 0.077
[1, 900] loss: 0.074
[2, 100] loss: 0.062
[2, 200] loss: 0.070
[2, 300] loss: 0.060
[2, 400] loss: 0.053
[2, 500] loss: 0.043
[2, 600] loss: 0.053
[2, 700] loss: 0.046
[2, 800] loss: 0.058
[2, 900] loss: 0.051
[3, 100] loss: 0.041
[3, 200] loss: 0.035
[3, 300] loss: 0.037
[3, 400] loss: 0.032
[3, 500] loss: 0.043
[3, 600] loss: 0.043
[3, 700] loss: 0.048
[3, 800] loss: 0.042
[3, 900] loss: 0.029
[4, 100] loss: 0.022
[4, 200] loss: 0.033
[4, 300] loss: 0.031
[4, 400] loss: 0.034
[4, 500] loss: 0.034
[4, 600] loss: 0.032
[4, 700] loss: 0.032
[4, 800] loss: 0.032
[4, 900] loss: 0.021
[5, 100] loss: 0.020
[5, 200] loss: 0.022
[5, 300] loss: 0.020
[5, 400] loss: 0.026
[5, 500] loss: 0.015
[5, 600] loss: 0.028
[5, 700] loss: 0.029
[5, 800] loss: 0.024
[5, 900] loss: 0.028
[6, 100] loss: 0.017
[6, 200] loss: 0.020
[6, 300] loss: 0.019
[6, 400] loss: 0.019
[6, 500] loss: 0.020
[6, 600] loss: 0.027
[6, 700] loss: 0.019
[6, 800] loss: 0.017
[6, 900] loss: 0.018
[7, 100] loss: 0.019
[7, 200] loss: 0.011
[7, 300] loss: 0.011
[7, 400] loss: 0.020
[7, 500] loss: 0.016
[7, 600] loss: 0.013
[7, 700] loss: 0.011
[7, 800] loss: 0.016
[7, 900] loss: 0.017
[8, 100] loss: 0.008
[8, 200] loss: 0.010
[8, 300] loss: 0.016
[8, 400] loss: 0.010
[8, 500] loss: 0.018
[8, 600] loss: 0.012
[8, 700] loss: 0.016
[8, 800] loss: 0.010
[8, 900] loss: 0.012
[9, 100] loss: 0.008
[9, 200] loss: 0.006
[9, 300] loss: 0.010
[9, 400] loss: 0.014
[9, 500] loss: 0.010
[9, 600] loss: 0.010
[9, 700] loss: 0.010
[9, 800] loss: 0.011
[9, 900] loss: 0.012
[10, 100] loss: 0.010
[10, 200] loss: 0.009
[10, 300] loss: 0.014
[10, 400] loss: 0.006
[10, 500] loss: 0.005
[10, 600] loss: 0.007
[10, 700] loss: 0.011
[10, 800] loss: 0.009
[10, 900] loss: 0.016
Accuracy of the network on the 10000 test images: 99 %
THE END