Pytorch学习笔记3——实例MNIST

本文首先介绍了数据预处理的方式,如dataset,dataloader。其次通过全连接网络来进行训练。

torchvision

torchvision是pytorch的一个图形库,它服务于PyTorch深度学习框架的,主要用来构建计算机视觉模型。以下是torchvision的构成:

  • torchvision.datasets: 一些加载数据的函数及常用的数据集接口;
  • torchvision.models:包含常用的模型结构(含预训练模型),例如AlexNet、VGG、ResNet等;
  • torchvision.transforms:常用的图片变换,例如裁剪、旋转等
  • torchvision.utils: 其他的一些有用的方法。

ToTensor() 作用:

1. 将输入转为tensor
2. 规范图片格式为 (channel, height, width)     常见的图片格式为:H,W,C
3. 将像素取值范围规范到(0,1)					图像取值在0-255之间,totensor将图片的所有像素都除以255

torch.utils.data.DataLoader 对dataset进行封装:

1.乱序 shuffle
2.将数据采样为小批次 batch_size  : 小批次的批次训练
3. num_workers
4. 设置批次处理函数 collate_fn

如何解析模型预测结果

   import numpy as np
   np.argmax([0.9, 0.04, 0.06])
   torch.argamx

具体实例

#!/usr/bin/env python
# coding: utf-8

# In[1]:


import torchvision
from torchvision.transforms import ToTensor
import torch


# In[2]:


train_ds = torchvision.datasets.MNIST('data',
                                      train=True,
                                      transform=ToTensor(),
                                      download=True)


# In[3]:


test_ds = torchvision.datasets.MNIST('data',
                                      train=False,
                                      transform=ToTensor(),
                                      download=True)

常见的图片格式: (高, 宽, 通道)ToTensor()  作用:

    1. 将输入转为tensor
    2. 规范图片格式为 (channel, height, width)
    3. 将像素取值范围规范到(01)torch.utils.data.DataLoader  对dataset进行封装:
    1.乱序 shuffle
    2.将数据采样为小批次 batch_size  : 小批次的批次训练
    3. num_workers
    4. 设置批次处理函数 collate_fn
# In[4]:


train_dl = torch.utils.data.DataLoader(train_ds, 
                                       batch_size=64,
                                       shuffle=True)


# In[5]:


test_dl = torch.utils.data.DataLoader(test_ds, 
                                       batch_size=64)


# In[6]:


imgs, labels = next(iter(train_dl))


# In[7]:


imgs.shape


# In[8]:


import matplotlib.pyplot as plt
import numpy as np


# #创建一个 10 * 1 点(point)的图, 
# 创建一个新的 1 * 1 的子图,接下来的图样绘制在其中的第 1 块(也是唯一的一块)
# subplot(1,1,1)

# In[9]:
#展示前十张图片

plt.figure(figsize=(10, 1))
for i, img in enumerate(imgs[:10]):
    npimg = img.numpy()
    npimg = np.squeeze(npimg)
    # 绘制图片一行十列
    plt.subplot(1, 10, i+1)
    plt.imshow(npimg)
    plt.axis('off')


# In[10]:


labels[:10]


# # 激活函数

# In[11]:


# relu激活: f(x) = max(x, 0)


# In[12]:


input = torch.randn(5)


# In[13]:


input


# In[14]:


torch.relu(input)


# In[15]:


torch.sigmoid(input)


# In[16]:


torch.tanh(input)


# In[17]:


from torch import nn


# In[18]:


nn.LeakyReLU(input)


# In[19]:


#创建多层感知器模型


# In[20]:


from torch import nn


# In[21]:


# nn.Linear() # 全连接层 要求输入的数据是一维   (batch, features)


# In[22]:


class Model(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear_1 = nn.Linear(28*28, 120)
        self.linear_2 = nn.Linear(120, 84)
        self.linear_3 = nn.Linear(84, 10)
    def forward(self, input):
        x = input.view(-1, 1*28*28)
        x = torch.relu(self.linear_1(x))
        x = torch.relu(self.linear_2(x))
        logits = self.linear_3(x)
        return logits    # 未激活的输出,叫做logits


# In[23]:


#模型输出是C个可能值上概率, C表示类别总数  np.argmax([0.1, 0.2, 0.8])

#  logits                                 【5, 10, 40】


# # 如何解析模型预测结果
# import numpy as np
# 
# np.argmax([0.9, 0.04, 0.06])  
# 
# # torch.argamx

# In[24]:


# 两个概率分布的计算: [0.9, 0.04, 0.06]     [0, 0, 1]


# In[25]:


# 定义损失函数
loss_fn = torch.nn.CrossEntropyLoss()


# #损失函数的输入:
# 
# loss_fn : target : 0,1,2、、、、  并不是独热编码的形式
# 
#            input: logits

# In[26]:


# 优化: 根据计算得到的损失,调整模型参数,降低损失的过程  Adam、SGD


# In[27]:


device = 'cuda' if torch.cuda.is_available() else 'cpu'
model = Model().to(device)   # 初始化模型


# In[28]:


opt = torch.optim.SGD(model.parameters(), lr=0.001)


# # 编写训练循环

# In[29]:


# 训练函数
def train(dl, model, loss_fn, optimizer):
    size = len(dl.dataset)    #获取总数据集的大小
    num_batches = len(dl)     #获取总批次数
        
    train_loss, correct = 0, 0
        
    for x, y in dl:
        x, y = x.to(device), y.to(device)
        pred = model(x)
        loss = loss_fn(pred, y)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        with torch.no_grad():
            correct += (pred.argmax(1) == y).type(torch.float).sum().item()
            train_loss += loss.item()
    correct /= size
    train_loss /= num_batches
    return correct, train_loss


# In[30]:


# 测试函数
def test(test_dl, model, loss_fn):
    size = len(test_dl.dataset)    
    num_batches = len(test_dl)
    test_loss, correct = 0, 0
    with torch.no_grad():
        for x, y in test_dl:
            x, y = x.to(device), y.to(device)
            pred = model(x)
            loss = loss_fn(pred, y)
            test_loss += loss.item()
            correct += (pred.argmax(1) == y).type(torch.float).sum().item()
        correct /= size
        test_loss /= num_batches
        return correct, test_loss


# In[31]:


# 训练50 个epoch, 每一个epoch代表将全部数据集训练一遍


# In[33]:


epochs = 50
train_loss = []
train_acc = []
test_loss = []
test_acc = []

for epoch in range(epochs):
    epoch_acc, epoch_loss = train(train_dl, model, loss_fn, opt)
    epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)
    train_acc.append(epoch_acc)
    train_loss.append(epoch_loss)
    test_acc.append(epoch_test_acc)
    test_loss.append(epoch_test_loss)
    
    template = ("epoch:{:2d}, train_Loss:{:.5f}, train_acc:{:.1f},test_Loss:{:.5f}, test_acc:{:.1f}")
    
    print(template.format(epoch, epoch_loss, epoch_acc*100, epoch_test_loss, epoch_test_acc*100))
print('Done')


# In[34]:


import matplotlib.pyplot as plt


# In[35]:


plt.plot(range(epochs), train_loss, label='train_loss')
plt.plot(range(epochs), test_loss, label='test_loss')
plt.legend()


# In[36]:


plt.plot(range(epochs), train_acc, label='train_acc')
plt.plot(range(epochs), test_acc, label='test_acc')
plt.legend()


# In[ ]:





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值