44.卷积神经网络代码实现

卷积神经网络(CNN)相比于传统的多层感知机(MLP),最大的特点在于卷积层的引入。卷积层通过局部感知和权重共享的机制,有效地减少了网络参数的数量,使得网络更容易训练。本篇文章将通过经典的LeNet网络结构,从代码实现的角度,带大家一步一步地构建一个卷积神经网络。

什么是LeNet

LeNet是由Yann LeCun等人在1998年提出的卷积神经网络,也是最早出现的卷积神经网络之一,主要用于解决手写数字识别问题。LeNet在手写数字识别上的成功,使得卷积神经网络的应用受到了极大的关注,并为后来的卷积网络发展奠定了良好的基础。

LeNet的结构如图所示:
- 包含两个卷积层(Conv Layer)
- 两个下采样层(Pooling Layer)
- 三个全连接层(Fully Connected Layer)

输入图像尺寸为32x32,经过两次卷积和池化后,进入三个全连接层,最终输出对应0到9的10个数字的分类结果。

LeNet网络结构

LeNet的网络结构如下:
1. 输入:32x32的图像
2. 第一卷积层:6个5x5的卷积核,步长为1
3. 第一池化层:2x2的最大池化层
4. 第二卷积层:16个5x5的卷积核
5. 第二池化层:2x2的最大池化层
6. 三个全连接层:120个、84个和10个神经元

代码实现

1. 导入必要的库

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
from torchsummary import summary
import matplotlib.pyplot as plt
from tqdm import tqdm

2. 定义LeNet网络结构

class LeNet(nn.Module):
    def __init__(self):
        super(LeNet, self).__init__()
        self.conv1 = nn.Conv2d(in_channels=1, out_channels=6, kernel_size=5)
        self.conv2 = nn.Conv2d(in_channels=6, out_channels=16, kernel_size=5)
        self.fc1 = nn.Linear(in_features=16*4*4, out_features=120)
        self.fc2 = nn.Linear(in_features=120, out_features=84)
        self.fc3 = nn.Linear(in_features=84, out_features=10)

    def forward(self, x):
        x = torch.relu(self.conv1(x))
        x = torch.max_pool2d(x, kernel_size=2, stride=2)
        x = torch.relu(self.conv2(x))
        x = torch.max_pool2d(x, kernel_size=2, stride=2)
        x = x.view(-1, 16*4*4)
        x = torch.relu(self.fc1(x))
        x = torch.relu(self.fc2(x))
        x = self.fc3(x)
        return x

net = LeNet()

3. 模型摘要

summary(net, (1, 28, 28))

4. 准备数据集

transform = transforms.Compose([
    transforms.Resize((32, 32)),
    transforms.ToTensor(),
    transforms.Normalize((0.5,), (0.5,))
])

trainset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=32, shuffle=True)

testset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=32, shuffle=False)

5. 定义损失函数和优化器

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.02, momentum=0.9)

6. 训练模型

num_epochs = 10
train_loss = []
train_accuracy = []

for epoch in range(num_epochs):
    running_loss = 0.0
    correct = 0
    total = 0

    for inputs, labels in tqdm(trainloader):
        optimizer.zero_grad()
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        running_loss += loss.item()
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

    epoch_loss = running_loss / len(trainloader)
    epoch_accuracy = 100 * correct / total
    train_loss.append(epoch_loss)
    train_accuracy.append(epoch_accuracy)
    print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {epoch_loss:.4f}, Accuracy: {epoch_accuracy:.2f}%')

7. 可视化损失和准确率

plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(train_loss, label='Training Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.subplot(1, 2, 2)
plt.plot(train_accuracy, label='Training Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy (%)')
plt.legend()
plt.show()

8. 测试模型

net.eval()
correct = 0
total = 0
with torch.no_grad():
    for inputs, labels in testloader:
        outputs = net(inputs)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print(f'Test Accuracy: {100 * correct / total:.2f}%')

总结

在本篇文章中,我们介绍了经典的LeNet卷积神经网络,包括其网络结构和具体的代码实现。通过这次实现,我们不仅复习了卷积神经网络的基础知识,还掌握了如何在代码中实现一个完整的卷积神经网络模型。同学们可以在此基础上,调整参数或改进网络结构,进一步提高模型的性能。希望这篇文章对大家有所帮助,祝大家学习愉快!

如果有任何问题或建议,欢迎在评论区留言讨论。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好的,以下是一个简单的卷积神经网络代码实现(使用Python和PyTorch框架): 首先,需要导入必要的库和模块: ```python import torch import torch.nn as nn import torch.optim as optim import torch.nn.functional as F ``` 接下来,定义一个卷积神经网络的类: ```python class ConvNet(nn.Module): def __init__(self): super(ConvNet, self).__init__() self.conv1 = nn.Conv2d(3, 16, 3, padding=1) self.conv2 = nn.Conv2d(16, 32, 3, padding=1) self.pool = nn.MaxPool2d(2, 2) self.fc1 = nn.Linear(32 * 8 * 8, 128) self.fc2 = nn.Linear(128, 10) def forward(self, x): x = self.pool(F.relu(self.conv1(x))) x = self.pool(F.relu(self.conv2(x))) x = x.view(-1, 32 * 8 * 8) x = F.relu(self.fc1(x)) x = self.fc2(x) return x ``` 上述代码定义了一个包含两个卷积层和两个全连接层的简单卷积神经网络。该网络的输入是一个3通道的图像,输出是一个10维的向量,表示图像属于10个不同的类别之一。 接下来,定义数据加载器和优化器: ```python train_loader = torch.utils.data.DataLoader(train_data, batch_size=64, shuffle=True) test_loader = torch.utils.data.DataLoader(test_data, batch_size=64, shuffle=False) net = ConvNet() criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9) ``` 最后,训练和测试模型: ```python for epoch in range(10): running_loss = 0.0 for i, data in enumerate(train_loader, 0): inputs, labels = data optimizer.zero_grad() outputs = net(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() running_loss += loss.item() if i % 100 == 99: print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 100)) running_loss = 0.0 correct = 0 total = 0 with torch.no_grad(): for data in test_loader: images, labels = data outputs = net(images) _, predicted = torch.max(outputs.data, 1) total += labels.size(0) correct += (predicted == labels).sum().item() print('Accuracy of the network on the 10000 test images: %d %%' % ( 100 * correct / total)) ``` 上述代码中,我们使用交叉熵损失和随机梯度下降优化器进行训练,最后计算模型在测试集上的准确率。 ### 回答2: 卷积神经网络(Convolutional Neural Network,CNN)是一种常用于图像识别和处理的深度学习模型。下面我简单介绍一下CNN代码实现方式。 首先,我们需要导入相关的库,如TensorFlow或Keras。这些库提供了已经实现好的卷积和神经网络的函数和类。 接下来,我们需要建立CNN的模型架构。一般来说,一个CNN模型由卷积层(Convolutional Layer)、池化层(Pooling Layer)、全连接层(Fully Connected Layer)和输出层(Output Layer)组成。 在建立模型时,我们可以通过调用相关的函数或类来创建卷积层、池化层和全连接层,并指定它们的参数,如卷积核大小、池化窗口大小和全连接层的节点数。我们还可以选择不同的激活函数,如ReLU或sigmoid函数,来增加模型的非线性性能。 在模型建立好后,我们需要定义损失函数和优化算法来训练模型。常用的损失函数包括交叉熵损失函数(cross-entropy loss)和均方误差损失函数(mean-squared error loss),而优化算法则包括梯度下降法(gradient descent),Adam算法等。 最后,我们可以加载数据集进行训练和测试。这些数据集通常包含一些图像和相应的标签。我们可以使用相关的函数或类导入数据集,并将其传入模型进行训练。在训练过程中,模型会根据定义的损失函数和优化算法调整参数,以使得模型的预测结果尽可能接近真实标签。训练完成后,我们可以使用测试集评估模型的性能,如准确率、精确率和召回率等指标。 这就是简单的卷积神经网络代码实现的步骤。当然,真正实现一个完整的CNN模型可能需要更多的代码和调试,并根据具体的问题进行相应的调整。 ### 回答3: 卷积神经网络(Convolutional Neural Network,简称CNN)是一类广泛应用于图像识别、语音识别等领域的深度学习模型。下面以Python语言为例,简要介绍CNN代码实现过程。 首先,我们需要引入相关的库文件,例如tensorflow、keras等。 ```python import tensorflow as tf from tensorflow import keras ``` 接下来,我们需要构建CNN模型。通过keras库提供的API,可以方便地构建卷积层、池化层、全连接层等。 ```python model = keras.Sequential([ keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)), keras.layers.MaxPooling2D((2, 2)), keras.layers.Conv2D(64, (3, 3), activation='relu'), keras.layers.MaxPooling2D((2, 2)), keras.layers.Flatten(), keras.layers.Dense(64, activation='relu'), keras.layers.Dense(10, activation='softmax') ]) ``` 上述代码中,我们定义了一个包含两个卷积层和两个池化层的CNN模型。第一层是一个卷积层,包含32个卷积核,每个卷积核的大小为3x3,并使用ReLU激活函数。输入图像的形状为28x28x1。紧接着是一个池化层,使用2x2的窗口进行最大池化。再接下来是第二个卷积层和池化层,卷积核个数变为64。之后是一个Flatten层,用于将特征图展平为一维向量。最后的两个全连接层,分别包含64个和10个神经元,并使用ReLU和Softmax作为激活函数。 完成模型构建后,我们可以编译模型,设置优化器、损失函数和评估指标。 ```python model.compile(optimizer='adam', loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), metrics=['accuracy']) ``` 然后,我们可以加载和准备数据集。以MNIST手写数字识别数据集为例: ```python (x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data() x_train = x_train.reshape((60000, 28, 28, 1)) x_test = x_test.reshape((10000, 28, 28, 1)) x_train = x_train / 255.0 x_test = x_test / 255.0 ``` 下一步是对模型进行训练。 ```python model.fit(x_train, y_train, epochs=5, batch_size=64) ``` 最后,我们可以对模型进行评估。 ```python test_loss, test_acc = model.evaluate(x_test, y_test, verbose=2) print('\nTest accuracy:', test_acc) ``` 通过以上代码实现,我们可以建立一个简单的卷积神经网络模型,并使用MNIST手写数字数据集进行训练和评估。当然,这只是一个简单的示例,实际应用中的卷积神经网络可能更加复杂和庞大,需要根据具体问题进行适当的调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值