使用神经网络学习分类值的分布
Posted
技术标签:
【中文标题】使用神经网络学习分类值的分布【英文标题】:Use neural network to learn distribution of values for classification 【发布时间】:2019-09-13 05:24:58 【问题描述】:目的是使用神经网络对一维输入进行分类。有两个类应该分类,A
和B
。每个用于确定类的输入都是一个介于0.0
和1.0
之间的数字。
class A
的输入值均匀分布在 0
和 1
之间,如下所示:
class B
的输入值都在0.4
到0.6
的范围内,如下所示:
现在我想训练一个神经网络,它可以学习将0.4
到0.6
范围内的值分类为B
,其余的分类为A
。所以我需要一个可以近似一个类的上限和下限的神经网络。我之前的尝试都没有成功——神经网络总是为所有输入返回 50% 的概率,并且在 epoch 期间损失不会减少。
在 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】:您的模型架构中可能会发生一些变化。
首先,loss不应该是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% 的验证集准确率,并且每个 epoch 确实减少了损失。
(顺便说一句,在我看来,决策树更适合这里,因为它的行为会像您描述的那样明确地执行分类)
【讨论】:
你是绝对的英雄!所有这些改进都是必不可少的并且非常有用,尤其是 class_weight 参数是关键。非常感谢。以上是关于使用神经网络学习分类值的分布的主要内容,如果未能解决你的问题,请参考以下文章