def call(self, x): if len(x) != 2: raise Exception('input layers must be a list: mean and stddev') if len(x[0].shape) != 2 or len(x[1].shape) != 2: raise Exception('input shape is not a vector [batchSize, latentSize]') mean = x[0] stddev = x[1] if self.reg == 'bvae': # kl divergence: latent_loss = -0.5 * K.mean(1 + stddev - K.square(mean) - K.exp(stddev), axis=-1) # use beta to force less usage of vector space: # also try to use <capacity> dimensions of the space: latent_loss = self.beta * K.abs(latent_loss - self.capacity/self.shape.as_list()[1]) self.add_loss(latent_loss, x) elif self.reg == 'vae': # kl divergence: latent_loss = -0.5 * K.mean(1 + stddev - K.square(mean) - K.exp(stddev), axis=-1) self.add_loss(latent_loss, x) epsilon = K.random_normal(shape=self.shape, mean=0., stddev=1.) if self.random: # 'reparameterization trick': return mean + K.exp(stddev) * epsilon else: # do not perform random sampling, simply grab the impulse value return mean + 0*stddev # Keras needs the *0 so the gradinent is not None
def correlation_coefficient_loss(y_true, y_pred): x = y_true y = y_pred mx = K.mean(x) my = K.mean(y) xm, ym = x-mx, y-my r_num = K.sum(tf.multiply(xm,ym)) r_den = K.sqrt(tf.multiply(K.sum(K.square(xm)), K.sum(K.square(ym)))) r = r_num / r_den r = K.maximum(K.minimum(r, 1.0), -1.0) return 1 - K.square(r)
def yolo_loss(args, anchors, num_classes, ignore_thresh=.5, print_loss=False): '''Return yolo_loss tensor Parameters ---------- yolo_outputs: list of tensor, the output of yolo_body or tiny_yolo_body y_true: list of array, the output of preprocess_true_boxes anchors: array, shape=(N, 2), wh num_classes: integer ignore_thresh: float, the iou threshold whether to ignore object confidence loss Returns ------- loss: tensor, shape=(1,) ''' num_layers = len(anchors) // 3 # default setting yolo_outputs = args[:num_layers] y_true = args[num_layers:] anchor_mask = [[6, 7, 8], [3, 4, 5], [0, 1, 2] ] if num_layers == 3 else [[3, 4, 5], [1, 2, 3]] input_shape = K.cast( K.shape(yolo_outputs[0])[1:3] * 32, K.dtype(y_true[0])) grid_shapes = [ K.cast(K.shape(yolo_outputs[l])[1:3], K.dtype(y_true[0])) for l in range(num_layers) ] loss = 0 m = K.shape(yolo_outputs[0])[0] # batch size, tensor mf = K.cast(m, K.dtype(yolo_outputs[0])) # if print_loss: # grid_shapes = tf.Print(grid_shapes, [grid_shapes], message='grid_shapes: ') # y_true = tf.Print(y_true, [y_true], message='y_true: ') for l in range(num_layers): object_mask = y_true[l][..., 4:5] true_class_probs = y_true[l][..., 5:] """ grid 是 [[0,0],[1,0],[2,0],... [0,1],[1,1],[2,1],... [0,2],[1,2],[2,2],... ] grid_shapes= [[7,10],[14,20]] """ # NOTE 这里的pred_xy, pred_wh是用来计算ignore mask的, grid, raw_pred, pred_xy, pred_wh = yolo_head(yolo_outputs[l], anchors[anchor_mask[l]], num_classes, input_shape, calc_loss=True) # if print_loss: # # grid = tf.Print(grid, [grid], message='grid: ', summarize=50) # # grid_shapes = tf.Print(grid_shapes, [grid_shapes], message='grid_shapes: ', summarize=50) # # K.print_tensor(grid, message='grid: ') pred_box = K.concatenate([pred_xy, pred_wh]) # Darknet raw box to calculate loss. # 这里也是吧 true xy wh 都转换到全局 y_true_xy = y_true[l][..., :2] y_true_wh = y_true[l][..., 2:4] # if print_loss: # y_true_xy = tf.Print(y_true_xy, [y_true_xy], message='y_true_xy: ') # y_true_wh = tf.Print(y_true_wh, [y_true_wh], message='y_true_wh: ') # NOTE 【0-1】乘上grid 的wh 得到 【0-7】 和 【0-10】之间的值,然后减去gird,得到相对grid的【0-1】之间的值 raw_true_xy = y_true_xy * grid_shapes[l][::-1] - grid # NOTE 【0-1】之间先转换成全局,再除anchor,再log。就是原始yolo wh预测的值 raw_true_wh = K.log(y_true_wh / anchors[anchor_mask[l]] * input_shape[::-1]) raw_true_wh = K.switch(object_mask, raw_true_wh, K.zeros_like(raw_true_wh)) # avoid log(0)=-inf # 这个box_loss_scale是 全局的【0-1】wh乘积 box_loss_scale = 2 - y_true[l][..., 2:3] * y_true[l][..., 3:4] # Find ignore mask, iterate over each of batch. ignore_mask = tf.TensorArray(K.dtype(y_true[0]), size=1, dynamic_size=True) object_mask_bool = K.cast(object_mask, 'bool') # 这里计算 def loop_body(b, ignore_mask): true_box = tf.boolean_mask(y_true[l][b, ..., 0:4], object_mask_bool[b, ..., 0]) iou = box_iou(pred_box[b], true_box) best_iou = K.max(iou, axis=-1) ignore_mask = ignore_mask.write( b, K.cast(best_iou < ignore_thresh, K.dtype(true_box))) return b + 1, ignore_mask _, ignore_mask = K.control_flow_ops.while_loop(lambda b, *args: b < m, loop_body, [0, ignore_mask]) ignore_mask = ignore_mask.stack() ignore_mask = K.expand_dims(ignore_mask, -1) # K.binary_crossentropy is helpful to avoid exp overflow. # NOTE 这个的raw的意思就是原始yolo所输出的内容 xy_loss = object_mask * box_loss_scale * K.binary_crossentropy( raw_true_xy, raw_pred[..., 0:2], from_logits=True) wh_loss = object_mask * box_loss_scale * 0.5 * K.square( raw_true_wh - raw_pred[..., 2:4]) confidence_loss = object_mask * K.binary_crossentropy(object_mask, raw_pred[..., 4:5], from_logits=True) + \ (1 - object_mask) * K.binary_crossentropy(object_mask, raw_pred[..., 4:5], from_logits=True) * ignore_mask class_loss = object_mask * K.binary_crossentropy( true_class_probs, raw_pred[..., 5:], from_logits=True) xy_loss = K.sum(xy_loss) / mf wh_loss = K.sum(wh_loss) / mf confidence_loss = K.sum(confidence_loss) / mf class_loss = K.sum(class_loss) / mf loss += xy_loss + wh_loss + confidence_loss + class_loss # if print_loss: # loss = tf.Print(loss, [loss, xy_loss, wh_loss, confidence_loss, class_loss, K.sum(ignore_mask)], message='loss: ') return loss
def euclidean_distance(vects): x, y = vects[0], vects[1] return K.sqrt(K.sum(K.square(x - y), axis=1, keepdims=True))
def rmsle(y_true, y_pred): """ RMS log-error """ return K.sqrt( K.mean(K.square(tf.math.log1p(y_true) - tf.math.log1p(y_pred))))
def TVRegularizer(self, x, weight=1e-6, beta=1.0, input_size=(224, 224)): delta = 1e-8 h, w = input_size d_h = K.square(x[:, :h - 1, :w - 1, :] - x[:, 1:, :w - 1, :]) d_w = K.square(x[:, :h - 1, :w - 1, :] - x[:, :h - 1, 1:, :]) return weight * K.mean(K.sum(K.pow(d_h + d_w + delta, beta/2.)))
def contrastive_loss(y_true, y_pred): margin = 1 return K.mean(y_true * K.square(y_pred) + (1 - y_true) * K.square(K.maximum(margin - y_pred, 0)))
def call(self, inputs, training=None): stddev = K.sqrt(K.mean(K.square(inputs)))*0.05 def noised(): return inputs + K.random_normal(shape=array_ops.shape(inputs), mean=0., stddev=stddev) return K.in_train_phase(noised, noised, training=training)
def content_loss(base, combination): return K.sum(K.square(combination - base))
def content_loss(x, target): ''' Content loss is simply the MSE between activations of a layer ''' return K.mean(K.square(target - x), axis=(1, 2, 3))
def style_loss(x, target, norm_by_channels=False): ''' Style loss is the MSE between Gram matrices computed using activation maps. ''' x_gram = gram_matrix(x, norm_by_channels=norm_by_channels) return K.mean(K.square(target - x_gram), axis=(1, 2))
def content_loss(content_image, target_image): return K.sum(K.square(target_image - content_image))
def calculate_mse(tensor1, tensor2): return K.mean(K.square(tensor1 - tensor2))
def l2_norm(x): return K.sqrt(K.sum(K.square(x), 1))
def yolo_loss(args, anchors, num_classes, ignore_thresh=.5): '''Return yolo_loss tensor Parameters ---------- yolo_outputs: list of tensor, the output of yolo_body y_true: list of array, the output of preprocess_true_boxes anchors: array, shape=(T, 2), wh num_classes: integer ignore_thresh: float, the iou threshold whether to ignore object confidence loss Returns ------- loss: tensor, shape=(1,) ''' yolo_outputs = args[:3] y_true = args[3:] anchor_mask = [[6, 7, 8], [3, 4, 5], [0, 1, 2]] input_shape = K.cast( K.shape(yolo_outputs[0])[1:3] * 32, K.dtype(y_true[0])) grid_shapes = [ K.cast(K.shape(yolo_outputs[l])[1:3], K.dtype(y_true[0])) for l in range(3) ] loss = 0 m = K.shape(yolo_outputs[0])[0] for l in range(3): object_mask = y_true[l][..., 4:5] true_class_probs = y_true[l][..., 5:] pred_xy, pred_wh, pred_confidence, pred_class_probs = yolo_head( yolo_outputs[l], anchors[anchor_mask[l]], num_classes, input_shape) pred_box = K.concatenate([pred_xy, pred_wh]) # Darknet box loss. xy_delta = (y_true[l][..., :2] - pred_xy) * grid_shapes[l][::-1] wh_delta = K.log(y_true[l][..., 2:4]) - K.log(pred_wh) # Avoid log(0)=-inf. wh_delta = K.switch(object_mask, wh_delta, K.zeros_like(wh_delta)) box_delta = K.concatenate([xy_delta, wh_delta], axis=-1) box_delta_scale = 2 - y_true[l][..., 2:3] * y_true[l][..., 3:4] # Find ignore mask, iterate over each of batch. ignore_mask = tf.TensorArray(K.dtype(y_true[0]), size=1, dynamic_size=True) object_mask_bool = K.cast(object_mask, 'bool') def loop_body(b, ignore_mask): true_box = tf.boolean_mask(y_true[l][b, ..., 0:4], object_mask_bool[b, ..., 0]) iou = box_iou(pred_box[b], true_box) best_iou = K.max(iou, axis=-1) ignore_mask = ignore_mask.write( b, K.cast(best_iou < ignore_thresh, K.dtype(true_box))) return b + 1, ignore_mask _, ignore_mask = K.control_flow_ops.while_loop(lambda b, *args: b < m, loop_body, [0, ignore_mask]) ignore_mask = ignore_mask.stack() ignore_mask = K.expand_dims(ignore_mask, -1) box_loss = object_mask * K.square(box_delta * box_delta_scale) confidence_loss = object_mask * K.square(1-pred_confidence) + \ (1-object_mask) * K.square(0-pred_confidence) * ignore_mask class_loss = object_mask * K.square(true_class_probs - pred_class_probs) loss += K.sum(box_loss) + K.sum(confidence_loss) + K.sum(class_loss) return loss / K.cast(m, K.dtype(loss))
def first_order_loss(y_true, y_pred): y_true = math_ops.cast(y_true, y_pred.dtype) b = tf.where(y_true == 1.0, 3.0, 1) loss = K.mean(K.square(y_true - y_pred) * b) return loss
def yolo_loss(args, anchors, num_classes, ignore_thresh=.5, print_loss=False): '''Return yolo_loss tensor Parameters ---------- yolo_outputs: list of tensor, the output of yolo_body or tiny_yolo_body y_true: list of array, the output of preprocess_true_boxes anchors: array, shape=(N, 2), wh num_classes: integer ignore_thresh: float, the iou threshold whether to ignore object confidence loss Returns ------- loss: tensor, shape=(1,) ''' num_layers = len(anchors) // 3 # default setting yolo_outputs = args[:num_layers] y_true = args[num_layers:] anchor_mask = [[6, 7, 8], [3, 4, 5], [0, 1, 2] ] if num_layers == 3 else [[3, 4, 5], [1, 2, 3]] input_shape = K.cast( K.shape(yolo_outputs[0])[1:3] * 32, K.dtype(y_true[0])) grid_shapes = [ K.cast(K.shape(yolo_outputs[l])[1:3], K.dtype(y_true[0])) for l in range(num_layers) ] loss = 0 m = K.shape(yolo_outputs[0])[0] # batch size, tensor mf = K.cast(m, K.dtype(yolo_outputs[0])) for l in range(num_layers): object_mask = y_true[l][..., 4:5] true_class_probs = y_true[l][..., 5:] grid, raw_pred, pred_xy, pred_wh = yolo_head(yolo_outputs[l], anchors[anchor_mask[l]], num_classes, input_shape, calc_loss=True) pred_box = K.concatenate([pred_xy, pred_wh]) # Darknet raw box to calculate loss. raw_true_xy = y_true[l][..., :2] * grid_shapes[l][::-1] - grid raw_true_wh = K.log(y_true[l][..., 2:4] / anchors[anchor_mask[l]] * input_shape[::-1]) raw_true_wh = K.switch(object_mask, raw_true_wh, K.zeros_like(raw_true_wh)) # avoid log(0)=-inf box_loss_scale = 2 - y_true[l][..., 2:3] * y_true[l][..., 3:4] # Find ignore mask, iterate over each of batch. ignore_mask = tf.TensorArray(K.dtype(y_true[0]), size=1, dynamic_size=True) object_mask_bool = K.cast(object_mask, 'bool') def loop_body(b, ignore_mask): true_box = tf.boolean_mask(y_true[l][b, ..., 0:4], object_mask_bool[b, ..., 0]) iou = box_iou(pred_box[b], true_box) best_iou = K.max(iou, axis=-1) ignore_mask = ignore_mask.write( b, K.cast(best_iou < ignore_thresh, K.dtype(true_box))) return b + 1, ignore_mask _, ignore_mask = K.control_flow_ops.while_loop(lambda b, *args: b < m, loop_body, [0, ignore_mask]) ignore_mask = ignore_mask.stack() ignore_mask = K.expand_dims(ignore_mask, -1) # K.binary_crossentropy is helpful to avoid exp overflow. xy_loss = object_mask * box_loss_scale * K.binary_crossentropy( raw_true_xy, raw_pred[..., 0:2], from_logits=True) wh_loss = object_mask * box_loss_scale * 0.5 * K.square( raw_true_wh - raw_pred[..., 2:4]) confidence_loss = object_mask * K.binary_crossentropy(object_mask, raw_pred[..., 4:5], from_logits=True) + \ (1 - object_mask) * K.binary_crossentropy(object_mask, raw_pred[..., 4:5], from_logits=True) * ignore_mask class_loss = object_mask * K.binary_crossentropy( true_class_probs, raw_pred[..., 5:], from_logits=True) xy_loss = K.sum(xy_loss) / mf wh_loss = K.sum(wh_loss) / mf confidence_loss = K.sum(confidence_loss) / mf class_loss = K.sum(class_loss) / mf loss += xy_loss + wh_loss + confidence_loss + class_loss if print_loss: loss = tf.Print(loss, [ loss, xy_loss, wh_loss, confidence_loss, class_loss, K.sum(ignore_mask) ], message='loss: ') return loss
def dist(x): a, b = x return K.sqrt(K.maximum(K.sum(K.square(a - b), axis=1), K.epsilon()))
def _window_std_filter(self, inputs, epsilon=K.epsilon()): c1 = self._average_filter(inputs) c2 = self._average_filter(K.square(inputs)) output = K.sqrt(c2 - c1 * c1) + epsilon return output
def euclideanDistanceCountingLoss(yTrue, yPred): counting_loss = K.mean(K.square(yTrue - yPred)) return counting_loss
def _contrastive_loss(y1, D): g = tf.constant(1.0, shape=[1], dtype=tf.float32) return K.mean(y1 * K.square(D) + (g - y1) * K.square(K.maximum(g - D, 0)))
def temp_norm(ten, axis=None): if axis is None: axis = 1 if K.image_data_format() == 'channels_first' else K.ndim(ten) - 1 return K.sqrt(K.epsilon() + K.sum(K.square(ten), axis=axis))
def feature_loss(self, y_true, y_pred): """コンテンツ特徴量の損失関数""" norm = K.prod(K.cast(K.shape(y_true)[1:], 'float32')) return K.sum( K.square(y_pred - y_true), axis=(1, 2, 3) )/norm
decoder = Model(latent_inputs, outputs, name='decoder') decoder.summary() plot_model(decoder, to_file='vae_cnn_decoder.png', show_shapes=True) # instantiate VAE model outputs = decoder(encoder(inputs)[2]) vae = Model(inputs, outputs, name='vae') if __name__ == '__main__': # VAE loss = mse_loss or xent_loss + kl_loss reconstruction_loss = mean_absolute_error(K.flatten(inputs), K.flatten(outputs)) reconstruction_loss *= image_size * image_size kl_loss = 1 + z_log_var - K.square(z_mean) - K.exp(z_log_var) kl_loss = K.sum(kl_loss, axis=-1) kl_loss *= -0.5 vae_loss = K.mean(reconstruction_loss + kl_loss) vae.add_loss(vae_loss) vae.compile(optimizer='rmsprop') vae.summary() plot_model(vae, to_file='vae_cnn.png', show_shapes=True) # train the autoencoder vae.fit(x_train, epochs=epochs, batch_size=batch_size, validation_data=(x_test, None)) plot_results(models, data, batch_size=batch_size, model_name="vae_cnn")
def mean_squared_error(y_true, y_pred): return K.mean(K.square(y_pred - y_true), axis=-1)
def mse_keras(y_true, y_pred): SS_res = K.sum( K.square( y_true - y_pred ) ) SS_tot = K.sum( K.square( y_true - K.mean( y_true ) ) ) return ( SS_res/SS_tot)
def __init__(self, model, layer_name, index_feature, kind_of_optim='squared'): """ Initialisation function of the Optimization of the feature map Parameters ---------- model : keras model layer_name : string : the layer you want to use index_feature : string : the index of the feature in the given layer kind_of_optim : string The kind of optimisation maded on the given feature. The default is 'squared'. Use 'pos' for the positive feature maximisation and 'neg' for the negative one Returns ------- None """ self.model = model self.layer_name = layer_name self.index_feature = index_feature self.kind_of_optim = kind_of_optim dream = model.input # Get the symbolic outputs of each "key" layer (we gave them unique names). layers_all = [layer.name for layer in model.layers] if layer_name not in layers_all: raise ValueError('Layer ' + layer_name + ' not found in model.') # Define the loss. loss = K.variable(0.) for layer_local in model.layers: if layer_local.name == layer_name: x = layer_local.output # We avoid border artifacts by only involving non-border pixels in the loss. if K.image_data_format() == 'channels_first': raise (NotImplementedError) x_index_feature = x[:, index_feature, :, :] x_index_feature = K.expand_dims(x_index_feature, axis=1) scaling = K.prod( K.cast(K.shape(x_index_feature), 'float32')) loss = loss + K.sum( K.square(x_index_feature[:, :, 2:-2, 2:-2])) / scaling else: x_index_feature = x[:, :, :, index_feature] x_index_feature = K.expand_dims(x_index_feature, axis=-1) scaling = K.prod( K.cast(K.shape(x_index_feature), 'float32')) if self.kind_of_optim == 'squared': loss = loss + K.sum( K.square(x_index_feature[:, 2:-2, 2:-2, :])) / scaling elif self.kind_of_optim == 'pos': loss = loss + K.sum(x_index_feature[:, 2:-2, 2:-2, :]) / scaling elif self.kind_of_optim == 'neg': loss = loss - K.sum(x_index_feature[:, 2:-2, 2:-2, :]) / scaling # Compute the gradients of the dream wrt the loss. grads = K.gradients(loss, dream)[0] # Normalize gradients. grads /= K.maximum(K.mean(K.abs(grads)), K.epsilon()) # Set up function to retrieve the value # of the loss and gradients given an input image. outputs = [loss, grads] self.fetch_loss_and_grads = K.function([dream], outputs)
def YOLOLoss(args, anchors, num_classes, ignore_threshold=0.5, print_loss=False): '''Return YOLO Loss Tensor Return: loss: tensor, shape=(1,) ''' num_layers = len(anchors) // 3 yolo_outputs = args[:num_layers] y_true = args[num_layers:] anchor_mask = [[6, 7, 8], [3, 4, 5], [0, 1, 2] ] if num_layers == 3 else [[3, 4, 5], [1, 2, 3]] input_shape = K.cast( K.shape(yolo_outputs[0])[1:3] * 32, K.dtype(y_true[0])) grid_shape = [ K.cast(K.shape(yolo_outputs[l])[1:3], K.dtype(y_true[0])) for l in range(num_layers) ] loss = 0 # batch size, tensor batch_size = K.shape(yolo_outputs[0])[0] fbatch_size = K.cast(batch_size, K.dtype(yolo_outputs[0])) for l in range(num_layers): object_mask = y_true[l][..., 4:5] true_class_prob = y_true[l][..., 5:] grid, raw_pred, pred_xy, pred_wh = YOLOHead(yolo_outputs[l], anchors[anchor_mask[l]], num_classes, input_shape, calc_loss=True) pred_box = K.concatenate([pred_xy, pred_wh]) raw_true_xy = y_true[l][..., :2] * grid_shape[l][::-1] - grid raw_true_wh = K.log(y_true[l][..., 2:4] / anchors[anchor_mask[l]] * input_shape[::-1]) raw_true_wh = K.switch(object_mask, raw_true_wh, K.zeros_like(raw_true_wh)) box_loss_scale = 2 - y_true[l][..., 2:3] * y_true[l][..., 3:4] ignore_mask = tf.TensorArray(K.dtype(y_true[0]), size=1, dynamic_size=True) object_mask_bool = K.cast(object_mask, 'bool') def loop(b, ignore_mask): true_box = tf.boolean_mask(y_true[l][b, ..., 0:4], object_mask_bool[b, ..., 0]) iou = box_iou(pred_box[b], true_box) best_iou = K.max(iou, axis=-1) ignore_mask = ignore_mask.write( b, K.cast(best_iou < ignore_threshold, K.dtype(true_box))) return b + 1, ignore_mask _, ignore_mask = K.control_flow_ops.while_loop( lambda b, *args: b < fbatch_size, loop, [0, ignore_mask]) ignore_mask = ignore_mask.stack() ignore_mask = K.expand_dims(ignore_mask, -1) xy_loss = object_mask * box_loss_scale * K.binary_crossentropy( raw_true_xy, raw_pred[..., 0:2], from_logits=True) wh_loss = object_mask * box_loss_scale * .5 * K.square( raw_true_wh - raw_pred[..., 2:4]) confidence_loss = object_mask * K.binary_crossentropy(object_mask, raw_pred[..., 4:5], from_logits=True) + \ (1 - object_mask) * K.binary_crossentropy(object_mask, raw_pred[..., 4:5], from_logits=True) * ignore_mask class_loss = object_mask * K.binary_crossentropy( true_class_prob, raw_pred[..., 5:]) xy_loss = K.sum(xy_loss) / fbatch_size wh_loss = K.sum(wh_loss) / fbatch_size confidence_loss = K.sum(confidence_loss) / fbatch_size class_loss = K.sum(class_loss) / fbatch_size loss += xy_loss + wh_loss + confidence_loss + class_loss if print_loss: loss = tf.Print(loss, [ loss, xy_loss, wh_loss, confidence_loss, class_loss, K.sum(ignore_mask) ], message='Loss: ') return loss
def contents_feature_loss(y_contents, contents_pred): norm = K.prod(K.cast(K.shape(y_contents)[1:], 'float32')) # 二乗誤差 return K.sum(K.square(contents_pred - y_contents), axis=(1, 2, 3)) / norm
def reg(weight_matrix): return K.sum(coeff * K.square(1.0 / weight_matrix))
def R2_score(y_true, y_pred): SS_res = K.sum(K.square( y_true-y_pred )) SS_tot = K.sum(K.square( y_true - K.mean(y_true) ) ) return ( 1 - SS_res/(SS_tot) )
def loss_2nd(y_true, y_pred): b_ = np.ones_like(y_true) b_[y_true != 0] = beta x = K.square((y_true - y_pred) * b_) t = K.sum(x, axis=-1, ) return K.mean(t)