Keras模型训练报错ValueError: Failed to find data adapter that can handle input: <class 'NoneType'>, <class 'NoneType'>的解决方法咨询
ValueError: Failed to find data adapter that can handle input: <class 'NoneType'>, <class 'NoneType'> Hey there, let's break down what's causing this error and how to fix it quickly:
Root Cause
The error pops up because you're passing validation_data and validation_labels to model.fit() and model.evaluate()—but these variables don't exist anywhere in your code. You also commented out the validation_data_dir line, so even if you wanted to load validation data, there's no path defined for it.
Step-by-Step Fix
1. Uncomment and define your validation data directory
First, uncomment the validation_data_dir line and make sure it points to your actual validation data folder:
# Uncomment this line and set the correct path validation_data_dir = 'data/validation'
2. Generate bottleneck features for validation data
Just like you did for training data, you need to extract VGG16's bottleneck features for your validation set. Add this code right after generating the training bottleneck features:
# Generate bottleneck features for validation data generator_val = datagen.flow_from_directory( validation_data_dir, target_size=(img_width, img_height), batch_size=batch_size, class_mode=None, shuffle=False) nb_val_samples = len(generator_val.filenames) predict_size_val = int(math.ceil(nb_val_samples / batch_size)) bottleneck_features_val = VGG16.predict_generator(generator_val, predict_size_val) np.save('bottleneck_features_val.npy', bottleneck_features_val)
3. Load and process validation labels
Next, load the validation bottleneck data and convert its labels to categorical format—again, mirroring how you handled training data:
# Load validation bottleneck features validation_data = np.load('bottleneck_features_val.npy') # Get validation labels and convert to categorical generator_val_labels = datagen.flow_from_directory( validation_data_dir, target_size=(img_width, img_height), batch_size=batch_size, class_mode='categorical', shuffle=False) validation_labels = generator_val_labels.classes validation_labels = to_categorical(validation_labels, num_classes=num_classes)
4. Update model.fit() and model.evaluate()
Now that validation_data and validation_labels are properly defined, your training and evaluation calls will work as expected.
Full Modified Code Snippet (Key Sections)
Here's how your updated code should look in the relevant parts:
# Uncomment and set validation data path validation_data_dir = 'data/validation' # ... [existing training bottleneck code] ... # Add validation bottleneck generation generator_val = datagen.flow_from_directory( validation_data_dir, target_size=(img_width, img_height), batch_size=batch_size, class_mode=None, shuffle=False) nb_val_samples = len(generator_val.filenames) predict_size_val = int(math.ceil(nb_val_samples / batch_size)) bottleneck_features_val = VGG16.predict_generator(generator_val, predict_size_val) np.save('bottleneck_features_val.npy', bottleneck_features_val) # ... [existing training data loading code] ... # Load and process validation data validation_data = np.load('bottleneck_features_val.npy') generator_val_labels = datagen.flow_from_directory( validation_data_dir, target_size=(img_width, img_height), batch_size=batch_size, class_mode='categorical', shuffle=False) validation_labels = generator_val_labels.classes validation_labels = to_categorical(validation_labels, num_classes=num_classes) # ... [model definition code] ... # Now fit the model with valid validation data history = model.fit(train_data, train_labels, epochs=7, batch_size=batch_size, validation_data=(validation_data, validation_labels)) # Evaluate with valid data too (eval_loss, eval_accuracy) = model.evaluate( validation_data, validation_labels, batch_size=batch_size, verbose=1)
Quick Notes
- Make sure your
data/validationfolder follows the same structure asdata/train(subfolders for each class with images inside). - If you're using a newer TensorFlow version,
predict_generatoris deprecated—you can replace it withgenerator_val.reset()followed byVGG16.predict(generator_val, steps=predict_size_val).
内容的提问来源于stack exchange,提问作者Dropzz

