栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

深度学习之参数管理

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

深度学习之参数管理

        我们在选择架构和设置了超参数后,就进入训练阶段,我们的目标是找到使损失函数最小化的参数值。经过训练,我们需要使用这些参数作出未来的预测。有时,我么需要提取参数以便在其他环境中复用他们,将模型保存到磁盘,以便在其他软件中可以执行

        本节介绍:

                1、访问参数,用于调式、诊断和可视化

                2、参数初始化

                3、在不同模型组建间共享参数

#我们首先关注具有单隐藏层的多层感知机

例子:

import torch
from torch import nn

net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 1))
X = torch.rand(size=(2, 4))
参数访问

        可以通过索引来访问模型的任意层。这就像模型是一个列表一样 ,检查第二个全连接层的参数

print(net[2].state_dict())
目标参数
   从第二个神经网络层提取偏置,提取后返回的是一个参数类实例,并进一步访问该参数的值。
# print(type(net[2].bias))
# print(net[2].bias)
# print(net[2].bias.data)

        参数是复合的对象,包含值、梯度和额外信息。这就是我们需要显式请求值的原因,除了值之外,我们还可以访问每个参数的梯度。由于我们还没有调用这个网络的反向传播,所以参数的梯度处于初始状态

net[2].weight.grad == None
一次性访问所有参数
    访问第一个全连接层的参数
print(*[(name, param.shape) for name, param in net[0].named_parameters()])
     访问所有层的参数
print(*[(name, param.shape) for name, param in net.named_parameters()])
从嵌套块收集参数

       先定义一个生成块的的函数,然后将这些块组合到更大的块中

        

def block1():
    return  nn.Sequential(nn.Linear(4,8),nn.ReLU(),nn.Linear(8,4),nn.ReLU())

def block2():
    net = nn.Sequential()
    for i in range(4):
        net.add_module(f'block {i}',block1())
    return  net

regnet = nn.Sequential(block2(),nn.Linear(4,1))
X = torch.rand(size=(2,4))
regnet(X)

          查看网络的组织情况

print(rgnet) 

                  

 可以像访问列表一样访问网络的各层
rgnet[0][1][0].bias.data
参数初始化

        PyTorch的nn.init模块提供了多种预置初始化方法

       内置初始化

              调用内置初始化器,将所有权重参数初始化为标准差为0.01的高斯随机变量并将偏置参数置0        

def init_normal(m):
    if type(m) == nn.Linear:
        nn.init.normal_(m.weight, mean=0, std=0.01)
        nn.init.zeros_(m.bias)
net.apply(init_normal)
net[0].weight.data[0], net[0].bias.data[0]

              所有参数初始化为给定的常数

def init_constant(m):
    if type(m) == nn.Linear:
        nn.init.constant_(m.weight, 1)
        nn.init.zeros_(m.bias)
net.apply(init_constant)
net[0].weight.data[0], net[0].bias.data[0]

                对某些块应用不同的初始化方法

def xavier(m):
    if type(m) == nn.Linear:
        nn.init.xavier_uniform_(m.weight)
def init_42(m):
    if type(m) == nn.Linear:
        nn.init.constant_(m.weight, 42)

net[0].apply(xavier)
net[2].apply(init_42)
print(net[0].weight.data[0])
print(net[2].weight.data)

             自定义初始化

def my_init(m):
    if type(m) == nn.Linear:
        print("Init", *[(name, param.shape)
                        for name, param in m.named_parameters()][0])
        nn.init.uniform_(m.weight, -10, 10)
        m.weight.data *= m.weight.data.abs() >= 5

net.apply(my_init)
net[0].weight[:2]

                参数绑定

# 我们需要给共享层一个名称,以便可以引用它的参数。
shared = nn.Linear(8, 8)
net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(),
                    shared, nn.ReLU(),
                    shared, nn.ReLU(),
                    nn.Linear(8, 1))
net(X)
# 检查参数是否相同
print(net[2].weight.data[0] == net[4].weight.data[0])
net[2].weight.data[0, 0] = 100
# 确保它们实际上是同一个对象,而不只是有相同的值。
print(net[2].weight.data[0] == net[4].weight.data[0])

小结
  • 我们有几种方法可以访问、初始化和绑定模型参数。
  • 我们可以使用自定义初始化方法。

                                      

来源:动手学深度学习   

                

                                  

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/268954.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号