异或神经网络,损失不下降

XOR neural network, the losses don't go down

我正在使用 Mxnet 训练 XOR 神经网络,但损失并没有下降,它们始终高于 0.5。

下面是我在 Mxnet 1.1.0 中的代码; Python3.6; OS X 埃尔卡皮坦 10.11.6

我尝试了 2 个损失函数——平方损失和 softmax 损失,都没有用。

from mxnet import ndarray as nd
from mxnet import autograd
from mxnet import gluon
import matplotlib.pyplot as plt

X = nd.array([[0,0],[0,1],[1,0],[1,1]])
y = nd.array([0,1,1,0])
batch_size = 1
dataset = gluon.data.ArrayDataset(X, y)
data_iter = gluon.data.DataLoader(dataset, batch_size, shuffle=True)

plt.scatter(X[:, 1].asnumpy(),y.asnumpy())
plt.show()

net = gluon.nn.Sequential()
with net.name_scope():
    net.add(gluon.nn.Dense(2, activation="tanh"))
    net.add(gluon.nn.Dense(1, activation="tanh"))
net.initialize()

softmax_cross_entropy = gluon.loss.SigmoidBCELoss()#SigmoidBinaryCrossEntropyLoss()
square_loss = gluon.loss.L2Loss()
trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': 0.3})

train_losses = []

for epoch in range(100):
    train_loss = 0
    for data, label in data_iter:
        with autograd.record():
            output = net(data)
            loss = square_loss(output, label)
        loss.backward()
        trainer.step(batch_size)

        train_loss += nd.mean(loss).asscalar()
    train_losses.append(train_loss)

plt.plot(train_losses)
plt.show()

我在其他地方找到了这个问题,所以我要 post 在这里回答。

基本上,我的原始代码中的问题是 multi-dimensional。

  1. 权重初始化。请注意,我使用了默认初始化

net.initialize()

实际上是这样

net.initialize(initializer.Uniform(scale=0.07))

显然这些初始权重太小了,网络永远跳不出来。所以修复是

net.initialize(mx.init.Uniform(1))

这样做之后,网络可以收敛使用 sigmoid/tanh 作为 激活 ,并使用 L2Loss 作为 损失函数。它适用于 sigmoidSigmoidBCELoss。但是,它仍然无法与 tanhSigmoidBCELoss 一起使用,可以通过下面的第二项修复。

  1. SigmoidBCELoss输出层这2个场景必须用到

    2.1。 线性激活SigmoidBCELoss(from_sigmoid=False)

    2.2。 Non-linear激活SigmoidBCELoss(from_sigmoid=True),其中non-linear函数的输出落在(0, 1).

在我的原始代码中,当我使用 SigmoidBCELoss 时,我要么使用所有 sigmoid,要么使用所有 tanh。所以只需要将输出层的激活值从tanh改为sigmoid,网络就可以收敛了。我仍然可以在隐藏层中有 tanh

希望对您有所帮助!