手写字符的识别+pytorch

import torch
import torch.nn as nn
import numpy as np
import torchvision
import torchvision.transforms as transforms
import matplotlib.pyplot as plt


'''
确定当前环境是否支持 GPU 运行
'''
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(device)



'''
加载 PyTorch 中的自带数据集合
该数据集合存在于 torchvision.datasets 中,可以直接利用 torchvision.datasets.MNIST 获得
'''
# 将数据集合下载到指定目录下,这里的transform表示,数据加载时所需要做的预处理操作
# 加载训练集合
train_dataset = torchvision.datasets.MNIST(root='./data',
                                           train=True,
                                           transform=torchvision.transforms.ToTensor(),
                                           download=True)
# 加载测试集合
test_dataset = torchvision.datasets.MNIST(root='./data',
                                          train=False,
                                          transform=transforms.ToTensor())
print(train_dataset, test_dataset)
print("-------------------------------")

'''
把数据放入数据加载器中
'''
batch_size = 100
# 根据数据集定义数据加载器
train_loader = torch.utils.data.DataLoader(dataset=train_dataset,
                                           batch_size=batch_size,
                                           shuffle=True)

test_loader = torch.utils.data.DataLoader(dataset=test_dataset,
                                          batch_size=batch_size,
                                          shuffle=False)
print(train_loader, test_loader)


'''
在定义完 PyTorch 能够识别的数据加载器后
我们可以加载几张图片,观察一下图片效果:
'''
# 加载测试集中的前 6 张图片
examples = iter(test_loader)
example_data, example_targets = examples.next()

for i in range(6):
    plt.subplot(2, 3, i+1)
    plt.imshow(example_data[i][0], cmap='gray')

plt.show()


# 输入节点数就为图片的大小:28×28×1
input_size = 784
# 由于数字为 0-9,因此是10分类问题,因此输出节点数为 10
num_classes = 10


'''
利用 PyTorch 建立一个简单的神经网络模型用于手写字符的识别

第一层为输入层,节点数量和图像大小相同。
第二次为隐藏层,节点数为 500 。
第三层为输出层,节点大小为 10 ,节点数大小和类别相同。
'''
# 包含了一个隐含层的全联机神经网络
class NeuralNet(nn.Module):
    # 输入数据的维度,中间层的节点数,输出数据的维度
    def __init__(self, input_size, hidden_size, num_classes):
        super(NeuralNet, self).__init__()
        self.input_size = input_size
        self.l1 = nn.Linear(input_size, hidden_size)
        self.relu = nn.ReLU()
        self.l2 = nn.Linear(hidden_size, num_classes)

    def forward(self, x):
        out = self.l1(x)
        out = self.relu(out)
        out = self.l2(out)
        return out


device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# 建立了一个中间层为 500 的三层神经网络,且将模型转为当前环境支持的类型(CPU 或 GPU)
model = NeuralNet(input_size, 500, num_classes).to(device)
print(model)


'''
损失和优化器的定义
'''
criterion = nn.CrossEntropyLoss()
'''
利用 PyTorch 中定义的梯度下降算法的优化算法,Adam 算法,来进行模型的训练
'''
# 此时学习率为 0.001 ,你也可以根据实际情况,自行设置
learning_rate = 0.001
# 定义 Adam 优化器用于梯度下降
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
print(optimizer)



'''
模型的训练

通过 模型的正向传播,输出预测结果。
通过 预测结果和真实标签计算损失。
通过 后向传播,获得梯度。
通过 梯度更新模型的权重。
进行 梯度的清空。
    循环上面操作,直到损失较小为止。
'''
num_epochs = 2
# 数据总长度
n_total_steps = len(train_loader)
for epoch in range(num_epochs):
    for i, (images, labels) in enumerate(train_loader):
        # 因为全连接会把一行数据当做一条数据,因此我们需要将一张图片转换到一行上
        # 原始数据集的大小: [100, 1, 28, 28]
        # 将每一张图片都转为一行向量,
        # resize 后的向量大小: [100, 784]
        images = images.reshape(-1, 28*28).to(device)
        labels = labels.to(device)

        # 正向传播以及损失的求取
        outputs = model(images)
        loss = criterion(outputs, labels)

        # 反向传播
        # 下面三句话固定:梯度清空,反向传播,权重更新
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        if (i+1) % 100 == 0:
            print(
                f'Epoch [{epoch+1}/{num_epochs}], Step [{i+1}/{n_total_steps}], Loss: {loss.item():.4f}')
print("模型训练完成")



'''
模型已经训练完毕。
接下来,让我们先放入几张图片观察一下,预测结果是否和真实一致:
'''
# 测试样例
examples = iter(test_loader)
example_data, example_targets = examples.next()

# 图片的展示
for i in range(3):
    plt.subplot(1, 3, i+1)
    plt.imshow(example_data[i][0], cmap='gray')
plt.show()

# 结果的预测
images = example_data
images = images.reshape(-1, 28*28).to(device)
labels = labels.to(device)

# 正向传播以及损失的求取
outputs = model(images)
# 将 Tensor 类型的变量 example_targets 转为 numpy 类型的,方便展示
print("上面三张图片的真实结果:", example_targets[0:3].detach().numpy())
# 将得到预测结果
# 由于预测结果是 N×10 的矩阵,因此利用 np.argmax 函数取每行最大的那个值,最为预测值
not print("上面三张图片的预测结果:", np.argmax(outputs[0:3].detach().cpu().numpy(), axis=1))



'''
模型的测试

在训练完模型后,我们将导入测试数据集,对模型进行测试,对比模型的预测结果和实际结果,进而得到模型的识别准确率。
模型的测试代码很简单,其实就是将数据传入模型之中,并进行一次正向传播即可。
简单的说,就是复制上面的模型训练代码,然后更换数据集,删除后面的梯度下降相关的代码即可。
'''
# I测试数据,计算模型的识别准确率
with torch.no_grad():
    n_correct = 0
    n_samples = 0
    for images, labels in test_loader:
        # 和训练代码一致
        images = images.reshape(-1, 28*28).to(device)
        labels = labels.to(device)
        outputs = model(images)

        # 进行模型训练
        _, predicted = torch.max(outputs.data, 1)
        n_samples += labels.size(0)
        n_correct += (predicted == labels).sum().item()

    acc = 100.0 * n_correct / n_samples
    print(f'Accuracy of the network on the 10000 test images: {acc} %')
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HHHTTY-

你的鼓励将是我创作的最大动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值