Как решить проблему с форматом ввода на Keras

#python #tensorflow #keras #deep-learning #conv-neural-network

Вопрос:

Я тренирую CNN с помощью Keras. Архитектура модели выглядит следующим образом:

 model.add(layers.Conv2D(32, (3, 3), activation='relu',input_shape=(150, 150, 3),padding='same'))
model.add(layers.MaxPooling2D((2, 2),strides=(2,2), padding='same'))
model.add(layers.Conv2D(64, (3, 3), activation='relu', padding='same'))
model.add(layers.MaxPooling2D((2, 2),strides=(2,2), padding='same'))
model.add(layers.Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(layers.MaxPooling2D((2, 2), strides=(2,2),padding='same'))
model.add(layers.Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(layers.MaxPooling2D((2, 2),strides=(2,2), padding='same'))
model.add(layers.Flatten())
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
 

Составление и подгонка части модели-это:

 model.compile(loss='binary_crossentropy',optimizer=optimizers.RMSprop(lr=1e-4),metrics=['acc'])

train_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(train_dir,target_size=(150, 150),batch_size=20, class_mode='binary')
val_generator = test_datagen.flow_from_directory(val_dir,target_size=(150, 150),batch_size=20,class_mode='binary')


history = model.fit_generator(train_generator,steps_per_epoch=100,epochs=30,validation_data=val_generator,validation_steps=50)
 

Это приводит меня к следующей ошибке:

   warnings.warn('`Model.fit_generator` is deprecated and '
2021-07-10 13:04:09.841898: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:176] None of the MLIR Optimization Passes are enabled (registered 2)
Epoch 1/30
Traceback (most recent call last):
  File "C:/Users/User/PycharmProjects/dog_vs_cat/model.py", line 33, in <module>
    history = model.fit_generator(train_generator,steps_per_epoch=100,epochs=30,validation_data=val_generator,validation_steps=50)
  File "C:UsersUserAppDataLocalProgramsPythonPython36libsite-packageskerasenginetraining.py", line 1932, in fit_generator
    initial_epoch=initial_epoch)
  File "C:UsersUserAppDataLocalProgramsPythonPython36libsite-packageskerasenginetraining.py", line 1158, in fit
    tmp_logs = self.train_function(iterator)
  File "C:UsersUserAppDataLocalProgramsPythonPython36libsite-packagestensorflowpythoneagerdef_function.py", line 889, in __call__
    result = self._call(*args, **kwds)
  File "C:UsersUserAppDataLocalProgramsPythonPython36libsite-packagestensorflowpythoneagerdef_function.py", line 950, in _call
    return self._stateless_fn(*args, **kwds)
  File "C:UsersUserAppDataLocalProgramsPythonPython36libsite-packagestensorflowpythoneagerfunction.py", line 3024, in __call__
    filtered_flat_args, captured_inputs=graph_function.captured_inputs)  # pylint: disable=protected-access
  File "C:UsersUserAppDataLocalProgramsPythonPython36libsite-packagestensorflowpythoneagerfunction.py", line 1961, in _call_flat
    ctx, args, cancellation_manager=cancellation_manager))
  File "C:UsersUserAppDataLocalProgramsPythonPython36libsite-packagestensorflowpythoneagerfunction.py", line 596, in call
    ctx=ctx)
  File "C:UsersUserAppDataLocalProgramsPythonPython36libsite-packagestensorflowpythoneagerexecute.py", line 60, in quick_execute
    inputs, attrs, num_outputs)
tensorflow.python.framework.errors_impl.InvalidArgumentError:  Default MaxPoolingOp only supports NHWC on device type CPU
     [[node sequential/max_pooling2d/MaxPool (defined at UsersUserAppDataLocalProgramsPythonPython36libsite-packageskeraslayerspooling.py:355) ]] [Op:__inference_train_function_1187]

Errors may have originated from an input operation.
Input Source operations connected to node sequential/max_pooling2d/MaxPool:
 sequential/conv2d/Relu (defined at UsersUserAppDataLocalProgramsPythonPython36libsite-packageskerasbackend.py:4700)

Function call stack:
train_function


Process finished with exit code 1
 

Я поискал, и мне посоветовали использовать data_format="channels_last" в качестве входной формы, которую я использую. Затем я изменил форму ввода на (3,150,150) с data_format="channels_first" , она по-прежнему выдает ту же ошибку.

Я использую Keras 2.4.3.

Какая-нибудь помощь?

Комментарии:

1. Что вы использовали в качестве входного слоя?

2. модель.добавить(слои. Conv2D(32, (3, 3), активация=’relu’,input_shape=(150, 150, 3),заполнение=’то же самое’)) Похоже, я пропустил самый важный слой при написании вопроса.

3. Теперь ваша проблема решена? в противном случае, можно попробовать выполнить в автономном коде, чтобы воспроизвести вашу проблему? чтобы мы могли попытаться вам помочь. Спасибо!

Ответ №1:

Этот код работает нормально, когда я повторил ту же проблему в keras версии 2.4.3

Рабочий пример кода:

 !pip install keras==2.4.3
import keras

model = Sequential()
#add model layers
model.add(layers.Conv2D(32, (3, 3), activation='relu',input_shape=(150, 150, 3),padding='same'))
model.add(layers.MaxPooling2D((2, 2),strides=(2,2), padding='same'))
model.add(layers.Conv2D(64, (3, 3), activation='relu', padding='same'))
model.add(layers.MaxPooling2D((2, 2),strides=(2,2), padding='same'))
model.add(layers.Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(layers.MaxPooling2D((2, 2), strides=(2,2),padding='same'))
model.add(layers.Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(layers.MaxPooling2D((2, 2),strides=(2,2), padding='same'))
model.add(layers.Flatten())
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

train_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(train_directory,target_size=(150, 150),batch_size=5, class_mode='binary')
val_generator = test_datagen.flow_from_directory(Val_directory ,target_size=(150, 150),batch_size=5,class_mode='binary')
#Modified
from keras.optimizers import RMSprop
model.compile(loss='binary_crossentropy',optimizer=RMSprop(),metrics=['acc'])
history = model.fit(train_generator,epochs=4,steps_per_epoch=4,validation_data=val_generator,validation_steps=50)
 

Выход:

 Epoch 1/4
4/4 [==============================] - ETA: 0s - loss: 1.0794 - acc: 0.7500WARNING:tensorflow:Your input ran out of data; interrupting training. Make sure that your dataset or generator can generate at least `steps_per_epoch * epochs` batches (in this case, 50 batches). You may need to use the repeat() function when building your dataset.
4/4 [==============================] - 4s 753ms/step - loss: 1.0794 - acc: 0.7500 - val_loss: 1.4395 - val_acc: 0.5000
Epoch 2/4
4/4 [==============================] - 1s 348ms/step - loss: 0.3407 - acc: 0.8500
Epoch 3/4
4/4 [==============================] - 1s 349ms/step - loss: 0.6352 - acc: 0.7500
Epoch 4/4
4/4 [==============================] - 1s 357ms/step - loss: 0.3096 - acc: 0.9000