如何在pytorch中只训练线性层权重矩阵对角线上的权重?

qoefvg9y  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(91)

正如标题所说,我试图对角化线性层权重矩阵,并在训练期间将所有其他权重冻结为0。这相当于一个简单缩放先前输出的层。似乎我无法冻结pytorchTensor的一部分,尽管使用requires_grad函数。我写这篇文章是为了一个有效的调优方法,所以仅仅对角化矩阵对我没有帮助。如果有,请告诉我。我忽略了一些缩放层,或者你知道怎么做,让我知道。谢谢。

gojuced7

gojuced71#

一个选项是遮罩图层的渐变矩阵

layer = nn.Linear(d_in, d_out)
grad_mask = torch.eye(layer.weight.shape)

# stuff happens here, at some point loss.backward() is called and populates layer.weight.grad

layer.weight.grad = layer.weight.grad * grad_mask

字符串
也就是说,如果你只想要对角线,而你希望所有其他值都为零,为什么要使用线性层呢?你可以直接将输入乘以对角线值。

import torch
import torch.nn as nn

d_weight = 8
weight = torch.zeros(d_weight, d_weight)
diag_values = torch.randn(d_weight)
weight = torch.diagonal_scatter(weight, diag_values, 0)

layer = nn.Linear(d_weight, d_weight, bias=False)
layer.weight.data = weight.data

x = torch.randn(1,8)
y1 = layer(x)
y2 = x*diag_values

(y1 == y2).all()
>True


你可以把它作为一个模块

class MyLayer(nn.Module):
    def __init__(self, weight_tensor):
        super().__init__()
        self.weight_tensor = nn.Parameter(weight_tensor)
        
    def forward(self, x):
        return x * self.weight_tensor

相关问题