Skip to content
Snippets Groups Projects
class1_neural_network.py 43.9 KiB
Newer Older
            self,
            peptides,
            allele_encoding=None,
            batch_size=4096,
            output_index=0):
        Predict affinities.

        If peptides are specified as EncodableSequences, then the predictions
        will be cached for this predictor as long as the EncodableSequences object
        remains in memory. The cache is keyed in the object identity of the
        EncodableSequences, not the sequences themselves.

        Parameters
        ----------
Tim O'Donnell's avatar
Tim O'Donnell committed
        peptides : EncodableSequences or list of string
        
        allele_encoding : AlleleEncoding, optional
Tim O'Donnell's avatar
Tim O'Donnell committed
            Only required when this model is a pan-allele model
        batch_size : int
            batch_size passed to Keras

Tim O'Donnell's avatar
Tim O'Donnell committed
        numpy.array of nM affinity predictions 
Tim O'Donnell's avatar
Tim O'Donnell committed
        assert self.prediction_cache is not None
        use_cache = (
            allele_encoding is None and
            isinstance(peptides, EncodableSequences))
        if use_cache and peptides in self.prediction_cache:
            return self.prediction_cache[peptides].copy()

Tim O'Donnell's avatar
Tim O'Donnell committed
        x_dict = {
            'peptide': self.peptides_to_network_input(peptides)
        }
        if allele_encoding is not None:
            (allele_encoding_input, allele_representations) = (
                self.allele_encoding_to_network_input(allele_encoding))
            x_dict['allele'] = allele_encoding_input
            self.set_allele_representations(allele_representations)
            network = self.network()
        else:
            network = self.network(borrow=True)
        raw_predictions = network.predict(x_dict, batch_size=batch_size)
        predictions = numpy.array(raw_predictions, dtype = "float64")
        if output_index is not None:
            predictions = predictions[:,output_index]
        result = to_ic50(predictions)
        if use_cache:
            self.prediction_cache[peptides] = result
        return result
Tim O'Donnell's avatar
Tim O'Donnell committed

    def make_network(
Tim O'Donnell's avatar
Tim O'Donnell committed
            self,
Tim O'Donnell's avatar
Tim O'Donnell committed
            peptide_encoding,
Tim O'Donnell's avatar
Tim O'Donnell committed
            allele_amino_acid_encoding,
            allele_dense_layer_sizes,
            peptide_dense_layer_sizes,
            peptide_allele_merge_method,
            peptide_allele_merge_activation,
Tim O'Donnell's avatar
Tim O'Donnell committed
            layer_sizes,
            dense_layer_l1_regularization,
            dense_layer_l2_regularization,
            activation,
            init,
            output_activation,
            dropout_probability,
            batch_normalization,
Tim O'Donnell's avatar
Tim O'Donnell committed
            locally_connected_layers,
Tim O'Donnell's avatar
Tim O'Donnell committed
            allele_representations=None):
Tim O'Donnell's avatar
Tim O'Donnell committed
        """
        Helper function to make a keras network for class1 affinity prediction.
        """
Tim O'Donnell's avatar
Tim O'Donnell committed

        # We import keras here to avoid tensorflow debug output, etc. unless we
        # are actually about to use Keras.

        from keras.layers import Input
        import keras.layers
Tim O'Donnell's avatar
Tim O'Donnell committed
        from keras.layers.core import Dense, Flatten, Dropout
Tim O'Donnell's avatar
Tim O'Donnell committed
        from keras.layers.embeddings import Embedding
        from keras.layers.normalization import BatchNormalization

Tim O'Donnell's avatar
Tim O'Donnell committed
        peptide_encoding_shape = self.peptides_to_network_input([]).shape[1:]
        peptide_input = Input(
            shape=peptide_encoding_shape,
            dtype='float32',
            name='peptide')
        current_layer = peptide_input
