我是MXNet的新手(我正在Python3中使用它)

他们的教程系列鼓励您定义自己的gluon blocks

因此,可以说这是您的块(常见的卷积结构):

class CNN1D(mx.gluon.Block):
    def __init__(self, **kwargs):
        super(CNN1D, self).__init__(**kwargs)
        with self.name_scope():
            self.cnn = mx.gluon.nn.Conv1D(10, 1)
            self.bn = mx.gluon.nn.BatchNorm()
            self.ramp = mx.gluon.nn.Activation(activation='relu')

    def forward(self, x):
        x = mx.nd.relu(self.cnn(x))
        x = mx.nd.relu(self.bn(x))
        x = mx.nd.relu(self.ramp(x))
        return x


这是其示例结构的镜像。
mx.nd.relu vs mx.gluon.nn.Activation有什么区别?

应该是

x = self.ramp(x)


代替

x = mx.nd.relu(self.ramp(x))

最佳答案

看起来

mx.gluon.nn.Activation(activation=<act>)


是用于从NDArray模块调用大量基础激活的包装器。

因此,从原则上讲,在前向定义中是否使用

x = self.ramp(x)


要么

x = mx.nd.relu(x)


要么

x = mx.nd.relu(self.ramp(x))


因为relu只是简单地取最大值0和传递的值(因此,除了轻微的运行时间增加之外,多个应用程序只会影响单个调用而不会影响该值)。

因此,在这种情况下,它并不重要。当然,与其他激活功能一起堆叠多个调用可能会产生影响。

在MXNets文档中,当定义nd.relu时,它们在正向定义中使用gluon.Block。与使用mx.gluon.nn.Activation(activation='relu')相比,这可能会带来较少的开销。

从风味上讲,gluon模块是高级抽象。因此,我认为在定义块时应使用
ramp = mx.gluon.nn.Activation(activation=<act>)代替nd.<act>(x),然后在前向定义中调用self.ramp(x)

但是,鉴于此刻所有自定义的Block教程/文档都坚持使用relu激活,这是否会产生持久影响还有待观察。

一起使用mx.gluon.nn.Activation似乎是从NDArray模块从Gluon模块调用激活函数的一种方式。

关于python-3.x - MXNet:nn.Activation与nd.relu?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46285711/

10-10 11:17