#ifndef TH_GENERIC_FILE #define TH_GENERIC_FILE "generic/BCECriterion.c" #else #define EPS 1e-12 void THNN_(BCECriterion_updateOutput)(THNNState *state, THTensor *input, THTensor *target, THTensor *output, bool sizeAverage, THTensor *weights) { THNN_CHECK_NELEMENT(input, target); THNN_CHECK_NELEMENT(input, weights); THNN_CHECK_DIM_SIZE(output, 1, 0, 1); real sum = 0; if(weights) TH_TENSOR_APPLY3(real, input, real, target, real, weights, real x = *input_data; real y = *target_data; real w = *weights_data; THAssertMsg(x >= 0. && x <= 1., "input value should be between 0~1, but got %f", (double) x); sum -= (log(x + EPS) * y + log(1. - x + EPS) * (1. - y)) * w; ) else TH_TENSOR_APPLY2(real, input, real, target, real x = *input_data; real y = *target_data; THAssertMsg(x >= 0. && x <= 1., "input value should be between 0~1, but got %f", (double) x); sum -= log(x + EPS) * y + log(1. - x + EPS) * (1. - y); ); if (sizeAverage) sum /= THTensor_(nElement)(input); THTensor_(set1d)(output, 0, sum); } void THNN_(BCECriterion_updateGradInput)(THNNState *state, THTensor *input, THTensor *target, THTensor *gradInput, bool sizeAverage, THTensor *weights) { THNN_CHECK_NELEMENT(input, target); THNN_CHECK_NELEMENT(input, weights); real norm = (sizeAverage ? 1./((real)THTensor_(nElement)(input)) : 1.); THTensor_(resizeAs)(gradInput, input); TH_TENSOR_APPLY3(real, gradInput, real, input, real, target, real x = *input_data; real y = *target_data; *gradInput_data = - norm * (y - x) / ((1. - x + EPS) * (x + EPS)); ); if(weights) THTensor_(cmul)(gradInput, gradInput, weights); } #undef EPS #endif