Keras:简单数据的简单神经网络无法工作

4

我尝试创建一个非常简单的神经网络:一个隐藏层,有两个神经元。针对一些非常简单的数据:只有一个特征。

import numpy as np
X=np.concatenate([np.linspace(0,10,100),np.linspace(11,20,100),np.linspace(21,30,100)])
y=np.concatenate([np.repeat(0,100),np.repeat(1,100),np.repeat(0,100)])

enter image description here

这是模型

from keras.models import Sequential
from keras.layers import Dense
model = Sequential()
model.add(Dense(2, activation='sigmoid'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='sgd', metrics=['accuracy'])
model.fit(X, y, epochs=200)

理论上,这个模型应该是有效的。但即使经过1000个时期,准确率仍然为0.667。

Epoch 999/1000
10/10 [==============================] - 0s 1ms/step - loss: 0.5567 - accuracy: 0.6667
Epoch 1000/1000
10/10 [==============================] - 0s 2ms/step - loss: 0.5566 - accuracy: 0.6667

我认为我做错了什么。你能建议一些修改吗?
看起来有很多局部最小值,初始化可能会改变最终模型。这是在R中使用nnet包进行测试时的情况。我不得不测试很多种子,我找到了这个模型(和其他模型)。

enter image description here

这是我想用keras创建的结构:一个有2个神经元的隐藏层,激活函数为sigmoid。因此,我想知道keras是否存在与初始化相关的问题。使用R中的nnet包时,我认为它不是一个“完美”的包。我认为keras会更加高效。如果初始化很重要,keras是否会测试不同的初始化?如果没有,为什么呢?也许是因为通常情况下,随着更多的数据(和更多的特征),它可以更好地工作(而不需要测试许多初始化)?例如,对于kmeans,似乎测试了不同的初始化。
1个回答

3
这个问题展示了对神经网络来说输入数据归一化的重要性。如果没有进行归一化,有时训练神经网络会很困难,因为优化可能会卡在某些局部最小值处。
我想从数据集的可视化开始。这个数据集是一维的,在使用标准归一化后,它看起来像下面这样。
X_original = np.concatenate([np.linspace(0, 10, 100), np.linspace(
11, 20, 100), np.linspace(21, 30, 100)])
X = (X_original - X_original.mean())/X_original.std()

y = np.concatenate(
        [np.repeat(0, 100), np.repeat(1, 100), np.repeat(0, 100)])
plt.figure()
plt.scatter(X, np.zeros(X.shape[0]), c=y)
plt.show()

enter image description here 将这些数据点分成各自的类别的最佳方式是在输入空间上画两条线。由于输入空间为1D,分类边界只是1D点。

这意味着单层网络(例如逻辑回归)无法对此数据集进行分类。但是,一个带有两个层和非线性激活的神经网络应该能够对数据集进行分类。

现在,在进行规范化和以下训练脚本后,模型可以轻松学习分类点的方法。

model = Sequential()
model.add(Dense(2, activation='sigmoid'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy',
                  optimizer=keras.optimizers.Adam(1e-1), metrics=['accuracy'])
model.fit(X, y, epochs=20)


Train on 300 samples
Epoch 1/20
300/300 [==============================] - 1s 2ms/sample - loss: 0.6455 - accuracy: 0.6467
Epoch 2/20
300/300 [==============================] - 0s 79us/sample - loss: 0.6493 - accuracy: 0.6667
Epoch 3/20
300/300 [==============================] - 0s 85us/sample - loss: 0.6397 - accuracy: 0.6667
Epoch 4/20
300/300 [==============================] - 0s 100us/sample - loss: 0.6362 - accuracy: 0.6667
Epoch 5/20
300/300 [==============================] - 0s 115us/sample - loss: 0.6342 - accuracy: 0.6667
Epoch 6/20
300/300 [==============================] - 0s 96us/sample - loss: 0.6317 - accuracy: 0.6667
Epoch 7/20
300/300 [==============================] - 0s 93us/sample - loss: 0.6110 - accuracy: 0.6667
Epoch 8/20
300/300 [==============================] - 0s 110us/sample - loss: 0.5746 - accuracy: 0.6667
Epoch 9/20
300/300 [==============================] - 0s 142us/sample - loss: 0.5103 - accuracy: 0.6900
Epoch 10/20
300/300 [==============================] - 0s 124us/sample - loss: 0.4207 - accuracy: 0.9367
Epoch 11/20
300/300 [==============================] - 0s 124us/sample - loss: 0.3283 - accuracy: 0.9833
Epoch 12/20
300/300 [==============================] - 0s 124us/sample - loss: 0.2553 - accuracy: 0.9800
Epoch 13/20
300/300 [==============================] - 0s 138us/sample - loss: 0.2030 - accuracy: 1.0000
Epoch 14/20
300/300 [==============================] - 0s 124us/sample - loss: 0.1624 - accuracy: 1.0000
Epoch 15/20
300/300 [==============================] - 0s 150us/sample - loss: 0.1375 - accuracy: 1.0000
Epoch 16/20
300/300 [==============================] - 0s 122us/sample - loss: 0.1161 - accuracy: 1.0000
Epoch 17/20
300/300 [==============================] - 0s 115us/sample - loss: 0.1025 - accuracy: 1.0000
Epoch 18/20
300/300 [==============================] - 0s 126us/sample - loss: 0.0893 - accuracy: 1.0000
Epoch 19/20
300/300 [==============================] - 0s 121us/sample - loss: 0.0804 - accuracy: 1.0000
Epoch 20/20
300/300 [==============================] - 0s 132us/sample - loss: 0.0720 - accuracy: 1.0000

由于该模型非常简单,学习率和优化器的选择会影响学习速度。使用SGD优化器和学习率为1e-1,与使用相同学习率的Adam优化器相比,模型的训练时间可能会更长。


非常感谢您的回答,我们确实可以看到归一化的重要性。对于多元线性回归,归一化数据似乎也很重要。从理论上来说它并没有影响,但在数值求解优化问题时很重要。 - John Smith
你有更多关于归一化如何影响梯度下降的信息吗?我不明白为什么这是一个大问题。我的意思是,我们可以使梯度下降“更强大”。因为理论上,我认为归一化并不会减少局部最小值的数量,对吧? - John Smith
通常情况下,当您使用标准归一化进行归一化时,您会减少数据集的方差并将数据集居中在零周围。这将有助于更好地收敛。但是理论上,您可以找到一组超参数和权重初始化,即使没有归一化也能够学习。 - Mitiku
当使用10个数据点进行测试时,Keras无法(快速)收敛。对于小数据集,我们应该使用哪种优化器?我知道在实际情况下,我们有更多的数据,但这只是为了说明目的。 - John Smith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接