(pytorch-深度学习系列)模型参数的初始化与访问操作-学习笔记

模型参数的初始化与访问操作

学习 如何初始化以及访问模型参数,以及如何在多层之间共享模型参数
首先定义一个含有单个隐藏层的多层感知机,使用默认方式初始化该模型的参数,并且进行一次前向计算:

import torch
from torch import nn
from torch.nn import initnet = nn.Sequential(nn.Linear(4, 3), nn.ReLU(), nn.Linear(3, 1))  # pytorch已进行默认初始化print(net)
X = torch.rand(2, 4)
Y = net(X).sum()

输出:

Sequential((0): Linear(in_features=4, out_features=3, bias=True)(1): ReLU()(2): Linear(in_features=3, out_features=1, bias=True)
)

接着尝试访问模型参数
由于Sequentail类与Module类的继承关系,可以通过Module类的parameters()函数或者named_parameters()来访问所有的参数:

print(type(net.named_parameters()))
for name, param in net.named_parameters():print(name, param.size())

输出:
named_parameters()返回参数的名称以及其该参数值(tensor变量)

<class 'generator'>
0.weight torch.Size([3, 4])
0.bias torch.Size([3])
2.weight torch.Size([1, 3])
2.bias torch.Size([1])

其中“0“、”2“为层数索引,我们可以通过下面的方法访问网络的任意一层:

for name, param in net[0].named_parameters():print(name, param.size(), type(param))

输出结果:

weight torch.Size([3, 4]) <class 'torch.nn.parameter.Parameter'>
bias torch.Size([3]) <class 'torch.nn.parameter.Parameter'>

由于我们采用了下标索引访问网络的某一层,所以结果中没有了层数索引,返回的参数类型为:“torch.nn.parameter.Parameter”,这是Tensor的子类,需要注意的是,如果一个Tensor是Parameter,他就会自动被添加到模型的参数列表中。
我们可以用下面的例子来理解:

class MyModel(nn.Module):def __init__(self, **kwargs):super(MyModel, self).__init__(**kwargs)self.weight1 = nn.Parameter(torch.rand(20, 20))self.weight2 = torch.rand(20, 20)def forward(self, x):passn = MyModel()
for name, param in n.named_parameters():print(name)

输出:

weight1

发现只输出了参数weight1,但是没有输出参数weight2,这说明参数weight1在参数列表中,而参数weight2不在参数列表中

初始化模型参数

将权重参数初始化成均值为0、标准差为0.01的正态分布随机数,并依然将偏差参数清零:

for name, param in net.named_parameters():if 'weight' in name:init.normal_(param, mean=0, std=0.01)print(name, param.data)for name, param in net.named_parameters():if 'bias' in name:init.constant_(param, val=0)print(name, param.data)

我们查看torch.nn.init.normal_函数,观察torch默认初始化的方式:

def normal_(tensor, mean=0, std=1):with torch.no_grad():return tensor.normal_(mean, std)

这里使用一个inplace改变Tensor的值,这个过程不记录梯度
根据相同的实现方式,我们来实现一个自定义的初始化方法。在下面的例子里,我们令权重有一半概率初始化为0,有另一半概率初始化为[−10,−5][-10,-5][10,5][5,10][5,10][5,10]两个区间里均匀分布的随机数。

def init_weight_(tensor):with torch.no_grad():tensor.uniform_(-10, 10)tensor *= (tensor.abs() >= 5).float()for name, param in net.named_parameters():if 'weight' in name:init_weight_(param)

我们还可以使用在之前的blog中提到的改变Parameter的data属性,来改写模型参数的同时不改变参数的梯度:

for name, param in net.named_parameters():if 'bias' in name:param.data += 1print(name, param.data)

这里通过param.data改变模型参数,但是不会影响param的梯度。

共享模型的参数

如何实现在多层之间共享模型的参数
(1)对Sequential中传入同一个Module实例,这两个层的参数是共享的:

linear = nn.Linear(1, 1, bias=False)
net = nn.Sequential(linear, linear) 
print(net)
for name, param in net.named_parameters():init.constant_(param, val=3)print(name, param.data)

输出:

Sequential((0): Linear(in_features=1, out_features=1, bias=False)(1): Linear(in_features=1, out_features=1, bias=False)
)
0.weight tensor([[3.]])

根据输出结果可以发现,网络有两层,但是weight参数只有一个,这时候,这两个层共享参数。

