numpy
一些numpy的基础知识,我只整理了些看到用到的。
np.hstack()
import numpy as np
a = [[1,2,3],
[4,5,6],
[7,8,9]]
print(a)
b = np.hstack(a)
print(b)
结果:
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
[1 2 3 4 5 6 7 8 9]
就是返回numpy的数组
顺便提一下np.stack,是用来增加维度的
view
import torch
a = torch.randn(1, 2, 3, 4)
print('a = ', a)
print('shape a = ', a.shape)
b = a.view(1, 24)
print('b = ', b)
print('shape b = ', b.shape)
结果:
a = tensor([[[[ 0.6292, -0.5430, 0.1855, 0.3432],
[-0.2682, -0.0130, -0.0158, -2.1024],
[-1.8120, 0.6240, -0.5457, -1.4022]],
[[ 1.3685, 0.2492, 0.5201, -0.9838],
[-1.0728, -0.0744, 0.9459, 0.9389],
[ 1.0513, 2.8753, -0.1406, 1.2180]]]])
shape a = torch.Size([1, 2, 3, 4])
b = tensor([[ 0.6292, -0.5430, 0.1855, 0.3432, -0.2682, -0.0130, -0.0158, -2.1024,
-1.8120, 0.6240, -0.5457, -1.4022, 1.3685, 0.2492, 0.5201, -0.9838,
-1.0728, -0.0744, 0.9459, 0.9389, 1.0513, 2.8753, -0.1406, 1.2180]])
shape b = torch.Size([1, 24])
我认为这个view就是将矩阵转换形式,以便与torch.nn中不同函数的输入输出的size
这么说有些抽象,举个例子,设置一个nn.Linear函数fc
操作一下:
fc = torch.nn.Linear(24, 1) # input_size = 48, output_size = 1
out = fc(b)
print('out shape = ', out.shape)
print(out)
结果是:
out shape = torch.Size([1, 1])
tensor([[0.3557]], grad_fn=<AddmmBackward>)
感觉这就是我常见的那个图,大概长下面这个样子:
不同的层次里面有不同数量的接口,函数的输入输出位置的数字就是代表这些接口数量。要相互匹配,才能顺利运行。
这里说的匹配,并不是随意设置的,比如说图片,输入一个图片,图片的表达形式大概是[1,2,3],是三维数组(这个数字是我编的),然后我们把它当作输入到fc中。但是因为**PyTorch的nn.Linear()是用于设置网络中的全连接层的,需要注意的是全连接层的输入与输出都是二维张量,一般形状为[batch_size, size],不同于卷积层要求输入输出是四维张量。**定义如下:
所以,我们要把四维张量a转化成二维张量b之后,才能作为输入。这时,a.view(1, 24),就能实现这个功能,转换成二维数组b。
unsqueeze() 和 unsqueeze_()
torch.unsqueeze(input, dim, out=None)
-
作用:扩展维度
返回一个新的张量,对输入的既定位置插入维度 1 -
注意: 返回张量与输入张量共享内存,所以改变其中一个的内容会改变另一个。
如果dim为负,则将会被转化dim+input.dim()+1 -
参数:
tensor (Tensor) – 输入张量
dim (int) – 插入维度的索引 要在哪个位置扩充就写几
out (Tensor, optional) – 结果张量
一样,我们用例子来直观的说明以下:
import torch
a = torch.Tensor([1, 2, 3, 4])
print('a = ', a)
print('shape a = ', a.size)
c = torch.unsqueeze(a, 1)
print(c)
print('shape of c: ', c.shape)
结果:
a = tensor([1., 2., 3., 4.])
shape a = <built-in method size of Tensor object at 0x0000025533D31228>
tensor([[1.],
[2.],
[3.],
[4.]])
shape of c: torch.Size([4, 1])
就是,我们用unsqueeze函数在索引为1的位置上扩展了维度,就由[4]变成了[4, 1]
感觉吧,实际用的时候,我可能需要不断地debug才能找出正确的形式……至少先知道要这样操作!
而至于unsqueeze_(),就是在操作的时候,u_是 in_place 的操作,在执行后会改变原来张量的维度。(也就是,原本a的维度也会改变)而u() 就是必须要用新的参数来“接盘”。
torch.gather()
这个gather函数啊,就是指定某行或者某列,然后按照给定的index来选择数据放到新的matrix里面。
torch.gather(input, dim, index, out = None)
举个例子:
m1 = torch.Tensor([[1, 2, 3], [4, 5, 6]])
print(m1)
index1 = torch.LongTensor([[0, 1, 1], [1, 0, 1]])
index2 = torch.LongTensor([[0, 1, 1], [2, 1, 0]])
print(torch.gather(m1, dim=0, index=index1)) # dim = 0: according to column
print(torch.gather(m1, dim=1, index=index2)) # dim = 1: according to line
结果:
tensor([[1., 2., 3.],
[4., 5., 6.]])
tensor([[1., 5., 6.],
[4., 2., 6.]])
tensor([[1., 2., 2.],
[6., 5., 4.]])
Process finished with exit code 0
可以看出,dim == 0的时候,产生新的matrix就是按照原来的matrix的列来选择的,而dim =/= 1的时候,产生的新的matrix就成了按照行来选择了。