我们先定义一个含单隐藏层的多层感知机模型,并由此展开讲解模型参数的访问等操作。
多层感知机模型
1.访问模型参数
对于Sequential类构建的模型,参数的访问有两种方式:
(a)可以使用网络提供的named_parameters()方法遍历访问模型参数;
(b)使用方括号[]索引下标的方式访问网络中的任意层(索引从0开始)。
参数访问
2.自定义模型中定义参数和非参数
torch.nn.Parameter()的理解
这个函数可以理解为类型转换函数,将一个不可训练的类型Tensor转换成可以训练的类型parameter,并将这个parameter绑定到这个module里面(net.parameter()中就有这个绑定的parameter,所以在参数优化的时候可以进行优化的),所以经过类型转换就变成了模型的一部分,成为了模型中根据训练可以改动的参数了。
使用这个函数的目的也是想让某些变量在学习的过程中不断地修改更新其值以达到最优化。
构建带参模型
从上图可知,weight1被定义为parameter类型,故自动加入了模型参数列表;而weight2仅仅在Tensor类型。
3.初始化模型参数
PyTorch的init模块中自带很多不同的参数初始化方方法,
均匀分布:服从 U(a,b)
torch.nn.init.uniform_(tensor, a=0, b=1)
正态分布:服从 N(mean,std)
torch.nn.init.normal_(tensor, mean=0, std=1)
常数初始化:初始化整个矩阵为常数val
torch.nn.init.constant_(tensor, val)
我们使用正态分布演示初始化参数。
参数初始化
我们也可以自定义初始化方法:
自定义初始化
4.共享模型参数
我们知道模型参数本身就是Tensor的子类,想要共享参数,只要在Module类的forward函数中多次调用同一个层即可实现该层的参数共享,即同一个 Module 实,参数共享。
我们使用默认初始化方法演示:
参数共享
使用常数初始化参数演示:
参数共享
上述代码中print参数时就输出了一次(0.weight tensor([[3.]])),也就是说net.named_parameters()只包含一个元素,即nn.Sequential中的两个层其实是使用的同一个对象,即:linear,因此实现了参数共享。
且linear这个模型参数在网络中复用了2次,并且模型参数初始化为3,同时这个模型参数是一个输入一个输出的。
因此,前向传播:y=x*w1*w2=1*3*3=9
反向传播求梯度:y=w^2*x,关于w求导的梯度是2w*x=2*3*1(x取1)=6
总结
模型参数的基本操作可以辅助我们更好地理解模型的构造,同时也是模型训练的起点,因此掌握参数的基本操作非常重要。
留言与评论(共有 0 条评论) “” |