Python中'ctx'和'self'的区别是什么?

12

在使用深度学习库PyTorch时,我遇到了这样的定义。 ctxself有相同的行为吗?

class LinearFunction(Function):

    @staticmethod
    def forward(ctx, input, weight, bias=None):
        ctx.save_for_backward(input, weight, bias)
        output = input.mm(weight.t())
        if bias is not None:
            output += bias.unsqueeze(0).expand_as(output)
        return output

    @staticmethod
    def backward(ctx, grad_output):
        input, weight, bias = ctx.saved_variables
        grad_input = grad_weight = grad_bias = None
        if ctx.needs_input_grad[0]:
            grad_input = grad_output.mm(weight)
        if ctx.needs_input_grad[1]:
            grad_weight = grad_output.t().mm(input)
        if bias is not None and ctx.needs_input_grad[2]:
            grad_bias = grad_output.sum(0).squeeze(0)

        return grad_input, grad_weight, grad_bias

3
静态方法完全不涉及self。它们是静态的。换句话说,它们被使用时就像在类外定义的函数一样。对这些方法来说,ctx是显式传递的,它和self没有任何关系。 - sytech
2
我猜测 ctx 在某种程度上是 context 的缩写。 - sam
2个回答

9

静态方法(@staticmethod)是直接使用类 type 调用的,而不是该类的实例:

LinearFunction.backward(x, y)

如果你没有实例,那么在静态方法中使用self是没有意义的。

在这里,ctx只是一个普通的参数,当调用你的方法时,你需要传递它。


1
@staticmethod是一个装饰器函数。
从文档中可以得知:
静态方法不接收隐式的第一个参数。当使用@staticmethod修饰的函数被调用时,我们不会像通常使用方法一样传递类的实例给它。这意味着我们可以将一个函数放在类里面,但我们无法访问该类的实例(当您的方法不使用实例时,这非常有用)。
当您需要一个不访问类的任何属性但有意义归属于该类的实用函数时,您可以使用静态函数。
在您的示例中,ctx参数,并且在技术上是self的属性,在其中可以放置许多张量。
注意:当您定义torch.nn.Module时,只需定义forward()函数,而不是@staticmethod。当您定义新的自动求导函数时,您需要定义forward()backward()函数,这两个函数都是@staticmethod

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接