Keras ValueError: Shapes (64,) and (32,) are incompatible on tuning CNN with Bayesian optimization

Viewed 135

I'm try to tune a CNN net with Bayesian optimizanion with this code:

class CNNHyperModel(kt.HyperModel):
  
  def __init__(self, window_size):
    self.window_size = window_size    

  def build(self, hp):

    input_sequence_data = Input(shape=(self.window_size, 4), name="sequence_data")
    hidden = Conv1D(64, kernel_size=5, activation="relu")(input_sequence_data)
    hidden = BatchNormalization()(hidden)
    hidden = Conv1D(64, kernel_size=5, activation="relu")(hidden)
    hidden = BatchNormalization()(hidden)
    hidden = Conv1D(64, kernel_size=5, activation="relu")(hidden)
    hidden = BatchNormalization()(hidden)
    hidden = MaxPool1D()(hidden)
    hidden = Conv1D(hp.Choice('units', [32, 64, 128]), kernel_size=hp.Choice('kernel_size', [5, 10]), activation="relu")(hidden)
    hidden = BatchNormalization()(hidden)
    hidden = Flatten()(hidden)
    hidden = Dense(hp.Choice('units1', [10, 32, 64]), activation="relu")(hidden)
    hidden = Dropout(0.1)(hidden)
    hidden = Dense(hp.Choice('units2', [10, 32, 64]), activation="relu")(hidden)
    hidden = Dropout(0.1, name="last_hidden")(hidden)

    last_hidden_cnn = hidden
    output_cnn = Dense(1, activation="sigmoid")(last_hidden_cnn)

    cnn = Model(
        inputs=input_sequence_data,
        outputs=output_cnn,
        name="BinaryClassificationCNN"
    )

    cnn.compile(
        optimizer=tf.keras.optimizers.Nadam(learning_rate=2e-3),
        loss="binary_crossentropy",
        metrics=get_complete_binary_metrics()
    )

    cnn.summary()
    
    return cnn


def baesyan_optimization_CNN_classification(
    train_sequence: MixedSequence,
    test_sequence: MixedSequence,
    input_shape: int
)->Tuple[Model, Layer, Layer]:
    
    tuner = BayesianOptimization(
      CNNHyperModel(input_shape),
      objective='val_accuracy',
      max_trials=2
    )

    tuner.search(
      train_sequence,
      validation_data=test_sequence,
      epochs=10,
      verbose=False,
      callbacks=[
          EarlyStopping(
              "loss",
              min_delta=0.001,
              patience=2,
              mode="min"
          ),
      ]
    )

    return tuner.get_best_models()[0]

def get_cnn_sequence(
    genome: Genome,
    bed: pd.DataFrame,
    y: np.ndarray,
    batch_size: int = 576
) -> MixedSequence:
    """Returns sequence to train a CNN model on genomic sequences.
    
    Implementative details
    -------------------------
    This sequence can be used for either binary classification or
    for regresssion, just change the y accordingly.
    
    Parameters
    -------------------------
    genome: Genome,
        The genome from where to extract the genomic sequence.
    bed: pd.DataFrame,
        The BED file coordinates describing where to extract the sequences.
    y: np.ndarray,
        The values the model should predict.
    batch_size: int = 1024,
        The size of the batches to generate
    
    Returns
    --------------------------
    MixedSequence object to train a CNN.
    """
    return MixedSequence(
        x={
            "sequence_data": BedSequence(
                genome,
                bed,
                batch_size=batch_size,
            )
        },
        y=VectorSequence(
            y,
            batch_size=batch_size
        )
    )

This is the code where I try to get the model:

# Create a list to store all the computed performance
all_binary_classification_performance = []

training_histories = {}

