defbinary_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: tf.nn.sigmoid_cross_entropy_with_logits# expects logits, Keras expects probabilities.ifnotfrom_logits:# transform back to logits_epsilon=_to_tensor(epsilon(),output.dtype.base_dtype)output=tf.clip_by_value(output,_epsilon,1-_epsilon)output=tf.log(output/(1-output))returntf.nn.sigmoid_cross_entropy_with_logits(labels=target,logits=output)defcategorical_crossentropy(target,output,from_logits=False,axis=-1):"""Categorical crossentropy between an output tensor and a target tensor.
# Arguments
target: A tensor of the same shape as `output`.
output: A tensor resulting from a softmax
(unless `from_logits` is True, in which
case `output` is expected to be the logits).
from_logits: Boolean, whether `output` is the
result of a softmax, or is a tensor of logits.
axis: Int specifying the channels axis. `axis=-1`
corresponds to data format `channels_last`,
and `axis=1` corresponds to data format
`channels_first`.
# Returns
Output tensor.
# Raises
ValueError: if `axis` is neither -1 nor one of
the axes of `output`.
"""output_dimensions=list(range(len(output.get_shape())))ifaxis!=-1andaxisnotinoutput_dimensions:raiseValueError('{}{}{}'.format('Unexpected channels axis {}. '.format(axis),'Expected to be -1 or one of the axes of `output`, ','which has {} dimensions.'.format(len(output.get_shape()))))# Note: tf.nn.softmax_cross_entropy_with_logits# expects logits, Keras expects probabilities.ifnotfrom_logits:# scale preds so that the class probas of each sample sum to 1output/=tf.reduce_sum(output,axis,True)# manual computation of crossentropy_epsilon=_to_tensor(epsilon(),output.dtype.base_dtype)output=tf.clip_by_value(output,_epsilon,1.-_epsilon)return-tf.reduce_sum(target*tf.log(output),axis)else:returntf.nn.softmax_cross_entropy_with_logits(labels=target,logits=output)
其中BCE对应binary_crossentropy, CE对应categorical_crossentropy,两者都有一个默认参数from_logits,用以区分输入的output是否为logits(即为未通过激活函数的原始输出,这与TF的原生接口一致),但这个参数默认情况下都是false,所以通常情况下我们只需要关心 if not from_logits: 这个分支下的代码块即可。可以看到在binary_crossentropy中,就是简单的对output进行了一个还原,即将通过了激活函数的输出重新还原成logits,然后再调用TF的sigmoid_cross_entropy_with_logits函数。