2017-01-17 5 views
3

현재 사용자 지정 손실 계층을 구현 중이고 그 과정에서 objective.py 파일 [1]의 평균 제곱 오류 구현을 우연히 발견했습니다. 나는 평균이 각 미니 배치 (텐서의 0 축)에서 각 출력마다 샘플을 통해 따로 따로 수행되었다고 항상 생각했기 때문에이 손실 계산에 대한 나의 이해에서 뭔가를 놓쳤다.하지만 평균은 실제로 하나의 벡터에서 마지막 축을 가로 질러 행해지므로 출력을 가로 질러 행해지는 것을 의미합니다. 내 맞춤형 손실 레이어에서 작업하는 동안 우연히 발견했습니다. 출력의 일부를 할인하여 특정 장소의 교육용 출력을 특정 값으로 설정해야하기 때문입니다. 어쨌든, 평균 제곱 오류에 대한 나의 이해가 올바르지 않습니까? 왜 Keras가 마지막 축을 사용하고 1xn 출력 벡터를 1x1 출력 벡터로 바꿀까요?Keras 평균 제곱 오류 손실 계층

감사합니다.

[1] https://github.com/fchollet/keras/blob/master/keras/objectives.py#L7

+0

K.mean의 의미는 무엇이라고 생각하십니까? :) –

+0

죄송합니다 - 제 질문을 조정했습니다. 나는 제곱이 어디에서 일어나는 지 보지 못했다는 것을 의미했다. –

+0

K.square –

답변

5

MSE를 손실에 대한 문제의 코드는 다음이다 : 여기

def mean_squared_error(y_true, y_pred): 
    return K.mean(K.square(y_pred - y_true), axis=-1) 

먼저 y_pred 및 y_true 감산되고, 그 결과는 K.square로 전달되는 등의 기대치에 도달하면 매개 변수의 제곱을 반환하고 그 결과는 평균을 계산하는 K.mean에 주어집니다.

그래서 코드는 분명히 할 일을하고 있습니다. 왜 마지막 축을 조작했는지에 관해서는 클래스와는 아무런 관련이 없습니다. 단지 관례에 불과합니다. 일반적으로 MSE 정의에는 클래스가 없습니다.

+0

아, 코드에서 K.square를 놓친 것 같습니다. 부스. 개인 네트워크에 있습니다. 불행히도 코드를 복사/붙여 넣기 할 수 없으며 손으로 잼해야합니다. 이 경우 부적절하게 손에 걸렸습니다. 따라서 당신은 제가 마지막에 물었던 마지막 질문에 대해 옳습니다. –

+0

답변 해 주셔서 감사합니다. btw! 그러나 축은 정말로 내 질문의 원인입니다. 실제로 그들은 축 = 0 대신에 axis = -1을 사용한다는 것과 네트워크를 통과하는 텐서를 어떻게 정의 할 것인가에 대한 관례가 있기 때문에 axis = 0 대신에 -1을 사용한다는 것이 나에게 매우 큰 의미를 부여합니다. 그들은 배치 크기를 텐서의 첫 번째 차원으로 사용하도록 강요합니다. 벡터에서 출력의 단일 값 집합에 대해 강제로 마지막 차원이되도록합니다. 이것은 그들이 각 개별적으로가 아니라 모든 출력을 통해 손실을 감수하고 있음을 의미합니다. –

+0

나는 내 복사에서 내가 뭘 잘못했는지 안다. 실수로 mean_squared 대신 mean_absolute_error를 복사했습니다. 그 부분은 고정되어 있지만 축 문제는 여전히 나를 귀찮게합니다. –

2

