一篇文章入门深度学习框架PyTorch

  • 1 Tensor(张量)
  • 2 Variable(变量)
  • 3 Dataset(数据集)
  • 4 nn.Module(模组)
  • 5 torch.optim(优化)
    • 一阶优化算法
    • 二阶优化算法
  • 6 模型的保存和加载

1 Tensor(张量)

  • PyTorch里面处理的最基本的操作对象就是TensorTensor表示的是一个多维矩阵,比如零维就是一个点,一维就是向量,二维就是一般的矩阵,多维就相当于一个多维数组
  • TensorNumpy是对应的,可以和Numpyndarray互相转换,唯一不同的是PyTorch可以再GPU上运行,numpy只能在CPU上运行。
  • 常用的不同类型的Tensor32位浮点型torch.FloatTensor64位浮点型torch.DoubleTensor16位整型torch.ShortTensor32位整型torch.IntTensor64位整型torch.LongTensor
import torch
import numpy as np# 定义一个三行两列给定元素矩阵
a = torch.Tensor([[2, 3], [4, 8], [7, 9]])
# 显示矩阵元素
print('a is {}'.format(a))
# 显示矩阵大小
print('a size is {}'.format(a.size()))# torch.tensor默认的是torch.FloatTensor数据类型
b = torch.LongTensor(([[2, 3], [4, 8], [7, 9]]))
print('b is {}'.format(b))# 创建一个全是0的空Tensor
c = torch.zeros((3, 2))
print('zeros tensor {}'.format(c))# 取一个正太分布作为随机初始值
d = torch.randn((3, 2))
print('d is {}'.format(d))# 可以像Numpy一样通过索引的方式取得其中的元素,也可以改变它的值
a[0, 1] = 100  # 将a的第一行与第二列的元素改变为100
print('changed a is {}'.format(a))# Tensor可以和Numpy.ndarray之间相互转换
numpy_b = b.numpy()  # 将b装换为Numpy的数据类型
print('converse to numpy is \n {}'.format(numpy_b))e = np.array([[2, 3], [4, 5]])
torch_e = torch.from_numpy(e)  # 将Numpy转换为Tensor
print('from numpy to torch.Tensor is \n {}'.format(torch_e))f_torch_e = torch_e.float()  # 如果需要更改Tensor的数据类型,只需要在转换后的tensor后面加上需要的类型
print('change data type to float tensor \n {}'.format(f_torch_e))# 如果支持GPU加速,Tensor放到GPU上
if torch.cuda.is_available():a_cuda = a.cuda()print(a_cuda)
  • 结果
D:\software\anaconda3\envs\pytorch_gpu\python.exe D:/IDEA/pytorch_gpu/src/demo.py
a is tensor([[2., 3.],[4., 8.],[7., 9.]])
a size is torch.Size([3, 2])
b is tensor([[2, 3],[4, 8],[7, 9]])
zeros tensor tensor([[0., 0.],[0., 0.],[0., 0.]])
d is tensor([[-0.3689, -0.8400],[ 1.1293, -0.3011],[-0.4752,  0.5565]])
changed a is tensor([[  2., 100.],[  4.,   8.],[  7.,   9.]])
converse to numpy is [[2 3][4 8][7 9]]
from numpy to torch.Tensor is tensor([[2, 3],[4, 5]], dtype=torch.int32)
change data type to float tensor tensor([[2., 3.],[4., 5.]])
tensor([[  2., 100.],[  4.,   8.],[  7.,   9.]], device='cuda:0')Process finished with exit code 0

2 Variable(变量)

  • Variable是神经网络计算图里特有的一个概念,提供了自动求导功能,位于torch.autograd.variable,在Numpy里不存在。神经网络在做运算的时候,需要先构造一个计算图谱,在里面进行前向传播和反向传播。
  • Variable和Tensor本质上没有区别,不过Variable会被放入一个计算图中,然后进行前向传播,反向传播,自动求导。
  • Variable属性结构图
  • Variable有三个重要的属性:data,grad,grad_fn。通过data可以取出Variable里面的Tensor数值,grad_fn表示的是得到这个Variable的操作,比如通过加减还是乘除来得到,grad是这个Variable的反向传播梯度。
  • 自动求导是不需要明确哪个函数对哪个函数求导,直接通过一行代码对所有的需要梯度的变量进行求导。
