Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'NoneType' object is not subscriptable - error at Keras custom callback class

I am getting this error when I am defining a custom callback function.

'NoneType' object is not subscriptable

Code sample

class Metrics(tf.keras.callbacks.Callback):     
  def on_train_begin(self, logs={}):
        self._data = []
  def on_epoch_end(self, batch, logs={}):
        X_val, y_val = self.validation_data[0], self.validation_data[1]
        y_predict = np.asarray(model.predict(X_val))
        y_val = np.argmax(y_val, axis=1)
        y_predict = np.argmax(y_predict, axis=1)
        self._data.append({
          'val_jaccard': jaccard(y_val, y_predict),
          'val_f1': f1_score(y_val, y_predict),
          'val_precision': recall_score(y_val, y_predict),
          'val_jaccard': precision_score(y_val, y_predict),
     })
    return

metrics = Metrics()
model.fit((item for item in image_data),steps_per_epoch=steps_per_epoch, 
     epochs=20, validation_data = (item for item in image_data_val), validation_steps = valid_step , callbacks = [metrics], verbose=2)

Previously I was getting another error: "AttributeError: 'Sequential' object has no attribute 'validation_data'. In order to solve that error, I removed self.model.validation_data with self.validation_data as suggested here. After which I landed up to this error. I am not able to understand the source of this error

Keras version is 2.2.4

Complete traceback as requested

Epoch 1/20

Exception ignored in: <bound method BaseSession._Callable.__del__ of <tensorflow.python.client.session.BaseSession._Callable object at 0x7f8fbe48fa20>>
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/client/session.py", line 1473, in __del__
    self._session._session, self._handle)
tensorflow.python.framework.errors_impl.CancelledError: (None, None, 'Session has been closed.')
Exception ignored in: <bound method BaseSession._Callable.__del__ of <tensorflow.python.client.session.BaseSession._Callable object at 0x7f8fbe42f2e8>>
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/client/session.py", line 1473, in __del__
    self._session._session, self._handle)
tensorflow.python.framework.errors_impl.CancelledError: (None, None, 'Session has been closed.')

---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-102-43fa8dafc96c> in <module>()
      5     model.fit((item for item in image_data),steps_per_epoch=steps_per_epoch, epochs=20,
      6                     validation_data = (item for item in image_data_val),
----> 7                     validation_steps = valid_step , callbacks = [metrics], verbose=2)
      8     eval_model=model.evaluate(image_batch, label_batch)
      9     eval_model

4 frames

/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py in 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_freq, max_queue_size, workers, use_multiprocessing, **kwargs)
    671           use_multiprocessing=use_multiprocessing,
    672           shuffle=shuffle,
--> 673           initial_epoch=initial_epoch)
    674     if training_utils.is_eager_dataset_or_iterator(x):
    675       # Make sure that y, sample_weights, validation_split are not passed.

/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py in fit_generator(self, generator, steps_per_epoch, epochs, verbose, callbacks, validation_data, validation_steps, validation_freq, class_weight, max_queue_size, workers, use_multiprocessing, shuffle, initial_epoch)
   1431         shuffle=shuffle,
   1432         initial_epoch=initial_epoch,