Tim O'Donnell's avatar
Tim O'Donnell committed

        inputs = [peptide_input]

        kernel_regularizer = None
        l1 = dense_layer_l1_regularization
        l2 = dense_layer_l2_regularization
        if l1 > 0 or l2 > 0:
            kernel_regularizer = keras.regularizers.l1_l2(l1, l2)

        for (i, locally_connected_params) in enumerate(locally_connected_layers):
            current_layer = keras.layers.LocallyConnected1D(
                name="lc_%d" % i,
                **locally_connected_params)(current_layer)

        current_layer = Flatten(name="flattened_0")(current_layer)
Tim O'Donnell's avatar
Tim O'Donnell committed

        for (i, layer_size) in enumerate(peptide_dense_layer_sizes):
            current_layer = Dense(
                layer_size,
                name="peptide_dense_%d" % i,
                kernel_regularizer=kernel_regularizer,
                activation=activation)(current_layer)

Tim O'Donnell's avatar
Tim O'Donnell committed
        if batch_normalization:
            current_layer = BatchNormalization(name="batch_norm_early")(
                current_layer)
            allele_input = Input(
Tim O'Donnell's avatar
Tim O'Donnell committed
                dtype='float32',
                name='allele')
            inputs.append(allele_input)
Tim O'Donnell's avatar
Tim O'Donnell committed
            allele_layer = Embedding(
                name="allele_representation",
                input_dim=allele_representations.shape[0],
Tim O'Donnell's avatar
Tim O'Donnell committed
                output_dim=numpy.product(allele_representations.shape[1:], dtype=int),
Tim O'Donnell's avatar
Tim O'Donnell committed
                trainable=False)(allele_input)
            for (i, layer_size) in enumerate(allele_dense_layer_sizes):
                    layer_size,
                    name="allele_dense_%d" % i,
                    kernel_regularizer=kernel_regularizer,
            allele_layer = Flatten(name="allele_flat")(allele_layer)

            if peptide_allele_merge_method == 'concatenate':
                current_layer = keras.layers.concatenate([
                ], name="allele_peptide_merged")
            elif peptide_allele_merge_method == 'multiply':
                current_layer = keras.layers.multiply([
                ], name="allele_peptide_merged")
Tim O'Donnell's avatar
Tim O'Donnell committed
            else:
                raise ValueError(
                    "Unsupported peptide_allele_encoding_merge_method: %s"
                    % peptide_allele_merge_method)

            if peptide_allele_merge_activation:
                current_layer = keras.layers.Activation(
                    peptide_allele_merge_activation,
                    name="alelle_peptide_merged_%s" %
                         peptide_allele_merge_activation)(current_layer)
Tim O'Donnell's avatar
Tim O'Donnell committed
            
        for (i, layer_size) in enumerate(layer_sizes):
Tim O'Donnell's avatar
Tim O'Donnell committed
                layer_size,
                activation=activation,
                kernel_regularizer=kernel_regularizer,
                name="dense_%d" % i)(current_layer)
Tim O'Donnell's avatar
Tim O'Donnell committed
            if batch_normalization:
                current_layer = BatchNormalization(
                    name="batch_norm_%d" % i)(current_layer)
Tim O'Donnell's avatar
Tim O'Donnell committed

            if dropout_probability > 0:
                current_layer = Dropout(
                    rate=1 - dropout_probability,
                    name="dropout_%d" % i)(current_layer)
            kernel_initializer=init,
            activation=output_activation,
            name="output")(current_layer)
        model = keras.models.Model(
            inputs=inputs,
            outputs=[output],
            name="predictor")
Tim O'Donnell's avatar
Tim O'Donnell committed
        return model

    def set_allele_representations(self, allele_representations):
        """

        Parameters
        ----------
        model
        allele_representations

        """
Tim O'Donnell's avatar
Tim O'Donnell committed
        reshaped = allele_representations.reshape((allele_representations.shape[0], -1))
        layer = self.network().get_layer("allele_representation")
        (existing,) = layer.get_weights()
Tim O'Donnell's avatar
Tim O'Donnell committed
        if existing.shape == reshaped.shape:
            layer.set_weights([reshaped])
Tim O'Donnell's avatar
Tim O'Donnell committed
            raise NotImplementedError(
                "Network surgery required: %s != %s" % (
Tim O'Donnell's avatar
Tim O'Donnell committed
                    str(existing.shape), str(reshaped.shape)))