torch.nn文档学习总结

torch.nn,是torch框架神经网络包,内含有容器、卷积、池化、激活函数等数种相关函数和类,是torch学习过程中必经的一条路

目录

    • 1.容器
    • 2.卷积层
    • 3.池化层
    • 4.填充层
    • 5.激活层
    • 6.归一化层
    • 7.循环层
    • 8.线性网络层
    • 9.稀疏层
    • 10.距离函数
    • 11.损失函数
    • 12.其他(视觉相关)
    • 参考资料

1.容器

容器可分为Module,Sequential,ModuleList,ModuleDict,ParameterList ,ParameterDict

  • Module
''' 1.nn.Module,神经网络模型的基类,写网络模型都要继承于它'''
class BananaNet(nn.Module):	#创建一个BananaNet,需要继承nn.Module类
    def __init__(self):
        super(BananaNet, self).__init__()

''' 2.add_module() ,向当前模块中添加一个子模块 '''
def module1():
    x = nn.Sequential()	# 创建一个空序列容器
    x.add_module('conv1', nn.Conv2d(3, 32, 3)) # 从空序列容器中加入一个卷积
    x.add_module('conv2', nn.Conv2d(32, 32, 3))# 从空序列容器中再加入一个卷积
    return x

''' 3.apply(),将fn递归地应用于所有子模块(modules.chldren()的返回值)和模块自身,一般在初始化中用到'''
# 定义一个参数初始化函数
def init_weight(m):
    if isinstance(m,nn.Conv2d):	# isinstance是python的基本函数,用于判断变量a是否为数据类型A
        m.weight.data.normal_(0,1)  # 所有Conv2d里的参数初始化为正态分布采样的样本,均值0,方差1,下同
    if isinstance(m,nn.BatchNorm2d):
        m.weight.data.normal_(0,1)
module1 = module1()
module1.apply(init_weight)	# 对于module1,对其进行参数操作初始化

''' 4.buffers(),返回模块的缓冲区的迭代器'''
for buffer in module1.buffers():
    print(type(buffer.data),buffer.size())

''' 5.children(),返回当前模块的所有子模块的迭代器'''
for i in module1.children():
    continue
    print(next(i.named_modules()))   # next用于获取迭代器中下一个项目的值

''' 6.eval(),train(),分别是测试和训练模式'''
module1.train()
module1.eval()

''' 7.cpu(),cuda(),将参数和缓冲转移到cpu/gpu的内存上进行优化操作'''
module1.cpu()
# module1.cuda(0)   # 需要用到cuda

''' 8.load_state_dict(state_dict, strict=True) 加载模型参数至模块中,strict为True表示state_dict中的key值必须与模型中的保持一致'''
# print(module1.state_dict())   # 是一个OrderedDict(内包含模块的所有子模块的名称和参数)
# torch.save(module1.state_dict(),'1.pth')    # 保存模型
# state_dict1 = torch.load('model/resnet34-333f7ec4.pth')   # 加载模型
# for i in state_dict1:           # 是一个OrderedDict(内包含模块的所有子模块的名称和参数)
#     print(i,state_dict1[i].size())                        # 查看模型子模块的名称和长度
# print(module1.load_state_dict(state_dict=state_dict1))    # 加载模型

''' 9.named_modules(),包含模块和子模块的名称和对应的参数的迭代器'''
for name,module in module1.named_modules():
    continue
    print(name,module)

''' 10.named_buffers(),模块缓冲区的迭代器'''
for name,buf in module1.named_buffers():
    continue
    print(name,buf)

''' 11.named_children(),当前直连的子模块的迭代器,每次返回的元素是由子模块的名字和子模块自身组成的元组'''
for name,child in module1.named_children():
    continue
    print(name,child)

''' 12.named_parameters(),包含参数的名称和参数数值的迭代器'''
for name,param in module1.named_parameters():
    continue
    print(name,param)#打印出来的就没有模块本身的了

''' 13.to(),对tensor指定dtype,device,'''
module1.to(device=torch.device('cpu'),dtype=torch.double)       #或"cuda:0"

  • Sequential() 顺序容器
  • ModuleList() 模块列表
  • ModuleDict() 模块字典
  • ParameterList() 参数列表
  • ParameterDict() 参数字典
