I am following a course on machine learning and am making a CNN model with the cats and dogs data from Kaggle.
When I fit the model with a validation generator as validation data, the model will run for one full epoch, a second failed epoch and stops at the third epoch with error:
line 2 AttributeError: 'NoneType' object has no attribute 'items'
The code I wrote is almost exactly as in the video but, the video is from 2019 so I had to make some adjustments:
model.fit()
> video: model.fit_generator()
I would like to understand what is causing this error.
As far as I have been able to figure out, the issue has something to do with the validation_generator
/ validation_data
parameter:
These two options will make the model run to completion but, still alternate between a full epoch and a failed epoch with 0 value and 0 loss.
validation_data
and validation_steps
in the fit()validation_steps
to 49I have also tried changing the loss and optimizer in compile()
, as well as change the output layer.
This is my full code, python 3.11, tensorflow 2.16.1:
import numpy as np
import pandas as pd
%matplotlib inline
import matplotlib as mpl
import matplotlib.pyplot as plt
import os
import tensorflow as tf
# from tensorflow import keras
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# Source files https://drive.google.com/file/d/16AlwTDOeyFaiP3RPxKOk5s80IycK80X4/view
# set Train/Test/Validation locations
main_dir = '/home/_/VSCode/Python/udemy/Data Files/cats_and_dogs'
train_dir = main_dir + '/train'
test_dir = main_dir +'/test'
validation_dir = main_dir + '/validation'
# Create Generator objects and rescale
train_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)
# Create generators:
train_generator = train_datagen.flow_from_directory(
train_dir,
target_size = (150, 150),
batch_size = 20,
class_mode = 'binary',
color_mode = 'rgb'
)
validation_generator = test_datagen.flow_from_directory(
validation_dir,
target_size = (150, 150),
batch_size = 10,
class_mode = 'binary',
color_mode = 'rgb'
)
# Test validation generator (works)
for data_batch, labels_batch in validation_generator:
print('Data batch shape:', data_batch.shape)
print('Labels batch shape:', labels_batch.shape)
break
model = tf.keras.Sequential()
model.add(tf.keras.layers.Input(shape=(150, 150, 3)))
# Create 4 Convolutional layers and pooling layers
model.add(tf.keras.layers.Conv2D(32, (3,3), activation='relu'))
model.add(tf.keras.layers.MaxPooling2D((2, 2)))
model.add(tf.keras.layers.Conv2D(64, (3,3), activation='relu'))
model.add(tf.keras.layers.MaxPooling2D((2, 2)))
model.add(tf.keras.layers.Conv2D(128, (3,3), activation='relu'))
model.add(tf.keras.layers.MaxPooling2D((2, 2)))
model.add(tf.keras.layers.Conv2D(256, (3,3), activation='relu'))
model.add(tf.keras.layers.MaxPooling2D((2, 2)))
# Flatten and Dense layers
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(512, activation='relu'))
model.add(tf.keras.layers.Dense(1, activation='sigmoid'))
# Compile the model
model.compile(loss='binary_crossentropy',
optimizer = tf.keras.optimizers.RMSprop(learning_rate=1e-4),
metrics = ['accuracy'])
2024-06-10 14:56:36.689735: I external/local_tsl/tsl/cuda/cudart_stub.cc:32] Could not find cuda drivers on your machine, GPU will not be used.
2024-06-10 14:56:37.069020: I external/local_tsl/tsl/cuda/cudart_stub.cc:32] Could not find cuda drivers on your machine, GPU will not be used.
2024-06-10 14:56:41.409236: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT
Found 2000 images belonging to 2 classes.
Found 1000 images belonging to 2 classes.
# Fit the model -> validation_data on, validation_steps 50 (batch_size = 10)
model_history2 = model.fit(
x = train_generator,
steps_per_epoch = 100,
epochs = 20,
validation_data = validation_generator,
validation_steps = 50
)
The output:
Epoch 1/20
/home/user/.local/share/virtualenvs/udemy-B00hqPiI/lib/python3.11/site-packages/keras/src/trainers/data_adapters/py_dataset_adapter.py:121: UserWarning: Your `PyDataset` class should call `super().__init__(**kwargs)` in its constructor. `**kwargs` can include `workers`, `use_multiprocessing`, `max_queue_size`. Do not pass these arguments to `fit()`, as they will be ignored.
self._warn_if_super_not_called()
100/100 ━━━━━━━━━━━━━━━━━━━━ 143s 1s/step - accuracy: 0.5086 - loss: 0.6935 - val_accuracy: 0.5380 - val_loss: 0.6850
Epoch 2/20
2024-06-09 22:15:15.482783: W tensorflow/core/framework/local_rendezvous.cc:404] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence
[[{{node IteratorGetNext}}]]
/usr/lib/python3.11/contextlib.py:155: UserWarning: Your input ran out of data; interrupting training. Make sure that your dataset or generator can generate at least `steps_per_epoch * epochs` batches. You may need to use the `.repeat()` function when building your dataset.
self.gen.throw(typ, value, traceback)
100/100 ━━━━━━━━━━━━━━━━━━━━ 9s 93ms/step - accuracy: 0.0000e+00 - loss: 0.0000e+00 - val_accuracy: 0.5480 - val_loss: 0.6847
Epoch 3/20
100/100 ━━━━━━━━━━━━━━━━━━━━ 0s 1s/step - accuracy: 0.5600 - loss: 0.6801
2024-06-09 22:18:25.040161: W tensorflow/core/framework/local_rendezvous.cc:404] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence
[[{{node IteratorGetNext}}]]
line 2 AttributeError: 'NoneType' object has no attribute 'items'
Full error report:
line 2 AttributeError: 'NoneType' object has no attribute 'items'
Hide Details
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[4], line 2
1 # Fit the model
----> 2 model_history2 = model.fit(
3 x = train_generator,
4 steps_per_epoch = 100,
5 epochs = 20,
6 validation_data = validation_generator,
7 validation_steps = 50
8
9 )
File ~/.local/share/virtualenvs/udemy-B00hqPiI/lib/python3.11/site-packages/keras/src/utils/traceback_utils.py:122, in filter_traceback.<locals>.error_handler(*args, **kwargs)
119 filtered_tb = _process_traceback_frames(e.__traceback__)
120 # To get the full stack trace, call:
121 # `keras.config.disable_traceback_filtering()`
--> 122 raise e.with_traceback(filtered_tb) from None
123 finally:
124 del filtered_tb
File ~/.local/share/virtualenvs/udemy-B00hqPiI/lib/python3.11/site-packages/keras/src/backend/tensorflow/trainer.py:350, in TensorFlowTrainer.fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_batch_size, validation_freq)
329 self._eval_epoch_iterator = TFEpochIterator(
330 x=val_x,
331 y=val_y,
(...)
337 shuffle=False,
338 )
339 val_logs = self.evaluate(
340 x=val_x,
341 y=val_y,
(...)
347 _use_cached_eval_dataset=True,
348 )
349 val_logs = {
--> 350 "val_" + name: val for name, val in val_logs.items()
351 }
352 epoch_logs.update(val_logs)
354 callbacks.on_epoch_end(epoch, epoch_logs)
AttributeError: 'NoneType' object has no attribute 'items'
You could use validation_batch_size
instead of validation_steps
to solve the problem.