zoukankan      html  css  js  c++  java
  • 参数初始化

    一、前言

    1、深度学习框架提供默认随机初始化

    2、深度学习框架提供了最常用的规则,也允许创建自定义初始化方法

    3、默认情况下,Pytorch会根据一个范围均匀地初始化权重和偏置矩阵,这个范围是根据输入和输出维度计算出来的

    二、内置初始化

    1、下面代码将所有权重参数初始化为标准差为0.01的正态分布,且将偏置参数设置为0

    # 内置的初始化器
    # m就是一个module
    def init_normal(m):
        if type(m) == nn.Linear:
            # 给权重赋值-将所有权重参数初始化为标准差为0.01的正态分布
            nn.init.normal_(m.weight, mean=0, std=0.01)
            # 给偏置赋值-将偏置设为0
            nn.init.zeros_(m.bias)
    
    # 将net里面所以层遍历一遍
    net.apply(init_normal)
    net[0].weight.data[0], net[0].bias.data[0]
    
    # 输出结果
    
    (tensor([-0.0210, -0.0141, -0.0058,  0.0037]), tensor(0.))

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

    # 将参数初始化为给定的常数
    def init_constant(m):
        if type(m) == nn.Linear:
            '''
            torch.nn.init.constant_(tensor, val)[source]
            用值val填充向量tensor
            
            '''
            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]
    
    #输出结果
    
    (tensor([1., 1., 1., 1.]), tensor(0.))
    

    3、对不同的块应用不同的初始化方法

    # 对不同的块用不同的初始化方法
    
    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)
    
    #输出结果
    
    tensor([ 0.1352, -0.2794,  0.1592,  0.3462])
    tensor([[42., 42., 42., 42., 42., 42., 42., 42.]])
    

      

    三、自定义初始化

    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]
    
    #输出结果
    
    Init weight torch.Size([8, 4])
    Init weight torch.Size([1, 8])
    tensor([[ 0.0000,  5.1760,  0.0000, -7.1530],
            [ 0.0000,  0.0000,  0.0000, -0.0000]], grad_fn=<SliceBackward>)
    

    我们可以直接设置参数,先直接定位到参数再给其赋值

    net[0].weight.data[:] += 1
    net[0].weight.data[0, 0] = 42
    net[0].weight.data[0]
    
    #输出结果
    
    tensor([42.0000,  6.1760,  1.0000, -6.1530])
    

      

    四、参数绑定

    1、在多个层间共享参数。我们可以定义一个稠密层,然后使用他的参数来设置另一个层的参数

    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]中的值,net[4]也会改变。说明使用的其实是一个对象
    net[2].weight.data[0, 0] = 100
    print(net[2].weight.data[0,0])
    print(net[4].weight.data[0,0])
    
    # 确保它们实际上是同一个对象,而不只是有相同的值。
    print(net[2].weight.data[0] == net[4].weight.data[0])
    
    # 输出结果
    
    tensor([True, True, True, True, True, True, True, True])
    tensor(100.)
    tensor(100.)
    tensor([True, True, True, True, True, True, True, True])
    

      

  • 相关阅读:
    使用getattr() 分类: python基础学习 divide into python 2014-02-24 15:50 198人阅读 评论(0) 收藏
    使用locals()获得类,进行分发 分类: python 小练习 divide into python python基础学习 2014-02-21 14:51 217人阅读 评论(0) 收藏
    第1课第4.4节_Android硬件访问服务编写HAL代码
    第4.3节_Android硬件访问服务编写APP代码
    函数说明
    第1课第1节_编写第1个Android应用程序实现按钮和复选框
    vue生命周期
    程序代码中,怎么区分status和state?
    百度UEditor -- ZeroClipboard is not defined
    webstorm 设置ES6语法支持以及添加vuejs开发配置
  • 原文地址:https://www.cnblogs.com/xiaoqing-ing/p/15090238.html
Copyright © 2011-2022 走看看