from torch.autograd.variable import *# Create Variable
# requires_grad表示是否对变量求梯度
x = Variable(torch.Tensor([1]), requires_grad=True)
w = Variable(torch.Tensor([2]), requires_grad=True)
b = Variable(torch.Tensor([3]), requires_grad=True)# Build a Computational graph
y = w * x + b  # y=2*x+3# Compute gradients 自动求导
# 对于标量求导,参数可以不写
y.backward()  # same as y.backward(torch.FloatTensor([1]))# print out the gradients
print(x.grad)
print(w.grad)
print(b.grad)
  • 运行结果
D:\software\anaconda3\envs\pytorch_gpu\python.exe D:/IDEA/pytorch_gpu/src/demo.py
tensor([2.])
tensor([1.])
tensor([1.])Process finished with exit code 0
  • 上面是标量的求导,也可以做矩阵的求导
from torch.autograd.variable import *
import torchx = torch.randn(3)
x = Variable(x, requires_grad=True)
y = x * 2
print(y)
# 矩阵求导
y.backward(torch.FloatTensor([1, 0.1, 0.01]))
print(x.grad)
  • 运行结果
D:\software\anaconda3\envs\pytorch_gpu\python.exe D:/IDEA/pytorch_gpu/src/demo.py
tensor([-0.4075, -1.0235, -2.4338], grad_fn=<MulBackward0>)
tensor([2.0000, 0.2000, 0.0200])Process finished with exit code 0

3 Dataset(数据集)

  • 在处理任何机器学习问题之前都需要数据读取并进行预处理。torch.utils.data.Dataset是代表这一数据的抽象类,可以自己定义数据类型集成和重写这个抽象类。
import torch
from torch.utils.data import Dataset
import pandas as pdclass myDataset(Dataset):def __init__(self, csv_file, txt_file, root_dir, other_file):self.csv_data = pd.read_csv(csv_file)with open(txt_file, 'r') as f:data_list = f.readlines();self.txt_data = data_listself.root_dir = root_dirdef __len__(self):return len(self.csv_data)def __getitem__(self, item):data = (self.csv_data[item], self.txt_data[item])return data
  • 通过上面的方式,可以定义需要的数据类,通过迭代的方式取得每一个数据,但是很难实现取batch,shuffle或者多线程取数据,可以通过torch.utils.data.DataLoader
import torch
from torch.utils.data import Dataset, DataLoader
import pandas as pd
from torch.utils.data._utils.collate import default_collateclass myDataset(Dataset):def __init__(self, csv_file, txt_file, root_dir, other_file):self.csv_data = pd.read_csv(csv_file)with open(txt_file, 'r') as f:data_list = f.readlines()self.txt_data = data_listself.root_dir = root_dirdef __len__(self):return len(self.csv_data)def __getitem__(self, item):data = (self.csv_data[item], self.txt_data[item])return datadataiter = DataLoader(myDataset, batch_size=32, shuffle=True, collate_fn=default_collate)

4 nn.Module(模组)

  • 在PyTorch里面编写神经网络,所有的层结构和损失函数都来自于torch.nn,所有的模型构建都继承自nn.Module基类。
import torch.nn as nnclass net_name(nn.Module):def __init__(self, other_arguments):super(net_name, self).__init__()self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size)# other network layersdef forward(self, x):x = self.conv1(x)return x
  • 这样就建立了一个计算图,并且这个结构可以复用多次,每次调用就相当于用该计算图定义的相同参数做一次前向传播,这得益于PyTorch的自动求导功能,所以我们不需要自己编写反向传播,而所有的网络层都由nn这个包得到,如线性层nn.Linear.
  • 定义完模型之后,需要通过nn这个包定义损失函数,常见的损失函数有均方误差、多分类的交叉熵、二分类的交叉熵.
criterion = nn.CrossEntropyLoss()
loss = criterion(output, target)

5 torch.optim(优化)

  • 在机器学习或者深度学习中,需要通过修改参数使得损失函数最小化或者最大化,优化算法就是一种调整模型参数更新的策略。

一阶优化算法

  • 一阶优化算法使用各个参数的梯度值来更新参数,最常用的一阶优化算法是梯度下降。梯度就是导数的多变量表达式,函数的梯度形成了一个向量场,同时也是一个方向,这个方向上的方向导数最大,且等于梯度。梯度下降的功能是通过寻找最小值,控制方差,更新模型参数,最终使模型收敛,网络的参数更新公式是:

θ=θ−η⋅∂J(θ)∂θ\theta=\theta-\eta \cdot {{\partial J(\theta)}\over{\partial \theta}} θ=θ−η⋅∂θ∂J(θ)​

