Keras 자체 Loss Function 에 대한 깊이 있 는 연구

9938 단어 KerasLossFunction
본 고 는 Keras 가 가지 고 있 는 자주 사용 하 는 Loss Function 을 연구 하고 자 한다.
1. categorical_crossentropy VS. sparse_categorical_crossentropy


이들 의 주요 차 이 는 integer tensor 인지 아 닌 지 를 입력 하 는 것 이다.문서 에서 우 리 는 양자 가 어떻게 선택 하 는 지 에 대한 설명 을 찾 을 수 있다.

여기 있 는 Integer target 과 Categorical target 을 설명 합 니 다.실제로 Integer target 은 독 열 인 코딩 을 통 해 Categorical target 이 되 었 습 니 다.예 를 들 어 설명 합 니 다.

(   5)
Integer target: [1,2,4]
Categorical target: [[0. 1. 0. 0. 0.]
					 [0. 0. 1. 0. 0.]
					 [0. 0. 0. 0. 1.]]
Keras 에서 to 를 제 공 했 습 니 다.categorical 방법 으로 양자 의 전환 을 실현 합 니 다.

from keras.utils import to_categorical
categorical_labels = to_categorical(int_labels, num_classes=None)
categorical 주의crossentropy 와 sparsecategorical_crossentropy 의 입력 매개 변수 output 는 모두 softmax 가 출력 한 tensor 입 니 다.우 리 는 모두 softmax 의 출력 이 여러 분포 에 복종 한 다 는 것 을 안다.
그래서 categoricalcrossentropy 와 sparsecategorical_crossentropy 는 여러 분류 문제 에 응용 해 야 합 니 다.
우 리 는 이 두 개의 소스 코드 를 다시 보고 검증 합 시다.