''' 14.Sequential(),顺序容器'''
model1 = nn.Sequential(
    nn.Conv2d(3,32,3,1,1),
    nn.Conv2d(32,32,3,1,1),
    nn.ReLU()
)   # model1的名称按0开始自动命名
from collections import OrderedDict
model2 = nn.Sequential(OrderedDict([
    ('conv1',nn.Conv2d(3,32,3,1,1)),
    ('conv2',nn.Conv2d(32,32,3,1,1)),
    ('relu',nn.ReLU())
]))
model2.add_modules('conv3',nn.Conv2d(32,32,3,1,1))

''' 15.ModuleList,将一维module存储在一个列表中'''
model3 = nn.ModuleList([nn.Linear(10,10) for i in range(10)])
model3.insert(3,nn.Conv2d(10,10,3,1,1))     # 在索引为3的位置插入一个子模块
# print([a for a,b in model3.named_children()])

''' 16.ModuleDict,将一维Module存储在一个字典中'''
model4 = nn.ModuleDict({
     
    "conv1":nn.Conv2d(1,4,3,1,1),
    "conv2":nn.Conv2d(4,1,3,1,1)
})
# clear()移除所有;
# items()迭代器;
# keys()键迭代器;
# values()值迭代器;
# pop(key)返回并删除名为key的模块;
# update()更新键值对
# print([(a,b) for a,b in ]model4.named_children())   # 与model4.items()一样

''' 17.ParameterList,ParameterDict,存储参数的,跟上面结构一样,也是列表、字典'''
param1 = nn.ParameterDict({
     
    "param1":nn.Parameter(torch.randn(1,2)),
    "param2":nn.Parameter(torch.rand(3,4)),
})
# print([a for a,b in param1.items()])

2.卷积层

''' 18.Conv123d 卷积操作'''
m_C = nn.Conv2d(1,3,3,1,1)     # nn.functional.conv123d
# print([j for i,j in m_C.named_parameters()])       # generator,也可以用next()生成

''' 19.ConvTranspose123d 转置卷积/反卷积/小数步长卷积操作,宽高计算在notes中'''
m_T = nn.ConvTranspose2d(1,3,3,1,1) # nn.functional.conv_transpose123d
# print(m_T)

''' 20.unfold和fold,参考https://blog.csdn.net/LoseInVain/article/details/88139435'''
# unfold是从批量的输入张量中提取滑动局部块,fold是将一组滑动局部块数组合成一个大的张量
inp = torch.randn(1, 3, 10, 12)     # 输入(N,C,*)
inp_unf = nn.functional.unfold(inp, (4, 5)) # 输出(N,C*∏(kernel_size),L),其中L为输出区块的数量
# 这里的unfold是函数,而Unfold是层,使用差不多
# print(inp_unf.shape)      # 1,60,56,其中,60=3x4x5 56=(10-4+1)x(12-5+1)

3.池化层

''' 21.MaxPool123d 最大池化操作,没有参数,不用学习,下同'''
''' 22.AvePool123d 平均池化操作'''
''' 23.MaxUnpool123d 最大池化操作的逆过程,一般用不到'''
''' 24.LPPool123d 二维幂平均池化操作 (∑x^p)^(1/p),p=1,平均池化,p->∞,最大池化 '''
''' 25.AdaptiveMaxPool123d、AdaptiveAvePool123d 自适应池化操作,强行池化到指定尺寸大小'''
x = torch.rand(1,3,32,32)
m_AMP = nn.AdaptiveAvgPool2d((13,13))   #强制池化到指定尺寸大小
# print(m_AMP(x).shape)   # 1,3,13,13

4.填充层

''' 26.ReflectionPad123d,镜像填充'''
''' 27.ReplicationPad123d,复制填充'''
''' 28.ZeorPad2d,零填充'''
''' 29.Constant123d,常数填充'''
x = torch.rand(1,3,3).reshape(1,1,3,3)
m_R = nn.ReflectionPad2d(2)
# print(m_R(x))

5.激活层