因为模型参数包含了梯度,所以在反向传播计算时,这些共享参数的梯度是累加的:

x = torch.ones(1, 1)
y = net(x).sum()
print(y)
y.backward()
print(net[0].weight.grad) # 单次梯度是3,两次所以就是6,weight的值在上面输出了,是3

输出:

tensor(9., grad_fn=<SumBackward0>)
tensor([[6.]])

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/507990.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(pytorch-深度学习系列)pytorch实现自定义网络层,并自设定前向传播路径-学习笔记

pytorch实现自定义网络层&#xff0c;并自设定前向传播路径-学习笔记 1. 不包含模型参数的自定义网络层 首先我们自定义一个网络层&#xff0c; 定义一个网络层&#xff0c;使其不包含模型参数&#xff0c;并在forward()函数中进行运算&#xff1a; import torch from torc…

(pytorch-深度学习系列)读取和存储数据-学习笔记

读取和存储数据 我们可以使用pt文件存储Tensor数据&#xff1a; import torch from torch import nnx torch.ones(3) torch.save(x, x.pt)这样我们就将数据存储在名为x.pt的文件中了 我们可以从文件中将该数据读入内存&#xff1a; x2 torch.load(x.pt) print(x2)还可以存…

(pytorch-深度学习系列)pytorch使用GPU计算-学习笔记

pytorch使用GPU计算 在之前的blog中早已经讲过如何配置pytorch的GPU加速环境 查看GPU加速是否可用&#xff1a; import torch from torch import nnprint(torch.cuda.is_available()) # true 查看GPU是否可用print(torch.cuda.device_count()) #GPU数量&#xff0c; 1torch.…

(pytorch-深度学习系列)CNN二维卷积层-学习笔记

二维卷积层 在二维互相关运算中&#xff0c;卷积窗口从输入数组的最左上方开始&#xff0c;按从左往右、从上往下的顺序&#xff0c;依次在输入数组上滑动。当卷积窗口滑动到某一位置时&#xff0c;窗口中的输入子数组与核数组按元素相乘并求和&#xff0c;得到输出数组中相应…

(pytorch-深度学习系列)卷积神经网络中的填充(padding)和步幅(stride)

卷积神经网络中的填充(padding)和步幅(stride) 之前写过一篇blog&#xff0c;描述CNN网络层的输入和输入尺寸的计算关系&#xff0c;但是并没有描述的很全面&#xff0c;这里全面描述了影响输出尺寸的两个超参数padding和stride&#xff0c;查阅了相关资料&#xff0c;编码理解…

(pytorch-深度学习系列)CNN的多输入通道和多输出通道

CNN的多输入通道和多输出通道 之前的输入都视为二维数组&#xff0c;但是真实数据往往具有更高的维度&#xff0c;彩色图像有RGB三个颜色通道&#xff0c;那么这个图像&#xff08;高为h&#xff0c;宽为w&#xff09;可以表示为3∗h∗w3*h*w3∗h∗w的多维数组&#xff0c;一般…

(pytorch-深度学习系列)CNN中的池化层-学习笔记

CNN中的池化层 首先&#xff0c;池化&#xff08;pooling&#xff09;层的提出是为了缓解卷积层对位置的过度敏感性。 什么意思&#xff1f; 比如在图像边缘检测问题中&#xff0c;实际图像里&#xff0c;我们的目标物体不会总出现在固定位置&#xff0c;即使我们连续拍摄同…

(pytorch-深度学习系列)卷积神经网络LeNet-学习笔记

卷积神经网络LeNet 先上图&#xff1a;LeNet的网络结构 卷积(6个5∗5的核)→降采样(池化)(2∗2的核&#xff0c;步长2)→卷积(16个5∗5的核)→降采样(池化)(2∗2的核&#xff0c;步长2)→全连接16∗5∗5→120→全连接120→84→全连接84→10\begin{matrix}卷积 \\ (6个5*5的核…

(pytorch-深度学习系列)深度卷积神经网络AlexNet

深度卷积神经网络AlexNet 文字过多&#xff0c;但是重点已经标出来了 背景 在LeNet提出后的将近20年里&#xff0c;神经网络一度被其他机器学习方法超越&#xff0c;如支持向量机。虽然LeNet可以在早期的小数据集上取得好的成绩&#xff0c;但是在更大的真实数据集上的表现并…

(pytorch-深度学习系列)使用重复元素的网络(VGG)

