总结最近python遇到的一些函数
写的比较草率,仅限于个人理解函数用,尽请谅解。
1. transpose()
#维度变化
x=torch.Tensor(2,3,4,5)#四维矩阵,只有空间位置没有数据
print(x.size())#torch.Size([2, 3, 4, 5])
y=x.transpose(0,1).transpose(3,2).transpose(1,3)
#先转置0维和1维度,之后在第2,3维之间转置,最后在1,3之间转置
#3,2,4,5
#3,2,5,4
#3,4,5,2
#torch.Size([3, 4, 5, 2])
a=torch.randn(2,3,4)
print(a)
a.transpose(1,0)
print(a)
>>>
>tensor([[[-0.0570, 0.4011, 0.4544, -1.2798],
[ 1.2265, -0.6709, 1.6337, 0.0487],
[ 0.2063, 0.4153, -0.0498, -0.9830]],
[[-0.3779, -0.3283, 0.7248, -0.0482],
[-0.6548, -1.8118, 0.4777, -1.2178],
[-0.0967, 1.7349, -0.7934, 0.0189]]])
tensor([[[-0.0570, 0.4011, 0.4544, -1.2798],
[ 1.2265, -0.6709, 1.6337, 0.0487],
[ 0.2063, 0.4153, -0.0498, -0.9830]],
[[-0.3779, -0.3283, 0.7248, -0.0482],
[-0.6548, -1.8118, 0.4777, -1.2178],
[-0.0967, 1.7349, -0.7934, 0.0189]]])
参考链接transpose()函数
2. contiguous()
x=torch.randn(3,2)
y=torch.transpose(x,0,1)
print("修改前x",x)
print("修改前y",y)
y[0,0]=11
print("修改后x",x)
print("修改后y",y)
>>>
修改前x tensor([[ 0.5270, -1.3783],
[-1.2449, 1.8523],
[-0.0860, -0.1530]])
修改前y tensor([[ 0.5270, -1.2449, -0.0860],
[-1.3783, 1.8523, -0.1530]])
修改后x tensor([[11.0000, -1.3783],
[-1.2449, 1.8523],
[-0.0860, -0.1530]])
修改后y tensor([[11.0000, -1.2449, -0.0860],
[-1.3783, 1.8523, -0.1530]])
改变了y的元素的值的同时,x的元素的值也发生了变化。contiguous本意是连续的的意思。浅拷贝,y指向x变量所处的位置。
加入contiguous之后:
x=torch.randn(3,2)
y=torch.transpose(x,0,1).contiguous()
print("修改前x",x)
print("修改前y",y)
y[0,0]=11
print("修改后x",x)
print("修改后y",y)
>>>
修改前x tensor([[-1.0669, -0.5065],
[ 0.6513, 1.1275],
[ 0.8071, 0.2781]])
修改前y tensor([[-1.0669, 0.6513, 0.8071],
[-0.5065, 1.1275, 0.2781]])
修改后x tensor([[-1.0669, -0.5065],
[ 0.6513, 1.1275],
[ 0.8071, 0.2781]])
修改后y tensor([[11.0000, 0.6513, 0.8071],
[-0.5065, 1.1275, 0.2781]])
对y使用了contiguous之后,改变y的值,但是x的值没有改变。
参考链接contiguous()函数
3. torch.nn.MSELoss()相关loss知识、熵的概念
详解机器学习中的熵、条件熵、相对熵和交叉熵为什么交叉熵(cross-entropy)可以用于计算代价?
torch.nn.MSELoss()及torch.optim.SGD的理解
4.nn.Linear()
5.unsqueeze_(增加维度)
参考链接unsqueeze_(增加维度)用法 在第0维位置增加一个维度。
6. enumerate(train_loader,0)
enumerate(train_loader,0)中,用于可迭代\可遍历的数据对象组合为一个索引序列,同时列出数据和数据下标。0表示从索引从0开始。
for i, data in enumerate(trainloader, 0):
#data里面包含图像数据(inputs)(tensor类型的)和标签(labels)(tensor类型)。0是从第0个开始的意思。i代表第几个。
inputs, labels = data
enumerate()返回一个enumerate对象。
7.torch.optim.SGD()参数详解
实现随机梯度下降算法(momentum可选)。
class torch.optim.SGD(params, lr=, momentum=0, dampening=0, weight_decay=0, nesterov=False)[source]
Nesterov动量基于On the importance of initialization and momentum in deep learning中的公式.
参数:
params (iterable) – 待优化参数的iterable或者是定义了参数组的dict
lr (float) – 学习率
momentum (float, 可选) – 动量因子(默认:0)
weight_decay (float, 可选) – 权重衰减(L2惩罚)(默认:0)
dampening (float, 可选) – 动量的抑制因子(默认:0)
nesterov (bool, 可选) – 使用Nesterov动量(默认:False)
8. .item()、items()不一样
和直接取这个值,是显示精度的区别,item()返回的是一个浮点型数据,所以我们在求loss或者accuracy时,一般使用item(),而不是直接取它对应的元素x[1,1]。
import torch
x = torch.randn(2, 2)
print(x)
print(x[1,1])
print(x[1,1].item())
>>>
tensor([[ 0.4702, 0.5145],
[-0.0682, -1.4450]])
tensor(-1.4450)
-1.445029854774475
而items():
9. nelement() 求解torch当中参数个数
10. torch.eyes()、torch.ones()、torch.zeros()
eyes()常常用于生成独热码,主对角线数据为1,其他为0
ones()全1矩阵,输入nm
zeros()全0矩阵,输入nm
import torch
a=torch.eye(3)
print(a.shape)
print(a[1])#输出第二行one_hot编码
b=torch.ones(5,5)
c=torch.ones(3)
print(b)
print(c)
d=torch.zeros(4)
e=torch.zeros(4,5)
print(d)
print(e)
>>>
torch.Size([3, 3])
tensor([0., 1., 0.])
tensor([[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.]])
tensor([1., 1., 1.])
tensor([0., 0., 0., 0.])
tensor([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]])
11.detach()和detach_()
detach()
detach_()
12. torch.rand()、torch.randint()、torch.randn()、torch.randlike()
torch.rand和torch.randn有什么区别?
一个是均匀分布,一个是标准正态分布。
randint(low=0, high, size, out=None, dtype=None)
randint_like(input, low=0, high, dtype=None)
a=torch.randint(1,4,(2,3,2))#生成2*3*2的张量,第一第二个参数是上下限,[上限,下限)。这可以取1 2 3,不能取4
print(a)
b=torch.randint_like(a,4)#4是取值上限,这里下限默认为0,可以取0 1 2 3,不能取4,tensor的维度和a是一样的
print(b)
>>>
tensor([[[3, 1],
[3, 1],
[3, 1]],
[[2, 2],
[2, 1],
[1, 2]]])
tensor([[[3, 2],
[0, 1],
[2, 2]],
[[0, 0],
[3, 2],
[2, 3]]])
13. torch.max(x,dim=?)
input输入的是一个tensor,dim是max函数索引的维度0/1,0是每列最大值,1是每行最大值。
返回两个值,一个是每一行最大的tensor,一个是所在位置。
input=torch.randn(2,3)
print(input)
max_tensor_co=torch.max(input,dim=0)[0]#每列最大值
max_position_co=torch.max(input,dim=0)[1]#每列最大值所在位置
max_tensor_li=torch.max(input,dim=1)[0]#每行最大值
max_position_li=torch.max(input,dim=1)[1]#每行最大值所在位置
print(max_tensor_co,max_position_co,max_tensor_li,max_position_li)
>>>
>tensor([[-0.0734, -0.1197, 0.3043],
[-0.5986, 1.3822, -1.6141]])
tensor([-0.0734, 1.3822, 0.3043]) tensor([0, 1, 0]) tensor([0.3043, 1.3822]) tensor([2, 1])
14. eq()、ge()等判断比较值的函数
比如ge(a,b)就是a>=b
15. topk()
取tensor的前k大元素的tensor,返回value和indices
16. view()
在不想算的地方放-1,自动帮助tensor计算
17. expand和expand_as()
expand()函数只能将size=1的维度扩展到更大的尺寸,如果扩展其他size()的维度会报错
expand_as()函数与expand()函数类似,功能都是用来扩展张量中某维数据的尺寸,区别是它括号内的输入参数是另一个张量,作用是将输入tensor的维度扩展为与指定tensor相同的size
18. dropout和spatial dropout的区别
dropout会随机独立地将部分元素置零,而SpatialDropout1D会随机地对某个特定的纬度全部置零。因此SpatialDropout1D需要指定Dropout维度,即对应dropout函数中的参数noise_shape。
19. backward()
backward()知识点,知乎比我写的好 y.backward()
使用backward()函数反向传播计算tensor的梯度时,并不计算所有tensor的梯度,而是只计算满足这几个条件的tensor的梯度:1.类型为叶子节点、2.requires_grad=True、3.依赖该tensor的所有tensor的requires_grad=True。所有满足条件的变量梯度会自动保存到对应的grad属性里。
torch.autograd.grad()
outputs=y, input=x 加参数指定对象
grad[0]
20. repeat()
在指定维度上复制张量,并返回该张量。
import torch
x=torch.tensor([1,2,3])
print(x.repeat(4,2))#纵向*4,横向*2
print(x.repeat(4))
print(x.shape)
>>>
tensor([[1, 2, 3, 1, 2, 3],
[1, 2, 3, 1, 2, 3],
[1, 2, 3, 1, 2, 3],
[1, 2, 3, 1, 2, 3]])
tensor([1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3])
torch.Size([3])
21.torch.mean()
针对结果的33矩阵,以第一个位置【0,0】为例:
dim=0取第零维,即每个33矩阵的第一个数据
dim=1取第一维,即每个33矩阵的第一列平均
dim=2取第二维,即每个33矩阵的第一行平均
dim举例