-
我最初是在使用神经网络对一些波形数据进行分类。在这个问题中,我有一个大约200大小的向量,类别数量是256。然而,损失值一直没有下降。
-
所以我在想,如果波形本身就是标签会怎样?例如,
$wave_i(x) = N(i/256.0, (1/10000)^2)$
,会被标记为i
,这里的N代表正态分布。 -
对于非常小的类别,比如32或64,神经网络运行良好,并且学习速度很快。
-
然而,当我将类别数量设为
classes = 256
时,学习速度变得难以忍受的慢,甚至根本没有学习。 -
我使用的模型非常简单。我认为这足以记忆输入和输出的关系。(为什么?你可以很容易地构造一个单元,当
abs(input - const) < eps
时输出1。)model = Sequential([ Dense(classes, input_dim=200), Activation('sigmoid'), Dense(classes * 2), Activation('sigmoid'), Dense(classes), Activation('softmax'),])
然后,我以批量大小为256输入数据,每个不同的标签出现一次。
-
结果是,经过2500个周期后,损失值达到
2.xxxx
,准确率达到0.07
,在3000个周期后停止变化。(准确率大约在0.09
到0.1
之间)
我知道更多的变量需要更多的时间来学习。然而,很明显,每个输出单元都应该很容易地与其他单元区分开来(我有非常不同的输入集)。
def generator(): while 1: data = [numpy.random.normal(i/255.0,1/10000.0,225).tolist() for i in range(0, classes)] labels = to_categorical([i for i in range(0, classes)], classes) yield (data,labels)
回答:
当输入和输出之间存在非常简单的关联时,比如你所探讨的这种情况,神经网络的优势可能无法完全发挥出来。神经网络足够灵活,可以拟合任何函数,但很少能做到完美。当你处理一个简单的函数时,你可能会发现神经网络的拟合存在缺陷,而其他模型可能表现得更好。
为了获得更好的拟合效果,你可以尝试以下几种方法(按我会尝试的顺序排列):
-
尝试不同的优化器。你没有提到你使用的是哪种优化器,但Keras库提供了几个选择。
-
神经网络在训练和预测时对归一化后的输入特征表现更好。一个有效的选择是均值为0,标准差为1。在你的情况下,如果你在训练和测试时对每个批次进行预处理,如下所示:
data = (data - 0.5)/0.289
,可能会有所帮助。 -
增加隐藏层中神经元的数量,和/或更改激活函数。在这里,你的理想激活函数甚至可能类似于高斯分布(这样一个神经元就可以立即调整到每个类别),但这通常不是神经网络库中常见的。考虑删除中间层,只在softmax层之前设置一个隐藏层,例如
8*classes
个神经元。 -
在生成器中从输入示例中抽样,而不是每次都计算每个类别的示例。生成器可能过于规律——我曾见过经典的
xor
示例网络在重复输入相同数据时陷入类似你描述的情况。
* 更简单的网络模型看起来像这样:
model = Sequential([ Dense(classes * 8, input_dim=200), Activation('sigmoid'), Dense(classes), Activation('softmax'), ])