【发布时间】:2017-05-24 09:17:55
【问题描述】:
总的来说,我对机器学习有点陌生,我想做一个简单的实验来更熟悉神经网络自动编码器:制作一个非常基本的自动编码器,可以学习恒等函数。
我使用 Keras 来让生活更轻松,所以我首先这样做是为了确保它可以正常工作:
# Weights are given as [weights, biases], so we give
# the identity matrix for the weights and a vector of zeros for the biases
weights = [np.diag(np.ones(84)), np.zeros(84)]
model = Sequential([Dense(84, input_dim=84, weights=weights)])
model.compile(optimizer='sgd', loss='mean_squared_error')
model.fit(X, X, nb_epoch=10, batch_size=8, validation_split=0.3)
正如预期的那样,在训练数据和验证数据中损失为零:
Epoch 1/10
97535/97535 [==============================] - 27s - loss: 0.0000e+00 - val_loss: 0.0000e+00
Epoch 2/10
97535/97535 [==============================] - 28s - loss: 0.0000e+00 - val_loss: 0.0000e+00
然后我尝试做同样的事情,但没有初始化身份函数的权重,期望经过一段时间的训练后它会学会它。它没有。我让它在不同的配置下运行了 200 个 epoch,使用了不同的优化器、损失函数,并添加了 L1 和 L2 活动正则化器。结果各不相同,但我得到的最好的结果仍然很糟糕,看起来与原始数据完全不同,只是在相同的数字范围内。 数据只是一些在 1.1 附近波动的数字。我不知道激活层是否对这个问题有意义,我应该使用一个吗?
如果这一层的“神经网络”不能学习像恒等函数这样简单的东西,我怎么能指望它学习更复杂的东西呢?我做错了什么?
编辑
为了获得更好的上下文,这里有一种方法可以生成与我正在使用的数据集非常相似的数据集:
X = np.random.normal(1.1090579, 0.0012380764, (139336, 84))
我怀疑这些值之间的差异可能太小了。损失函数最终具有不错的值(大约1e-6),但精度不足以使结果具有与原始数据相似的形状。也许我应该以某种方式对其进行缩放/标准化?感谢您的建议!
更新
最后,正如建议的那样,问题在于数据集在 84 个值之间的变化太小,因此结果预测在绝对值(损失函数)方面实际上非常好,但将其与原始数据进行比较,变化很遥远。我通过围绕样本均值对每个样本中的 84 个值进行归一化并除以样本的标准偏差来解决它。然后我使用原始均值和标准差对另一端的预测进行非规范化。我想这可以通过几种不同的方式来完成,但我通过使用一些在张量上操作的 Lambda 层将这种规范化/非规范化添加到模型本身中来做到这一点。这样,所有的数据处理都被合并到模型中,这使得它更好地工作。如果您想查看实际代码,请告诉我。
【问题讨论】:
-
你用的是什么版本的keras?这个
model = Sequential(Dense(84, input_dim=84, weights=weights))在最新 (1.1.2) 中不起作用 -
@y300 对不起,我错过了
Dense层周围的[],因为Sequential的layers参数应该是一个可迭代的层。我现在修好了。顺便说一句,我正在使用 keras 1.2.0。 -
你能分享你的
X吗?optimizer='adam'对我来说效果很好
标签: machine-learning neural-network keras autoencoder