20230227 -
引言
对于torch中的权值初始化方式,以往都是采用默认的方式,或者利用初始化库里面的函数。但是如果想尝试一些自己的想法,那就必须自己来填充这部分数据,例如看到的内容,利用PCA的公式来对权值进行填充。
那么这里就必须对这个权值进行修改,但是查找了一下,发现很少有这部分内容,所以这里进行一些记录。但是总感觉我这个程序还是怪怪的,可能最后效果也不会好。
1. 权值的数据形状
为了拿到这个权值,可以使用state_dict
这个函数,因为我这里使用的是sequential
的形式定义的层,所以如果要拿到某一层的话,需要利用字典键值拿到某一层。
但是这里出现了一个问题,我是输入维度是128,输出是96,但这个权值矩阵的形状是(96,128)
,从这个数值上可以看到,他们是转置过的,但是毕竟不太清楚具体原理,所以还是查询了一下,在文章[1]中也说明了,确实是这样,而且他后续运算也是经过转置的。
好像我记得之前的时候,处理Keras权值的时候也存在这个问题。
同时因为我是用Sequential
定义的层,实际上我可以通过数组的形式来提取这个权值,model.l[0]
这样的形式,其中l
是Sequential
定义的。
2. 权值加载
一般为了训练模型的可复用,那么会经常保存模型,然后重新加载,这个采用save
和load
就足够了。这种一般你同一个定义的模型,他是不会出现什么错误的。不过当时我记得出现过一个GPU和CPU版本的问题,调整某个参数就可以了。
这里我的一个需求是,我需要把某个层的数值给进行修改,比如我就是要把某个层给设置成0,我可以直接用前面索引的形式[2],来进行复制
with troch.no_grad():
model.l[0] = nn.Parameter(torch.zeros(96,128))
这个no_grad()
是不是必须的,目前暂时不清楚,但是还是加上比较保险。
同时,如果想用state_dict()[‘key’]的形式来进行赋值,那么可以在no_grad()
下采用copy_
函数。
参考
[1]PyTorch - unexpected shape of model parameters weights
[2]How to set specific values for the weight and bias in a neural net?
[3]How to assign values to nn.Linear object