二阶优化算法

  • 二阶优化算法使用了二阶导数(也叫做Hessian方法)来最小化和最大化损失函数,主要基于牛顿法。但是由于二阶导数计算成本很高,所以这种方法并没有广泛使用。
  • torch.optim是一个实现各种优化算法的包,大多数常见的算法都能通过这个包来调用,比如随机梯度下降,以及添加动量的随机梯度下降,自适应学习率等。在调用的时候将需要优化的参数传入,这些参数必须是Variable,然后传入一些基本的设定,如学习率和动量。

6 模型的保存和加载

  • 在PyTorch里面使用torch.save来保存模型的结构和参数,有两种保存方式:

(1)保存整个模型的结构信息和参数信息,保存的对象是Model

# save方法:第一个参数是保存对象,第二个参数是保存路径及名称
torch.save(model,'./model.pth')

(2)保存模型的参数,保存的对象是模型的状态:model.state_dict()

# save方法:第一个参数是保存对象,第二个参数是保存路径及名称
torch.save(model.state_dict(),'./model_state.pth')
  • 加载模型有两种方式,对应于保存模型的方式,map_location=device 更换设备

(1)加载完整的模型结构和参数信息,在网络较大的时候,加载的时间较长,同时存储空间较大。

load_model=torch.load(‘model.pth', map_location=device)

(2)加载模型参数信息,需要先导入模型的结构,然后加载模型参数

model=YourModelClass()
model.load_state_dic(torch.load('model_state.pth', map_location=device))
# -*- coding: utf-8 -*-
# Import Package
import torch
import torch.nn as nn
from torchvision import transforms,datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F
import torch.optim as optim# Prepare Dataset
batch_size=64
transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307,),(0.3081,))
])
train_dataset=datasets.MNIST(root='./dataset/',train=True,download=True,transform=transform
)
train_loader=DataLoader(train_dataset,shuffle=True,batch_size=batch_size
)
test_dataset=datasets.MNIST(root='./dataset/',train=False,download=True,transform=transform
)
test_loader=DataLoader(train_dataset,shuffle=False,batch_size=batch_size
)# Design Model
class Net(nn.Module):def __init__(self):super(Net, self).__init__()self.l1=nn.Linear(784,512)self.l2=nn.Linear(512,256)self.l3=nn.Linear(256,128)self.l4=nn.Linear(128,64)self.l5=nn.Linear(64,10)def forward(self,x):x=x.view(-1,784)x=F.relu(self.l1(x))x=F.relu(self.l2(x))x=F.relu(self.l3(x))x=F.relu(self.l4(x))return self.l5(x)
model=Net()# Construct Loss and Optimizer
criterion=nn.CrossEntropyLoss()
optimizer=optim.SGD(model.parameters(),lr=0.01,momentum=0.5)# Train and Test
def train(epoch):running_loss=0.0for batch_idx,data in enumerate(train_loader,0):inputs,target=dataoptimizer.zero_grad()outputs=model(inputs)loss=criterion(outputs,target)loss.backward()optimizer.step()running_loss+=loss.item()if (batch_idx+1)%300==0:print('[%d, %5d] loss: %.3f'%(epoch+1,batch_idx+1,running_loss/300))running_loss=0
def test(test_model):correct=0total=0with torch.no_grad():for data in test_loader:images,labels=dataoutputs=test_model(images)_,predicted=torch.max(outputs.data,dim=1)total+=labels.size(0)correct+=(predicted==labels).sum().item()print("Accuracy on test set: %d %%"%(100*correct/total))for epoch in range(3):train(epoch)
# 保存模型(包括模型结构和参数)
torch.save(model,'model_structure_parameter.pth')# 加载保存模型(包括模型结构和参数)
test_model=torch.load('model_structure_parameter.pth')
test(test_model)for epoch in range(3):train(epoch)
# 保存模型(包括模型参数)
torch.save(model.state_dict(),'model__parameter.pth')# 加载保存模型(包括模型参数)
test_model=Net()
test_model.load_state_dict(torch.load('model__parameter.pth'))
test(test_model)

