XOR神经网络,损失不会下降

时间:2018-04-01 18:04:20

标签: python machine-learning neural-network perceptron mxnet

我使用Mxnet训练XOR神经网络,但损失不会下降,它们总是高于0.5。

以下是我在Mxnet 1.1.0中的代码; Python 3.6; OS X El Capitan 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()

1 个答案:

答案 0 :(得分:1)

我在其他地方发现了这个问题,所以我将在这里发布答案。

基本上,我原始代码中的问题是多维的。

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

    net.initialize()

    实际上

      

    net.initialize(initializer.Uniform(标度= 0.07))

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

      

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

    执行此操作后,网络可以使用sigmoid/tanh作为激活进行收敛,并使用L2Loss作为丢失功能。它适用于sigmoidSigmoidBCELoss。但是,它仍无法与tanhSigmoidBCELoss一起使用,可以通过下面的第二项修复。

    1. SigmoidBCELoss必须在输出层的这两种情况中使用。

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

      2.2。 非线性激活SigmoidBCELoss(from_sigmoid=True),其中非线性函数的输出属于(0,1)。

    2. 在我的原始代码中,当我使用SigmoidBCELoss时,我使用的是全部sigmoid或全部tanh。因此,只需将输出层中的激活从tanh更改为sigmoid,网络就可以收敛。我仍然可以在隐藏图层中使用tanh

      希望这有帮助!