我写了一个简单的神经网络/MLP,我得到了一些奇怪的准确度值,并想仔细检查一下。
这是我想要的设置:具有 913 个样本和 192 个特征 (913,192) 的特征矩阵。我正在对 2 个结果进行分类,因此我的标签是二元的并且具有形状 (913,1)。 1 个隐藏层,包含 100 个单元(目前)。所有激活将使用 tanh,所有损失将使用 l2 正则化,并使用 SGD 进行优化
代码如下。它是用 Keras 框架用 python 编写的(http://keras.io/),但我的问题并非特定于 Keras
input_size = 192
hidden_size = 100
output_size = 1
lambda_reg = 0.01
learning_rate = 0.01
num_epochs = 100
batch_size = 10
model = Sequential()
model.add(Dense(input_size, hidden_size, W_regularizer=l2(lambda_reg), init='uniform'))
model.add(Activation('tanh'))
model.add(Dropout(0.5))
model.add(Dense(hidden_size, output_size, W_regularizer=l2(lambda_reg), init='uniform'))
model.add(Activation('tanh'))
sgd = SGD(lr=learning_rate, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='mean_squared_error', optimizer=sgd, class_mode="binary")
history = History()
model.fit(features_all, labels_all, batch_size=batch_size, nb_epoch=num_epochs, show_accuracy=True, verbose=2, validation_split=0.2, callbacks=[history])
score = model.evaluate(features_all, labels_all, show_accuracy=True, verbose=1)
我想仔细检查我编写的代码在我选择的参数及其值等方面实际上是否正确。
使用上面的代码,我得到的训练和测试集准确率徘徊在 50-60% 左右。也许我只是使用了不好的功能,但我想测试看看可能出了什么问题,所以我手动将所有标签和功能设置为应该可预测的内容:
labels_all[:500] = 1
labels_all[500:] = 0
features_all[:500] = np.ones(192)*500
features_all[500:] = np.ones(192)
因此,我将前 500 个样本的标签设置为 1,其他所有样本都标记为 0。我将前 500 个样本中的每个样本的所有特征手动设置为 500,所有其他特征(对于其余样本)得到一个 1
当我运行此程序时,训练准确率约为 65%,验证准确率约为 0%。我原本期望这两个精度都非常高/几乎完美 - 这是不正确的吗?我的想法是,具有极高值的特征都具有相同的标签(1),而具有低值的特征则具有 0 标签
大多数情况下,我只是想知道我的代码/模型是否不正确,或者我的逻辑是否错误。
我不知道那个库,所以我无法告诉你这是否正确实现,但它看起来合法。
我认为你的问题在于激活函数 - tanh(500)=1 和 tanh(1)=0.76。这个差异对我来说似乎太小了。尝试使用 -1 而不是 500 进行测试,并将实际数据标准化为 [-2, 2] 左右。如果您需要完整的实数范围,请尝试使用线性激活函数。如果你只关心实数的正半部分,我建议softplus或ReLU。我检查过,所有这些功能都是由 Keras 提供的。
您也可以尝试对输出进行阈值处理 - 当期望 1 时回答 0.75,当期望 0 时回答 0.25 是有效的,但可能会影响您的准确性。
另外,尝试调整你的参数。我可以建议(根据我自己的经验)你会使用:
我想说,学习率、epoch 数、动量和 lambda 是这里最重要的因素 - 按从最重要到最不重要的顺序排列。
PS。我刚刚发现你正在统一初始化你的权重(这甚至是一个词吗?我不是母语人士......)。我无法告诉你为什么,但我的直觉告诉我这是一个坏主意。我会选择随机的初始权重。