pytorch学习记录----手写识别(使用腾讯智能钛平台跑模型)

目的

使用深度学习框架Pytorch,实现手写数字的识别。
深度学习入门的经典例子。数据集采用MNIST自带的手写数据集。数据集里面的数据长啥样?emmmm
差不多这个样吧
在这里插入图片描述

模型构建

,,这种东西对于我们这样的初学者来说,当然不大可能是自己定义啦,,,只要看的懂别人的,会调参即可。
同时,,我自己的电脑GPU有点辣鸡,所以emmm,,,当然是借助于云平台啦。。
去淘宝租也好,,找各大平台白嫖也可。。。反正,,学生党嘛,,哈哈。扯远了。
模型用的腾讯云的智能钛机器学习的例子的模型。我就大概解读下。

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 10, kernel_size=5) # 对图片进行第一次卷积。由于图片是灰色的,所以第一个参数是1,从中提取10个特征集
        self.conv2 = nn.Conv2d(10, 20, kernel_size=5)# 第二次卷积,从10个特征中提取20个特征
        self.conv2_drop = nn.Dropout2d()# 一种防止过拟和的操作。在训练的时候,随机砍掉一些神经元。完成之后再恢复。
        self.fc1 = nn.Linear(320, 50)# 第一个全连接层,第一个数字是输入单元数,第二个是输出单元数
        self.fc2 = nn.Linear(50, 10)# 第二个全连接层。(一共10种数字第二次输出就是10)

    def forward(self, x):# 向前传播计算
        x = F.relu(F.max_pool2d(self.conv1(x), 2))# 一次卷积,然后池化+非线性激活函数
        x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))# 第二次卷积+池化+非线性激活函数
        x = x.view(-1, 320)# 把张量变成1维的
        x = F.relu(self.fc1(x))# 第一次全连接,然后加激活函数
        x = F.dropout(x, training=self.training)# 进行一次Dropout,防止过拟合
        x = F.relu(self.fc2(x))# 第二次全连接+激活函数
        return F.log_softmax(x)# 输出结果

嘿嘿,这个注释详细吧。。。
都是我自己的理解,有啥不对的地方欢迎大佬们指出。

代码编写

数据集加载。老传统了,一个训练,一个测试,过程就不详解了。。

train_loader = torch.utils.data.DataLoader(
    datasets.MNIST('/cos_public/mnist/', train=True, download=False,
                   transform=transforms.Compose([
                       transforms.ToTensor(),
                       transforms.Normalize((0.1307,), (0.3081,))
                   ])),
    batch_size=args.batch_size, shuffle=True, **kwargs)
test_loader = torch.utils.data.DataLoader(
    datasets.MNIST('/cos_public/mnist/', train=False, transform=transforms.Compose([
                       transforms.ToTensor(),
                       transforms.Normalize((0.1307,), (0.3081,))
                   ])),
    batch_size=args.batch_size, shuffle=True, **kwargs)

有一点要注意啊,,我这里的'/cos_public/mnist/'是数据在腾讯的智能钛平台上的路径。你们要么改成自己的。

使用SGD优化器

optimizer = optim.SGD(model.parameters(), lr=args.lr, momentum=args.momentum)

训练代码。

def train(epoch):
    model.train()#  表示是训练,model会跟新参数
    for batch_idx, (data, target) in enumerate(train_loader):
        if args.cuda:#  使用GPU
            data, target = data.cuda(), target.cuda()
        data, target = Variable(data), Variable(target)
        optimizer.zero_grad()#  梯度清0
        output = model(data)#  走一遍模型
        loss = F.nll_loss(output, target)#  计算损失
        loss.backward()#  反向传播
        optimizer.step()# 跟新所有参数
        if batch_idx % args.log_interval == 0:
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, batch_idx * len(data), len(train_loader.dataset),
                100. * batch_idx / len(train_loader), loss.data))

测试代码,就是单纯的跑一遍模型,计算下损失,就不详细注释了。

