我使用 Keras 包:
from keras.models import Sequential
from keras.layers import Dense, Activation
model = Sequential([
Dense(100, input_shape=(52,)),
Activation('relu'),
Dense(40),
Activation('softmax'),
Dense(1),
Activation('tanh')
])
model.compile(optimizer='sgd',
loss='mean_absolute_error')
model.fit(train_x2, train_y, epochs=200, batch_size=52)
如何调整它,使其认为输出应该为零?我可以在最后更改它,但我希望它在学习时考虑到这个事实。
最佳答案
这里有一些不同的策略,选择实际上取决于您的用例。它们都具有不同的属性,这些属性会影响神经网络的行为:
sigmoid
或转移tanh
激活:这些限制过于严格,在 [0,1] 范围内,而不仅仅是正值。除了更具限制性之外,高/低值的梯度变得非常小。因此,如果样本卡在那里,可能需要很长时间才能回到 sigmoid/tanh 的中心。如果您可以接受这样的受限域,那么您可以查看并选择更多激活函数。relu
激活:这里的问题是当梯度低于零时,梯度可能为零。因此,如果样本卡在这里,它们将无法再学习。然而,尽管负域中的梯度为零,但它的计算速度非常快,并且在许多问题上往往表现良好。softplus
激活:RELU 的平滑版本,因此它永远不会陷入零梯度区域。然而,就像 sigmoid/tanh 一样,随着负值的增加,学习速度会变慢。exp(output)
:我发现这往往不太稳定(例如,增加非常快 < 0)。但是,当与其他函数配合使用时,它仍然可以工作,例如下游 log/ln 或 softmax。square(output)
:这是一个平滑函数,具有线性梯度。缺点是平方有时会导致您的值爆炸(或者如果 |output| < 1 则消失);必须谨慎使用标准化来防止这种情况发生。这通常用于损失函数,例如 MSE。abs(output)
:这是线性的,因此比square
有优势它不会改变值的大小,并且学习是恒定的。不过,它确实存在梯度不连续性,因此当输出接近于零时,可能会导致更多类似悬崖的梯度拓扑,并且梯度更新会跳过不连续性(梯度裁剪可能会有所帮助)。Piecewise[{{.5x^2, |x|<1}, {|x|-.5, |x|>=1}}]
:这混合了square
的平滑度与线性abs
,所以兼具了两者的优点。缺点是分段条件使得计算速度变慢(尽管可以说仍然比 exp 或 softplus 更快)。我不确定是否有人已经为此创造了一个名字,但也许可以将其称为softabs
。如果您对数据进行标准化,x 可能始终 < 1;所以在这种情况下,您可能只需使用square
就可以了。 This link对于平滑绝对值函数有一些额外的想法,可能更适合您的需求。
还有最后一点:如果您只想使经过训练的权重参数为正值,只需使用权重约束 (abs) 即可!
关于python - 如何在Python、Keras中限制神经网络的输出为正,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49982438/