Pytorch(一)

一.什么是Pytorch,为什么选择Pytroch?

简洁:PyTorch的设计追求最少的封装,尽量避免重复造轮子。
速度:PyTorch的灵活性不以速度为代价。
易用:PyTorch是所有的框架中面向对象设计的最优雅的一个。
活跃的社区:PyTorch提供了完整的文档,循序渐进的指南,作者亲自维护的论坛 供用户交流和求教问题。
https://blog.csdn.net/broadview2006/article/details/79147351

二.Pytroch的安装

使用官网生成命令
使用教程

1、可以选择直接安装python

官网下载:根据版本下载安装包:Download Windows x86-64 executable installer
在这里插入图片描述
如果没有勾选就要进行:环境变量配置
Pytroch的安装:
报错SyntaxError: invalid syntax
cmd窗口pip显示不是内部或外部命令
torch-0.4.1-cp36-cp36m-win_amd64.whl is not a supported wheel on this platform:注意python版本,32位的不能正确安装

2、也可以安装anaconda:安装后在官网生成命令,在anaconda prompt中运行。

在这里插入图片描述

3、不会配置环境,可以选择云平台:Colaboratory【Google助手帮助下可使用】

三.PyTorch基础概念

张量的定义和计算
自动求导

四.通用代码实现流程(实现一个深度学习的代码流程)

https://github.com/viki6666/Pytorch_learn/blob/master/MNIST.ipynb

学习笔记

1、张量:可以简单理解为N维数组的容器对象。
2、自动求导:通过variable和function进行自动求导。
3、基本流程:
使用神经网络来解决问题,你需要做的6件事

  • 加载数据和标签(如手写数字识别中的数据就是一张图片,而一张图片在计算机里面是一个由整数组成的矩阵,它的标签是当前这个图片到底是数字几)
  • 设计网络结构(如是共有几层神经网络,每层输入输出的矩阵格式,每层的激活函数是怎样的,当前层到底是卷积层还是循环神经网络层等等),初学者一定要关注输入数据矩阵形状是几乘几,输出数据是几乘几。但是不用关注它具体怎么优化参数。
  • 设计损失(误差)函数(以手写数字识别为例,神经网络会输出一个值表明当前这个图片到底是几,但是一开始肯定不准确。所以我们需要计算神经网络输出值与标签之间的误差。而误差计算有很多种我们需要告诉pytorch怎么计算误差。然后pytorch就会自动根据我们设定的误差计算方法去自动调整神经网络的参数)
  • 设置用于自动调整神经网络参数的优化器(在上一步我们提到了pytorch会自动帮我们自动调整神经网络的参数,但是具体用哪种优化器去调整参数呢?这需要我们告诉pytorch,因此我们需要用代码设置具体用哪个优化器调整参数)
    使用数据和标签训练神经网络
    这个神经网络已经训练好可以用于解决你的问题了。(你只用输入数据,然后用神经网络输出结果即可)
    4、伪代码:
import torch
# 1. 加载数据和标签
data,label = 加载数据()
# 2. 设计网络结构
model = torch.nn.Sequential(
    torch.nn.Linear(1层输入向量维数,1层输出的向量维数), # 输入向量维数其实就是当前这层的“神经元”的个数,输出向量维数和下一层输入向量维数要一样
    torch.nn.ReLU(), # 设置前面那一层的激活函数
    ....
    torch.nn.Linear(第n层输入向量维数, 第n层输出向量维数),
    torch.nn.ReLU(), # 设置前面那一层的激活函数
)
# 3. 设计损失函数,就是最简单的两点间距离(model_output-lable)^2
loss_fn = torch.nn.MSELoss(reduction='sum')
# 4. 设置用于自动调节神经网络参数的优化器
learning_rate = 1e-4
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
# 5. 训练神经网络
# 5. 训练神经网络(重复训练10次)
for t in range(10):
    model_output = model(data)
    # 5.1 用所设计算损失(误差)函数计算误差
    loss = loss_fn(model_output, label)
    # 5.2 每次训练前清零之前计算的梯度(导数)
    optimizer.zero_grad()
    # 5.3 根据误差反向传播计算误差对各个权重的导数
    loss.backward()
    # 5.4 根据优化器里面的算法自动调整神经网络权重
    optimizer.step()

##########现在你已经训练好了#################
# 6. 用这个神经网络解决你的问题,比如手写数字识别,输入一个图片矩阵,然后模型返回一个数字
result_digit = model(img_mattrix)

注释好的代码

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from torchvision import datasets, transforms

batch_size = 200
learning_rate = 0.01
epochs = 10
# 自动下载pytorch提供的mnist数据集,可能需要代理才能下载下来,我们这里以mnist数据集为例说明pytorch中交叉验证的用法
# transforms.ToTensor()将shape为(H,W,C)的nump.ndarray或img转为shape为(C,H,W)的tensor,其将每一个数值归一化到[0,1]直接除以255即可
# H和W分别为28和28,C为1
# transforms.Normalize((0.1307,), (0.3081,))将数据集按均值0.1307、标准差0.3081进行标准化,这个均值和标准差是官方例子给的
# 取得训练集
train_data_1 = datasets.MNIST("data", train=True, download=True, transform=transforms.Compose(
   [transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))]))
# 从训练集中取一个batch_size的样本用来训练,取时打乱数据
train_batch_data = DataLoader(train_data_1, batch_size=batch_size, shuffle=True)
# 取得测试集
test_data = datasets.MNIST("data", train=False, transform=transforms.Compose(
   [transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))]))
# 从测试集中取一个batch_size的样本用来测试,取时打乱数据
test_batch_data = torch.utils.data.DataLoader(test_data, batch_size=batch_size, shuffle=True)

