在 Pytorch 中隐式更改 nn.Parameter() 值的最佳方法?

问题描述 投票:0回答:2

假设我想优化一个向量

v
,使其范数等于 1。为此,我使用该向量定义了一个网络,如下所示:

class myNetwork(nn.Module):
    def __init__(self,initial_vector):
        super(myNetwork, self).__init__()
        #Define vector according to an initial column vector
        self.v = nn.Parameter(initial_vector)
    def forward(self,x):
        #Normalize vector so that its norm is equal to 1
        self.v.data = self.v.data / torch.sqrt(self.v.data.transpose(1,0) @ self.v.data) 
        #Multiply v times a row vector 
        out = x @ self.v
        return out 

使用

.data
是更新
v
的最佳方式吗?它是否考虑了反向传播期间的归一化?

python neural-network pytorch
2个回答
2
投票

您可以简单地使用

    def forward(self,x):
        return x @ self.v / (x**2).sum()

根据您的损失或网络的下游层,甚至完全跳过标准化。

    def forward(self,x):
        return x @ self.v

只要你的损失在规模上不变,这个方法就应该有效,标准每一步应该只有轻微的变化,但它并不严格稳定。如果你给出了很多步骤,也许值得在你的损失中添加一个术语

thinyvalue * ((myNetwork.v**2).sum()-1)**2
,以确保 $v$ 的范数被吸引到 1。


0
投票

您可以使用 pytorch 参数化。您可以首先定义以下 nn.Module,它将向量作为输入,返回相同的向量除以其范数(即范数 1 向量):

class NormalizeVector(nn.Module):
    def forward(self, eta):
        theta = eta / eta.norm()
        return theta

然后您只需在您定义的类中的参数上注册此参数化,并在转发调用中省略规范化:

from torch.nn.utils import parametrize

class myNetwork(nn.Module):
    def __init__(self,initial_vector):
        super(myNetwork, self).__init__()
        self.v = nn.Parameter(initial_vector)
        parametrize.register_parametrization(self, "v", NormalizeVector())


    def forward(self,x):
        #Multiply v times a row vector 
        out = x @ self.v
        return out 

参数化将使向量

v
保持单位长度。您可以使用相同的训练代码,并像其他方式一样访问
v
。您可以在此处查看更长的参数化教程。

© www.soinside.com 2019 - 2024. All rights reserved.