Beispiel #1
0
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_))