Pytorch 教程 2-模型

二、模型


2.1 模型的搭建

2.1.1 模型定义的三要

  • 必须继承nn.Module这个类,要让PyTorch知道这个类是一 个Module
  • __init(self)__ 中设置好需要的“组件”(如conv、pooling、Linear、BatchNorm等)
  • forward(self, x)中用定义好的“组件”进行组装,就像搭积木,把网络结构搭建出来

2.1.2 nn.Sequential

  • torch.nn.Sequential其实就是Sequential容器,该容器将一系列操作按先后顺序给抱起来,方便重复使用

2.2 权值初始化的10种方法

  • 初始化流程:
    1. 先设定什么层用什么初始化方法,初始化方法在torch.nn.init中给出
    2. 实例化一个模型之后,执行该函数,即可完成初始化

2.2.1 Xavier均匀分布

  • torch.nn.init.xavier_uniform_(tensor, gain=1)
    • 服从均匀分布 U ( − a , a ) U(-a, a) U(a,a),分布的参数 a = g a i n ∗ 6 f a n _ i n + f a n _ o u t a=gain* \sqrt{\frac{6}{fan\_in}+fan\_out} a=gainfan_in6+fan_out
    • gain的大小是依据激活函数来信来设定
    • eg:nn.init.xavier_uniform_(w, gain=nn.init.calculate_gain('relu'))

2.2.2 Xavier正态分布

  • torch.nn.init.xavier_normal_(tensor, gain=1)
    • 服从正态分布
    • m e a n = 0 mean=0 mean=0 s t d = g a i n ∗ 2 f a n _ i n + f a n _ o u t std=gain*\sqrt{\frac{2}{fan\_in}+fan\_out} std=gainfan_in2+fan_out std=gain*sqrt(2/fan_in+fan_out)

2.2.3 kaiming均匀分布

  • torch.nn.init.kaiming_uniform_(tensor, a=0, mode='fan_in', nonlinearity='leaky_relu')
    • 此为均匀分布, U ∼ ( − b o u n d , b o u n d ) U\sim(-bound,bound) U(bound,bound) b o u n d = 6 1 + a 2 ∗ f a n _ i n bound=\sqrt{\frac{6}{1+a^2}*fan\_in} bound=1+a26fan_in ,其中 a a a为激活函数的负半轴的斜率,relu是0
    • mode可选为fan_in(正向传播时方差一致)或fan_out(反向传播时,方差一致)
    • nonlinearity可选reluleaky_relu

2.2.4 kaiming正态分布

  • torch.nn.init.kaiming_normal_(tensor, a=0, mode='fan_in', nonlinearity='leaky_relu')
    • 此为0均值的正态分布, N ∼ ( 0 , s t d ) N\sim(0,std) N(0,std),其中 s t d = 2 1 + a 2 ∗ f a n _ i n std=\sqrt{\frac{2}{1+a^2}*fan\_in} std=1+a22fan_in ,其中 a a a为激活函数的负半轴的斜率,relu是0
    • mode可选为fan_in(正向传播时方差一致)或fan_out(反向传播时,方差一致)
    • nonlinearity可选reluleaky_relu

2.2.5 均匀分布初始化

  • torch.nn.init.uniform_(tensor, a=0, b=1)
    • 服从均匀分布 U ( a , b ) U(a,b) U(a,b)

2.2.6 正态分布初始化

  • torch.nn.init.normal_(tensor, mean=0, std=1)
    • 服从正态分布 N ( m e a n , s t d ) N(mean,std) N(mean,std)

2.2.7 常数初始化

  • torch.nn.init.constant_(tensor, val)
    • 使值为常数 v a l val val

2.2.8 单位矩阵初始化

  • torch.nn.init.eye_(tensor)
    • 将二维tensor初始化为单位矩阵

2.2.9 正交初始化

  • torch.nn.init.orthogonal_(tensor, gain=1)
    • 使得tensor是正交的

2.2.10 稀疏初始化

  • torch.nn.init.sparse_(tensor, sparsity, std=0.01)
    • 从正态分布 N ( 0 , s t d ) N(0,std) N(0,std)中进行稀疏化,使得每一个column有一部分为0
    • sparsity-每一个column稀疏的比例,即为0的比例

2.2.11 计算增益

  • torch.nn.init.calculate_gain(nonlinearity, param=None)

2.3 模型Finetune

一个良好的权值初始化,可以使收敛速度加快,甚至可以获得更好的精度。而在实际应用中,通常采用一个已经训练模型的模型的权值参数作为模型的初始化参数,也称之为Finetune,更宽泛的称之为迁移学习。迁移学习中的Finetune技术,本质上就是让新构建的模型,拥有一个较好的权值初始值。

  • finetune流程:
    • 保存模型,拥有一个预训练模型
    • 加载模型,把预训练模型中的权值取出来
    • 初始化,将权值对应的“放”到新模型中

2.3.1 Finetune之权值初始化

  • 保存模型的方法
    • 保存整个模型
    • 仅保存模型参数(官方推荐)
  • 保存模型
    1. 保存模型参数

      net = Net()
      torch.save(net.state_dict(), 'net_params.pkl')
      
    2. 加载模型(加载模型的参数)

      pretrained_dict = torch.load('net_params.pkl')
      
    3. 初始化

      将取到的权值,对应放到新模型中

      # 创建新模型net
      net = Net() 
      
      # 获取已创建net的state_dict
      net_state_dict = net.state_dict() 
      
      # 将pretrained_dict里不属于net_state_dict的键剔除掉
      pretrained_dict_1 = {k:v for k, v in pretrained_dict.items() if k in net_state_dict} 
      
      # 用预训练模型的参数字典对新模型的参数字典net_state_dict进行更新
      net_state_dict.updata(pretrained_dict_1)
      
      # 将更新了参数的字典“放”回到网络中
      net.load_state_dict(net_state_dict)
      

2.3.2不同层设置不同的学习率

采用finetune的训练过程中,有时候希望前面层的学习率低一些,改变不要太大,而后面的全连接层的学习率相对大一些。就需要对不同的层设置不同的学习率

  • 为不同层设置不同的学习率,主要通过优化器对多个参数组进行设置不同的参数

  • 实例

    将原始参数“切分”成fc3层参数和其余参数,为fc3层设置更大的学习率。挑选出特定的层的机制是利用内存地址作为过滤条件。

    # 将fc3层的参数net.fc3.parameters()从原始参数net.parameters()中剥离出来
    ingored_params = list(map(id, net.fc3.parameters())) # 返回的是parameters的内存地址
    base_params = filter(lambda p: id(p) not in ignored_params, net.parameters()) # 返回剥离了fc3层的参数的其余参数
    
    optimizer = optim.SGD(
    	[{'params': base_params},	{'params': net.fc3.parameters(), 'lr': 0.001*10}],
    	0.001, 
    	momentum=0.9, 
    	weight_decay=1e-4
    	)
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值