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

Posted

技术标签:

【中文标题】使用神经网络学习分类值的分布【英文标题】:Use neural network to learn distribution of values for classification 【发布时间】:2019-09-13 05:24:58 【问题描述】:

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

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

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

现在我想训练一个神经网络,它可以学习将0.40.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 参数是关键。非常感谢。

以上是关于使用神经网络学习分类值的分布的主要内容,如果未能解决你的问题,请参考以下文章

论文泛读183用于小样本文本分类的元学习对抗域适应网络

论文泛读183用于小样本文本分类的元学习对抗域适应网络

深度学习-------算法岗面试题

第21集 python机器学习:神经网络算法(续)

教你如何用Keras搭建分类神经网络

Keras深度学习实战——使用卷积神经网络实现性别分类