Something about PyTorch
-
torchvision.transfroms.Compose(trandforms)
将多个transform组合起来使用
例子:
1
2
3
4transforms.Compose([
transfroms.CenterCrop(10),
transforms.ToTensor(),
]) -
OrderedDict
是dict的子类,其最大特征是,它可以“维护”添加key-value对的额顺序。简单的来说,就是先添加的key-value对排在前面,后添加的key-value对排在后面
由于OrderedDict能维护key-value对的添加顺序,因此即使两个OrderedDict照中的key-value对完全相同,但只要他们的顺序不同,程序在判断他们是否相等时也依然会返回false。
1 | from collections import OrderedDict |
-
nn.LeakyReLU(inplace=True)
inplace=True
的意思是进行原地操作,例如x=x+5
对于x就是一个原地操作,y=x+5; x=y
完成了与x=x+5
同样的功能但不是原地操作,与上面的inplace=True
的含义是一样的,是对于Conv2d这样的上层网络传递下来的tensor直接进行修改,好处就是可以节省运算内存 -
batch normalization层的实现机理:
假设我们在网络中间经过某些卷积操作之后输出的feature map的尺寸为4 * 3 * 2 * 2
4为batch的大小, 3为channel的数目,2 * 2为feature map的长宽
所以对于一个batch Normalization层而言,去求均值与方差是对于所有batch中的同一个channel进行求取,batch normalization中的batch体现在这个地方
batch normalization层能够学习到的参数,对于一个特定的channel而言实际上是两个参数,gamma与beta,对于total的channel而言实际上是channel数目的两倍
-
meshgrid()
引入创建网格点的矩阵
示例一:创建一个2行3列的网格点矩阵。
1
2
3
4
5
6
7
8
9
10
11import numpy as np
import matplotlib.pyplot as plt
X = np.array([[0, 0.5, 1], [0, 0.5, 1]])
print("X的维度: {}, shape: {}".format(X.ndim, X.shape))
Y = np.array([[0, 0, 0], [1, 1, 1]])
print("Y的维度: {}, shape: {}".format(Y.ndim, Y.shape))
plt.plot(X, Y, 'o--')
plt.grid(True)
plt.show()当要描绘的 矩阵网格点的数据量小的时候,可以用上述方法构造网格点坐标数据;
但是如果是一个(256, 100)的整数矩阵网格,要怎样构造数据呢?
方法1:将x轴上的100个整数点组成的行向量,重复256次,构成shape(256,100)的X矩阵;将y轴上的256个整数点组成列向量,重复100次构成shape(256,100)的Y矩阵
显然方法1的数据构造过程很繁琐,也不方便调用,那么有没有更好的办法呢?of course!!!
那么meshgrid()就显示出它的作用了
使用meshgrid方法,你只需要构造一个表示x轴上的坐标的向量和一个表示y轴上的坐标的向量;然后作为参数给到meshgrid(),该函数就会返回相应维度的两个矩阵;
例如,你想构造一个2行3列的矩阵网格点,那么x生成一个shape(3,)的向量,y生成一个shape(2,)的向量,将x,y传入meshgrid(),最后返回的X,Y矩阵的shape(2,3)
示例二:使用meshgrid()
生成示例一种的网格点矩阵
1 | import numpy as np |
示例三:生成20行30列的网格点矩阵
只需要改变:
1 | x = np.linspace(0, 500, 30) |
repeat()
和expand()
的区别
torch.Tensor是包含一种数据类型元素的多维矩阵,torch.Tensor有两个实例方法可以用来扩展某维的数据的尺寸,分别是repeat()
和expand()
expand()
返回当前张量在某维扩展更大后的张量, 扩展(expand)张量不会分配新的内存,只是在存在的张量上创建一个新的视图(view),一个大小(size)等于1的维度扩展到更大的尺寸。示例:
1 | import torch |
1 | import torch |
repeat()
沿着特定的维度重复这个张量,和expand()不同的是,这个函数拷贝张量的数据。
1 | import torch |
1 | import torch |
squeeze()
和unsqueeze()
unsqueeze()函数
首先初始化一个a
1 | import torch |
可以看到a的维度是(2, 3)
在第二维增加一个维度,使其维度变为(2, 1, 3)
1 | 1) a = a.unsqueeze( |
可以看到维度已经变为(2, 1, 3)了,同样如果需要在倒数第二个维度上增加一个维度,可以用a.unsqueeze(-2)
squeeze()函数
1 | 1) a = a.squeeze( |
另外,
1 | a |
此时可以看到维度没有发生变化,这是因为只有维度为1时才会去掉
permute()
将tensor的维度换位
参数:参数是一系列的整数,代表原来张量的维度
1 | 1, 2, 3], [4, 5, 6]]]) a = np.array([[[ |
再比如,图片img的size比如是(28, 28, 3),就可以利用img.permute(2, 0, 1)
得到一个size为(3, 28, 28)的tensor
contiguous()
在PyTorch中,有一些对Tensor的操作不会真正改变Tensor中的内容,改变的仅仅是Tensor中字节位置的索引。这些操作有:
narrow(), view(), expand(), transpose()
例如在执行view()
操作之后,不会开辟新的内存空间才存放处理之后的数据,实际上新数据与原始数据共享同一块内存
而在调用contiguous()
之后,PyTorch会开辟出一块新的内存空间存放变换之后的数据,并会真正改变Tensor的内容,按照变换之后的顺序存放数据。
-
grid_sample(input, frig, mode='linear', padding_mode='zeros')
用于图像的恢复
input (N, C, H_in, W_in)
output (N, H_out, W_out, 2)
grid的索引值(数据坐标)对应output索引值(数据坐标)
grid中数值对应input的索引值(数据坐标)
grid(u, v) = x, y
output(u, v) 数值对应 input(x, y)
示意图:
nn.Upsample()
所用:上采样
定义:CLASS torch.nn.Upsample(size=None, scale_factor=None, mode='nearest', align_corners=None)
计算shape