🐡参数管理
2021-11-20
| 2023-8-6
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
Property
 
在选择了架构并设置了超参数后,就进入了训练阶段。 此时,我们的目标是找到使损失函数最小化的模型参数值。 经过训练后,我们将需要使用这些参数来做出未来的预测。 此外,有时我们希望提取参数,以便在其他环境中复用它们, 将模型保存下来,以便它可以在其他软件中执行, 或者为了获得科学的理解而进行检查。
之前我们只依靠深度学习框架来完成训练的工作, 而忽略了操作参数的具体细节。 这里将介绍以下内容:
  • 访问参数,用于调试、诊断和可视化。
  • 参数初始化。
  • 在不同模型组件间共享参数。
 
首先看一下具有单隐藏层的多层感知机:
 

参数访问

当通过Sequential类定义模型时, 我们可以通过索引来访问模型的任意层。 这就像模型是一个列表一样,每层的参数都在其属性中。 如下所示,可以检查第二个全连接层的参数:
输出的结果告诉我们:这个全连接层包含两个参数,分别是该层的权重和偏置。 两者都存储为单精度浮点数(float32)。 注意:参数名称允许唯一标识每个参数,即使在包含数百个层的网络中也是如此
 

目标参数

每个参数都表示为参数类的一个实例,要对参数执行任何操作,首先需要访问底层的数值
下面的代码从第二个全连接层(即第三个神经网络层)提取偏置, 提取后返回的是一个参数类实例,并进一步访问该参数的值
参数是复合的对象,包含值、梯度和额外信息。 这就是我们需要显式参数值的原因。 除了值之外,我们还可以访问每个参数的梯度。 在上面这个网络中,由于我们还没有调用反向传播,所以参数的梯度处于初始状态
 

一次性访问所有参数

当需要对所有参数执行操作时,逐个访问它们可能会很麻烦。下面将通过演示来比较访问第一个全连接层的参数和访问所有层:
 

从嵌套块收集参数

让我们看看,如果我们将多个块相互嵌套,参数命名约定是如何工作的。
我们首先定义一个生成块的函数(可以说是“块工厂”),然后将这些块组合到更大的块中
设计了网络后,我们看看它是如何工作的:
notion image
因为层是分层嵌套的,所以我们也可以像通过嵌套列表索引一样访问它们。 下面,我们访问第一个主要的块中、第二个子块的第一层的偏置项
 
 

参数初始化

深度学习框架提供默认随机初始化, 也允许我们创建自定义初始化方法通过其他规则实现初始化权重。
默认情况下,PyTorch会根据一个范围均匀地初始化权重和偏置矩阵, 这个范围是根据输入和输出维度计算出的。 PyTorch的nn.init模块提供了多种预置初始化方法

内置初始化

下面的代码将所有权重参数初始化为标准差为0.01的高斯随机变量, 且将偏置参数设置为0:
我们还可以将所有参数初始化为给定的常数,比如初始化为1:
我们还可以对某些块应用不同的初始化方法。 例如,下面使用Xavier初始化方法初始化第一个神经网络层, 然后将第三个神经网络层初始化为常量值42:

自定义初始化

在下面的例子中,使用以下的分布为任意权重参数定义初始化方法:
同样,实现了一个my_init函数来应用到net
注意,我们始终可以直接设置参数
 

参数绑定

有时我们希望在多个层间共享参数: 我们可以定义一个稠密层,然后使用它的参数来设置另一个层的参数
这个例子表明第三个和第五个神经网络层的参数是绑定的。 它们不仅值相等,而且由相同的张量表示。 因此,如果我们改变其中一个参数,另一个参数也会改变。
当参数绑定时,梯度会发生什么情况? 答案是由于模型参数包含梯度,因此在反向传播期间第二个隐藏层 (即第三个神经网络层)和第三个隐藏层(即第五个神经网络层)的梯度会加在一起。
  • PyTorch
  • 层与块自定义层
    目录