Keras如何在多标签学习中更新权重(实现方式)

时间:2018-03-02 13:24:15

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

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

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

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. 是否分别计算每个输出的错误,然后进行一次整体更新网络?

  3. 编辑:DanielMöller回答后的更新问题

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

    对于大小为1的batch_size,我的问题可能更清晰。

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

    对于未在输出之间共享的权重(从隐藏层到输出的权重),它们是根据模型所做的错误更新的,计算为所有输出上的错误总和,或者只是一个具体输出?

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

2 个答案:

答案 0 :(得分:0)

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

每处理完一批后,它将更新网络。所以,既不是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]
]

一批输出。

无论是内部循环还是进行矩阵计算所需的任何东西,它都是我们看不见的,无法访问的。

答案 1 :(得分:0)

我想在Daniel的答案中添加binary_crossentropy对应于tf.nn.sigmoid_cross_entropy_with_logits张量流中的实际操作,这确实计算了所有标签的单个标量(请参阅{{ 3}}了解详情)。个别损失从未实际计算过,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)

因此,所有渐变更新都基于此减少的损失值。 Theano T.nnet.binary_crossentropy功能和CNTK是相同的。