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中的函数

    1. 可以选择继承PyTorch中的Function对象, 实现Function的staticmethod, 分别为forward, backward
    2. 上面的方法需要计算函数的反向传播, 其实也可以向TensorFlow一样, 直接写前向传播公式, PyTorch会通过自动求微分autograd机制实现反向传播
    3. 方法一和方法二的区别, 方法一, 采用的是面向对象的思维, 如果要自定义一个新的函数, 需要继承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 学习的更多相关文章

  1. 【深度学习】Pytorch学习基础

    目录 pytorch学习 numpy & Torch Variable 激励函数 回归 区分类型 快速搭建法 模型的保存与提取 批训练 加速神经网络训练 Optimizer优化器 CNN MN ...

  2. Pytorch学习之源码理解:pytorch/examples/mnists

    Pytorch学习之源码理解:pytorch/examples/mnists from __future__ import print_function import argparse import ...

  3. Pytorch学习记录-torchtext和Pytorch的实例( 使用神经网络训练Seq2Seq代码)

    Pytorch学习记录-torchtext和Pytorch的实例1 0. PyTorch Seq2Seq项目介绍 1. 使用神经网络训练Seq2Seq 1.1 简介,对论文中公式的解读 1.2 数据预 ...

  4. Pytorch学习--编程实战:猫和狗二分类

    Pytorch学习系列(一)至(四)均摘自<深度学习框架PyTorch入门与实践>陈云 目录: 1.程序的主要功能 2.文件组织架构 3. 关于`__init__.py` 4.数据处理 5 ...

  5. 新手必备 | 史上最全的PyTorch学习资源汇总

    目录: PyTorch学习教程.手册 PyTorch视频教程 PyTorch项目资源      - NLP&PyTorch实战      - CV&PyTorch实战 PyTorch论 ...

  6. [深度学习] Pytorch学习(一)—— torch tensor

    [深度学习] Pytorch学习(一)-- torch tensor 学习笔记 . 记录 分享 . 学习的代码环境:python3.6 torch1.3 vscode+jupyter扩展 #%% im ...

  7. Pytorch学习笔记(二)---- 神经网络搭建

    记录如何用Pytorch搭建LeNet-5,大体步骤包括:网络的搭建->前向传播->定义Loss和Optimizer->训练 # -*- coding: utf-8 -*- # Al ...

  8. Pytorch学习笔记(一)---- 基础语法

    书上内容太多太杂,看完容易忘记,特此记录方便日后查看,所有基础语法以代码形式呈现,代码和注释均来源与书本和案例的整理. # -*- coding: utf-8 -*- # All codes and ...

  9. pytorch学习-WHAT IS PYTORCH

    参考:https://pytorch.org/tutorials/beginner/blitz/tensor_tutorial.html#sphx-glr-beginner-blitz-tensor- ...

  10. pytorch学习资料链接

    2017年12月25日15:06:44 官方文档:http://pytorch.org/docs/master/index.html 官方文档中文翻译:https://pytorch-cn.readt ...

随机推荐

  1. python 追踪函数调用

    from flask import Flask import traceback app = Flask(__name__) @app.route('/') def hello_world(): tr ...

  2. web 部署专题(六):nginx 安装(二) linux

    https://www.cnblogs.com/quzq/p/12131696.html 基础篇 一.环境 服务器版本:CentOS 7.2 为了保证学习阶段不遇到奇怪的事情,请保证以下四点(大神选择 ...

  3. 数据可视化之powerBI基础(十一)Power BI中的数据如何导出到Excel中?

    https://zhuanlan.zhihu.com/p/64415543 把Excel中数据加载到PowerBI中我们都已经熟悉了,但是怎么把在PowerBI中处理好的数据导出到Excel中呢?毕竟 ...

  4. 数据可视化之PowerQuery篇(七)Power Query应用技巧:批量更改列名

    https://zhuanlan.zhihu.com/p/130460772 ​今天分享一个PowerQuery的小技巧,导入到PowerBI中的数据,如果想要更改数据的列名,可以在PQ编辑器中直接双 ...

  5. 前端02 /HTML标签

    前端02 /HTML标签 目录 前端02 /HTML标签 1.特殊字符 2.标签分类 标签嵌套 1.块级标签(行内标签) 1.1div标签(块标签) 1.2p标签(块标签) 2.内联标签 2.1 sp ...

  6. IOS10 window.navigator.geolocation.getCurrentPosition 无法定位问题

    在iOS 10中,苹果对webkit定位权限进行了修改,所有定位请求的页面必须是https协议的. 如果是非https网页,在http协议下通过HTML5原生定位接口会返回错误,也就是无法正常定位到用 ...

  7. Python numpy 浮点数精度问题

    Python numpy 浮点数精度问题 在复现FP(fictitious play, Iterative solution of games by fictitious play-page393)算 ...

  8. java opencsv解析csv文件

    记一次使用opencsv解析csv文件时碰到的坑 最近在开发过程中需要解析csv文件,公司用的解析工具是opencsv,在根据opencsv的官方文档去解析时发现csv文件中含有繁体字,使用其自带的C ...

  9. ajax提交表单,包括跳入的坑!

    本来今天上午写了一个js执行上下文的一个了解.但是写一大半的时候出去有事,电脑关了啥都没了. 还是让我们进入正题 ajax提交表单,很简单,原生js的代码太复杂,我们就jq的去写. 创建html文件, ...

  10. 服务质量分析:腾讯会议&腾讯云Elasticsearch玩出了怎样的新操作?

    导语 | 腾讯会议于2019年12月底上线,两个月内日活突破1000万,被广泛应用于疫情防控会议.远程办公.师生远程授课等场景,为疫情期间的复工复产提供了重要的远程沟通工具.上线100天内,腾讯会议快 ...