从头学pytorch(十一):自定义层
自定义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
的子类,如果一个Tensor
是Parameter
,那么它会自动被添加到模型的参数列表里。所以在自定义含模型参数的层时,我们应该将参数定义成Parameter
,除了直接定义成Parameter
类外,还可以使用ParameterList
和ParameterDict
分别定义参数的列表和字典。
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(十一):自定义层的更多相关文章
- 从头学pytorch(一):数据操作
跟着Dive-into-DL-PyTorch.pdf从头开始学pytorch,夯实基础. Tensor创建 创建未初始化的tensor import torch x = torch.empty(5,3 ...
- 从头学pytorch(三) 线性回归
关于什么是线性回归,不多做介绍了.可以参考我以前的博客https://www.cnblogs.com/sdu20112013/p/10186516.html 实现线性回归 分为以下几个部分: 生成数据 ...
- 从头学pytorch(九):模型构造
模型构造 nn.Module nn.Module是pytorch中提供的一个类,是所有神经网络模块的基类.我们自定义的模块要继承这个基类. import torch from torch import ...
- 从头学pytorch(六):权重衰减
深度学习中常常会存在过拟合现象,比如当训练数据过少时,训练得到的模型很可能在训练集上表现非常好,但是在测试集上表现不好. 应对过拟合,可以通过数据增强,增大训练集数量.我们这里先不介绍数据增强,先从模 ...
- 从头学pytorch(七):dropout防止过拟合
上一篇讲了防止过拟合的一种方式,权重衰减,也即在loss上加上一部分\(\frac{\lambda}{2n} \|\boldsymbol{w}\|^2\),从而使得w不至于过大,即不过分偏向某个特征. ...
- 从头学pytorch(十二):模型保存和加载
模型读取和存储 总结下来,就是几个函数 torch.load()/torch.save() 通过python的pickle完成序列化与反序列化.完成内存<-->磁盘转换. Module.s ...
- 从头学pytorch(十五):AlexNet
AlexNet AlexNet是2012年提出的一个模型,并且赢得了ImageNet图像识别挑战赛的冠军.首次证明了由计算机自动学习到的特征可以超越手工设计的特征,对计算机视觉的研究有着极其重要的意义 ...
- 从头学pytorch(十九):批量归一化batch normalization
批量归一化 论文地址:https://arxiv.org/abs/1502.03167 批量归一化基本上是现在模型的标配了. 说实在的,到今天我也没搞明白batch normalize能够使得模型训练 ...
- 从头学pytorch(二十):残差网络resnet
残差网络ResNet resnet是何凯明大神在2015年提出的.并且获得了当年的ImageNet比赛的冠军. 残差网络具有里程碑的意义,为以后的网络设计提出了一个新的思路. googlenet的思路 ...
随机推荐
- 【vb.net机房收费系统】之没有包含要从继承的组件的已生成程序集 标签: vb.net继承 2015-05-02 15:19 1012人阅读
在敲到组合查询这个功能的时候,需要用到窗体的继承,但是在新建继承窗体的时候,出现了错误(没有包含要从继承的组件的已生成程序集).如下图: 问题的产生:当时没怎么注意,也不知道怎么弄的,最后反正是继承上 ...
- 安装pip3遇到:E: Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution).
安装pip3遇到:E: Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution). 具 ...
- Android SwipeActionAdapter结合Pinnedheaderlistview实现复杂列表的左右滑动操作
在上一篇博客<Android 使用SwipeActionAdapter开源库实现简单列表的左右滑动操作>里,已经介绍了利用SwipeActionAdapter来左右滑动操作列表: 然,有时 ...
- sspanel 常用审计规则
规则 禁用 BT 防止版权争议 BitTorrent protocol 数据包明文匹配 禁止 百度高精度定位 防止IP与客户端地理位置被记录 (api|ps|sv|offnavi|newvector| ...
- 将 vue.js 获取的 html 文本转化为纯文本
我存入数据表中的数据是使用 html 格式,获取数据是使用 vue 获取. 遇到了一个问题,就是界面上显示的数据是 html 格式的,但是我需要它显示纯文本. 怎么做呢?首先在 js 中写一个将 ...
- oracle merge into 新增或者修改
merge into sn_balance b1 using(select 'admin' as userid,1 as type1 from dual) b2 on(b1.userid=b2.use ...
- jquery实用应用之jquery操作radio、checkbox、select
本文收集一些jquery的实用技巧,非常实用的哦,其中对radio.checkbox.select选中与取值的方法. 获取一组radio被选中项的值var item = $('input[@name= ...
- springboot2.0.2+redis+spring-session 解决session共享的问题
准备工作 新建两个springboot2.0.2版本的服务,配置文件添加: #在默认设置下,Eureka服务注册中心也会将自己作为客户端来尝试注册它自己,所以我们需要禁用它的客户端注册行为 eurek ...
- java GUI(图形用户界面)
GUI Graphical User Interface(图形用户接口). 用图形的方式,来显示计算机操作的界面,这样更方便更直观. CLI Command line User Interface ( ...
- H3C IPv6地址表示方式