使用神经网络学习分类值的分布

时间:2019-04-24 01:28:12

标签: python tensorflow machine-learning keras neural-network

使用神经网络学习分类值的分布

目标是使用神经网络对一维输入进行分类。应该分类两个类别,AB。用于确定类别的每个输入都是介于0.01.0之间的数字。

class A的输入值在01之间均匀分布,如下所示: class A distribution

class B的输入值都在0.40.6的范围内,如下所示:

class B distribution

现在,我想训练一个神经网络,该网络可以学习将0.40.6范围内的值分类为B,其余分类为A。所以我需要一个可以近似一个类的上下限的神经网络。我以前的尝试没有成功-神经网络对于所有输入总是返回50%的概率,并且损失不会减少。

在Python中使用Tensorflow和Keras,我已经训练了以下简单模型:

model = keras.Sequential([
    keras.layers.Dense(1),
    keras.layers.Dense(5, activation=tf.nn.relu),
    keras.layers.Dense(5, activation=tf.nn.relu),
    keras.layers.Dense(2, activation=tf.nn.softmax)
])
model.compile(optimizer='adam', loss='mean_squared_error', metrics=['accuracy'])

(完整的培训脚本在下面链接)

从侧面讲,我可以想象神经网络是这样工作的:有些神经元仅在0.4以下触发,有些仅在0.6以上触发。如果这两组神经元中的任何一个触发,则为A类,如果都不触发,则为B类。不幸的是,事实并非如此。

如何使用神经网络对上述输入进行分类?

-

示例脚本:https://pastebin.com/xNJUqXyU

1 个答案:

答案 0 :(得分:2)

这里的模型体系结构可能会发生一些变化。

首先,损失不应为loss='mean_squared_error',最好使用loss='binary_crossentropy',它更适合于二进制分类问题。在这里我不会解释它们之间的区别,这可以在Keras文档中轻松找到。

您还需要更改最后一层的定义。您只需要最后一个节点,该节点将是属于类别1的概率(因此,拥有一个节点属于类别0的概率是多余的),并且您应该使用activation=tf.nn.sigmoid而不是softmax。

您可以做的其他事情是定义类权重以处理数据的不平衡。鉴于您在此处定义样本的方式,将第0类的权重设为第1类的4倍似乎很有意义。

完成所有这些更改后,您应该会看到类似以下的内容:

model = keras.Sequential([
keras.layers.Dense(1),
keras.layers.Dense(5, activation=tf.nn.relu),
keras.layers.Dense(5, activation=tf.nn.relu),
keras.layers.Dense(1, activation=tf.nn.sigmoid)
])

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

model.fit(np.array(inputs_training), np.array(targets_training), epochs=5, verbose=1, class_weight = {0:4, 1:1})

这使我在验证集上的准确度达到了96%,并且每个时期的确减少了损失。

(顺便说一句,在我看来,决策树在这里似乎更合适,因为它的行为表现得很像您描述的执行分类的目的)