我在R中从头开始攻击了一个深度前馈NN,并且它似乎更稳定了"硬sigmoid"激活 - 最大(0,min(1,x)) - 比ReLU。试图将它移植到TensorFlow,并注意到他们没有内置这个激活功能,只有relu6,它使用6的上截止点。这有什么原因吗? (我意识到你可以做relu6(x * 6)/ 6,但是如果TF家伙把6放在那里是有充分理由的,我想知道。) 另外,我想知道其他人是否在前馈网中有ReLU爆炸问题(我知道RNN问题)。
答案 0 :(得分:32)
Tensorflows文档(https://www.tensorflow.org/api_docs/python/tf/nn/relu6)指向以下文章:
......首先,我们将单位限制为6,因此我们的ReLU激活 功能是 y = min(max(x,0),6)。 在我们的测试中,这鼓励模型更早地学习稀疏特征。在[8]的表述中,这是 相当于想象每个ReLU单元只包含6个复制的偏移伯努利单元 而不是一个无限量。我们将以n为单位的ReLU单位称为ReLU-n单位。
http://www.cs.utoronto.ca/~kriz/conv-cifar10-aug2010.pdf
由于它起源于纸张,我怀疑他们用不同的n测试它并且在n = 6的情况下获得了最佳的测试结果。
答案 1 :(得分:28)
这有助于使网络为定点推理做好准备。 如果取消绑定上限,则会丢失太多位到Q部分 一个Q.f号码。保持ReLUs以6为界限将让他们接受 最多3位(最多8位),留下4/5位.f
然后,似乎6只是根据您希望能够将网络训练的参数压缩到的位数选择的任意值。 根据“为什么”只实现了值为6的版本,我认为这是因为这是最适合8位的值,这可能是最常见的用例。
答案 2 :(得分:0)
例如,如果您想要一个不同的数字,例如,如果您要对二进制数据使用硬编码的权重并且想要ReLU1(),则可以按以下方式实现:
class ReLU1(nn.Module):
def forward(self, x):
return F.relu6(x * 6.0) / 6.0
class ReLUX(nn.Module):
def __init__(self, max_value: float=1.0):
super(ReLUX, self).__init__()
self.max_value = float(max_value)
self.scale = 6.0/self.max_value
def forward(self, x):
return F.relu6(x * self.scale) / (self.scale)