# print("训练集大小:{},测试集大小:{}".format(len(train_data_1), len(test_data)))
#  torch.utils.data.random_split按照给定的长度将数据集划分成没有重叠的新数据集组合,50000+10000应当等于原有训练集的大小
train_data_1, validation_data_2 = torch.utils.data.random_split(train_data_1, [50000, 10000])
# 训练集重新划分成两部分,第一部分大小50000,第二部分大小10000
# print("训练集第一部分:{},训练集第二部分:{}".format(len(train_data_1), len(train_data_2)))
# 重新划分的两部分训练集各取一个batch_size的样本
train_batch_data_1 = torch.utils.data.DataLoader(train_data_1, batch_size=batch_size, shuffle=True)
validation_batch_data_2 = torch.utils.data.DataLoader(validation_data_2, batch_size=batch_size, shuffle=True)

#一个nn.Module包含各个层和一个forward(input)方法,该方法返回output
class FullyConnectedNeuralNet(nn.Module):
   def __init__(self):
      super(FullyConnectedNeuralNet, self).__init__()
      # 定义一个全连接神经网络结构,每层使用Leakly ReLU激活函数
      self.model = nn.Sequential(
         nn.Linear(784, 200),
         nn.LeakyReLU(inplace=True),
         nn.Linear(200, 200),
         nn.LeakyReLU(inplace=True),
         nn.Linear(200, 10),
         nn.LeakyReLU(inplace=True),
      )

   # 定义前向网络
   def forward(self, x):
      x = self.model(x)

      return x


DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
net = FullyConnectedNeuralNet().to(DEVICE)
# 定义优化算法为SGD,定义损失函数为交叉熵损失函数
optimizer = optim.SGD(net.parameters(), lr=learning_rate)
criteon = nn.CrossEntropyLoss().to(DEVICE)
iteration = int(len(train_data_1) / batch_size)
# 训练epochs轮
for epoch in range(epochs):
   # train_batch_data_1每次从train_data_1训练集中取出batch_size个样本进行训练
   for iter_index, (data, label) in enumerate(train_batch_data_1):
      # 改变张量形状为(len(train_batch_data),28*28)
      data = data.view(-1, 28 * 28)
      # 训练数据和训练标签都放到GPU中训练
      data, label = data.to(DEVICE), label.to(DEVICE)
      # 计算前向网络最后结果
      preds = net(data)
      # 计算损失函数结果
      loss = criteon(preds, label)
      # pytorch中计算时梯度是被积累的,但是每个batch_size训练后梯度需要清零
      optimizer.zero_grad()
      # 每轮iteration反向传播梯度更新参数
      loss.backward()
      # optimizer.step()用在每个batch中,使用optimizer.step(),模型参数才会更新
      optimizer.step()
      # 每训练100轮iteration100轮打印loss值
      if iter_index % 100 == 0:
         print("epoch:{} [{}/{}({:.1f}%)],train_loss:{:.4f}".format(epoch, iter_index * len(data),
                                                                    len(train_batch_data_1.dataset),
                                                                    100.0 * iter_index / len(train_batch_data_1),
                                                                    loss.item()))

   # test_loss为验证集的平均loss,acc为预测准确率
   validation_loss = 0
   validation_acc = 0
   # 每一轮epoch训练完后从validation_data_2中取出batch_size个样本用来验证
   for data, label in validation_batch_data_2:
      data = data.view(-1, 28 * 28)
      data, label = data.to(DEVICE), label.to(DEVICE)
      preds = net(data)
      validation_loss += criteon(preds, label).item()
      # 求每个预测向量中最大值的下标即为预测的标签
      # 第一个1是指在1号维度上找每个Tensor的最大值
      # 下标[0]为每个Tensor的最大值,[1]为每个Tensor最大值对应的index下标
      pred_label = preds.data.max(1)[1]
      # 计算预测标签与真实标签是否相同,相同说明预测正确
      validation_acc += pred_label.eq(label.data).sum()

   validation_loss /= len(validation_batch_data_2.dataset)
   print("Validation average loss:{:.4f},Validation accuracy:{}/{}({:.2f}%)".format(validation_loss, validation_acc,
                                                                                    len(
                                                                                       validation_batch_data_2.dataset),
                                                                                    100.0 * validation_acc / len(
                                                                                       validation_batch_data_2.dataset)))

# 测试集平均loss和准确率
test_loss = 0
test_acc = 0
# 从test_data中取出batch_size个样本用来测试
for data, label in test_batch_data:
   data = data.view(-1, 28 * 28)
   data, label = data.to(DEVICE), label.to(DEVICE)
   preds = net(data)
   test_loss += criteon(preds, label).item()
   pred_label = preds.data.max(1)[1]
   test_acc += pred_label.eq(label.data).sum()

test_loss /= len(test_batch_data.dataset)
print("Test average loss:{:.4f},Test accuracy:{}/{}({:.2f}%)".format(test_loss, test_acc, len(test_batch_data.dataset),
                                                                     100.0 * test_acc / len(test_batch_data.dataset)))

参考资料:
PyTorch 1.0 中文文档
pytorch神经网络实践(1): 安装与初次使用pytorch搭建神经网络实践手写数字识别教程
代码:https://blog.csdn.net/zgcr654321/article/category/8691719
学习路径:
https://www.zhihu.com/question/55720139/answer/147148105
学习资料:
汇总:ttps://mp.weixin.qq.com/s/YO8hoZzOWy025LhPdBGpEA
中文手册:https://github.com/zergtant/pytorch-handbook/tree/master/chapter1

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值