自定义layer

https://www.cnblogs.com/sdu20112013/p/12132786.html一文里说了怎么写自定义的模型.本篇说怎么自定义层.

分两种:

  • 不含模型参数的layer
  • 含模型参数的layer

核心都一样,自定义一个继承自nn.Module的类,在类的forward函数里实现该layer的计算,不同的是,带参数的layer需要用到nn.Parameter

不含模型参数的layer

直接继承nn.Module

import torch
from torch import nn class CenteredLayer(nn.Module):
def __init__(self, **kwargs):
super(CenteredLayer, self).__init__(**kwargs)
def forward(self, x):
return x - x.mean() layer = CenteredLayer()
layer(torch.tensor([1, 2, 3, 4, 5], dtype=torch.float)) net = nn.Sequential(nn.Linear(8, 128), CenteredLayer())
y = net(torch.rand(4, 8))
y.mean().item()

含模型参数的layer

  • Parameter
  • ParameterList
  • ParameterDict

Parameter类其实是Tensor的子类,如果一个TensorParameter,那么它会自动被添加到模型的参数列表里。所以在自定义含模型参数的层时,我们应该将参数定义成Parameter,除了直接定义成Parameter类外,还可以使用ParameterListParameterDict分别定义参数的列表和字典。

ParameterList用法和list类似

class MyDense(nn.Module):
def __init__(self):
super(MyDense,self).__init__()
self.params = nn.ParameterList([nn.Parameter(torch.randn(4,4)) for i in range(4)])
self.params.append(nn.Parameter(torch.randn(4,1))) def forward(self,x):
for i in range(len(self.params)):
x = torch.mm(x,self.params[i])
return x net = MyDense()
print(net)

输出

MyDense(
(params): ParameterList(
(0): Parameter containing: [torch.FloatTensor of size 4x4]
(1): Parameter containing: [torch.FloatTensor of size 4x4]
(2): Parameter containing: [torch.FloatTensor of size 4x4]
(3): Parameter containing: [torch.FloatTensor of size 4x4]
(4): Parameter containing: [torch.FloatTensor of size 4x1]
)
)

ParameterDict用法和python dict类似.也可以用.keys(),.items()

class MyDictDense(nn.Module):
def __init__(self):
super(MyDictDense, self).__init__()
self.params = nn.ParameterDict({
'linear1': nn.Parameter(torch.randn(4, 4)),
'linear2': nn.Parameter(torch.randn(4, 1))
})
self.params.update({'linear3': nn.Parameter(torch.randn(4, 2))}) # 新增 def forward(self, x, choice='linear1'):
return torch.mm(x, self.params[choice]) net = MyDictDense()
print(net) print(net.params.keys(),net.params.items()) x = torch.ones(1, 4)
net(x, 'linear1')

输出

MyDictDense(
(params): ParameterDict(
(linear1): Parameter containing: [torch.FloatTensor of size 4x4]
(linear2): Parameter containing: [torch.FloatTensor of size 4x1]
(linear3): Parameter containing: [torch.FloatTensor of size 4x2]
)
)
odict_keys(['linear1', 'linear2', 'linear3']) odict_items([('linear1', Parameter containing:
tensor([[-0.2275, -1.0434, -1.6733, -1.8101],
[ 1.7530, 0.0729, -0.2314, -1.9430],
[-0.1399, 0.7093, -0.4628, -0.2244],
[-1.6363, 1.2004, 1.4415, -0.1364]], requires_grad=True)), ('linear2', Parameter containing:
tensor([[ 0.5035],
[-0.0171],
[-0.8580],
[-1.1064]], requires_grad=True)), ('linear3', Parameter containing:
tensor([[-1.2078, 0.4364],
[-0.8203, 1.7443],
[-1.7759, 2.1744],
[-0.8799, -0.1479]], requires_grad=True))])

使用自定义的layer构造模型

layer1 = MyDense()
layer2 = MyDictDense() net = nn.Sequential(layer2,layer1)
print(net)
print(net(x))

输出

Sequential(
(0): MyDictDense(
(params): ParameterDict(
(linear1): Parameter containing: [torch.FloatTensor of size 4x4]
(linear2): Parameter containing: [torch.FloatTensor of size 4x1]
(linear3): Parameter containing: [torch.FloatTensor of size 4x2]
)
)
(1): MyDense(
(params): ParameterList(
(0): Parameter containing: [torch.FloatTensor of size 4x4]
(1): Parameter containing: [torch.FloatTensor of size 4x4]
(2): Parameter containing: [torch.FloatTensor of size 4x4]
(3): Parameter containing: [torch.FloatTensor of size 4x4]
(4): Parameter containing: [torch.FloatTensor of size 4x1]
)
)
)
tensor([[-4.7566]], grad_fn=<MmBackward>)

