class SiameseNet: def __init__(self, inputs, arch, siam_reg, y_true): self.orig_inputs = inputs # set up inputs self.inputs = { 'A': inputs['Unlabeled'], 'B': Input(shape=inputs['Unlabeled'].get_shape().as_list()[1:]), 'Labeled': inputs['Labeled'], } self.y_true = y_true # generate layers self.layers = [] self.layers += make_layer_list(arch, 'siamese', siam_reg) # create the siamese net self.outputs = stack_layers(self.inputs, self.layers) # add the distance layer self.distance = Lambda(costs.euclidean_distance, output_shape=costs.eucl_dist_output_shape)( [self.outputs['A'], self.outputs['B']]) #create the distance model for training self.net = Model([self.inputs['A'], self.inputs['B']], self.distance) # compile the siamese network self.net.compile(loss=costs.get_contrastive_loss(m_neg=1, m_pos=0.05), optimizer='rmsprop') def train(self, pairs_train, dist_train, pairs_val, dist_val, lr, drop, patience, num_epochs, batch_size): # create handler for early stopping and learning rate scheduling self.lh = LearningHandler(lr=lr, drop=drop, lr_tensor=self.net.optimizer.lr, patience=patience) # initialize the training generator train_gen_ = train_gen(pairs_train, dist_train, batch_size) # format the validation data for keras validation_data = ([pairs_val[:, 0], pairs_val[:, 1]], dist_val) # compute the steps per epoch steps_per_epoch = int(len(pairs_train) / batch_size) # train the network hist = self.net.fit_generator(train_gen_, epochs=num_epochs, validation_data=validation_data, steps_per_epoch=steps_per_epoch, callbacks=[self.lh]) return hist def predict(self, x, batch_sizes): # compute the siamese embeddings of the input data return train.predict(self.outputs['A'], x_unlabeled=x, inputs=self.orig_inputs, y_true=self.y_true, batch_sizes=batch_sizes)
class SiameseNet(object): """Class for Siamese Network.""" def __init__(self, inputs, arch, siam_reg, main_path, y_true): self.orig_inputs = inputs # set up inputs self.inputs = { 'A': inputs['Unlabeled'], 'B': Input(shape=inputs['Unlabeled'].get_shape().as_list()[1:]), 'Labeled': inputs['Labeled'], } self.main_path = os.path.join(main_path, 'siemese/') self.y_true = y_true # generate layers self.layers = [] self.layers += util.make_layer_list(arch, 'siamese', siam_reg) # create the siamese net self.outputs = stack_layers(self.inputs, self.layers) # add the distance layer self.distance = Lambda(affinities.euclidean_distance, output_shape=affinities.eucl_dist_output_shape)( [self.outputs['A'], self.outputs['B']]) # create the distance model for training self.net = Model([self.inputs['A'], self.inputs['B']], self.distance) # compile the siamese network self.net.compile(loss=affinities.get_contrastive_loss(m_neg=1, m_pos=0.05), optimizer='rmsprop') def train(self, pairs_train, dist_train, pairs_val, dist_val, lr, drop, patience, num_epochs, batch_size, dset, load=True): """Train the Siamese Network.""" if load: # load weights into model output_path = os.path.join(self.main_path, dset) load_model(self.net, output_path, '_siamese') return # create handler for early stopping and learning rate scheduling self.lh = util.LearningHandler(lr=lr, drop=drop, lr_tensor=self.net.optimizer.lr, patience=patience) # initialize the training generator train_gen_ = util.train_gen(pairs_train, dist_train, batch_size) # format the validation data for keras validation_data = ([pairs_val[:, 0], pairs_val[:, 1]], dist_val) # compute the steps per epoch steps_per_epoch = int(len(pairs_train) / batch_size) # train the network self.net.fit_generator(train_gen_, epochs=num_epochs, validation_data=validation_data, steps_per_epoch=steps_per_epoch, callbacks=[self.lh]) model_json = self.net.to_json() output_path = os.path.join(self.main_path, dset) save_model(self.net, model_json, output_path, '_siamese') def predict(self, x, batch_sizes): # compute the siamese embeddings of the input data return train.predict(self.outputs['A'], x_unlabeled=x, inputs=self.orig_inputs, y_true=self.y_true, batch_sizes=batch_sizes)
model.summary() # loop over all layers in the base model and freeze them so they will *not* be updated during the first training process for layer in baseModel.layers: layer.trainable = False # compile our model print("[INFO] compiling model...") opt = Adam(lr=INIT_LR, decay=DEC) model.compile(loss="binary_crossentropy", optimizer=opt, metrics=["accuracy"]) # train the head of the network print("[INFO] training head...") H = model.fit_generator(trainAug.flow(trainX, trainY, batch_size=BS), steps_per_epoch=len(trainX) // BS, validation_data=(testX, testY), validation_steps=len(testX) // BS, epochs=EPOCHS) # make predictions on the testing set print("[INFO] evaluating network...") predIdxs = model.predict(testX, batch_size=BS) # for each image in the testing set we need to find the index of the label with corresponding largest predicted probability predIdxs = np.argmax(predIdxs, axis=1) # show a nicely formatted classification report print( classification_report(testY.argmax(axis=1), predIdxs, target_names=lb.classes_))