使用重复元素的网络&#xff08;VGG&#xff09; VGG的名字来源于论文作者所在的实验室Visual Geometry Group&#xff0c;VGG提出了可以通过重复使用简单的基础块来构建深度模型的思路。 VGG Block(VGG 块) VGG块的组成规律是&#xff1a;连续使用数个相同的填充为1、窗口形…

(pytorch-深度学习系列)网络中的网络(NiN)

网络中的网络&#xff08;NiN&#xff09; LeNet、AlexNet和VGG在设计上的共同之处是&#xff1a;先以由卷积层构成的模块充分抽取空间特征&#xff0c;再以由全连接层构成的模块来输出分类结果。其中&#xff0c;AlexNet和VGG对LeNet的改进主要在于如何对这两个模块加宽&…

(pytorch-深度学习)包含并行连结的网络(GoogLeNet)

包含并行连结的网络&#xff08;GoogLeNet&#xff09; 在2014年的ImageNet图像识别挑战赛中&#xff0c;一个名叫GoogLeNet的网络结构大放异彩。它虽然在名字上向LeNet致敬&#xff0c;但在网络结构上已经很难看到LeNet的影子。GoogLeNet吸收了NiN中网络串联网络的思想&#…

(pytorch-深度学习)批量归一化

批量归一化 批量归一化&#xff08;batch normalization&#xff09;层能让较深的神经网络的训练变得更加容易 通常来说&#xff0c;数据标准化预处理对于浅层模型就足够有效了。随着模型训练的进行&#xff0c;当每层中参数更新时&#xff0c;靠近输出层的输出较难出现剧烈变…

(pytorch-深度学习)实现残差网络(ResNet)

实现残差网络(ResNet) 我们一般认为&#xff0c;增加神经网络模型的层数&#xff0c;充分训练后的模型理论上能更有效地降低训练误差。理论上&#xff0c;原模型解的空间只是新模型解的空间的子空间。也就是说&#xff0c;如果我们能将新添加的层训练成恒等映射f(x)xf(x) xf(…

(pytorch-深度学习)实现稠密连接网络(DenseNet)

稠密连接网络&#xff08;DenseNet&#xff09; ResNet中的跨层连接设计引申出了数个后续工作。稠密连接网络&#xff08;DenseNet&#xff09;与ResNet的主要区别在于在跨层连接上的主要区别&#xff1a; ResNet使用相加DenseNet使用连结 ResNet&#xff08;左&#xff09;…

(pytorch-深度学习)语言模型-学习笔记

语言模型 自然语言处理中最常见的数据是文本数据。我们可以把一段自然语言文本看作一段离散的时间序列。 假设一段长度为TTT的文本中的词依次为w1,w2,…,wTw_1, w_2, \ldots, w_Tw1​,w2​,…,wT​&#xff0c;那么在离散的时间序列中&#xff1a; wtw_twt​&#xff08;1≤t…

(pytorch-深度学习)循环神经网络

循环神经网络 在nnn元语法中&#xff0c;时间步ttt的词wtw_twt​基于前面所有词的条件概率只考虑了最近时间步的n−1n-1n−1个词。如果要考虑比t−(n−1)t-(n-1)t−(n−1)更早时间步的词对wtw_twt​的可能影响&#xff0c;需要增大nnn。 这样模型参数的数量将随之呈指数级增长…

配置jupyter-pytorch深度学习环境

配置jupyter-pytorch深度学习环境 安装anaconda3新建环境&#xff0c;命名为pytorch在虚拟环境里安装jupyter activate pytorch pip install jupyter安装可视化插件&#xff0c;ipywidgets&#xff0c;并且关联 pip install ipywidgets jupyter nbextension enable --py wid…

(pytorch-深度学习)SE-ResNet的pytorch实现

SE-ResNet的pytorch实现 残差块&#xff1a; class Resiual_block(nn.Module):def __init__(self, in, middle_out, out, kernel_size3, padding1):self.out_channel middle_outsuper(Resiual_block, self).__init__()self.shortcut nn.Sequential(nn.Conv2d(nin, nout, ke…

(pytorch-深度学习)循环神经网络的从零开始实现

循环神经网络的从零开始实现 首先&#xff0c;我们读取周杰伦专辑歌词数据集&#xff1a; import time import math import numpy as np import torch from torch import nn, optim import torch.nn.functional as F import sys sys.path.append("..") device tor…