Keras:X 和 Y 相同,但验证准确率为 50%,有什么问题?

数据挖掘 机器学习 神经网络 深度学习 张量流 喀拉斯
2021-10-11 04:24:12

我试图了解发生了什么,所以我构建了一个更简单的项目版本。我将 X 和 Y 设置为相同,并尝试使用 X 预测 Y,这应该非常简单,但我的设置不起作用。这是我的代码:

import numpy
import keras
import pandas


# I want to evaluate the model when X and Y are the same
# This should be very easy for the model to evaluate
X = numpy.random.randint(2, size=100000)
Y = X

# Setup the model
model = keras.models.Sequential()

model.add(keras.layers.Dense(1, input_dim=1, init='uniform', activation='relu'   ))
model.add(keras.layers.Dense(1,              init='uniform', activation='sigmoid'))

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

hist = model.fit(X, Y, nb_epoch=10, validation_split=.3, batch_size=10, verbose=1)

df             = pandas.DataFrame()
df['loss']     = hist.history['loss']
df['acc']      = hist.history['acc']
df['val_loss'] = hist.history['val_loss']
df['val_acc']  = hist.history['val_acc']
df.index       = df.index + 1
#
print(df)

这是我的输出:

        loss       acc  val_loss   val_acc
1   0.693162  0.504357  0.693300  0.496233
2   0.693150  0.503100  0.693250  0.496233
3   0.693157  0.502357  0.693132  0.503767
4   0.693171  0.502214  0.693119  0.503767
5   0.693167  0.502043  0.693121  0.503767
6   0.693129  0.504014  0.693133  0.503767
7   0.693167  0.503243  0.693129  0.503767
8   0.693157  0.502357  0.693181  0.496233
9   0.693180  0.502614  0.693141  0.503767
10  0.693170  0.502300  0.693119  0.503767

我希望准确率达到 100%,但事实并非如此。我究竟做错了什么?

是我遵循的示例。

3个回答

您应该考虑初始值如何影响 ReL 单位。例如,如果您使用init='one'图层activation='relu',您将获得所需的结果(在这个简单的设置中)。

问题是relu单位。在这样一个简单的网络中,它不是一个很好的选择。ReLU 很有可能从“死”开始——如果第一层神经元的权重为负(50/50 的机会),那么 0 和 1 输入都会产生 0 输出并且没有梯度,因此网络无法学会将它们分开。

改为tanh改为将完全解决问题,网络将轻松学习这种关系。这也适用于“泄漏的”ReLU 或任何其他没有 ReLU 简单截止的单元。

您的模型的泄漏 ReLU 版本如下所示:

model.add(keras.layers.Dense(1, input_dim=1, init='uniform' ))
model.add(keras.layers.advanced_activations.LeakyReLU(alpha=0.01))
model.add(keras.layers.Dense(1, init='uniform', activation='sigmoid'))

在具有更复杂输入数据的更大/更深的网络中,ReLU 单元的这个缺点通常影响较小,并且可以更容易地解决。

答案是上面的代码大部分时间都像我认为的那样工作。由于某些随机性,程序的每次运行都会略有不同,有时这种随机性意味着程序不会找到 X 和 Y 之间的链接。解决这个问题的方法是多次运行程序。运行 10 次后,我得到了 8/10 次成功的结果。