从头学pytorch(十一):自定义层的更多相关文章

  1. 从头学pytorch(一):数据操作

    跟着Dive-into-DL-PyTorch.pdf从头开始学pytorch,夯实基础. Tensor创建 创建未初始化的tensor import torch x = torch.empty(5,3 ...

  2. 从头学pytorch(三) 线性回归

    关于什么是线性回归,不多做介绍了.可以参考我以前的博客https://www.cnblogs.com/sdu20112013/p/10186516.html 实现线性回归 分为以下几个部分: 生成数据 ...

  3. 从头学pytorch(九):模型构造

    模型构造 nn.Module nn.Module是pytorch中提供的一个类,是所有神经网络模块的基类.我们自定义的模块要继承这个基类. import torch from torch import ...

  4. 从头学pytorch(六):权重衰减

    深度学习中常常会存在过拟合现象,比如当训练数据过少时,训练得到的模型很可能在训练集上表现非常好,但是在测试集上表现不好. 应对过拟合,可以通过数据增强,增大训练集数量.我们这里先不介绍数据增强,先从模 ...

  5. 从头学pytorch(七):dropout防止过拟合

    上一篇讲了防止过拟合的一种方式,权重衰减,也即在loss上加上一部分\(\frac{\lambda}{2n} \|\boldsymbol{w}\|^2\),从而使得w不至于过大,即不过分偏向某个特征. ...

  6. 从头学pytorch(十二):模型保存和加载

    模型读取和存储 总结下来,就是几个函数 torch.load()/torch.save() 通过python的pickle完成序列化与反序列化.完成内存<-->磁盘转换. Module.s ...

  7. 从头学pytorch(十五):AlexNet

    AlexNet AlexNet是2012年提出的一个模型,并且赢得了ImageNet图像识别挑战赛的冠军.首次证明了由计算机自动学习到的特征可以超越手工设计的特征,对计算机视觉的研究有着极其重要的意义 ...

  8. 从头学pytorch(十九):批量归一化batch normalization

    批量归一化 论文地址:https://arxiv.org/abs/1502.03167 批量归一化基本上是现在模型的标配了. 说实在的,到今天我也没搞明白batch normalize能够使得模型训练 ...

  9. 从头学pytorch(二十):残差网络resnet

    残差网络ResNet resnet是何凯明大神在2015年提出的.并且获得了当年的ImageNet比赛的冠军. 残差网络具有里程碑的意义,为以后的网络设计提出了一个新的思路. googlenet的思路 ...

随机推荐

  1. HDU-4807-Lunch Time(二分+费用流,思维)

    这道题非常好,如果没有真正弄懂费用流算法的人,只会套模版的人是肯定做不出来的. 我们其实这样考虑,费用流真正的思想是吧费用作为长度,然后跑最短路,同时保证路上的流量不为0,也就是增广: 跑到终点后,回 ...

  2. CF1054F Electric Scheme

    CF1054F Electric Scheme  其实没啥的. 离散化后,每行每列选择一个. 但是可能会相交 每行或每列相邻两个点成为一小段. 小段按照行列左右部点 小段有交,连inf边,每个s-左, ...

  3. [***]HZOJ 柱状图

    神仙题. 作者的正解: *logn).   算法三:对于100%的数据:  我们枚举屋顶位置再三分高度的做法,复杂度的瓶颈在于花费的计算.假设屋顶在i处,高度为hi,如果j<i,有hj-j=hi ...

  4. Android教程 -04 启动其它Activity,静态工厂设计模式传递数据

    视频建议采用超清模式观看, 欢迎点击订阅我的优酷 意图 Intent 一个应用程序肯定不只有一个界面,如何切换到其它界面,只时候就需要启动其它的Activity.启动Activity有多种方式.我在这 ...

  5. clear简单的例子

    非常实用,非常简单的例子,结果都在图片里 <html> <head> <style> .keepbj { width:800px; height: 300px; b ...

  6. theadClasses设置Bootstrap Table表头样式

    通过theadClasses属性设置表头样式. thead-light设置灰色背景 //bootstrap table初始化数据 itxst.com $('#table').bootstrapTabl ...

  7. Project Euler Problem 8-Largest product in a series

    直接暴力 写完才想到,代码写矬了,扫一遍就出结果了,哪还用我写的这么麻烦 ss = '''73167176531330624919225119674426574742355349194934 9698 ...

  8. H3C 数据封装与解封装

  9. 运行项目npm run dev时报错: ~Error: Cannot find module 'webpack-cli/bin/config-yargs', 原因是

    webpack@3.X运行项目npm run dev时报错: ~Error: Cannot find module 'webpack-cli/bin/config-yargs' 我的原因是:  web ...

  10. [C++] 自动关闭右下角弹窗

    最近腾讯.迅雷等各种客户端,都越发喜欢在屏幕的右下角弹框了. 有骨气的人当然可以把这些软件卸载了事,但是这些客户端在某些情况下却又还是有用的.怎么办呢? 作为码农,自己实现一个自动关闭右下角弹窗的程序 ...