def loss_function(self, y_true, y_pred): xent_loss = losses.categorical_crossentropy(y_true, y_pred) # Compute the distances from the current class-centers to add to loss class_ids = K.tf.argmax(y_true, axis=1, output_type=K.tf.int32) these_class_centers = K.gather(self.centers, class_ids) center_dist = K.sum(K.square(self.embeddings - these_class_centers), axis=1) center_loss = 0.5 * K.mean(center_dist) # How many samples per class in this batch: class_nums = K.sum(y_true, axis=0) # compute the differences for the class centers update diffs_arr = [] for i in range(self.num_classes): diff = K.cast( K.expand_dims(K.equal(class_ids, i), axis=-1), K.tf.float32) * (these_class_centers - self.embeddings) diff = K.sum(diff, axis=0, keepdims=True) diff = diff / (K.gather(class_nums, i) + 1) diffs_arr.append(diff) diffs = K.concatenate(diffs_arr, axis=0) # Update class centers: self.add_update(K.update_sub(self.centers, self.center_update_rate * diffs), inputs=self.embeddings) return xent_loss + self.center_loss_coeff * center_loss
def preprocessing(inputs): output = Lambda(lambda x: (x - K.min(x)) * 255 / (K.max(x) - K.min(x) + K.epsilon()), output_shape=inputs._keras_shape)(inputs) # output = 255 * inputs K.update_sub(output[:, 0, :, :], 123.68) K.update_sub(output[:, 1, :, :], 116.779) K.update_sub(output[:, 2, :, :], 103.939) return output[:, ::-1, :, :]
def get_updates(self, loss, params): grads = self.get_gradients(loss, params) self.updates = [K.update_add(self.iterations, 1)] t = K.cast(self.iterations, K.floatx()) + 1 lr_t = self.learning_rate * (K.sqrt(1. - K.pow(self.beta_2, t)) / (1. - K.pow(self.beta_1, t))) ms = [K.zeros(K.int_shape(p), dtype=K.dtype(p)) for p in params] vs = [K.zeros(K.int_shape(p), dtype=K.dtype(p)) for p in params] self.weights = [self.iterations] + ms + vs for p, g, m, v in zip(params, grads, ms, vs): m_t = (self.beta_1 * m) + (1. - self.beta_1) * g v_t = (self.beta_2 * v) + (1. - self.beta_2) * K.square(g) p_t = lr_t * m_t / (K.sqrt(v_t) + self.epsilon) self.updates.append(K.update(m, m_t)) self.updates.append(K.update(v, v_t)) self.updates.append(K.update_sub(p, p_t)) return self.updates
def get_updates(self, loss, params): updates = super(DecoupleWeightDecay, self).get_updates(loss, params) #TODO change loop to vectorized for p in params: updates.append(K.update_sub(p, self.weight_decay * p)) return updates