-> 1433         steps_name='steps_per_epoch')
   1434 
   1435   def evaluate_generator(self,

/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training_generator.py in model_iteration(model, data, steps_per_epoch, epochs, verbose, callbacks, validation_data, validation_steps, validation_freq, class_weight, max_queue_size, workers, use_multiprocessing, shuffle, initial_epoch, mode, batch_size, steps_name, **kwargs)
    329     if mode == ModeKeys.TRAIN:
    330       # Epochs only apply to `fit`.
--> 331       callbacks.on_epoch_end(epoch, epoch_logs)
    332     progbar.on_epoch_end(epoch, epoch_logs)
    333 

/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/callbacks.py in on_epoch_end(self, epoch, logs)
    309     logs = logs or {}
    310     for callback in self.callbacks:
--> 311       callback.on_epoch_end(epoch, logs)
    312 
    313   def on_train_batch_begin(self, batch, logs=None):

<ipython-input-101-71d6af0b20ff> in on_epoch_end(self, batch, logs)
     14 
     15   def on_epoch_end(self, batch, logs={}):
---> 16         X_val, y_val = self.validation_data[0], self.validation_data[1]
     17         y_predict = np.asarray(model.predict(X_val))
     18         y_val = np.argmax(y_val, axis=1)

TypeError: 'NoneType' object is not subscriptable

UPDATE

Based on the suggestion, I am using keras for callback i.e class Metrics(keras.callback.Callback). After this solution, my original error is gone but I am getting another error which is AttributeError: 'Metrics' object has no attribute 'on_train_batch_begin' I don't really know this error.

The traceback for the new error is

    Epoch 1/20

---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-60-43fa8dafc96c> in <module>()
      5     model.fit((item for item in image_data),steps_per_epoch=steps_per_epoch, epochs=20,
      6                     validation_data = (item for item in image_data_val),
----> 7                     validation_steps = valid_step , callbacks = [metrics], verbose=2)
      8     eval_model=model.evaluate(image_batch, label_batch)
      9     eval_model

3 frames

/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py in 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_freq, max_queue_size, workers, use_multiprocessing, **kwargs)
    671           use_multiprocessing=use_multiprocessing,
    672           shuffle=shuffle,
--> 673           initial_epoch=initial_epoch)
    674     if training_utils.is_eager_dataset_or_iterator(x):
    675       # Make sure that y, sample_weights, validation_split are not passed.

/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py in fit_generator(self, generator, steps_per_epoch, epochs, verbose, callbacks, validation_data, validation_steps, validation_freq, class_weight, max_queue_size, workers, use_multiprocessing, shuffle, initial_epoch)
   1431         shuffle=shuffle,
   1432         initial_epoch=initial_epoch,
-> 1433         steps_name='steps_per_epoch')
   1434 
   1435   def evaluate_generator(self,

/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training_generator.py in model_iteration(model, data, steps_per_epoch, epochs, verbose, callbacks, validation_data, validation_steps, validation_freq, class_weight, max_queue_size, workers, use_multiprocessing, shuffle, initial_epoch, mode, batch_size, steps_name, **kwargs)
    258       # Callbacks batch begin.
    259       batch_logs = {'batch': step, 'size': batch_size}
--> 260       callbacks._call_batch_hook(mode, 'begin', step, batch_logs)
    261       progbar.on_batch_begin(step, batch_logs)
    262 

/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/callbacks.py in _call_batch_hook(self, mode, hook, batch, logs)
    245     t_before_callbacks = time.time()
    246     for callback in self.callbacks:
--> 247       batch_hook = getattr(callback, hook_name)
    248       batch_hook(batch, logs)
    249     self._delta_ts[hook_name].append(time.time() - t_before_callbacks)

AttributeError: 'Metrics' object has no attribute 'on_train_batch_begin'
like image 498
user3050590 Avatar asked Aug 07 '19 09:08

user3050590


People also ask

How do I fix NoneType object is not Subscriptable?

TypeError: 'NoneType' object is not subscriptable Solution The best way to resolve this issue is by not assigning the sort() method to any variable and leaving the numbers.

What does NoneType object is not Subscriptable mean?

The error, NoneType object is not subscriptable, means that you were trying to subscript a NoneType object. This resulted in a type error. 'NoneType' object is not subscriptable is the one thrown by python when you use the square bracket notation object[key] where an object doesn't define the __getitem__ method.


1 Answers

Its a bug in tf.keras, they deprecated the validation_data parameter and no longer set the validation_data of the callback, its always set to None.

Your option is not to use tf.keras and just use the official keras package, I tested your code and it works in Keras 2.2.4. Alternatively you could also just pass your validation data to the __init__ of your callback and set it there.

like image 99
Dr. Snoopy Avatar answered Nov 15 '22 08:11

Dr. Snoopy