加载数据集(下)+手写数字识别MNIST pytorch代码(带注释)

 加载数据集

import torch
from torch import nn
from torch.nn import functional as F
from torch import optim
import torchvision
from matplotlib import pyplot as plt
from utils import plot_image,plot_curve,one_hot

batch_size=512
train_loader=torch.utils.data.DataLoader(
    torchvision.datasets.MNIST('mnist data',train=True,download=True,
                               transform=torchvision.transforms.Compose([
                                   torchvision.transforms.ToTensor(),
                                   torchvision.transforms.Normalize(
                                       (0.1307,),(0.3081,)
                                   )
                               ])),
    batch_size=batch_size,shuffle=True
)
test_loader=torch.utils.data.DataLoader(
    torchvision.datasets.MNIST('mnist data',train=False,download=True,
                               transform=torchvision.transforms.Compose([
                                   torchvision.transforms.ToTensor(),
                                   torchvision.transforms.Normalize(
                                       (0.1307,),(0.3081,)
                                   )
                               ])),
    batch_size=batch_size,shuffle=True
)
x,y=next(iter(train_loader))
print(x.shape,y.shape,x.min(),x.max())
plot_image(x,y,'image sample')

结果

torch.Size([512, 1, 28, 28]) torch.Size([512]) tensor(-0.4242) tensor(2.8215)

 

 

训练

# 创建网络:三层非线性层的嵌套
class Net(nn.Module):#继承nn.Module
    def __init__(self):
        super(Net, self).__init__()
        # xw+b 线性层
        self.fc1=nn.Linear(28*28,256)#输入的是28*28维特征(固定)的x->输出256(经验得出)维特征的y  此y就是一个中间过度的输出、
        self.fc2=nn.Linear(256, 64)
        self.fc3=nn.Linear(64,10)#10分类需要是个输出节点 所以一定是10   这是个维度就表示每一个样本对于0-9不同的概率
    def forward(self, x):
        #x:[b,1,28,28] b表示b章图片
        x=F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        # 最后一层加不加激活函数取决与经验值 这个就不加
        x=(self.fc3(x))
        return x
# 训练 求导跟更新
# 网络对象
net=Net()
# 优化器
optimizer = optim.SGD(net.parameters(), lr=0.01,momentum=0.9)
train_loss=[]
# 对数据集迭代三次
for epoch in range(3):
    # 对整个数据集迭代一次
    for batch_idx,(x,y) in enumerate(train_loader):
        # print(x.shape, y.shape)
        # x:[b=512,1,28,28],y:[512]
        # 全连接层xw+b层 此网络只能接受[b,feature]这样类型,而实际x:[b=512,1,28,28],所以需要打平
        # 打平[b,1,28,28]=>[b,784]
        x=x.view(x.size(0),28*28)
        out=net(x)
        # print(out.shape)=torch.Size([512, 10])
        y_onehot=one_hot(y)
        loss=F.mse_loss(out, y_onehot)
        train_loss.append(loss.item())
        optimizer.zero_grad()
        loss.backward()
        # w=w-lr*grad
        optimizer.step()
        if batch_idx % 10 == 0:
            print(epoch,batch_idx,loss.item())
plot_curve(train_loss)
# 得到了[w1,b1,w2,b2,w3,b3]

0 0 0.11067488044500351
0 10 0.0943082645535469
0 20 0.08495017886161804
0 30 0.07744021713733673
0 40 0.0714396983385086
0 50 0.0674654096364975
0 60 0.06324262917041779
0 70 0.059055496007204056
0 80 0.05903492122888565
0 90 0.0553865060210228
0 100 0.051882218569517136
0 110 0.04975864663720131
1 0 0.05097641423344612
1 10 0.045732591301202774
1 20 0.04423248767852783
1 30 0.04524523392319679
1 40 0.04314319044351578
1 50 0.04154777526855469
1 60 0.041426219046115875
1 70 0.038350772112607956
1 80 0.03864293918013573
1 90 0.039954546838998795
1 100 0.03705741837620735
1 110 0.03812757134437561
2 0 0.0377984382212162
2 10 0.03647816926240921
2 20 0.03585110604763031
2 30 0.03720710426568985
2 40 0.03573155403137207
2 50 0.035967521369457245
2 60 0.03404301032423973
2 70 0.03343154117465019
2 80 0.03460792452096939
2 90 0.03182953968644142
2 100 0.032444968819618225
2 110 0.029968297109007835

 测试 求准确率

#准确度测试
total_correct=0
for x,y in test_loader:
    x=x.view(x.size(0), 28 * 28)
    out = net(x)
    # out:[b,10]
    # 求第一个维度上面 (不是第0个 就是10所在的维度)最大值的索引
    # pred:[b]
    pred=out.argmax(dim=1)
    correct = pred.eq(y).sum().float()
    total_correct += correct.item()
total_num = len(test_loader.dataset)
acc=total_correct / total_num
print(acc)

结果0.8792

