machine-learning - 多标签分类收敛到全零

标签 machine-learning tensorflow multilabel-classification softmax

我正在尝试进行一对多多标签分类。我向每个分类器提供一批输入以及预期的标签。分类器使用 softmax 层进行输出来预测标签是或否。另外,我对每个分类器使用 softmax 交叉熵损失,并且每个分类器都尝试最小化其自身的损失。分类器在每一步中不断最小化损失,但预测每个标签为零。

我怀疑这是因为与整个数据集的大小相比,标签的正面示例非常小。

这是因为我训练模型的方式做错了,还是因为每个标签的数据分布不对称?

我希望限制负样本的数量,但只是想确保这是正确的方向。

这是我用于每个分类器的代码。我为每个标签都有一个分类器。

   self.w1 = tf.Variable(tf.truncated_normal([embedding_size, hidden_size],-0.1,0.1), dtype=tf.float32, name="weight1")
    self.b1 = tf.Variable(tf.zeros([hidden_size]), dtype=tf.float32, name="bias1")
    self.o1 = tf.sigmoid(tf.matmul(embed,self.w1) + self.b1)

    self.w2 = tf.Variable(tf.truncated_normal([hidden_size,2],-0.1,0.1), dtype=tf.float32, name="weight2")
    self.b2 = tf.Variable(tf.zeros([1]), dtype=tf.float32, name="bias2")
    self.logits = tf.matmul(self.o1, self.w2) + self.b2
    self.prediction = tf.nn.softmax(self.logits, name="prediction")

    self.loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=self.logits, labels=labels)) 
    self.optimizer = tf.train.AdamOptimizer(1e-3).minimize(self.loss)

编辑: 使用带有 sigmoid_cross_entropy_with_logits 的简单多标签分类器后,它仍然收敛到零。我发布了此版本的代码,以防有帮助:

    self.inp_x = tf.placeholder(shape=[None], dtype=tf.int32, name="inp_x")
    self.labels = tf.placeholder(shape=[None,num_labels], dtype=tf.float32, name="labels")
    self.embeddings = tf.placeholder(shape=[vocabulary_size,embedding_size], dtype=tf.float32,name="embeddings")
    self.embed = tf.nn.embedding_lookup(self.embeddings, self.inp_x)

    self.w1 = tf.Variable(tf.truncated_normal([embedding_size, hidden_size],-0.1,0.1), dtype=tf.float32, name="weight1")
    self.b1 = tf.Variable(tf.zeros([hidden_size]), dtype=tf.float32, name="bias1")
    self.o1 = tf.sigmoid(tf.matmul(self.embed,self.w1) + self.b1)
    self.w2 = tf.Variable(tf.truncated_normal([hidden_size,num_labels],-0.1,0.1), dtype=tf.float32, name="weight2")
    self.b2 = tf.Variable(tf.zeros([num_labels]), dtype=tf.float32, name="bias2")
    self.logits = tf.matmul(self.o1, self.w2) + self.b2
    self.prediction = tf.sigmoid(self.logits, name='prediction')

    self.loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits = self.logits, labels = self.labels))
    self.optimizer = tf.train.AdamOptimizer(1e-3).minimize(self.loss)

最佳答案

由于您没有提到实际的数据分布,因此很难猜测问题是出在您的代码还是数据集。但是,您可以尝试喂养一组均匀分布在各个类别中的集合并检查结果。如果问题确实是分布不均,您可以尝试以下操作:

  1. 通过复制实例来对正类(或少数类)进行过采样。
  2. 对多数类别进行欠采样。
  3. 使用加权损失函数。 Tensorflow 有一个名为 weighted_cross_entropy_with_logits 的内置函数,它提供了此功能,尽管仅适用于二元分类,您可以在其中指定要分配少数类别的 pos_weight
  4. 您还可以手动过滤负面实例,但此方法需要一些领域知识。

关于machine-learning - 多标签分类收敛到全零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43428357/

相关文章:

tensorflow keras评估函数

python - 如何将声音作为神经网络的输入?

machine-learning - 训练隐马尔可夫模型的问题和分类用途

python - CondaVerificationError : || ClobberError: Create a new conda environment with Python 2. 7.x 或 3.7.x

php - 将 XOR 神经网络修改为其他类型的神经网络

python - Sklearn - 如何预测所有目标标签的概率

c# - 使用仅在运行时已知的特征列的 DataTable 构建和训练模型的 ML.NET

python - 尝试 kfold cv 时出现类型错误 : only integer scalar arrays can be converted to a scalar index ,

python - 在 TensorFlow 模型中的每一行上使用 softmax 激活输出矩阵

r - MLR随机森林多标签获取特征重要性