https://github.com/tensorflow/tensorflow/blob/r1.13/tensorflow/python/keras/backend.py
--------------------------------------------------------------------------------------------------------------------
def categorical_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`.
  """
  rank = len(output.shape)
  axis = axis % rank
  # Note: nn.softmax_cross_entropy_with_logits_v2
  # expects logits, Keras expects probabilities.
  if not from_logits:
    # scale preds so that the class probas of each sample sum to 1
    output = output / math_ops.reduce_sum(output, axis, True)
    # manual computation of crossentropy
    epsilon_ = _to_tensor(epsilon(), output.dtype.base_dtype)
    output = clip_ops.clip_by_value(output, epsilon_, 1. - epsilon_)
    return -math_ops.reduce_sum(target * math_ops.log(output), axis)
  else:
    return nn.softmax_cross_entropy_with_logits_v2(labels=target, logits=output)
--------------------------------------------------------------------------------------------------------------------
def sparse_categorical_crossentropy(target, output, from_logits=False, axis=-1):
  """Categorical crossentropy with integer targets.
  Arguments:
      target: An integer tensor.
      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`.
  """
  rank = len(output.shape)
  axis = axis % rank
  if axis != rank - 1:
    permutation = list(range(axis)) + list(range(axis + 1, rank)) + [axis]
    output = array_ops.transpose(output, perm=permutation)
  # Note: nn.sparse_softmax_cross_entropy_with_logits
  # expects logits, Keras expects probabilities.
  if not from_logits:
    epsilon_ = _to_tensor(epsilon(), output.dtype.base_dtype)
    output = clip_ops.clip_by_value(output, epsilon_, 1 - epsilon_)
    output = math_ops.log(output)
  output_shape = output.shape
  targets = cast(flatten(target), 'int64')
  logits = array_ops.reshape(output, [-1, int(output_shape[-1])])
  res = nn.sparse_softmax_cross_entropy_with_logits(
      labels=targets, logits=logits)
  if len(output_shape) >= 3:
    # If our output includes timesteps or spatial dimensions we need to reshape
    return array_ops.reshape(res, array_ops.shape(output)[:-1])
  else:
    return res
categorical_crossentropy 가 교차 엔 트로피 를 계산 할 때 사용 하 는 것 은 nn.softmaxcross_entropy_with_logits_v2(labels=targets,logits=logits),sparsecategorical_crossentropy 는 N.sparse 를 사용 합 니 다.softmax_cross_entropy_with_logits(labels=targets,logits=logits)는 본질 적 으로 다 르 지 않 습 니 다.입력 매개 변수 logits 에 대한 요구 가 다 를 뿐 v2 는 logits 와 labels 형식 이 같 고(즉,요소 도 독 열)sparse 는 logits 의 요 소 를 수치 로 요구 합 니 다.위의 Integer format 과 Categorical format 의 대비 의미 와 유사 합 니 다.
다시 말 하면 categoricalcrossentropy 와 sparsecategorical_crossentropy 는 입력 매개 변수 target 유형 상의 차이 일 뿐 loss 의 계산 은 본질 적 으로 차이 가 없 으 며 교차 엔트로피 입 니 다.양 자 는 다 분류(Multi-class)임 무 를 대상 으로 한다.
2. Binary_crossentropy

이원 교차 엔트로피 는 이름 에서 알 수 있 듯 이 이 loss function 은 2 분류 에 적 용 될 수 있 습 니 다.문서 에 상세 한 설명 이 없 으 니 원본 코드 를 직접 보 세 요.

https://github.com/tensorflow/tensorflow/blob/r1.13/tensorflow/python/keras/backend.py
--------------------------------------------------------------------------------------------------------------------
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.sigmoid_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)
소스 코드 에서 N.sigmoid 를 사용 한 계산 을 볼 수 있 습 니 다.cross_entropy_with_logits,tensorflow 를 잘 아 는 사람 은 이 손실 함 수 를 잘 알 아야 합 니 다.간단 한 2 분류 에 도 사용 할 수 있 고 다 중 태그 작업 에 도 사용 할 수 있 습 니 다.또한 광범 위 하 게 응용 되 고 샘플 이 합 리 적 인 상황 에서(예 를 들 어 유형 불 균형 등 문제 가 존재 하지 않 는 다)상황 에서 직접 사용 할 수 있 습 니 다.
추가:keras 사용자 정의 loss function 의 간단 한 방법
먼저 Keras 에서 우리 가 자주 사용 하 는 목표 함수(예 를 들 어 mse,mae 등)가 어떻게 정의 되 는 지 보 세 요.

from keras import backend as K
def mean_squared_error(y_true, y_pred):
    return K.mean(K.square(y_pred - y_true), axis=-1)
def mean_absolute_error(y_true, y_pred):
    return K.mean(K.abs(y_pred - y_true), axis=-1)
def mean_absolute_percentage_error(y_true, y_pred):
    diff = K.abs((y_true - y_pred) / K.clip(K.abs(y_true), K.epsilon(), np.inf))
    return 100. * K.mean(diff, axis=-1)
def categorical_crossentropy(y_true, y_pred):
    '''Expects a binary class matrix instead of a vector of scalar classes.
    '''
    return K.categorical_crossentropy(y_pred, y_true)
def sparse_categorical_crossentropy(y_true, y_pred):
    '''expects an array of integer classes.
    Note: labels shape must have the same number of dimensions as output shape.
    If you get a shape error, add a length-1 dimension to labels.
    '''
    return K.sparse_categorical_crossentropy(y_pred, y_true)
def binary_crossentropy(y_true, y_pred):
    return K.mean(K.binary_crossentropy(y_pred, y_true), axis=-1)
def kullback_leibler_divergence(y_true, y_pred):
    y_true = K.clip(y_true, K.epsilon(), 1)
    y_pred = K.clip(y_pred, K.epsilon(), 1)
    return K.sum(y_true * K.log(y_true / y_pred), axis=-1)
def poisson(y_true, y_pred):
    return K.mean(y_pred - y_true * K.log(y_pred + K.epsilon()), axis=-1)
def cosine_proximity(y_true, y_pred):
    y_true = K.l2_normalize(y_true, axis=-1)
    y_pred = K.l2_normalize(y_pred, axis=-1)
    return -K.mean(y_true * y_pred, axis=-1)
따라서 상기 방법 을 본 떠 특정 작업 의 목표 함 수 를 스스로 정의 할 수 있 습 니 다.예 를 들 어 예측 치 와 실제 값 의 차 이 를 정의 합 니 다.

from keras import backend as K
def new_loss(y_true,y_pred):
    return K.mean((y_pred-y_true),axis = -1)
그리고 자신 이 정의 한 목표 함 수 를 사용 하여 컴 파일 합 니 다.

from keras import backend as K
def my_loss(y_true,y_pred):
    return K.mean((y_pred-y_true),axis = -1)
model.compile(optimizer=optimizers.RMSprop(lr),loss=my_loss,
metrics=['accuracy'])
이상 은 개인 적 인 경험 이 므 로 여러분 에 게 참고 가 되 기 를 바 랍 니 다.여러분 들 도 저 희 를 많이 응원 해 주시 기 바 랍 니 다.

좋은 웹페이지 즐겨찾기