【问题标题】:How does Keras update weights in multilabel learning (implementation-wise)Keras 如何在多标签学习中更新权重(实现方式)
【发布时间】:2018-08-10 17:18:35
【问题描述】:

假设我想使用神经网络和 Keras 解决多标签问题。

输出通常采用 y=[0, 1, 0, 1, 0, 0] 的形式,并且很容易使用二进制交叉熵和 sigmoid 来训练网络(例如,参见下面的代码)。

from keras.models import Sequential
from keras.layers import Dense

model = Sequential()
model.add(Dense(6, activation='relu')#Add 1 hidden layer
                                     #with 6 neurons, with relu activation
model.add(Dense(6, activation='sigmoid'))#Here we specify that we have 6 outputs
                                         #and we want outputs to be in [0,1]
model.compile(optimizer='Adam', loss='binary_crossentropy')
model.fit(xtrain, ytrain, batch_size=128)

当我在最后一行执行 fit 时,实现方面真正发生了什么?

  1. 网络是否更新多次次?在计算 6 个输出中的每一个的误差后一次,将其传播回来以升级权重?

  2. 它是否分别计算每个输出的误差,然后对网络进行一次整体更新?

编辑:Daniel Möller 回答后更新问题

model.fit(xtrain, ytrain, batch_size=1)

使用大小为 1 的 batch_size,我的问题可能更清楚。

在每次迭代中,我们从训练集中选择 1 个示例并进行前馈。然后,我们计算每个输出的误差。在这种情况下,问题如下:

对于未在输出之间共享的权重(从隐藏层到输出的权重),它们是根据模型产生的误差进行更新的,该误差计算为所有输出上的误差之和,还是仅按 1具体输出?

模型权重是根据误差总和更新一次,还是根据所有输出上的单个误差更新多次?

【问题讨论】:

    标签: machine-learning neural-network keras classification multilabel-classification


    【解决方案1】:

    对于所有效果,它应该被视为一个巨大的矩阵运算。

    每处理完一个批次,它就会更新网络。所以,1 和 2 都不是。

    它:3 - 它一次计算整个批次的误差,作为矩阵运算,然后对所有权重矩阵进行一次整体更新。但这将是多次更新,因为您将拥有多个大小为 128 的批次。

    Y 通常是这样的形式:

    [
        [1,0,0,1,0,0],
        [1,0,0,1,0,0],
        [0,0,0,1,1,0],
        [1,0,1,1,0,0]
    ]
    

    一批输出。


    无论它在内部进行循环还是进行矩阵计算所需的任何事情,它对我们来说都是不可见和不可访问的。

    【讨论】:

      【解决方案2】:

      我想在 Daniel 的回答中补充一点,binary_crossentropy 对应于 tensorflow 中的tf.nn.sigmoid_cross_entropy_with_logits 实际操作,它确实为所有标签计算了一个单个标量(有关详细信息,请参阅this question) .从来没有实际计算过单个损失,tensorflow 使用直接计算总和的公式。

      这里是源代码:

      def binary_crossentropy(target, output, from_logits=False):
        """Binary crossentropy between an output tensor and a target tensor.
      
        Arguments:
            target: A tensor with the same shape as `output`.
            output: A tensor.
            from_logits: Whether `output` is expected to be a logits tensor.
                By default, we consider that `output`
                encodes a probability distribution.
      
        Returns:
            A tensor.
        """
        # Note: nn.softmax_cross_entropy_with_logits
        # expects logits, Keras expects probabilities.
        if not from_logits:
          # transform back to logits
          epsilon_ = _to_tensor(epsilon(), output.dtype.base_dtype)
          output = clip_ops.clip_by_value(output, epsilon_, 1 - epsilon_)
          output = math_ops.log(output / (1 - output))
        return nn.sigmoid_cross_entropy_with_logits(labels=target, logits=output)
      

      所以所有梯度更新都是基于这个减少的损失值。 TheanoT.nnet.binary_crossentropy函数和CNTK是一样的。

      【讨论】:

        猜你喜欢
        • 2017-02-18
        • 2016-06-15
        • 1970-01-01
        • 2018-07-20
        • 2021-03-18
        • 1970-01-01
        • 2020-10-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多