哈喽,我是小壮!
创建卷积神经网络(CNN),很多初学者不太熟悉,今儿咱们来大概说说,给一个完整的案例进行说明。
CNN 用于图像分类、目标检测、图像生成等任务。它的关键思想是通过卷积层和池化层来自动提取图像的特征,并通过全连接层进行分类。
原理
1.卷积层(Convolutional Layer):
卷积层使用卷积操作从输入图像中提取特征。卷积操作涉及一个可学习的卷积核(filter/kernel),该核在输入图像上滑动,并计算滑动窗口下的点积。这有助于提取局部特征,使网络对平移不变性更强。
公式:
其中,x是输入,w是卷积核,b是偏置。
2.池化层(Pooling Layer):
池化层用于减小数据的空间维度,减少计算量,并提取最显著的特征。最大池化是常用的一种方式,在每个窗口中选择最大的值。
公式(最大池化):
3.全连接层(Fully Connected Layer):
全连接层用于将卷积和池化层提取的特征映射到输出类别。它连接到前一层的所有神经元。
实战步骤和详解
1.步骤
- 导入必要的库和模块。
- 定义网络结构:使用nn.Module定义一个继承自它的自定义神经网络类,定义卷积层、激活函数、池化层和全连接层。
- 定义损失函数和优化器。
- 加载和预处理数据。
- 训练网络:使用训练数据迭代训练网络参数。
- 测试网络:使用测试数据评估模型性能。
2.代码实现
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
# 定义卷积神经网络类
class SimpleCNN(nn.Module):
def __init__(self):
super(SimpleCNN, self).__init__()
# 卷积层1
self.conv1 = nn.Conv2d(in_channels=1, out_channels=16, kernel_size=3, stride=1, padding=1)
self.relu = nn.ReLU()
self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
# 卷积层2
self.conv2 = nn.Conv2d(in_channels=16, out_channels=32, kernel_size=3, stride=1, padding=1)
# 全连接层
self.fc1 = nn.Linear(32 * 7 * 7, 10) # 输入大小根据数据调整
def forward(self, x):
x = self.conv1(x)
x = self.relu(x)
x = self.pool(x)
x = self.conv2(x)
x = self.relu(x)
x = self.pool(x)
x = x.view(-1, 32 * 7 * 7)
x = self.fc1(x)
return x
# 定义损失函数和优化器
net = SimpleCNN()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(net.parameters(), lr=0.001)
# 加载和预处理数据
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=64, shuffle=True)
# 训练网络
num_epochs = 5
for epoch in range(num_epochs):
for i, (images, labels) in enumerate(train_loader):
optimizer.zero_grad()
outputs = net(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
if (i+1) % 100 == 0:
print(f'Epoch [{epoch+1}/{num_epochs}], Step [{i+1}/{len(train_loader)}], Loss: {loss.item()}')
# 测试网络
net.eval()
with torch.no_grad():
correct = 0
total = 0
for images, labels in test_loader:
outputs = net(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
accuracy = correct / total
print('Accuracy on the test set: {}%'.format(100 * accuracy))
分享说明:转发分享请注明出处。