''' 激活函数,输入(N,*),输出(N,*)'''
''' 30.ELU激活函数 max(0,x) + min(0,α(exp(x)-1)),α为自定义参数'''
''' 31.HardShrink激活函数,x>a and x<-a为x,否则为0  ;  SoftShrink,x>a为x-a,x
''' 32.Hardtanh激活函数,x>1为1 x<-1为-1,否则为x'''
''' 33.LeakyReLU激活函数,x>0为x,否则为ax,a为自定义斜率'''
''' 34.LogSigmoid激活函数,log(1/(1+exp(-x)))'''
''' 35.PReLU激活函数,跟LeakyReLU一样,但斜率a是可以学习的'''
''' 36.ReLU激活函数,x>0为x,否则0'''
''' 37.ReLU6,在ReLU基础上,加入条件,x>6时为6'''
''' 38.RReLU,跟LeakyReLU一样,但斜率a是均匀分布采样得到'''
''' 39.SELU,scale*[max(0,x)+min(0,α*(exp(x)-1))]'''
''' 40.CELU,x>0为x,否则为α*(exp(x/α)-1)'''
''' 41.Sigmoid,1/(1+exp(-x))'''
''' 42.Softplus,(1+exp(β*x))/β,类平滑ReLU'''
''' 43.Softsign,x/(1+|x|)'''
''' 44.tanh,[exp(x)+exp(-x)]/[exp(x)-exp(-x)]'''
''' 45.TanhShrink,x-tanh'''
''' 46.Threshold,x>threshold为x,否则为value'''
m_elu = nn.ELU()
x = torch.randn(2)
# print(x,m_elu(x))
''' 47.softmax,将一组数据通过自然指数与其求和的比例,归一化为(0,1)范围内的值,得到的结果,和为1,是一种归一化手段,常用分类'''
m_sf = nn.Softmax()
x = torch.rand(2,6,3,3)
# print(x,m_sf(x))
''' 48.softmin,同上,不过是计算的exp(-x)/Σ(exp(-xi))'''
''' 49.其他。softmax2d,logsoftmax,AdaptiveLogSoftmaxWithLoss'''

6.归一化层

''' 批正则化/归一化(N,C,H,W)分别代表batch,通道,高和宽'''
''' 50.BatchNorm123d(num_features) batch方向,对NHW做归一化,x^ = [ (x-E(x)) / sqrt(Var(x)+ε) ] * γ + β'''
''' 51.LayerNorm 通道方向,对CHW做归一化'''
''' 52.InstanceNorm 像素方向,对HW做归一化'''
''' 53.GroupNorm (num_groups,num_channels)跟batchnorm不同的在于,把channel分成了num_groups个了'''
''' 54.LocalResponseNorm 局部响应,起到抑制作用,小的抑制,大的放大,增强泛化能力'''
m_GM = nn.GroupNorm(num_channels=6,num_groups=3)
# print(x,m_GM(x))

7.循环层

''' 循环神经网络系列'''
''' RNN() RNNCell()'''
''' LSTM() LSTMCell()'''
''' GRU() GRUCell()'''

8.线性网络层

nn.Linear() 
nn.Bilinear()#双线性

9.稀疏层

embedding()
embeddingbag()

10.距离函数

''' CosineSimilarity,相似度=(x1*x2)/max(||x1||,||x2||)'''
''' PairwiseDistance,相似度=(Σ|x|^p)^(1/p)'''

11.损失函数

''' 损失函数'''
''' 55.L1Loss,平均绝对值误差(mean absolute error),若size_average为true,则计算平均绝对差之和,否则不计算平均,直接求和'''
''' 56.MSELoss,均方差(mean squared error),若size_average为true,则计算平方差之和,否则不计算平均,直接求和'''
''' 57.CrossEntropyLoss,交叉熵损失,常用分类问题,loss = -log(softmax(x)) = -log( exp(x)/Σ(exp(xi) ),softmax-->log-->按target位置分别取值,并求相反数的平均和'''
''' 具体计算过程:
pre = tensor([[0.8803, 0.6208, 0.8491],[0.5116, 0.0087, 0.0426]]) 
true = tensor([2, 0]) 
ans = loss(pre,true) 
    = (-ln[exp(0.8491)/sum(exp(0.8803),exp(0.6208),exp(0.8491))] -ln[exp(0.5116)/sum(exp(0.5116),exp(0.0087),exp(0.0426))]) / 2
    = 0.9208  '''
m = nn.CrossEntropyLoss()
y = torch.rand(2,3) # 3x5
y_target = torch.empty(2,dtype=torch.long).random_(3)
# print(y,y_target,m(y,y_target))
''' 58.CTCLoss,连接时间分类,解决时序问题的,参考https://zhuanlan.zhihu.com/p/67415439'''
''' 59.NLLoss,取值,求相反数的平局和,交叉熵损失多了softmax和log'''
''' 60.PoissonNLLoss,input-target*log(input)+log(target!)'''
''' 61.KLDivLoss,loss = Σ[y*(logy-x)]/n ,这是reduction='mean'的时候'''
x = torch.tensor([1.44,2.36,2.11])
y = torch.tensor([1.44,2.36,2.11])
m_KL = nn.KLDivLoss(reduction='none')#也可试试sum,mean,看看出现什么结果
# print(m_KL(x,y))
''' 62.BCELoss,loss = Σ[w * (y*log(x) + (1-y)*log(1-x) )]/n'''
''' 63.BCEWithLogitsLoss,在上面基础上,x先进行了一个sigmoid操作'''
''' 64.MarginRankingLoss,loss = max(0,y*(x1-x2)+margin),y值为-1或1,具体用到比较少'''
''' 65.HingeEmbeddingLoss,loss = xn,如果yn=1,否则max(0,▲-xn),yn=-1'''
''' 66.MultiLabelMarginLoss,多类别多分类hinge损失,loss = [ Σ( max(0,1- (x[yj]-xi) ) ) ]/N'''
loss = torch.nn.MultiLabelMarginLoss()
x = torch.autograd.Variable(torch.FloatTensor([0.1, 0.2, 0.4, 0.8]))
y = torch.autograd.Variable(torch.LongTensor([3, 0, -1, 1]))
# print(loss(x, y)) #0.8500
''' 67.SmoothL1Loss,如果|x-y|<1,则为z=(x-y)^2/2,否则z=|x-y|-0.5,同时,loss=Σz'''
''' 68.SoftMarginLoss,loss = Σlog(1+exp(-y*x))/x.nelement,可用在二分类或图像分割处理中'''
''' 69.MultiLabelSoftMarginLoss,上述的多分类版本,loss = -( Σy*log( ( 1+exp(-x) )^(-1) ) )/C+(1-y)*log(exp(-x)/(1+exp(-x)))'''
''' 70.CosineEmbeddingLoss,余弦相似度损失,y=1,则loss=1-cos(x1,x2),y=-1,则loss=max(0,cos(x1,x2)-margin) '''
''' 71.MultiMarginLoss,多分类Hinge损失,loss=Σmax(0,margin-x[y]+x[i])^p/N'''
''' 72.TripletMarginLoss,三元损失,欧氏距离度量,出自FaceNet'''

12.其他(视觉相关)

''' 73.PixelShuffle,亚像素卷积操作,上采样的一种,输入(N,C*r*r,H,W),输出(N,C,H*r,W*r)'''
m_PS = nn.PixelShuffle(3)
x = torch.rand(1,9,3,4)
# print(m_PS(x).shape) # 1,1,9,12
''' 74.UpSample,上采样操作,类似torch.nn.functional.interpolate'''
m_US = nn.Upsample(scale_factor=2,mode='nearest')#最近邻(nearest),线性插值(linear),双线性插值(bilinear),三次线性插值(trilinear)
# x = torch.rand(3,3).view(1,1,3,3).float()#不能是2D的
x = torch.range(1,4).view(1,1,2,2).float()
# print(x,m_US(x))
''' 75.UpsamplingNearest2d,与73不同在于,输入(N,C,H,W),输出(N,C,H*r,W*r),等同于nn.Upsample(mode='nearest')'''
m_UN = nn.UpsamplingNearest2d(scale_factor=2)
x = torch.rand(3,3).view(1,1,3,3).float()#不能是2D的
# print(x,m_US(x))
''' 76.UpsamplingBilinear2d,等同于nn.Upsample(mode='bilinear')'''

'''其他:多GPU和utils操作,参考https://pytorch.apachecn.org/docs/1.2/nn.html#vectortoprameters'''

参考资料

1.https://pytorch.apachecn.org/docs/1.2/nn.html
2.https://pytorch-cn.readthedocs.io/zh/latest/package_references/torch-nn/

你可能感兴趣的:(pytorch)