InseeFrLab / images-datascience

Collection of Docker images to build the data science catalog of the Onyxia project
MIT License
24 stars 23 forks source link

Python gpu tensorflow : Bug non identifié dans keras save() (qui fonctionne sur google colab) #200

Closed arnaud-feldmann closed 7 months ago

arnaud-feldmann commented 7 months ago

J'ai un bug bizarre que je ne comprends pas du tout :

Soit le code :

import numpy as np
import tensorflow as tf
from keras.applications import ResNet50V2
from keras.datasets import cifar100
from keras import Sequential
from keras.layers import Dense, UpSampling2D, Dropout, RandomFlip, RandomTranslation, RandomRotation,RandomBrightness, RandomContrast, RandomZoom
from keras.applications.resnet_v2 import preprocess_input
import re

n_epoch = 1
batch_size = 100
taux_validation = 0.1
num_classes = 100
n_images = 50000

def preprocessing(image, label):
    image = tf.image.resize(image, (224, 224))
    label = tf.squeeze(tf.one_hot(label, depth = num_classes), axis = 0)
    return  image, label

augmentation_donnees_keras = Sequential([
    RandomFlip("horizontal"),
    RandomTranslation(0.2,0.2),
    RandomRotation(0.2),
    RandomZoom(0.2),
    RandomContrast(0.2),
    RandomBrightness(0.2,value_range=(0,1))
])

def augmentation_donnees(image, label):
    return augmentation_donnees_keras(image/255.0, training = True)*255.0, label

def preprocess_resnet(image, label):
    return preprocess_input(image), label

train_dataset, test_dataset = cifar100.load_data()

validation_size = int(n_images * taux_validation)
train_dataset = tf.data.Dataset.from_tensor_slices(train_dataset).map(preprocessing).shuffle(n_images, reshuffle_each_iteration=False)
test_dataset = tf.data.Dataset.from_tensor_slices(test_dataset).map(preprocessing)

validation_dataset = train_dataset.take(validation_size).batch(batch_size).map(preprocess_resnet).cache().prefetch(tf.data.AUTOTUNE)
train_dataset = train_dataset.skip(validation_size).batch(batch_size).cache().map(augmentation_donnees,num_parallel_calls=3).map(preprocess_resnet, num_parallel_calls=3).prefetch(tf.data.AUTOTUNE)
test_dataset = test_dataset.batch(batch_size).map(preprocess_resnet, num_parallel_calls=5).prefetch(tf.data.AUTOTUNE)

model = Sequential([
    ResNet50V2(include_top=False, weights='imagenet', pooling="avg"),
    Dropout(0.25),
    Dense(256, activation="sigmoid", kernel_regularizer = tf.keras.regularizers.L1(0.001)),
    Dropout(0.5),
    Dense(num_classes, activation="softmax", kernel_regularizer = tf.keras.regularizers.L2(0.001))
])
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(train_dataset, epochs=n_epoch, batch_size=batch_size, validation_data = validation_dataset)

Si ya la mémoire et que je fais par la suite

model.evaluate(test_dataset)

ça fonctionne.

Par contre

import keras
model.save("model.keras")
model = keras.models.load_model("model.keras")

Et j'ai un bug.

ValueError: Input 0 of layer "dense_1" is incompatible with the layer: expected min_ndim=2, found ndim=1. Full shape received: (256,)

Le plus curieux c'est que cela passe sur Google Colab.

Par contre le fichier lui-même généré ne peut être lu sur google Colab. (malheureusement pour mon entrainement)

arnaud-feldmann commented 7 months ago

Il semble que le même code passe dans l'image 1.12 et pas dans 1.13.28. Mais j'ai plus de place en GPU sur sspcloud donc je peux plus tester ! :D

arnaud-feldmann commented 7 months ago

Ah ok j'avais pas remarqué que sur Colab c'était encore keras 2.x, ça doit expliquer cela.

arnaud-feldmann commented 7 months ago

Grâce au SSPCloud, j'ai signalé une issue sur Keras :D https://github.com/keras-team/keras/issues/19486 Et le type l'a résolue en un jour... Impressionnant de rapidité le type !