Pytorch的概念
Pytorch最重要的概念是tensor,意为“张量”。
Variable是能够构建计算图的 tensor(对 tensor 的封装)。借用Variable才能搭建神经网络。
Variable 操作和 tensor 是一样的,但是每个 Variabel 都有三个属性——.data、.grad、.grad_fn。
.data 对应 tensor 本身,.grad对应 tensor 的梯度,.grad_fn对应 Variable 的得到方式。
名称 | 含义 |
---|---|
.data | tensor 本身 |
.grad | tensor 的梯度 |
.grad_fn | Variable 的得到方式 |
强调:
目前版本的 Pytorch 中,tensor 和 Variable 已经合并。即:不再需要将 tensor 放到 Variable 中。
Pytorch的函数
一些基本的函数参考Tensor and Variable,是《深度学习入门之Pytorch》配套的GitHub。
网络层函数参考PyTorch中文文档
再次强调:
目前版本的Pytorch中,tensor和variable已经合并。即:不再需要将 tensor 放到 Variable 中。
以下函数须提前引入torch
库和numpy
库。
import torch
import numpy as np
ndarray转tensor: torch.Tensor(array)
和 torch.from_numpy(array)
。
ndarray
--> tensor
# 函数1
pytorch_tensor1 = torch.Tensor(numpy_tensor)
# 函数2
pytorch_tensor2 = torch.from_numpy(numpy_tensor)
tensor转ndarray: .numpy()
tensor
--> ndarray
注:tensor
需要在CPU
上,如不在CPU
上则需要用.cpu()
函数来转到CPU
上。
# 如果 pytorch tensor 在 cpu 上
numpy_array = pytorch_tensor1.numpy()
# 如果 pytorch tensor 在 gpu 上
numpy_array = pytorch_tensor1.cpu().numpy()
CPU和GPU互转:.cuda()
和 .cpu()
.cuda()
和 .cpu()
将所有的模型参数(parameters
)和buffers
互相传递。
device_id (int, optional)
– 如果指定的话,所有的模型参数都会复制到指定的设备上
.cuda()
将tensor
从 CPU 放到 GPU 上
# 将 tensor 放到第一个 GPU 上
gpu_tensor = torch.randn(10, 20).cuda(0)
# 将 tensor 放到第二个 GPU 上
gpu_tensor = torch.randn(10, 20).cuda(1)
.cpu()
将tensor
从 GPU 放到 CPU 上
cpu_tensor = gpu_tensor.cpu()
tensor的大小、数据类型、维度、元素个数
tensor的大小:.shape
和.size()
tensor的数据类型:.type()
tensor的维度:.dim()
tensor的元素个数:.numel()
tensor的 四则运算
四则运算的方法有两种,直接加减乘除 和 调用函数
直接加减乘除 示例:
import numpy as np
import torch
x = torch.ones(3, 3)
y = torch.ones(3, 3)
z1 = x + y
# tensor([[2., 2., 2.],
# [2., 2., 2.],
# [2., 2., 2.]])
z2 = x - y
# tensor([[0., 0., 0.],
# [0., 0., 0.],
# [0., 0., 0.]])
z3 = x * 3
# tensor([[3., 3., 3.],
# [3., 3., 3.],
# [3., 3., 3.]])
z4 = x / 2
# tensor([[0.5000, 0.5000, 0.5000],
# [0.5000, 0.5000, 0.5000],
# [0.5000, 0.5000, 0.5000]])
对应的 inplace 操作,即把需要修改的 tensor 放到 =
左边。
调用函数 示例:
import numpy as np
import torch
x = torch.ones(3, 3)
y = torch.ones(3, 3)
z = x.add(y)
# tensor([[2., 2., 2.],
# [2., 2., 2.],
# [2., 2., 2.]])
inplace 操作
直接对 tensor 进行操作而不需要另外开辟内存空间,一般是在操作符的后面加_
(下划线)
但更多还是直接重新赋值。
x = torch.ones(3, 3)
print(x.shape)
# torch.Size([3, 3])
# unsqueeze 进行 inplace
x.unsqueeze_(0)
print(x.shape)
# torch.Size([1, 3, 3])
# transpose 进行 inplace
x.transpose_(1, 0)
print(x.shape)
# torch.Size([3, 1, 3])
.zero_grad()
将module
中的所有模型参数的梯度设置为0。(用来重置)
用于反向传播一次后,将梯度重置为0,为下一次反向传播初始化。(避免梯度叠加引起的错误)
eval()
(待补)
将模型设置成evaluation
模式
仅仅当模型中有Dropout
和BatchNorm
是才会有影响。
class torch.nn.Sequential(* args)
(待补)
一个时序容器。Modules
会以他们传入的顺序被添加到容器中。当然,也可以传入一个OrderedDict
。
为了更容易的理解如何使用Sequential
, 下面给出了一个例子:
# Example of using Sequential
model = nn.Sequential(
nn.Conv2d(1,20,5),
nn.ReLU(),
nn.Conv2d(20,64,5),
nn.ReLU()
)
# Example of using Sequential with OrderedDict
model = nn.Sequential(OrderedDict([
('conv1', nn.Conv2d(1,20,5)),
('relu1', nn.ReLU()),
('conv2', nn.Conv2d(20,64,5)),
('relu2', nn.ReLU())
]))
forward(* input)
(待补)
定义了每次执行的计算步骤。
在所有的子类中都需要重写这个函数。
modules()
(待补)
返回一个包含 当前模型 所有模块 的迭代器。
import torch.nn as nn
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()
self.add_module("conv", nn.Conv2d(10, 20, 4))
self.add_module("conv1", nn.Conv2d(20 ,10, 4))
model = Model()
for module in model.modules():
print(module)
Model (
(conv): Conv2d(10, 20, kernel_size=(4, 4), stride=(1, 1))
(conv1): Conv2d(20, 10, kernel_size=(4, 4), stride=(1, 1))
)
Conv2d(10, 20, kernel_size=(4, 4), stride=(1, 1))
Conv2d(20, 10, kernel_size=(4, 4), stride=(1, 1))
可以看出,modules()
返回的iterator
不止包含子模块。这是和children()
的不同。
import torch.nn as nn
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()
submodule = nn.Conv2d(10, 20, 4)
self.add_module("conv", submodule)
self.add_module("conv1", submodule)
model = Model()
for module in model.modules():
print(module)
Model (
(conv): Conv2d(10, 20, kernel_size=(4, 4), stride=(1, 1))
(conv1): Conv2d(10, 20, kernel_size=(4, 4), stride=(1, 1))
)
Conv2d(10, 20, kernel_size=(4, 4), stride=(1, 1))
扩充函数:append(axis)[source]
和extend(axis)[source]
等价于python list 的 extend 方法。(待补)
等价于 list
的 append()
参数: 要 append 的东西。
常见参数有:
append(module)[source]
append(parameter)[source]