def test(epoch):
    model.eval()
    test_loss = 0
    correct = 0
    for data, target in test_loader:
        if args.cuda:
            data, target = data.cuda(), target.cuda()
        data, target = Variable(data, volatile=True), Variable(target)
        output = model(data)
        test_loss += F.nll_loss(output, target).data
        pred = output.data.max(1)[1] # get the index of the max log-probability
        correct += pred.eq(target.data).cpu().sum()

    test_loss = test_loss
    test_loss /= len(test_loader) # loss function already averages over batch size
    print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
        test_loss, correct, len(test_loader.dataset),
        100. * correct / len(test_loader.dataset)))

代码的大部分我们都完成了。但是!!我们是要在腾讯云的平台上让别人帮我们跑模型的。。所以,,还要加点输入参数和最后模型的保存。。所以完整代码为:

from __future__ import print_function
import argparse
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
from torch.autograd import Variable

# Training settings(看到这一堆,莫慌!我直接照着腾讯云的拿过来的。就是些后面要用的参数定义。然后下面的逻辑部分我前面都注释了。)
parser = argparse.ArgumentParser(description='PyTorch MNIST Example')
parser.add_argument('--batch-size', type=int, default=64, metavar='N',
                    help='input batch size for training (default: 64)')
parser.add_argument('--test-batch-size', type=int, default=1000, metavar='N',
                    help='input batch size for testing (default: 1000)')
parser.add_argument('--epochs', type=int, default=10, metavar='N',
                    help='number of epochs to train (default: 10)')
parser.add_argument('--lr', type=float, default=0.01, metavar='LR',
                    help='learning rate (default: 0.01)')
parser.add_argument('--momentum', type=float, default=0.5, metavar='M',
                    help='SGD momentum (default: 0.5)')
parser.add_argument('--no-cuda', action='store_true', default=False,
                    help='enables CUDA training')
parser.add_argument('--seed', type=int, default=1, metavar='S',
                    help='random seed (default: 1)')
parser.add_argument('--log-interval', type=int, default=10, metavar='N',
                    help='how many batches to wait before logging training status')
parser.add_argument('--export_dir', type=str,
                    help='path to export the train model (.pkl file)')
args = parser.parse_args()
args.cuda = not args.no_cuda and torch.cuda.is_available()

torch.manual_seed(args.seed)
if args.cuda:
    torch.cuda.manual_seed(args.seed)


kwargs = {'num_workers': 1, 'pin_memory': True} if args.cuda else {}
train_loader = torch.utils.data.DataLoader(
    datasets.MNIST('/cos_public/mnist/', train=True, download=False,
                   transform=transforms.Compose([
                       transforms.ToTensor(),
                       transforms.Normalize((0.1307,), (0.3081,))
                   ])),
    batch_size=args.batch_size, shuffle=True, **kwargs)
test_loader = torch.utils.data.DataLoader(
    datasets.MNIST('/cos_public/mnist/', train=False, transform=transforms.Compose([
                       transforms.ToTensor(),
                       transforms.Normalize((0.1307,), (0.3081,))
                   ])),
    batch_size=args.batch_size, shuffle=True, **kwargs)


class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
        self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
        self.conv2_drop = nn.Dropout2d()
        self.fc1 = nn.Linear(320, 50)
        self.fc2 = nn.Linear(50, 10)

    def forward(self, x):
        x = F.relu(F.max_pool2d(self.conv1(x), 2))
        x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))
        x = x.view(-1, 320)
        x = F.relu(self.fc1(x))
        x = F.dropout(x, training=self.training)
        x = F.relu(self.fc2(x))
        return F.log_softmax(x)

model = Net()
if args.cuda:
    model.cuda()

optimizer = optim.SGD(model.parameters(), lr=args.lr, momentum=args.momentum)

def train(epoch):
    model.train()
    for batch_idx, (data, target) in enumerate(train_loader):
        if args.cuda:
            data, target = data.cuda(), target.cuda()
        data, target = Variable(data), Variable(target)
        optimizer.zero_grad()
        output = model(data)
        loss = F.nll_loss(output, target)
        loss.backward()
        optimizer.step()
        if batch_idx % args.log_interval == 0:
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, batch_idx * len(data), len(train_loader.dataset),
                100. * batch_idx / len(train_loader), loss.data))

