Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在nn.顺序模型中使用自定义torch.autograd.Function_Python_Pytorch_Torch - Fatal编程技术网

Python 如何在nn.顺序模型中使用自定义torch.autograd.Function

Python 如何在nn.顺序模型中使用自定义torch.autograd.Function,python,pytorch,torch,Python,Pytorch,Torch,是否有任何方法可以在nn.Sequential对象中使用自定义torch.autograd.Function,或者我应该显式使用带有向前函数的nn.Module对象。具体来说,我正在尝试实现一个稀疏自动编码器,我需要将代码的L1距离(隐藏表示)添加到丢失中。 我在下面定义了自定义torch.autograd.Functionl1,然后尝试在nn.Sequential对象中使用它,如下所示。但是,当我运行时,我得到了错误TypeError:\uuuuu main\uuul1。惩罚不是模块子类如何解

是否有任何方法可以在
nn.Sequential
对象中使用自定义
torch.autograd.Function
,或者我应该显式使用带有向前函数的
nn.Module
对象。具体来说,我正在尝试实现一个稀疏自动编码器,我需要将代码的L1距离(隐藏表示)添加到丢失中。 我在下面定义了自定义
torch.autograd.Function
l1,然后尝试在
nn.Sequential
对象中使用它,如下所示。但是,当我运行时,我得到了错误
TypeError:\uuuuu main\uuul1。惩罚不是模块子类
如何解决此问题

class L1Penalty(torch.autograd.Function):
    @staticmethod
    def forward(ctx, input, l1weight = 0.1):
        ctx.save_for_backward(input)
        ctx.l1weight = l1weight
        return input, None

    @staticmethod
    def backward(ctx, grad_output):
        input, = ctx.saved_variables
        grad_input = input.clone().sign().mul(ctx.l1weight)
        grad_input+=grad_output
        return grad_input

nn.Module
API似乎工作正常,但在
l1
forward
方法中不应返回None

import torch, torch.nn as nn

class L1Penalty(torch.autograd.Function):
    @staticmethod
    def forward(ctx, input, l1weight = 0.1):
        ctx.save_for_backward(input)
        ctx.l1weight = l1weight
        return input

    @staticmethod
    def backward(ctx, grad_output):
        input, = ctx.saved_variables
        grad_input = input.clone().sign().mul(ctx.l1weight)
        grad_input+=grad_output
        return grad_input


class Model(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(10,10)
        self.fc2 = nn.Linear(10,6)
        self.fc3 = nn.Linear(6,10)
        self.fc4 = nn.Linear(10,10)
        self.relu = nn.ReLU(inplace=True)
        self.penalty = L1Penalty()

    def forward(self, x):
        x = self.fc1(x)
        x = self.relu(x)
        x = self.fc2(x)
        x = self.relu(x)
        x = self.penalty.apply(x)
        x = self.fc3(x)
        x = self.relu(x)
        x = self.fc4(x)
        x = self.relu(x)
        return x


model = Model()
a = torch.rand(50,10)
b = model(a)
print(b.shape)


正确的方法是这样做

导入火炬,火炬.nn作为nn
L1类惩罚(火炬自动悬挂功能):
@静力学方法
def前进(ctx,输入,L1重量=0.1):
ctx.save_for_backward(输入)
ctx.L1重量=L1重量
返回输入
@静力学方法
def向后(ctx、梯度输出):
输入,=ctx.saved\u变量
grad_input=input.clone().sign().mul(ctx.l1weight)
梯度输入+=梯度输出
返回梯度输入
创建充当包装器的Lambda类

类Lambda(nn.模块):
"""
输入:一个函数
返回:可以使用的模块
内部nn.顺序
"""
定义初始化(self,func):
super()。\uuuu init\uuuuu()
self.func=func
def forward(self,x):返回self.func(x)
塔达

model=nn.Sequential(
nn.线性(10,10),
nn.ReLU(),
nn.线性(10,6),
nn.ReLU(),
#稀疏
Lambda(L1处罚。适用),
nn.线性(6,10),
nn.ReLU(),
nn.线性(10,10),
nn.ReLU())
a=火炬兰特(50,10)
b=型号(a)
印刷品(b.shape)

有要共享的代码吗?当然,我已经编辑了这个问题。因此,在我看来,您希望在前进模式中像使用身份函数一样使用它,并希望在后退模式中用系数(0.1)乘以梯度。这是正确的吗?您的autograd函数似乎也不正确:
a=torch.rand(50,10);f=l1惩罚();b=f(a)
这给出了
TypeError:forward()缺少1个必需的位置参数:“input”
。这可能是您的问题的真正原因error@PiyushSingh在前进模式中,我想要你提到的身份,但在后退模式中,我想要在渐变中添加0.1*(该层的激活)。另外,当您将函数调用为f.apply(a)时,它也可以工作。然而,也许当我以这种方式实例化函数时;默认情况下,pytorch按您所做的方式调用它。但是我们的错误消息是不同的,我认为在后退模式下需要第二次返回L1。我尝试使用nn.Sequential编写,但您的版本现在可以工作了。谢谢
import torch, torch.nn as nn

class L1Penalty(torch.autograd.Function):
    @staticmethod
    def forward(ctx, input, l1weight = 0.1):
        ctx.save_for_backward(input)
        ctx.l1weight = l1weight
        return input

    @staticmethod
    def backward(ctx, grad_output):
        input, = ctx.saved_variables
        grad_input = input.clone().sign().mul(ctx.l1weight)
        grad_input+=grad_output
        return grad_input


class Model(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(10,10)
        self.fc2 = nn.Linear(10,6)
        self.fc3 = nn.Linear(6,10)
        self.fc4 = nn.Linear(10,10)
        self.relu = nn.ReLU(inplace=True)
        self.penalty = L1Penalty()

    def forward(self, x):
        x = self.fc1(x)
        x = self.relu(x)
        x = self.fc2(x)
        x = self.relu(x)
        x = self.penalty.apply(x)
        x = self.fc3(x)
        x = self.relu(x)
        x = self.fc4(x)
        x = self.relu(x)
        return x


model = Model()
a = torch.rand(50,10)
b = model(a)
print(b.shape)