예제 #1
0
    def _fit(self, X, batch_name, Y=None, shuffle_mode=True):

        datagen = generator_from_index(X,
                                       batch_name=batch_name,
                                       k=self.k,
                                       batch_size=self.batch_size,
                                       search_k=self.search_k,
                                       precompute=True,
                                       verbose=1)

        loss_monitor = 'loss'
        try:
            triplet_loss_func = triplet_loss(distance=self.distance,
                                             margin=self.margin)
        except KeyError:
            raise ValueError('Loss function `{}` not implemented.'.format(
                self.distance))

        if self.model_ is None:
            if type(self.model_def) is str:
                input_size = (X.obsm['X_pca'].shape[-1], )
                self.model_, anchor_embedding, _, _ = \
                    triplet_network(base_network(input_size),
                                    embedding_dims=self.embedding_dims)
            else:
                self.model_, anchor_embedding, _, _ = \
                    triplet_network(self.model_def,
                                    embedding_dims=self.embedding_dims)

            self.model_.compile(optimizer='adam', loss=triplet_loss_func)

        self.encoder = self.model_.layers[3]

        if self.verbose > 0:
            print('Training neural network')

        hist = self.model_.fit(
            datagen,
            epochs=self.epochs,
            callbacks=[callback for callback in self.callbacks] + [
                EarlyStopping(monitor=loss_monitor,
                              patience=self.n_epochs_without_progress)
            ],
            shuffle=shuffle_mode,
            workers=10,
            verbose=self.verbose)

        self.loss_history_ += hist.history['loss']
예제 #2
0
파일: test_network.py 프로젝트: yyht/ivis
def test_triplet_network():

    X = np.zeros(shape=(10, 5))
    embedding_dims = 3

    base_model = Sequential()
    base_model.add(Dense(8, input_shape=(X.shape[-1], )))

    model, _, _, _ = triplet_network(base_model,
                                     embedding_dims=embedding_dims,
                                     embedding_l2=0.1)
    encoder = model.layers[3]

    assert model.layers[3].output_shape == (None, 3)
    assert np.all(base_model.get_weights()[0] == encoder.get_weights()[0])
    assert np.all([
        isinstance(layer, keras.layers.InputLayer)
        for layer in model.layers[:3]
    ])

    assert encoder.output_shape == (None, embedding_dims)
예제 #3
0
    def _fit(self,
             X,
             batch_name,
             celltype_name=None,
             mask_batch=None,
             Y=None,
             shuffle_mode=True):

        datagen = generator_from_index(X,
                                       batch_name=batch_name,
                                       mask_batch=mask_batch,
                                       celltype_name=celltype_name,
                                       Y=Y,
                                       k_to_m_ratio=self.k_to_m_ratio,
                                       label_ratio=self.label_ratio,
                                       k=self.k,
                                       batch_size=self.batch_size,
                                       search_k=self.search_k,
                                       verbose=self.verbose,
                                       save_on_disk=self.save_on_disk,
                                       approx=self.approx)

        loss_monitor = 'loss'
        try:
            triplet_loss_func = triplet_loss(distance=self.distance,
                                             margin=self.margin)
        except KeyError:
            raise ValueError('Loss function `{}` not implemented.'.format(
                self.distance))

        if self.model_ is None:
            if type(self.model_def) is str:
                input_size = (X.obsm['X_pca'].shape[-1], )
                self.model_, anchor_embedding, _, _ = \
                    triplet_network(base_network(input_size),
                                    embedding_dims=self.embedding_dims)
            else:
                self.model_, anchor_embedding, _, _ = \
                    triplet_network(self.model_def,
                                    embedding_dims=self.embedding_dims)

            if Y is None:

                self.model_.compile(optimizer='adam', loss=triplet_loss_func)
            else:
                Y = le.fit_transform(Y)
                if is_categorical(self.supervision_metric):
                    if not is_multiclass(self.supervision_metric):
                        if not is_hinge(self.supervision_metric):
                            # Binary logistic classifier
                            if len(Y.shape) > 1:
                                self.n_classes = Y.shape[-1]
                            else:
                                self.n_classes = 1
                            supervised_output = Dense(
                                self.n_classes,
                                activation='sigmoid',
                                name='supervised')(anchor_embedding)
                        else:
                            # Binary Linear SVM output
                            if len(Y.shape) > 1:
                                self.n_classes = Y.shape[-1]
                            else:
                                self.n_classes = 1
                            supervised_output = Dense(
                                self.n_classes,
                                activation='linear',
                                name='supervised',
                                kernel_regularizer=regularizers.l1(
                                    l1=0.01))(anchor_embedding)
                    else:
                        if not is_hinge(self.supervision_metric):
                            validate_sparse_labels(Y)
                            self.n_classes = len(
                                np.unique(Y[Y != np.array(-1)]))
                            # Softmax classifier
                            supervised_output = Dense(
                                self.n_classes,
                                activation='softmax',
                                name='supervised')(anchor_embedding)
                        else:
                            self.n_classes = len(np.unique(Y, axis=0))
                            # Multiclass Linear SVM output
                            supervised_output = Dense(
                                self.n_classes,
                                activation='linear',
                                name='supervised',
                                kernel_regularizer=regularizers.l1(
                                    l1=0.01))(anchor_embedding)
                else:
                    # Regression
                    if len(Y.shape) > 1:
                        self.n_classes = Y.shape[-1]
                    else:
                        self.n_classes = 1
                    supervised_output = Dense(
                        self.n_classes, activation='linear',
                        name='supervised')(anchor_embedding)

                supervised_loss = keras.losses.get(self.supervision_metric)
                if self.supervision_metric == 'sparse_categorical_crossentropy':
                    supervised_loss = semi_supervised_loss(supervised_loss)

                final_network = Model(
                    inputs=self.model_.inputs,
                    outputs=[self.model_.output, supervised_output])
                self.model_ = final_network
                self.model_.compile(optimizer='adam',
                                    loss={
                                        'stacked_triplets': triplet_loss_func,
                                        'supervised': supervised_loss
                                    },
                                    loss_weights={
                                        'stacked_triplets':
                                        1 - self.supervision_weight,
                                        'supervised': self.supervision_weight
                                    })

                # Store dedicated classification model
                supervised_model_input = Input(
                    shape=(X.obsm['X_pca'].shape[-1], ))
                embedding = self.model_.layers[3](supervised_model_input)
                softmax_out = self.model_.layers[-1](embedding)

                self.supervised_model_ = Model(supervised_model_input,
                                               softmax_out)

        self.encoder = self.model_.layers[3]

        if self.verbose > 0:
            print('Training neural network')

        hist = self.model_.fit(
            datagen,
            epochs=self.epochs,
            callbacks=[callback for callback in self.callbacks] + [
                EarlyStopping(monitor=loss_monitor,
                              patience=self.n_epochs_without_progress)
            ],
            shuffle=shuffle_mode,
            workers=10,
            verbose=self.verbose)

        self.loss_history_ += hist.history['loss']