1 pytorch的常用各种函数
tensor的组合和分块
--->tensor.cat()/tensor.stack()(组合)
--->tensor.chunk()/tensor.split()(分块)
tensor的变形
--->tensor.view(),resize(),reshape()--调整Tensor的形状,元素总数相同
--->transpose()、permute()各维度之间的变换
--->squeeze()、unsqueeze()处理size()为1的维度
--->expand()、expand_as() 复制元素来扩展维度
1.1 张量的索引与组合
##使用...表示选择所有元素
a=torch.randn(3,3,28,28)
a[:,1,...].shape
torch.Size([3, 28, 28])
a=torch.randn(4,3,28,28)
a[:,1,...].shape
torch.Size([4, 28, 28])
##cat(对不同的张量进行拼接时,必须保证其他的维度一致)
a=torch.rand(2,3)
b=torch.rand(1,3)
torch.cat([a,b],dim=0).shape
[out]:tensor.Size([3,3])
##stack(再增加一个维度进行相加,叠加的基本单位为序列本身)
a=torch.rand(2,3)
b=torch.rand(2,3)
torch.stack([a,b],dim=0).shape
[out]:torch.Size([2,2,3])
1.2 张量的拆分
#split(可以按长度或者数量进行拆分)
a=torch.rand(2,3,3)
aa,bb=a.split(1,dim=0) ##数量拆分
aa.shape
[out]:torch.Size([1,3,3])
bb.shape
[out]:torch.Size([1,3,3])
cc,dd=a.split([1,1],dim=0) ##长度拆分
cc.shape
[out]:torch.Size([1,3,3])
dd.shape
[out]:torch.Size([1,3,3])
# chunk只能按照数量拆分,而不能按照长度拆分
a=torch.rand(4,3,3)
bb,cc=a.chunk([2,2],dim=0)---->会报错
#正确方法应该是
bb,cc=a.chunk(2,dim=0)
1.3 维度的扩展与压缩
b=torch.rand(32)
f=torch.rand(4,32,14,14)
b=b.unsqueeze(1).unsqueeze(2).unsqueeze(0)
b.shape
torch.Size([1, 32, 1, 1])
##squeeze维度删减
b.shape
torch.Size([1, 32, 1, 1])
b.squeeze(0).shape
torch.Size([32, 1, 1])
1.4 维度数目扩展
expand维度数目扩展(前提必须是 扩张的维度必须相同,同时对于不扩展的可以使用-1表示,维度中较大的数一般是不能变小)
b=torch.randn(1,32,14,14)
b.shape
[out]:torch.Size([1, 32, 14, 14])
##
b.expand(4,32,14,14).shape
[out]:torch.Size([4, 32, 14, 14])
##
b.expand(-1,32,14,28).shape
[out]:torch.Size([1, 32, 14, 14])
repeat扩展(在原来的维度上进行扩展次数)
b=torch.randn(1,32,14,14)
b.repeat(4,1,1,1).shape
[out]torch.Size([4,32,14,14])
permute交换维度
b=torch.randn(4,3,28,32)
b.permute(0,2,3,1).shape#按下标进行交换
[out]:torch.Size([4,28,32,3])
2 Autograd与计算图
autograd自动求导是动态图,指在程序运行时,每次前向传播时是从头开始构建计算图,这样不同的前向传播就可以有不同的传播图。
参考来源:https://zhuanlan.zhihu.com/p/69294347
3 神经网络工具箱torch.nn
3.1 nn.module
3.1.1 nn.Parameter函数
在类init()中需要定义网络学习的参数,在此使用nn.Parameter()函数定义了全连接的w和b,这是一种特殊的Tensor的构造方法,默认需要求导,即requires_grad为True。
3.1.2 forward()函数与反向传播
forward()函数用来进行网络的前向传播,并需要传入相应的Tensor。
3.1.3 多个module的嵌套
即定义好一个nn.module,可以多次进行调用
3.1.4 nn.Module与nn.functional库
利用nn.functional定义的网络层不可自动学习参数,需要nn.Parameter封装。
nn.functional的设计初衷是针对一些不需要学习参数的层,如激活函数BN。
总的来说,对于需要学习参数的层,最好使用nn.Module,对于无参数学习的层,可以使用nn.functional。
3.1.5 nn.Sequential()模块
当模块中只是简单的前馈网络时,即上一层的输出直接作为下一层的输入,即可以快速搭建nn.Sequential()模块来快速搭建模块。而不必手动在forward()函数中一层一层的向前传播。
from torch import nn
class Perception(nn.Module):
def __init__(self,in_dim,hid_dim,out_dim):
super(Perception,self).__init__()
##利用nn.Sequential()快速搭建网络模块
self.layer==nn.Sequential(
nn.Linear(in_dim,hid_dim),
nn.Sigmoid(),
nn.Linear(hid_mid,out_dim),
nn.Sigmoid()
)
def forward(self,x):
y=self.layer(x)
return y
3.2 损失函数
损失反映模型最后预测结果与实际真实值之间的差距,可以用来分析训练过程的好坏,模型是否收敛等问题
output=torch.Tensor([[0.7654,0.0308],[0.7892,0.0386],[0.7779,0.0331],[0.7781,0.0326]])
output.shape
[out]:torch.Size([4, 2])
label=torch.Tensor([0,1,1,0]).long()
criterion=nn.CrossEntropyLoss()
loss_nn=criterion(output,label)
loss_nn
[out]:tensor(0.7627)