Pytorch
本学习笔记基于【深度学习Pytorch入门】5天从Pytorch入门到实战!PyTorch深度学习快速入门教程 150全集 绝对通俗易懂(深度学习框架/神经网络)_哔哩哔哩_bilibili
Tensorflow:静态图优先
Pytorch:动态图优先
Tensor数据类型
数据类型
类型 |
类型 |
32位浮点型 |
(默认)torch.FloatTensor |
64位浮点型 |
torch.DoubleTensor |
16位整型 |
torch.shortTensor |
32位整型 |
torch.IntTensor |
64位整型 |
torch.LongTensor |
维度DIM
Tensor:张量,可以理解为任意维度的矩阵
Pytorch 没有string类型,其句子用编码one-bot or enbeding 向量表示
Dim0(标量):torch.tensor(1.3)
即生成了一个值为1.3的变量 注意 :1.3为0维标量 [1.3]为1维矢量
通常应用于loss计算
>>> a=torch.tensor(1.2) >>> a.shape torch.Size([]) >>> len(a.shape) 0 >>> a.size() torch.Size([]) >>>
|
Dim1(向量):通常应用于节点输入bias 或者是Linear Input
>>> torch.tensor([1.1]) tensor([1.1000]) >>> torch.tensor([1.1,2.1]) tensor([1.1000, 2.1000]) >>> torch.FloatTensor(1) tensor([-1.0842e-19]) >>> torch.FloatTensor(2) tensor([0.0000, 0.0078]) >>> torch.ones(2) tensor([1., 1.])
|
Dim2:通常用于多张图片的 Linear Input Batch
>>> a=torch.randn(2,3) >>> a tensor([[-0.4689, -1.2038, -1.6282], [-0.8379, -1.1376, -1.9624]]) >>> a.shape torch.Size([2, 3]) >>> a.size(0) 2 >>> a.size(1) 3 >>> a.shape[0] 2 >>> a.shape[1] 3
|
Dim3: 用于 RNN Input Batch
>>> a=torch.rand(1,2,3) >>> a tensor([[[0.4257, 0.1625, 0.1817], [0.3695, 0.8208, 0.5442]]]) >>> a.shape torch.Size([1, 2, 3]) >>> a[0] tensor([[0.4257, 0.1625, 0.1817], [0.3695, 0.8208, 0.5442]]) >>> a[0][1] tensor([0.3695, 0.8208, 0.5442]) >>> a[0][1][1] tensor(0.8208) >>>
|
$$
\begin{bmatrix}\begin{bmatrix}0.4257&0.1625&0.1817\end{bmatrix}\\\begin{bmatrix}0.3695&0.8208&0.5442\end{bmatrix}\end{bmatrix}
$$
Dim4:适用于 图片 [batch,channel,height,width]
>>> a=torch.rand(2,3,28,28) >>> a.shape torch.Size([2, 3, 28, 28]) >>> a.numel() 4704 >>> a.dim() 4
|
创建Tensor
从np.array创建
>>> a=np.array([2,3.3]) >>> torch.from_numpy(a) tensor([2.0000, 3.3000], dtype=torch.float64) >>> a=np.ones([2,3]) >>> torch.from_numpy(a) tensor([[1., 1., 1.], [1., 1., 1.]], dtype=torch.float64)
|
numpy_a=a.numpy()
可将Tensor转换位numpy数据类型
从list创建:
>>> torch.tensor([[1,2,3,4,5],[3,4,5,6,7]]) tensor([[1, 2, 3, 4, 5], [3, 4, 5, 6, 7]])
|
注意:tensor()输入参数为初始化数据 Tensor()输入参数为shape或list
>>> torch.Tensor(2,3) tensor([[2.3063e-31, 8.6740e-43, 8.4078e-45], [0.0000e+00, 2.3073e-31, 8.6740e-43]]) >>> torch.Tensor([2,3]) tensor([2., 3.]) >>> torch.tensor(2,3) 报错
|
不初始化:
>>> torch.FloatTensor(2,2,3) tensor([[[0., 0., 0.], [0., 0., 0.]],
[[0., 0., 0.], [0., 0., 0.]]]) >>> torch.IntTensor(2,2,3) tensor([[[1, 0, 1], [0, 1, 0]],
[[1, 0, 1], [0, 1, 0]]], dtype=torch.int32) >>> torch.empty(2,2,2) tensor([[[ 6.4011e+23, 1.7866e+25], [-2.2864e-31, 7.7961e+34]],
[[ 1.1093e+27, 4.1709e-08], [ 3.7392e-38, -1.2803e-26]]])
|
随机初始化:rand
:[0,1]间均匀分布
rand_like(a)
相当于rand(a.shape)
rand_int(min,max,shape)
randn(shape)
(0,1)正态分布
normal(mean=torch.full([shape],mean),std=torch.full([shape],std))
:自定义正态分布,均值mean 方差 std
torch.full:
>>> torch.full([2,3],1) tensor([[1, 1, 1], [1, 1, 1]])
|
torch.arrange:
>>> torch.arange(1,10,2) tensor([1, 3, 5, 7, 9])
|
torch.linspace:
>>> torch.linspace(0,10,4) tensor([ 0.0000, 3.3333, 6.6667, 10.0000]) 等分为4个数据
|
torch.eye:单位矩阵
>>> torch.eye(3,3) tensor([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) >>> torch.eye(3,5) tensor([[1., 0., 0., 0., 0.], [0., 1., 0., 0., 0.], [0., 0., 1., 0., 0.]])
|
randperm: 随机打散 可设置为种子每次相同打散方法
索引与切片
与python
一样
间隔切片
>>> a=torch.Tensor(4,3,28,28) >>> a[:,:,0:28:2,0:28:2].shape torch.Size([4, 3, 14, 14])
|
第二个:
后为步长
index_select(维度,torch.tensor[所选index])
:第二个参数必须是tensor
>>> a=torch.Tensor(4,3,28,28) >>> a.index_select(0,torch.tensor([0,2])).shape torch.Size([2, 3, 28, 28])
|
...
:所有的维度
>>> a.shape torch.Size([4, 3, 28, 28]) >>> a[1,...].shape torch.Size([3, 28, 28]) >>> a[...,:2].shape torch.Size([4, 3, 28, 2])
|
masked_select():
>>> a=torch.randn(3,4) >>> a tensor([[ 0.2088, -0.1852, 0.6233, 0.5107], [ 1.6500, 0.3151, 1.1227, 1.7956], [-1.1915, 0.8243, -0.0114, 0.7303]]) >>> mask=a.ge(0.5) >>> mask tensor([[False, False, True, True], [ True, False, True, True], [False, True, False, True]]) >>> a.masked_select(mask) tensor([0.6233, 0.5107, 1.6500, 1.1227, 1.7956, 0.8243, 0.7303]) >>> a.masked_select(mask).shape torch.Size([7])
|
维度变换
reshape:
>>> a=torch.rand(4,1,28,28) >>> a.shape torch.Size([4, 1, 28, 28]) a.reshape(4,28*28).shape torch.Size([4, 784]) >>> a.reshape(4,28*28).shape torch.Size([4, 784]) >>> a.reshape(4*28,28).shape torch.Size([112, 28]) >>> a.reshape(4*1,28,28).shape torch.Size([4, 28, 28])
|
squeeze/unsqueeze:
unsqueeze():参数取值范围 [-dim-1,dim+1) 正索引 是在当前索引 之后 插入,负索引是在当前索引 之前 插入
>>> a.shape torch.Size([4, 1, 28, 28]) >>> a.unsqueeze(3).shape torch.Size([4, 1, 28, 1, 28]) >>> a.unsqueeze(-3).shape torch.Size([4, 1, 1, 28, 28])
|
squee(idx): 删除当前维度
transpose/t/permute:
transpose:维度交换
>>> a.shape torch.Size([4, 1, 28, 28]) >>> a.transpose(1,3).shape torch.Size([4, 28, 28, 1])
|
t:只能用于矩阵 二维
permute:重构 输入参数为维度
>>> a.shape torch.Size([4, 1, 28, 28]) >>> a.permute(0,2,3,1).shape torch.Size([4, 28, 28, 1])
|
expand/repeat:
expand: 需要时才复制数据,输入参数为扩张后的大小,只有为1的才能扩张,-1表示该维度保持不限
repeat:一开始就复制数据,输入参数为复制次数
>>> a.shape torch.Size([4, 1, 28, 28]) >>> a.expand(-1,4,28,28).shape torch.Size([4, 4, 28, 28]) >>> a.repeat(4,1,1,1).shape torch.Size([16, 1, 28, 28])
|
合并与分割
cat
除了需要合并的dim以外,其他的dim大小应该相同
>>> a=torch.rand(4,32,8) >>> b=torch.rand(5,32,8) >>> torch.cat([a,b],dim=0).shape torch.Size([9, 32, 8])
|
stack
重新在合并的dim维度之前添加一个维度,该维度不同取值显示合并前不同内容
要求所有dim的大小一样
>>> torch.stack([a,b],dim=1).shape torch.Size([4, 2, 32, 8])
|
split
通过长度拆分
>>> a.shape torch.Size([3, 4, 32]) >>> b.shape torch.Size([1, 4, 32]) >>> c.shape torch.Size([1, 4, 32]) >>> d.shape torch.Size([1, 4, 32]) >>> a1,a2=a.split([2,1],dim=0) >>> a1.shape torch.Size([2, 4, 32]) >>> a2.shape torch.Size([1, 4, 32]) >>> a1,a2=a.split(2,dim=0) >>> a1.shape torch.Size([2, 32, 5]) >>> a2.shape torch.Size([2, 32, 5])
|
chunk
通过数量拆分
>>> a1,a2=a.chunk(2,dim=0) >>> a1.shape torch.Size([2, 32, 5]) >>> a2.shape torch.Size([2, 32, 5])
|
Broadcasting
大维度缺失可自动添加,且每个维度可以自动扩张
>>> a=torch.rand(4,4,32,32) >>> b=torch.rand(4,1,1) >>> c=a+b >>> c.shape torch.Size([4, 4, 32, 32])
|
b:[4,1,1]→[1,4,1,1]→[4,4,32,32]
>>> a=torch.rand(1,3) >>> b=torch.rand(3,1) >>> c=a+b >>> c.shape torch.Size([3, 3])
|
a:[1,3]→[3,3]
b:[3,1]→[3,3]