PyTorch搭建卷积神经网络(CNN)实现手写数字识别

1.卷积神经网络介绍

卷积神经网络(Convolutional Neural Networks, CNN)是一类包含卷积计算且具有深度结构的前馈神经网络(Feedforward Neural Networks),是深度学习(deep learning)的代表算法之一 。卷积神经网络具有表征学习(representation learning)能力,能够按其阶层结构对输入信息进行平移不变分类(shift-invariant classification),因此也被称为“平移不变人工神经网络(Shift-Invariant Artificial Neural Networks, SIANN)” 

2.卷积神经网络架构 

卷积神经网络主要包括卷积层,采样层(一般做最大池化)和全连接层(FC层)。

3.Pytorch实现卷积神经网络 

  • 卷积层:nn.Conv2d() 

其参数如下:

  • 池化层:nn.MaxPool2d()

其参数如下: 

4.实现MINST手写数字识别

一共定义了五层,其中两层卷积层,两层池化层,最后一层为FC层进行分类输出。其网络结构如下:

 具体的图片大小计算如下图:

 5.代码实现

import torch
from torchvision import transforms  # 是一个常用的图片变换类
from torchvision import datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F

batch_size = 64
transform = transforms.Compose(
    [
        transforms.ToTensor(),  # 把数据转换成张量
        transforms.Normalize((0.1307,), (0.3081,))  # 0.1307是均值,0.3081是标准差
    ]
)
train_dataset = datasets.MNIST(root='../dataset/mnist',
                               train=True,
                               download=True,
                               transform=transform)
train_loader = DataLoader(train_dataset,
                          shuffle=True,
                          batch_size=batch_size)
test_dataset = datasets.MNIST(root='../dataset/mnist',
                              train=False,
                              download=True,
                              transform=transform)
test_loader = DataLoader(test_dataset,
                         shuffle=True,
                         batch_size=batch_size)


class CNN(torch.nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.layer1 = torch.nn.Sequential(
            torch.nn.Conv2d(1, 25, kernel_size=3),
            torch.nn.BatchNorm2d(25),
            torch.nn.ReLU(inplace=True)
        )

        self.layer2 = torch.nn.Sequential(
            torch.nn.MaxPool2d(kernel_size=2, stride=2)
        )

        self.layer3 = torch.nn.Sequential(
            torch.nn.Conv2d(25, 50, kernel_size=3),
            torch.nn.BatchNorm2d(50),
            torch.nn.ReLU(inplace=True)
        )

        self.layer4 = torch.nn.Sequential(
            torch.nn.MaxPool2d(kernel_size=2, stride=2)
        )

        self.fc = torch.nn.Sequential(
            torch.nn.Linear(50 * 5 * 5, 1024),
            torch.nn.ReLU(inplace=True),
            torch.nn.Linear(1024, 128),
            torch.nn.ReLU(inplace=True),
            torch.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)  # 在进入全连接层之前需要把数据拉直Flatten
        x = self.fc(x)
        return x


model = CNN()
# 下面两行代码主要是如果有GPU那么就使用GPU跑代码,否则就使用cpu。cuda:0表示第1块显卡
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")  # 将数据放在GPU上跑所需要的代码
model.to(device)  # 将数据放在GPU上跑所需要的代码
criterion = torch.nn.CrossEntropyLoss()  # 使用交叉熵损失
optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.5)  # momentum表示冲量,冲出局部最小


def train(epochs):
    running_loss = 0.0
    for batch_idx, data in enumerate(train_loader, 0):
        inputs, target = data
        inputs, target = inputs.to(device), target.to(device)  # 将数据放在GPU上跑所需要的代码
        optimizer.zero_grad()
        # 前馈+反馈+更新
        outputs = model(inputs)
        loss = criterion(outputs, target)
        loss.backward()
        optimizer.step()

        running_loss += loss.item()
        if batch_idx % 300 == 299:  # 不让他每一次小的迭代就输出,而是300次小迭代再输出一次
            print('[%d,%5d] loss:%.3f' % (epoch + 1, batch_idx + 1, running_loss / 300))
            running_loss = 0.0
    torch.save(model, 'model_{}.pth'.format(epochs))


def test():
    correct = 0
    total = 0
    with torch.no_grad():  # 下面的代码就不会再计算梯度
        for data in test_loader:
            inputs, target = data
            inputs, target = inputs.to(device), target.to(device)  # 将数据放在GPU上跑所需要的代码
            outputs = model(inputs)
            _, predicted = torch.max(outputs.data, dim=1)  # _为每一行的最大值,predicted表示每一行最大值的下标
            total += target.size(0)
            correct += (predicted == target).sum().item()
    print('Accuracy on test set:%d %%' % (100 * correct / total))


if __name__ == '__main__':
    for epoch in range(10):
        train(epoch)
        test()

 6.结果

         

  • 15
    点赞
  • 95
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是用Python搭建CNN-GRU实现多变量特征提取的步骤: 1. 导入所需的库: ``` python import numpy as np from keras.models import Sequential from keras.layers import Dense, Dropout, Activation, Flatten, Reshape from keras.layers import Conv1D, MaxPooling1D from keras.layers import GRU ``` 2. 定义模型: ``` python model = Sequential() # 添加卷积层和池化层 model.add(Conv1D(filters=32, kernel_size=3, padding='same', input_shape=(timesteps, input_dim))) model.add(Activation('relu')) model.add(MaxPooling1D(pool_size=2)) # 添加卷积层和池化层 model.add(Conv1D(filters=64, kernel_size=3, padding='same')) model.add(Activation('relu')) model.add(MaxPooling1D(pool_size=2)) # 添加卷积层和池化层 model.add(Conv1D(filters=128, kernel_size=3, padding='same')) model.add(Activation('relu')) model.add(MaxPooling1D(pool_size=2)) # 添加GRU层 model.add(GRU(units=128, return_sequences=True)) model.add(Dropout(0.2)) # 添加GRU层 model.add(GRU(units=64, return_sequences=False)) model.add(Dropout(0.2)) # 添加全连接层 model.add(Dense(units=output_dim)) model.add(Activation('softmax')) # 编译模型 model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) ``` 3. 训练模型: ``` python model.fit(X_train, Y_train, batch_size=batch_size, epochs=epochs, validation_data=(X_test, Y_test)) ``` 其中,X_train是训练数据,Y_train是训练标签,batch_size是批量大小,epochs是训练次数,X_test是测试数据,Y_test是测试标签。 4. 预测: ``` python Y_pred = model.predict(X_test) ``` 其中,Y_pred是预测结果。 希望这个回答对你有所帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值