import torch
from torch import nn
from torch.nn import functional as F
from torch import optim
import torchvision
from matplotlib import pyplot as plt
from utils import plot_image,plot_curve,one_hot
# 加载数据
batch_size=512
train_loader=torch.utils.data.DataLoader(
    torchvision.datasets.MNIST('mnist data',train=True,download=True,
                               transform=torchvision.transforms.Compose([
                                   torchvision.transforms.ToTensor(),
                                   torchvision.transforms.Normalize(
                                       (0.1307,),(0.3081,)
                                   )
                               ])),
    batch_size=batch_size,shuffle=True
)
test_loader=torch.utils.data.DataLoader(
    torchvision.datasets.MNIST('mnist data',train=False,download=True,
                               transform=torchvision.transforms.Compose([
                                   torchvision.transforms.ToTensor(),
                                   torchvision.transforms.Normalize(
                                       (0.1307,),(0.3081,)
                                   )
                               ])),
    batch_size=batch_size,shuffle=True
)
# x,y=next(iter(train_loader))
# print(x.shape,y.shape,x.min(),x.max())
# torch.Size([512, 1, 28, 28]) torch.Size([512]) tensor(-0.4242) tensor(2.8215)
# plot_image(x,y,'image sample')
# 创建网络:三层非线性层的嵌套
class Net(nn.Module):#继承nn.Module
    def __init__(self):
        super(Net, self).__init__()
        # xw+b 线性层
        self.fc1=nn.Linear(28*28,256)#输入的是28*28维特征(固定)的x->输出256(经验得出)维特征的y  此y就是一个中间过度的输出、
        self.fc2=nn.Linear(256, 64)
        self.fc3=nn.Linear(64,10)#10分类需要是个输出节点 所以一定是10   这是个维度就表示每一个样本对于0-9不同的概率
    def forward(self, x):
        #x:[b,1,28,28] b表示b章图片
        x=F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        # 最后一层加不加激活函数取决与经验值 这个就不加
        x=(self.fc3(x))
        return x
# 训练 求导跟更新
# 网络对象
net=Net()
# 优化器
optimizer = optim.SGD(net.parameters(), lr=0.01,momentum=0.9)
train_loss=[]
# 对数据集迭代三次
for epoch in range(3):
    # 对整个数据集迭代一次
    for batch_idx,(x,y) in enumerate(train_loader):
        # print(x.shape, y.shape)
        # x:[b=512,1,28,28],y:[512]
        # 全连接层xw+b层 此网络只能接受[b,feature]这样类型,而实际x:[b=512,1,28,28],所以需要打平
        # 打平[b,1,28,28]=>[b,784]
        x=x.view(x.size(0),28*28)
        out=net(x)
        # print(out.shape)=torch.Size([512, 10])
        y_onehot=one_hot(y)
        loss=F.mse_loss(out, y_onehot)
        train_loss.append(loss.item())
        optimizer.zero_grad()
        loss.backward()
        # w=w-lr*grad
        optimizer.step()
#         if batch_idx % 10 == 0:
#             print(epoch,batch_idx,loss.item())
# plot_curve(train_loss)
# 得到了[w1,b1,w2,b2,w3,b3]
#准确度测试
total_correct=0
for x,y in test_loader:
    x=x.view(x.size(0), 28 * 28)
    out = net(x)
    # out:[b,10]
    # 求第一个维度上面 (不是第0个 就是10所在的维度)最大值的索引
    # pred:[b]
    pred=out.argmax(dim=1)
    correct = pred.eq(y).sum().float()
    total_correct += correct.item()
total_num = len(test_loader.dataset)
acc=total_correct / total_num
print(acc)

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
我可以回答这个问题。以下是一个使用 PyTorch 实现手写数字识别 MNIST 数据集代码示例: ``` import torch import torch.nn as nn import torch.optim as optim import torchvision.datasets as datasets import torchvision.transforms as transforms # 定义神经网络模型 class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv2d(1, 32, kernel_size=3) self.conv2 = nn.Conv2d(32, 64, kernel_size=3) self.dropout1 = nn.Dropout2d(0.25) self.dropout2 = nn.Dropout2d(0.5) self.fc1 = nn.Linear(9216, 128) self.fc2 = nn.Linear(128, 10) def forward(self, x): x = self.conv1(x) x = nn.functional.relu(x) x = self.conv2(x) x = nn.functional.relu(x) x = nn.functional.max_pool2d(x, 2) x = self.dropout1(x) x = torch.flatten(x, 1) x = self.fc1(x) x = nn.functional.relu(x) x = self.dropout2(x) x = self.fc2(x) output = nn.functional.log_softmax(x, dim=1) return output # 加载数据集 train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transforms.ToTensor()) test_dataset = datasets.MNIST(root='./data', train=False, download=True, transform=transforms.ToTensor()) # 定义训练参数 batch_size = 64 learning_rate = 0.01 momentum = 0.5 # 定义优化器和损失函数 model = Net() optimizer = optim.SGD(model.parameters(), lr=learning_rate, momentum=momentum) criterion = nn.CrossEntropyLoss() # 训练模型 train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True) test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=batch_size, shuffle=False) epochs = 10 for epoch in range(epochs): model.train() for batch_idx, (data, target) in enumerate(train_loader): optimizer.zero_grad() output = model(data) loss = criterion(output, target) loss.backward() optimizer.step() model.eval() test_loss = 0 correct = 0 with torch.no_grad(): for data, target in test_loader: output = model(data) test_loss += criterion(output, target).item() pred = output.argmax(dim=1, keepdim=True) correct += pred.eq(target.view_as(pred)).sum().item() test_loss /= len(test_loader.dataset) accuracy = 100. * correct / len(test_loader.dataset) print('Epoch: {}, Test set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)'.format( epoch, test_loss, correct, len(test_loader.dataset), accuracy)) ``` 这个代码实现了一个卷积神经网络,用于对 MNIST 数据集中的手写数字进行分类。训练过程中使用了随机梯度下降优化器和交叉熵损失函数。在训练结束后,输出了测试集上的平均损失和准确率。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值