def test(epoch):
    model.eval()
    test_loss = 0
    correct = 0
    for data, target in test_loader:
        if args.cuda:
            data, target = data.cuda(), target.cuda()
        data, target = Variable(data, volatile=True), Variable(target)
        output = model(data)
        test_loss += F.nll_loss(output, target).data
        pred = output.data.max(1)[1] # get the index of the max log-probability
        correct += pred.eq(target.data).cpu().sum()

    test_loss = test_loss
    test_loss /= len(test_loader) # loss function already averages over batch size
    print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
        test_loss, correct, len(test_loader.dataset),
        100. * correct / len(test_loader.dataset)))


for epoch in range(1, args.epochs + 1):
    train(epoch)
    test(epoch)
torch.save(model.state_dict(), args.export_dir) #最后一步。保存模型。。腾讯云官方不会给我们保存的,,,所以代码中要自己写清楚。

最后一步要注意,我把模型保存到了args.export_dir中,也就是输入参数中的最后一项。。那一项写你要保存的腾讯云的路径即可。

训练

在这里插入图片描述
上传代码。参数我写的这个

--batch-size 64
--test-batch-size 1000
--epochs 10
--lr 0.01
--momentum 0.5
--export_dir ${cos}/Pymodel/mode.pkl

最后一项就是模型保存的地方。
点击运行就开始了。训练好了之后,
在这里插入图片描述

模型就在这儿了,下下来即可
在这里插入图片描述

模型测试

使用下面的代码进行下测试:

class Net(nn.Module): # 模型定义,就不用说了吧,前面一样
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
        self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
        self.conv2_drop = nn.Dropout2d()
        self.fc1 = nn.Linear(320, 50)
        self.fc2 = nn.Linear(50, 10)

    def forward(self, x):
        x = F.relu(F.max_pool2d(self.conv1(x), 2))
        x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))
        x = x.view(-1, 320)
        x = F.relu(self.fc1(x))
        x = F.dropout(x, training=self.training)
        x = F.relu(self.fc2(x))
        return F.log_softmax(x,dim=1)

img = Image.open("./9.png") # 打开要测试的图片

plt.imshow(img) # 显示下看看

# [N, C, H, W]

train_transform = transforms.Compose([ # 我们训练数据的时候,怎么操作了,现在就要把我们要测试的数据也转化成训练的时候的样子。
        transforms.Grayscale(),
        transforms.Resize((28, 28)),
		transforms.ToTensor(),
        transforms.Normalize((0.1307,), (0.3081,))
])

img = train_transform(img)# 进行转化
# expand batch dimension
img = torch.unsqueeze(img, dim=0)# 维度转化

# create model
model = Net() # 定义模型
# load model weights
model_weight_path = "./mode.pkl" # 加载我们训练好的权重
model.load_state_dict(torch.load(model_weight_path))
# 定义数组,方便输出显示的数字
index_to_class = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']


model.eval()
with torch.no_grad(): # 测试,所以不计算梯度
    # predict class
    y = model(Variable(img)) # 走一遍模型
    # print(y.size())
    output = torch.squeeze(y) # 维度转化
    # print(output)
    predict = torch.softmax(output, dim=0) # 拿到的数据进行映射
    # print(predict)
    predict_cla = torch.argmax(predict).numpy() # 获取映射后最大的的值
    # print(predict_cla)
print(index_to_class[predict_cla], predict[predict_cla].numpy()) # 输出最大可能的值,和它的概率
plt.show() # 图片展示

关于手写图片嘛,,直接打开电脑自带的图画(注意,训练的时候背景是黑的,所以我们也要这样,然后大小是45x45(训练的数据是45x45的)。)。
在这里插入图片描述

然后跑起来试试叭
在这里插入图片描述
嘿嘿,,识别出结果是4,几率是97%。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值