저는 동료들과 대화를 나누고 나서이 상황을 이해하고 문제에 대한 적절한 해결책을 가지고 있다고 생각합니다. Theano가 GPU에서 행렬 연산을 실행하는 지연된 텐서 함수를 제공한다는 것을 알았지 만, Keras의 손실 함수는 컴파일 된 theano 실행 그래프가 실제로 캐시 할만큼 똑똑한 방식으로 작성된다는 점을 인식하지 못했습니다. 네트워크를 통해 손실 값을 적절히 역 전파 할 수 있습니다. 내가 만들고있는 네트워크 유형 때문에, Theano가 함수에 의해 계산 된 후에 Theano가 실제로 손실을 어떻게 처리하는지 완전히 이해하지 않고서는 내 자신의 맞춤형 손실 함수를 작성했습니다.

내가 말할 수있는 것부터 Keras의 마지막 축 사용이 ​​문제가된다는 것이 내 관심사였다. 필자의 경우에는 완전 컨볼 루션 (full-convolutional) 깊은 신경망이 있고 손실 함수에 대한 입력은 (x, 7, 16, 16)이고 여기서 x는 미니 배치의 크기입니다. 일반적으로 신경망은 첫 번째 차원이 미니 배치 크기이고 두 번째 (일반적으로 마지막) 차원이 출력 벡터의 실제 크기 인 행렬을 출력합니다. 이 때문에 평균 제곱 오류의 실제 "평균"부분을 수행하기 위해 출력 텐서의 마지막 축을 사용하는 것은 정확하지 않습니다. 대신 축은 백 - 전파에 대해 구별해야하는 실제 회귀 출력 특성 7 가지이므로 0부터 시작해야합니다 (0부터 시작하는 인덱싱의 경우).

저는 원래 축 = -1이 정확하지 않을 수 있다는 것을 알았고 제가 왜이 문제를 게시 한 이유는 그 이유를 설명 할 수 없었기 때문입니다. 신경 네트워크 뒤에있는 수학에 뛰어 들어야하기 때문에 오랜 시간이 걸렸습니다.하지만 마침내 그 차이를 해결할 수있었습니다 (나는라고 생각합니다). 나는이 같은 문제 또는 테아 노 텐서 프레임 워크에 대한 이해의 갭을 경험할 미래의 사람들을 위해이 응답을 게시하고 있습니다.

1

하자 세부 손실이 모든 손실 계산의 axis=-1이 올바른지 보여 Keras에서 계산하는 방법의 단계 :

  • 그래서 우리는 우리가 compile에 전달합니다 losses.py의 손실을 선택 우리 모델의 방법.

  • compile에서 총 손실이 계산됩니다. 여러 단계에서 발생합니다. The first step은 모델의 각 출력에 대해 하나씩 손실 목록을 만듭니다.

  • 이 첫 번째 단계는 호출 문서에 따른 계좌로 weightsmask 파라미터를 가지고 새로운 목적 함수를 리턴 _weighted_masked_objective 기본적
  • '목적 함수 마스킹 샘플 가중치에 대한 지원을 추가'_weighted_masked_objective 사용자는 fit 메서드를 사용할 때 제공합니다.

질문에 중요한 줄만 포함하도록 코드를 자르면 이와 비슷한 결과가 나옵니다.

def _weighted_masked_objective(fn): 
    def weighted(y_true, y_pred, weights, mask=None): 
      score_array = fn(y_true, y_pred) # Compute loss as in losses.py 
      return K.mean(score_array) # Average over all axis 

class Model(Container): 
    def compile(self, optimizer, loss, metrics=None, loss_weights=None, 
       sample_weight_mode=None, weighted_metrics=None, 
       target_tensors=None, **kwargs): 
     weighted_losses = [_weighted_masked_objective(fn) for fn in loss_functions] 

그래서 마지막에, 손실은 참으로 모든 차원에 걸쳐 평균되고, axis=-1의 사용은 코드

NB에서 다른 지점에서 마스킹 및 손실의 가중치를 활성화 단지 우아한 방법입니다 : 질문에 대답하지 않기 때문에 다른 단계를 설명하지 않았습니다.

관련 문제