pytorch cnn卷积神经网络代码详解 注释详细

"""---------------------cnn卷积神经网络---------------------"""
import torch
from torch import nn, optim
import torch.nn.functional as F
from torch.autograd import Variable
from torch.utils.data import DataLoader
from torchvision import transforms
from torchvision import datasets
from log1 import Logged

# 定义超参数
batch_size = 128
learning_rate = 1e-2
num_epoches = 20

"""04-Convolutional Neural Network"""
def to_np(x):
    return x.cpu().data.numpy()


# 下载训练集 MNIST 手写数字训练集
train_dataset = datasets.MNIST(
    root='F:/PycharmProjects/pytorch-beginner-master/02-Logistic Regression/data', train=False, transform=transforms.ToTensor(), download=True)

test_dataset = datasets.MNIST(
    root='F:/PycharmProjects/pytorch-beginner-master/02-Logistic Regression/data', train=False, transform=transforms.ToTensor())

train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)


#定义 Convolution Network 模型
#nn.Sequential:这个表示将一个有序的模块写在一起,也就相当于将神经网络的层按顺序放在一起,这样可以方便结构显示
class Cnn(nn.Module):
    def __init__(self, in_dim, n_class):
        super(Cnn, self).__init__()
        self.conv = nn.Sequential(
            # 开始输入[batch_size=128, in_dim=1, 28,28]经过第一层Conv2d后,用公式W2 = ((input-kernel_size+2padding)/stride) + 1计算输出为:[128,6,28,28]
            nn.Conv2d(in_channels=in_dim, out_channels=6, kernel_size=3, stride=1, padding=1),
            # 修正线性单元,是神经元的激活函数 默认设置为False,表示新创建一个对象对其修改,也可以设置为True,表示直接对这个对象进行修改
            nn.ReLU(True),#输入[128,6,28,28],输出为:[128,6,28,28]
            # 池化层可以非常有效地缩小矩阵的尺寸。从而减少最后全连接层中的参数
            nn.MaxPool2d(2, 2),#输入:[128,6,28,28]输出:[128,6,14,14]
            nn.Conv2d(6, 16, kernel_size=5, stride=1, padding=0),#输入:[128,6,14,14]输出:[128,16,10,10]
            nn.ReLU(True), #
        nn.MaxPool2d(kernel_size=2, stride=2))#输入:[128,16,10,10]输出:[128,16,5,5]

    self.fc = nn.Sequential(
        nn.Linear(400, 120), #输入为:[128,400],输出为:[128,120]
        nn.Linear(120, 84), #输入为:[128,120],输出为:[128,84]
        nn.Linear(84, n_class))#输入为:[128,84],输出为:[128,10]

def forward(self, x):
    out = self.conv(x)#输入x=[128,1,28,28],上面__init__一步步说明了out=[128,16,5,5]的由来
    #返回一个有相同数据但大小不同的tensor,-1就代表这个位置由其他位置的数字来推断
    out = out.view(out.size(0), -1)#out变为[128,x] x=128*16*5*5/128,所以x值为400,out为[128,400]
    out = self.fc(out)#进入这个函数看,输出为[128,10]
    return out


model = Cnn(in_dim=1, n_class=10)  # 图片大小是28x28
use_gpu = torch.cuda.is_available()  # 判断是否有GPU加速
if use_gpu:
    model = model.cuda()
# 定义loss和optimizer
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=learning_rate)
#logger = Logged('F:/PycharmProjects/pytorch-beginner-master/04-Convolutional Neural Network/logs')
#开始训练
for epoch in range(num_epoches):
    print('epoch {}'.format(epoch + 1))
    print('*' * 10)
    for i, data in enumerate(train_loader, 1):
        img, label = data
        if use_gpu:
            img = img.cuda()
            label = label.cuda()
        img = Variable(img)
        label = Variable(label)
        # 向前传播

    # 开始输入为[batch_size=128, in_dim=1, 28,28] 其分别代表:batch_size组数据,通道数为1,
    # 高度为28,宽为28,输出为[batch_size=128,n_class=10],详情进model函数看
    out = model(img)
    loss = criterion(out, label)

    # 向后传播
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if i % 20 == 0:
        print("loss: ", loss.data.item())


model.eval()
for data in test_loader:
    img, label = data
    if use_gpu:
        with torch.no_grad():
            img = Variable(img).cuda()
            label = Variable(label).cuda()
    else:
        with torch.no_grad():
            img = Variable(img)
            label = Variable(label)
    out = model(img)
    loss = criterion(out, label)