# For each task
for task in tqdm(((samples['promoter'],labels['promoter'], 'Promoter'),), desc="Tasks"):

    # We get the task data with binarized labels
    X, y, task_name = task
    training_histories[task_name] = []

    bed = to_bed(X)

    # Get the number of features of this specific dataset
    number_of_features = X.shape[1]
    # Start the main loop, iterating through the holdouts
    for holdout_number, (train_indices, test_indices) in tqdm(
        enumerate(holdouts_generator.split(X, y)),
        total=number_of_splits,
        leave=False,
        desc="Computing holdouts"
    ):  
        # Get the training and test data
        train_bed, test_bed = bed.iloc[train_indices], bed.iloc[test_indices]
        train_X, test_X = X.iloc[train_indices], X.iloc[test_indices]
        train_y, test_y = y.iloc[train_indices], y.iloc[test_indices]

        print(train_X.shape)
        print(test_X.shape)
        print(train_bed.shape)

        # Flatten the output values
        train_y = train_y.values.flatten()
        print(train_y.shape)
        test_y = test_y.values.flatten()
        print(test_y.shape)

        train_sequence_ffnn = get_ffnn_sequence(train_X.values, train_y)
        test_sequence_ffnn = get_ffnn_sequence(test_X.values, test_y)

        train_sequence_cnn = get_cnn_sequence(genome, train_bed, train_y)
        test_sequence_cnn = get_cnn_sequence(genome, test_bed, test_y)

        train_sequence_mmnn = get_mmnn_sequence(genome, train_bed, train_X.values, train_y)
        test_sequence_mmnn = get_mmnn_sequence(genome, test_bed, test_X.values, test_y)

        bffnn = baesyan_optimization_FFNN_classification(train_sequence_ffnn, test_sequence_ffnn, number_of_features)
        #last_hidden_ffnn = bffnn.get_layer(name='last_hidden')
        bcnn = baesyan_optimization_CNN_classification(train_sequence_cnn, test_sequence_cnn, 256)    <-----
        #last_hidden_cnn = bcnn.get_layer(name='last_hidden')

        ffnn, input_epigenomic_data, _ = build_fixed_model_FFNN_classification(number_of_features)
        cnn, input_sequence_data, _ = build_fixed_model_CNN_classification(256)
        '''mmnn1 = fixed_MMNN_classification(
              input_epigenomic_data=input_epigenomic_data, 
              input_sequence_data=input_sequence_data,
              last_hidden_ffnn=last_hidden_ffnn,
              last_hidden_cnn=last_hidden_cnn
              )'''
        mmnn2 = fixed_MMNN_classification(input_shape=number_of_features, window_size=256)

        for model, train_sequence, test_sequence in tqdm(
            (    
                #(bffnn, train_sequence_ffnn, test_sequence_ffnn),
                #(bcnn, train_sequence_cnn, test_sequence_cnn),
                (ffnn, train_sequence_ffnn, test_sequence_ffnn),
                (cnn, train_sequence_cnn, test_sequence_cnn),
                #(mmnn1, train_sequence_mmnn, test_sequence_mmnn),
                (mmnn2, train_sequence_mmnn, test_sequence_mmnn),
            ),
            desc="Training models",
            leave=False
        ):

          # execute_boruta_feature_selection(...)

          # We compute the model performance
          history, performance = train_model(
              model,
              model.name,
              task_name,
              cell_line,
              train_sequence,
              test_sequence,
              holdout_number
          )
          training_histories[task_name].append(history)
          all_binary_classification_performance.append(performance)
 
# We convert the computed performance list into a DataFrame
all_binary_classification_performance = pd.concat(all_binary_classification_performance)

where there is a arrow in a code, every time I got this error:

---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-49-07a0a85efac1> in <module>()
     48         bffnn = baesyan_optimization_FFNN_classification(train_sequence_ffnn, test_sequence_ffnn, number_of_features)
     49         #last_hidden_ffnn = bffnn.get_layer(name='last_hidden')
---> 50         bcnn = baesyan_optimization_CNN_classification(train_sequence_cnn, test_sequence_cnn, 256)
     51         #last_hidden_cnn = bcnn.get_layer(name='last_hidden')
     52 

6 frames

<ipython-input-47-3f8fcd30527d> in baesyan_optimization_CNN_classification(train_sequence, test_sequence, input_shape)
     26     )
     27 
---> 28     return tuner.get_best_models()[0]

/usr/local/lib/python3.7/dist-packages/keras_tuner/engine/tuner.py in get_best_models(self, num_models)
    389         """
    390         # Method only exists in this class for the docstring override.
--> 391         return super(Tuner, self).get_best_models(num_models)
    392 
    393     def _deepcopy_callbacks(self, callbacks):

/usr/local/lib/python3.7/dist-packages/keras_tuner/engine/base_tuner.py in get_best_models(self, num_models)
    280         """
    281         best_trials = self.oracle.get_best_trials(num_models)
--> 282         models = [self.load_model(trial) for trial in best_trials]
    283         return models
    284 

/usr/local/lib/python3.7/dist-packages/keras_tuner/engine/base_tuner.py in <listcomp>(.0)
    280         """
    281         best_trials = self.oracle.get_best_trials(num_models)
--> 282         models = [self.load_model(trial) for trial in best_trials]
    283         return models
    284 

/usr/local/lib/python3.7/dist-packages/keras_tuner/engine/tuner.py in load_model(self, trial)
    328         with maybe_distribute(self.distribution_strategy):
    329             model.load_weights(
--> 330                 self._get_checkpoint_fname(trial.trial_id, best_epoch)
    331             )
    332         return model

/usr/local/lib/python3.7/dist-packages/keras/utils/traceback_utils.py in error_handler(*args, **kwargs)
     65     except Exception as e:  # pylint: disable=broad-except
     66       filtered_tb = _process_traceback_frames(e.__traceback__)
---> 67       raise e.with_traceback(filtered_tb) from None
     68     finally:
     69       del filtered_tb

/usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/tensor_shape.py in assert_is_compatible_with(self, other)
   1169     """
   1170     if not self.is_compatible_with(other):
-> 1171       raise ValueError("Shapes %s and %s are incompatible" % (self, other))
   1172 
   1173   def most_specific_compatible_shape(self, other):

ValueError: Shapes (64,) and (32,) are incompatible

This error is not always the same, sometimes change the shape to ValueError: Shapes (64,) and (8,) are incompatible.

The input shape of net is (256,4).

0 Answers
Related