我对机器学习有点新意,我想做一个简单的实验来更熟悉神经网络自动编码器:制作一个非常基本的自动编码器来学习身份功能.
我正在使用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个时代,使用不同的优化器,丢失函数以及添加L1和L2活动正则化器.结果各不相同,但我得到的最好的仍然非常糟糕,看起来没有原始数据,只是在同一数值范围内.数据只是一些数字在1.1左右振荡.我不知道激活层是否对这个问题有意义,我应该使用它吗?
如果一层的"神经网络"无法学习像身份函数这样简单的东西,我怎么能指望它学习更复杂的东西呢?我究竟做错了什么?
为了获得更好的上下文,这里有一种生成与我正在使用的数据集非常相似的数据集的方法:
X = np.random.normal(1.1090579, 0.0012380764, (139336, 84))
我怀疑值之间的差异可能太小.损失函数最终具有不错的值(大约1e-6
),但结果的精确度不足以使其具有与原始数据类似的形状.也许我应该以某种方式扩展/规范它?谢谢你的建议!
最后,正如所建议的那样,问题在于数据集在84个值之间的变化太小,因此得到的预测实际上在绝对值(损失函数)方面相当不错,但是将其与原始数据进行比较,变化是遥远.我通过将样本平均值周围的84个值标准化并除以样本的标准偏差来解决它.然后我使用原始均值和标准差来对另一端的预测进行非规范化.我想这可以通过几种不同的方式完成,但我通过使用在张量上操作的一些Lambda层将这种规范化/非规范化添加到模型本身中来实现.这样,所有数据处理都被整合到模型中,这使得它更好地使用.如果您想查看实际代码,请与我们联系.