print("test loss: ", loss.data.item())

# 保存模型
torch.save(model.state_dict(), 'F:/PycharmProjects/pytorch-beginner-master/04-Convolutional Neural Network/cnn.pth')
  • 10
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
卷积神经网络(Convolutional Neural Networks,CNN)是一种深度学习神经网络,广泛应用于图像识别、语音识别、自然语言处理等领域。在本文中,我们将使用PyTorch实现一个简单的CNN,并对其进行详细的解释和应用实例。 ## CNN的基本结构 CNN由多个卷积层、池化层和全连接层组成。其中,卷积层和池化层是CNN最重要的部分。 ### 卷积层 卷积层CNN中最基本的层,它通过将输入数据与一组卷积核进行卷积操作,提取出数据特征。卷积层的输入为一个三维张量,维度分别为(通道数,高度,宽度),卷积核也是一个三维张量,维度分别为(输入通道数,卷积核高度,卷积核宽度),卷积层的输出为一个三维张量,维度同输入。 在PyTorch中,我们可以通过使用`nn.Conv2d`类来创建卷积层,例如: ``` import torch.nn as nn # 创建一个输入通道数为3,输出通道数为16,卷积核大小为3x3的卷积层 conv_layer = nn.Conv2d(in_channels=3, out_channels=16, kernel_size=3) ``` ### 池化层 池化层是CNN中用于降低特征图尺寸的一种方式。它通过对特征图进行下采样,减少特征图尺寸,同时保留重要的特征信息。常用的池化方式有最大池化和平均池化。 在PyTorch中,我们可以通过使用`nn.MaxPool2d`和`nn.AvgPool2d`类来创建最大池化层和平均池化层,例如: ``` # 创建一个2x2的最大池化层 max_pool_layer = nn.MaxPool2d(kernel_size=2) # 创建一个2x2的平均池化层 avg_pool_layer = nn.AvgPool2d(kernel_size=2) ``` ### 全连接层 全连接层是CNN中最后一层,它将卷积层和池化层提取出的特征图转换为一个一维向量,并连接到一个或多个全连接层进行分类或回归。在PyTorch中,我们可以使用`nn.Linear`类来创建全连接层,例如: ``` # 创建一个输入维度为256,输出维度为10的全连接层 fc_layer = nn.Linear(in_features=256, out_features=10) ``` ## CNN的应用实例 接下来,我们将使用PyTorch实现一个简单的CNN,并对其进行应用实例,以MNIST数据集为例,进行手写数字识别。 首先,我们需要导入必要的库: ``` import torch import torch.nn as nn import torch.optim as optim import torchvision import torchvision.transforms as transforms ``` 然后,我们需要定义CNN的结构。在本例中,我们定义一个包含两个卷积层和两个最大池化层的CNN,以及一个全连接层进行分类。其中,每个卷积层的卷积核大小为3x3,池化层的池化大小为2x2。 ``` class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv2d(in_channels=1, out_channels=16, kernel_size=3) self.pool1 = nn.MaxPool2d(kernel_size=2) self.conv2 = nn.Conv2d(in_channels=16, out_channels=32, kernel_size=3) self.pool2 = nn.MaxPool2d(kernel_size=2) self.fc1 = nn.Linear(in_features=32 * 5 * 5, out_features=120) self.fc2 = nn.Linear(in_features=120, out_features=10) def forward(self, x): x = self.pool1(torch.relu(self.conv1(x))) x = self.pool2(torch.relu(self.conv2(x))) x = x.view(-1, 32 * 5 * 5) x = torch.relu(self.fc1(x)) x = self.fc2(x) return x ``` 接下来,我们需要对训练数据进行预处理。在本例中,我们对数据进行了归一化,并将其转换为张量。 ``` transform = transforms.Compose( [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=64, shuffle=True, num_workers=2) testset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform) testloader = torch.utils.data.DataLoader(testset, batch_size=64, shuffle=False, num_workers=2) ``` 然后,我们定义损失函数和优化器。 ``` criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9) ``` 最后,我们进行训练和测试。 ``` for epoch in range(10): running_loss = 0.0 for i, data in enumerate(trainloader, 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 testloader: 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)) ``` 经过10次迭代的训练,最终得到的测试集准确率约为98%。 ## 总结 本文介绍了CNN的基本结构和应用实例,并使用PyTorch实现了一个简单的CNN进行手写数字识别。CNN是深度学习中非常重要的一种神经网络,广泛应用于图像识别、语音识别、自然语言处理等领域,希望本文对您有所帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值