[Python] Does the fact that i have just train, test split using keras image_from_dataset...

Discussão em 'Python' iniciado por Stack, Abril 10, 2025.

  1. Stack

    Stack Membro Participativo

    I've been trying to figure out why my metrics were low after training. I had an F1 score of 75% which is not what i expected at all. I reviewed the code and I suspected the issue was the train, validation split but also the fact that i was evaluating the model on the validation set y_pred = (model.predict(val_ds) > 0.5).astype(int). I read the keras documentation to see if i made mistakes or if there was a way to split my dataset into train, validation, test split but i didn't find anything that could point out if i made a mistake. Here's my code:

    import tensorflow as tf
    from tensorflow.keras.applications import DenseNet169
    from tensorflow.keras.layers import Dense, GlobalAveragePooling2D, RandomFlip, RandomRotation, Dropout
    from tensorflow.keras.models import Model, Sequential
    from tensorflow.keras.optimizers import Adam
    from tensorflow.keras.regularizers import l2
    from tensorflow.keras.applications.densenet import preprocess_input
    from sklearn.metrics import confusion_matrix, f1_score
    import numpy as np

    # Define constants
    IMG_SIZE = (224, 224) # Match DenseNet169 input size
    BATCH_SIZE = 32
    EPOCHS = 15
    DATA_DIR = "colon_images"
    CLASS_NAMES = ["cancerous", "normal"]
    SPLIT_RATIO = 0.2

    # Load datasets directly at 224x224
    def create_dataset(subset):
    return tf.keras.utils.image_dataset_from_directory(
    DATA_DIR,
    validation_split=SPLIT_RATIO,
    subset=subset,
    seed=42,
    image_size=IMG_SIZE, # Directly load at target size
    batch_size=BATCH_SIZE,
    label_mode='binary'
    )

    train_ds = create_dataset("training")
    val_ds = create_dataset("validation")

    # Preprocessing with augmentation (augmentations only active during training)
    preprocessing = Sequential([
    RandomFlip("horizontal"),
    RandomRotation(0.1),
    tf.keras.layers.Lambda(preprocess_input) # Correct normalization
    ])

    # Build model
    base_model = DenseNet169(
    weights='imagenet',
    include_top=False,
    input_shape=IMG_SIZE + (3,)
    )

    inputs = tf.keras.Input(shape=IMG_SIZE + (3,))
    x = preprocessing(inputs)
    x = base_model(x)
    x = GlobalAveragePooling2D()(x)
    x = Dense(512, activation='relu', kernel_regularizer=l2(0.01))(x)
    x = Dropout(0.5)(x) # Regularization
    outputs = Dense(1, activation='sigmoid')(x)
    model = Model(inputs, outputs)

    # Phase 1: Train top layers
    base_model.trainable = False
    model.compile(
    optimizer=Adam(1e-3),
    loss='binary_crossentropy',
    metrics=['accuracy', tf.keras.metrics.AUC(name='auc'),
    tf.keras.metrics.Precision(name='precision'),
    tf.keras.metrics.Recall(name='recall')]
    )

    # Train with callbacks monitoring AUC
    early_stop = tf.keras.callbacks.EarlyStopping(
    monitor='val_auc', patience=3, mode='max', verbose=1
    )
    checkpoint = tf.keras.callbacks.ModelCheckpoint(
    'best_model.h5', save_best_only=True, monitor='val_auc', mode='max'
    )

    history = model.fit(
    train_ds,
    validation_data=val_ds,
    epochs=EPOCHS,
    callbacks=[early_stop, checkpoint]
    )

    # Phase 2: Fine-tune entire model
    base_model.trainable = True
    model.compile(
    optimizer=Adam(1e-5), # Very low learning rate
    loss='binary_crossentropy',
    metrics=['accuracy', tf.keras.metrics.AUC(name='auc')]
    )

    history_fine = model.fit(
    train_ds,
    validation_data=val_ds,
    epochs=EPOCHS,
    initial_epoch=history.epoch[-1],
    callbacks=[early_stop, checkpoint]
    )

    # Evaluation
    y_pred = (model.predict(val_ds) > 0.5).astype(int)
    y_true = np.concatenate([y for _, y in val_ds], axis=0)

    print(f"F1 Score: {f1_score(y_true, y_pred):.3f}")


    `

    Continue reading...

Compartilhe esta Página