PyTorch 学习
PyTorch
torch.autograd模块
- 深度学习的算法本质上是通过反向传播求导数, PyTorch的autograd模块实现了此功能, 在Tensor上的所有操作, autograd都会为它们自动提供微分, 避免手动计算导数的复杂过程。
- autograd.Variable是autograd的核心类, 它简单封装了Tensor(最新版PyTorch已经将Variable和Tensor的API合并, 以后直接使用Tensor即可, 不要使用Variable了)
- backward: 一个Scalar变量调用backward方法可以实现反向传播, 计算出各个变量的梯度
- data: 数据
- grad: 梯度
- grad_fn: 计算梯度的函数
- 注意:
- 方向传播backward中grad的值是累加的, 第二次反向传播的梯度就加上第一次反向传播的梯度, 这不是我们期望的, 所以进行了一次反向传播之后应该清空梯度, 使用grad.data.zero_()
torch.nn模块
torch.autograd提供了反向传播的功能, 已经可以仅仅通过torch.autograd来写深度学习代码了, 但是在大多数情况下还是略显麻烦, torch.nn提供了神经网络设计的模块化接口, torch.nn模块是以torch.autograd为基础的。
torch.nn.Module是torch.nn模块的核心类
- 使用torch.nn.Module搭建LeNet
#!/usr/bin/env python
# -*- coding: utf-8 -*- import torch as t
from torch.autograd import Variable
import torch.optim as optim
import torch.nn as nn
import torch.nn.functional as F class LeNet(nn.Module): def __init__(self):
super(LeNet, self).__init__()
# 需要学习的参数要写在__init__()中, 并且作为属性
# 在__init__()并不是定义图, 是在设置要学习的参数(进行初始化), nn.Conv2d这么多的参数就是在确定卷积核的维度而已
# 接着随机初始化参数W与b
self.conv1 = nn.Conv2d(1, 6, 5)
self.conv2 = nn.Conv2d(6, 16, 5)
self.fc1 = nn.Linear(16 * 5 * 5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10) def forward(self, x):
# 这里才是搭建网络的步骤
net = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
net = F.max_pool2d(F.relu(self.conv2(net)), 2)
net = net.view(net.size()[0], -1)
net = F.relu(self.fc1(net))
net = F.relu(self.fc2(net))
net = self.fc3(net)
return net def main(argv=None):
# 创建网络
lenet = LeNet()
# PyTorch中维度是通道优先, 与TensorFlow不同
# 伪造数据
x = Variable(t.randn(1, 1, 32, 32))
labels = Variable(t.arange(0, 10).type(t.FloatTensor)) # 前向传播
out = lenet(x)
# 定义损失函数
criterion = nn.MSELoss()
# 计算损失
loss = criterion(out, labels)
# 反向传播前先清空grad
lenet.zero_grad() loss.backward()
"""
# 手动实现SGD(最简单的优化策略)
learning_rate = 0.01
for f in lenet.parameters():
f.data.sub_(f.data * learning_rate)
"""
# 使用PyTorch提供的SGD
optimizer = optim.SGD(lenet.parameters(), lr=0.01)
optimizer.step() if __name__ == '__main__':
main()扩展PyTorch中的函数
- 可以选择继承PyTorch中的Function对象, 实现Function的staticmethod, 分别为forward, backward
- 上面的方法需要计算函数的反向传播, 其实也可以向TensorFlow一样, 直接写前向传播公式, PyTorch会通过自动求微分autograd机制实现反向传播
- 方法一和方法二的区别, 方法一, 采用的是面向对象的思维, 如果要自定义一个新的函数, 需要继承Function对象; 方法二, 一般定义的是一个函数。他们关系就像是PyTorch中的nn.ReLU和nn.funcional.relu一样
torchvision模块
- 提供已经预训练的网络模型(AlexNet, VGG, ResNet等), 在torchvision.models中
- 提供常用的数据集(MSCOCO, MNIST, CIFAR等), 在torchvision.datasets中
- 图像预处理模块, torchvision.transform
- CenterCrop
- ToTensor
- ToPILImage
- RandomHorizontalFlip
- Resize
- Normalize
- Compose用于将多个操作何为一个Sequence
- 工具模块, torchvision.utils
- make_grid, 将图像拼进去指定的网格中
- save_image, 将Tensor转为Image并保存到磁盘中
自定义数据集
import os
import numpy as np
import torch as t
import torch.nn as nn
import PIL
from PIL import Image
from torch.utils.data.dataset import Dataset
from torch.utils.data.dataloader import default_collate
from torch.utils.data import DataLoader
from torchvision import Transform as T
class BaseCatVsDogDataset(Dataset):
def __init__(self, root, transform=None):
ims = os.listdir(root)
self.ims = [os.path.join(root, im) for im in ims]
self.transform = transform
def __getitem__(self, idx):
im_path = self.ims[idx]
label = 1 if 'dog' in os.split('/')[0] else 0
im = Image.open(im_path)
if self.transform:
data = self.transform(im)
else:
data = t.Tensor(np.asarray(im))
return data, label
def __len__(self):
return len(self.ims)
class CatVsDogDataset(BaseCatVsDogDataset):
"""
Notes
-----
Subclass ``CatVsDogDataset`` are used to prevent abnormal exit of program caused by abnormal data
"""
def __init__(self, root, transform=None):
super(CatVsDogDataset, self).__init__(root, transform=transform)
def __getitem__(self, idx):
try:
return super(CatVsDogDataset, self).__getitem__(idx)
except:
# An exception returns to None
return None, None
def collate_fn(batch):
"""
Parameters
----------
batch : list
At this point, batch hasn't been integrated into [batch_size, C, H, W],
and each image is placed in a list [(im, label), (im, label), ...]
"""
# Filter out None values
batch = filter(lambda x: x[0] is not None, batch)
# Splice the values in batch whose type is ``list`` into a matrix
return default_collate(batch)
def main():
transform = T.Compose([T.Resize(224), T.CenterCrop(224), T.RandomHorizontalFlip(), T.ToTensor(), T.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])])
dataset = CatVsDogDataset('./data', transform=transform)
dataloader = DataLoader(dataset, shuffle=True, batch_size=64, drop_last=False, collate_fn=collate_fn)
for ims, labels in dataloader:
print(ims.size(), labels.size())
if __name__ == '__main__':
main()
visdom工具
- 先启动守护进程,
nohup python -m visdom.server &
- 创建vis对象,
vis = visdom.Visdom(env='test')
, env为环境名称 - 绘制标量变化,
vis.line(X=x, Y=y, win='sin', opts={'title': 'This is a title'})
, win是窗口名称, opts提供额外的属性, title为标题 - 绘制分布图,
vis.histogram(X=x, Y=y, win='test', opts={'title': 'This is a new title'})
- 先启动守护进程,
PyTorch规范
- 目录结构
.
├── README.md
├── checkpoints: 保存训练好的权重
├── config.py: 配置信息, 里面是一个DefaultConfig类, 还有一个parse方法, 用于解析命令行参数来覆盖DefaultConfig中的默认配置
├── data: 处理数据集
│ ├── __init__.py
│ └── dataset.py: 里面定义了一个数据集名称的类
├── dataset: 存放训练和测试的数据
├── main.py: 启动文件, 包含有train, val, test三个函数, 其中train会调用val在训练中进行交叉验证, test需要用户另外再启动一个进程执行
├── models: 存放网络模型
│ ├── __init__.py: 在文件中导入模型, 方便在main.py中导入
│ ├── basemodule.py: 扩展了nn.Module, 主要添加了load和save模型的方法
│ └── resnet34.py: 不继承nn.Module, 而是继承BaseModule
├── requirements.txt: 程序依赖说明文件
├── tmp: 临时目录, 如果在该目录下创建一个debug文件, 则程序进入debug模式
└── utils: 工具
├── __init__.py
└── visualize.py: 封装了visdom的可视化
- config.py中一般配置
- num_workers
- use_gpu
- lr
- max_epoch
- batch_size
- save_path
- env
- debug_file
- data_root
试手项目
- DogVsCat
- FastNeuralStyle
- RNN写诗
可能用到的函数
- nn.InstanceBatchNorm2d(ch, affine=True)
- nn.ReLU(inplace=True)
- tensor.item()
- nn.ReflectionPad2d(ch, scale_factor=2)
- meter.value()[0]
- torch.bmm: batch matmul
- nn.ReflectionPad2d(size): 镜像padding
- clamp(min, max): if x < min: min, if x > max: max, else x
- torchvision.transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])是现将图片归一化到0-1, 在减去均值除以标准差, 所以要可视化的话要乘以标准差, 加上均值
- with torch.no_grad(): 类似于之前版本中的volatile=True, 比requires_grad优先级要高
- 如果使用已经预训练好的模型, 拿来用的话, 需要调用eval()方法来去掉一些DropOut层, 在使用如下方式不计算梯度
for param in model.parameters():
param.requires_grad = False
NLP
- 像素的大小天生就具有色彩信息, 但是词的数值大小很难表征词的含义, 最初人们为了方便, 采用 One-Hot 的编码方式, 一般来说中文语料库的字平均在 8000-50000, 而词则在几十万左右, 使用 One-Hot 的编码方式很方便, 但是冗余很多, 并且无法体现词于词之间的关系 ( 使用 One-Hot 编码之后的每一个词都是正交的, 即任意两个词不相关 ), 如果语料库很大, One-Hot 的维度会非常的高, 在深度学习中容易造成维度灾难, 于是诞生了词向量 (Word Vector/Word Embedding)
- 词向量从 One-Hot 发展过来, 将 One-Hot 表示的高纬度映射到低纬度, 同时保留词与词之间的相关性, 如果特征相近, 则词与词之间靠的近; Embedding 是一个映射关系 ( 一个矩阵 ), 如果有 N 个词, 每一个词的维度降维到了 W, 则矩阵的维度为 (N, W). 假如输入了一组序列 (N, W), 其中 N 为 Batch Size, W 为序列的长度, 也就是词的个数, 通过词向量 (矩阵的维度为 (NumberOfWords, Dimension)) 映射得 (N, W * Dimension); 在 PyTorch 中, 词向量模块在 torch.nn.Embedding
其他
- 转置卷积维度计算公式
- \(H_{out}=(H_{in}-1)\times{stride}-2\times{padding}+ksize\)就是卷积维度公式的逆过程
- PyTorch 的 CrossEntropy 可以自动转 One-Hot
- 获取 Tensor 中的变量值, 调用 item() 方法
- 研究表明, 几乎所有神经网络的第一层学习到的都是关于线条和颜色的信息, 直观理解就是像素组成颜色, 点组成线, 这与人眼的感知特征十分相像, 在往上层, 神经网络开始关注一些复杂的特征, 例如拐角或者某些特殊的形状, 这些特征可以看成是低层次的特征组合, 随着深度的加深, 神经网络关注的信息逐渐抽象, 例如有一些卷积核关注的是这张图中有个鼻子, 或者是图中有张人脸, 以及对象之间的空间关系, 例如鼻子在人脸的中间等(这不是我说的, 是唐进民作者说的)
- 取patch像素中的值并累加就会抛弃空间信息, 因为一张图片的像素随机打乱得到的累加也是一样的, 但是亮度信息还保留, 因此还会有纹理信息, 色彩信息等
- PyTorch中网络中的__init__方法中定义了self.left = nn.Conv2d(in_ch, out_ch, 3, 1)等, 此时就会在使用的optimizer中会有一个param_group, PyTorch支持分层设置学习率, 使用
for param_group in optimizer.param_groups:
param_group['lr'] = lr * lr_decay
- PyTorch中, 对于Scalar的Tensor, 使用item()可是直接返回里面的数值
- torchnet.meter对象直接不能直接相加, 需要调用value()[0]获取里面的tensor才能相加, value()返回的是元组, [0]是我们期望的元素, [1]是Inf
- visdom.line参数一般是这样设置的
vis.line(X=np.array([x]), Y=np.array([y]), win=name, opts={'title': name}, update=None if not x else 'append')
- 一般上采样的方法
- 使用转置卷积, 但是当ksize / stride无法整除时容易导致checkerboard artifact(棋盘效应), 虽然理论上神经网络可以小心地学习从而消除棋盘效应
- 先对features map进行插值上采样, 将大小resize到我们期望的大小, 再使用padding或者reflectionpadding进行卷积
- 转置卷积维度计算公式
PyTorch 学习的更多相关文章
- 【深度学习】Pytorch学习基础
目录 pytorch学习 numpy & Torch Variable 激励函数 回归 区分类型 快速搭建法 模型的保存与提取 批训练 加速神经网络训练 Optimizer优化器 CNN MN ...
- Pytorch学习之源码理解:pytorch/examples/mnists
Pytorch学习之源码理解:pytorch/examples/mnists from __future__ import print_function import argparse import ...
- Pytorch学习记录-torchtext和Pytorch的实例( 使用神经网络训练Seq2Seq代码)
Pytorch学习记录-torchtext和Pytorch的实例1 0. PyTorch Seq2Seq项目介绍 1. 使用神经网络训练Seq2Seq 1.1 简介,对论文中公式的解读 1.2 数据预 ...
- Pytorch学习--编程实战:猫和狗二分类
Pytorch学习系列(一)至(四)均摘自<深度学习框架PyTorch入门与实践>陈云 目录: 1.程序的主要功能 2.文件组织架构 3. 关于`__init__.py` 4.数据处理 5 ...
- 新手必备 | 史上最全的PyTorch学习资源汇总
目录: PyTorch学习教程.手册 PyTorch视频教程 PyTorch项目资源 - NLP&PyTorch实战 - CV&PyTorch实战 PyTorch论 ...
- [深度学习] Pytorch学习(一)—— torch tensor
[深度学习] Pytorch学习(一)-- torch tensor 学习笔记 . 记录 分享 . 学习的代码环境:python3.6 torch1.3 vscode+jupyter扩展 #%% im ...
- Pytorch学习笔记(二)---- 神经网络搭建
记录如何用Pytorch搭建LeNet-5,大体步骤包括:网络的搭建->前向传播->定义Loss和Optimizer->训练 # -*- coding: utf-8 -*- # Al ...
- Pytorch学习笔记(一)---- 基础语法
书上内容太多太杂,看完容易忘记,特此记录方便日后查看,所有基础语法以代码形式呈现,代码和注释均来源与书本和案例的整理. # -*- coding: utf-8 -*- # All codes and ...
- pytorch学习-WHAT IS PYTORCH
参考:https://pytorch.org/tutorials/beginner/blitz/tensor_tutorial.html#sphx-glr-beginner-blitz-tensor- ...
- pytorch学习资料链接
2017年12月25日15:06:44 官方文档:http://pytorch.org/docs/master/index.html 官方文档中文翻译:https://pytorch-cn.readt ...
随机推荐
- java 基础(一) Sublime Text3搭建Java编译环境(Windows系统)
1. 首先配置好Java环境变量我的jdk版本是1.8.0_191,存放目录是C:\Program Files\Java,因此添加以下环境变量 (1)系统变量→新建 JAVA_HOME 变量,变量值为 ...
- 数据可视化之分析篇(十)Power BI应用:如何计算在职员工数量?
https://zhuanlan.zhihu.com/p/128652582 经常碰到的一类问题是,如何根据起止日期来计算某个时间点的数量,比如: 已知合同的生效日期和到期日期,特定日期的有效合同有 ...
- python之爬虫(九)PyQuery库的使用
PyQuery库也是一个非常强大又灵活的网页解析库,如果你有前端开发经验的,都应该接触过jQuery,那么PyQuery就是你非常绝佳的选择,PyQuery 是 Python 仿照 jQuery 的严 ...
- hihoCoder 1052 基因工程 最详细的解题报告
题目来源:基因工程 解题思路:假设基因序列长度为N,则需要计算基因序列前K个和后K个相同所需要的最少改变次数sum. 假设基因序列为 ATACGTCT (即M=8),K=6:interval=M-K= ...
- 《Head First 设计模式》:装饰者模式
正文 一.定义 装饰者模式动态地将责任(功能)附加到对象上.若要扩展功能,装饰者提供了比继承更有弹性的替代方案. 要点: 装饰者和被装饰者有相同的超类型. 可以用一个或多个装饰者包装一个对象. 既然装 ...
- JavaScript动画实例:螺旋线
数学中有各式各样富含诗意的曲线,螺旋线就是其中比较特别的一类.螺旋线这个名词来源于希腊文,它的原意是“旋卷”或“缠卷”.例如,平面螺旋便是以一个固定点开始向外逐圈旋绕而形成的曲线.在2000多年以前, ...
- 事件的event对象基本解释
事件流: 描述的是在页面中接受事件的顺序主要分为两种: 事件冒泡.事件捕获 事件event对象:1. type 获取事件类型2. target获取事件目标3. stopPropagation() 阻止 ...
- Python Ethical Hacking - BACKDOORS(7)
Handling Errors: If the client or server crashes, the connection will be lost. Backdoor crashes if: ...
- NVIDIA GPU Pascal架构简述
NVIDIA GPU Pascal架构简述 本文摘抄自英伟达Pascal架构官方白皮书:https://www.nvidia.com/en-us/data-center/resources/pasca ...
- JQuery对下拉列表Select的一些操作
1.假如select中存在选项,需要清空的情况: $("#search").find("option").remove(); $("#search&q ...