一篇文章入门深度学习框架PyTorch相关推荐

  1. numpy pytorch 接口对应_拆书分享篇深度学习框架PyTorch入门与实践

    <<深度学习框架PyTorch入门与实践>>读书笔记 <深度学习框架PyTorch入门与实践>读后感 小作者:马苗苗  读完<<深度学习框架PyTorc ...

  2. 好书分享——《深度学习框架PyTorch:入门与实践》

    内容简介 : <深度学习框架PyTorch:入门与实践>从多维数组Tensor开始,循序渐进地带领读者了解PyTorch各方面的基础知识.结合基础知识和前沿研究,带领读者从零开始完成几个经 ...

  3. (翻译)60分钟入门深度学习工具-PyTorch

    60分钟入门深度学习工具-PyTorch 作者:Soumith Chintala 原文翻译自: https://pytorch.org/tutorials/beginner/deep_learning ...

  4. DL框架之PyTorch:深度学习框架PyTorch的简介、安装、使用方法之详细攻略

    DL框架之PyTorch:PyTorch的简介.安装.使用方法之详细攻略 DL框架之PyTorch:深度学习框架PyTorch的简介.安装.使用方法之详细攻略 目录 PyTorch的简介 1.pyto ...

  5. 深度学习框架PyTorch快速开发与实战

    深度学习框架PyTorch快速开发与实战 邢梦来,王硕,孙洋洋 著 ISBN:9787121345647 包装:平装 开本:16开 用纸:胶版纸 正文语种:中文 出版社:电子工业出版社 出版时间:20 ...

  6. DL:深度学习框架Pytorch、 Tensorflow各种角度对比

    DL:深度学习框架Pytorch. Tensorflow各种角度对比 目录 先看两个框架实现同样功能的代码 1.Pytorch.Tensorflow代码比较 2.Tensorflow(数据即是代码,代 ...

  7. 深度学习框架PyTorch入门与实践:第二章 快速入门

    本章主要介绍两个内容,2.1节介绍如何安装PyTorch,以及如何配置学习环境:2.2节将带领读者快速浏览PyTorch中主要内容,给读者一个关于PyTorch的大致印象. 2.1 安装与配置 2.1 ...

  8. 深度学习框架Pytorch入门与实践——读书笔记

    2 快速入门 2.1 安装和配置 pip install torch pip install torchvision#IPython魔术命令 import torch as t a=t.Tensor( ...

  9. 深度学习框架pytorch入门之张量Tensor(一)

    文章目录 一.简介 二.查看帮助文档 三.Tensor常用方法 1.概述 2.新建方法 (1)Tensor(*sizes) tensor基础构造函数 (2)ones(*sizes) 构造一个全为1的T ...

最新文章

  1. UWP Composition API - 锁定列的FlexGrid
  2. Sping面试题 Top 50
  3. 编辑流程图_作为一名采购商,做不好采购?送你5套采购流程图模板
  4. python字典与json转换_python字典与json转换的方法总结
  5. UNP Chapter 27 - 客户-服务器程序其他设计方法
  6. mysql sqlite 性能优化_MySQL和Sqlite3性能测试
  7. 触类旁通:那些关于 TBL$OR$IDX$PART$NUM 的诡异案例和知识
  8. linux 局域网内互ping丢包_ping命令还能这么用?
  9. Redis数据类型SortedSET
  10. 解决python3报错UnicodeDecodeError: 'ascii' codec can't decode byte 0xaa in position 1: ordinal not in ra
  11. ado控件连接mysql_VB利用ADO控件连接access数据库
  12. ppt流程图箭头分叉_职场PPT实战:流程图只能箭头方框?设计师教你新思路
  13. 黑盒测试测试用例__判定表
  14. 【群晖Nas开启WebDAV服务,路由器映射端口,实现Win10远程映射网路驱动器】
  15. 双远心镜头原理及选型方法(二)
  16. 并发编程之:深入解析线程池
  17. 初学python:输入某年某月某日,判断这一天是这一年的第几天
  18. ESP8266(ESP模块)Arduino开发环境快速搭建方法--含网盘离线文件
  19. 五点三次平滑滤波在消除随机噪声中的应用以及其Maltab程序
  20. nyist-部分和问题

热门文章

  1. 微信公众号支付调用chooseWXPay提示“errmsg choosewxpay fail”
  2. 【转帖】.Net中C#的DllImport的用法
  3. linux看电视系统,教你如何在Linux操作系统下观看电视节目
  4. python读取ini文件编码格式_Python读取txt(.ini)文件BOM问题
  5. mysql存储过程时间_mysql时间操作函数和存储过程
  6. 【数据结构与算法-2】链表
  7. 数组查找———二分(折半)查找法
  8. java构造方法重载_Java 重载、重写、构造函数的实例详解
  9. 域控 批量导入 用户_kerberos域用户提权分析
  10. 随机手机号码_骗妹子手机号码,还记得iPhone自带计算器的小魔术吗?,看教程...