【问题标题】:'NoneType' object is not subscriptable - error at Keras custom callback class“NoneType”对象不可下标 - Keras 自定义回调类出错
【发布时间】:2019-08-07 09:40:39
【问题描述】:

我在定义自定义回调函数时收到此错误。

'NoneType' object is not subscriptable

代码示例

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)

之前我遇到了另一个错误:"AttributeError: 'Sequential' object has no attribute 'validation_data'. 为了解决该错误,我按照建议here 删除了self.model.validation_dataself.validation_data。之后我遇到了这个错误。我无法理解此错误的来源

Keras 版本是 2.2.4

按要求完成回溯

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

更新

根据建议,我正在使用 keras 进行回调,即class Metrics(keras.callback.Callback)。在这个解决方案之后,我原来的错误消失了,但我得到另一个错误是AttributeError: 'Metrics' object has no attribute 'on_train_batch_begin' 我真的不知道这个错误。

新错误的回溯是

    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'

【问题讨论】:

标签: tensorflow keras tf.keras


【解决方案1】:

这是tf.keras 中的一个错误,他们弃用了validation_data 参数并且不再设置回调的validation_data,它始终设置为None。

您的选择是不使用tf.keras,而只使用官方的keras 包,我测试了您的代码,它在Keras 2.2.4 中工作。或者,您也可以将验证数据传递给回调的__init__ 并将其设置在那里。

【讨论】:

  • @mdaoust 他们是谁?在 Keras 中还没有看到这样的变化。另外我看不到原始帖子中的哪里有生成器。 Keras 也接受 fit 中的 steps 参数但忽略它们。
  • 对,我本可以在我的其他评论中更清楚(已修复)。 (item for item in image_data) 是一个 python 生成器。没有办法知道它有多长。 Model.fit 很清楚它supports generators
  • 他们(keras 作者)已将fit_generator 的所有功能合并到fit 中。请注意,他们(海报)正在传递生成器,所以我认为这不是问题
  • @mdaoust 该链接适用于 TensorFlow 2.0,在这里我得到了相互矛盾的信息,因为 OP 声称使用的是 Keras 2.2.4,我可以从 tensorflow 1.14 重现 tf.keras 的问题。请注意,tf.keras 中的版本是 '2.2.4-tf',而不是 '2.2.4'
  • @MatiasValdenegro 我已经尝试过您的解决方案,现在我收到此错误 'AttributeError: 'Metrics' object has no attribute 'on_train_batch_begin' 我的 keras 版本是 2.2.4
【解决方案2】:

我认为您可以通过将validation_dataset 传递给您的Metrics 类而不是依赖于..来解决这个问题。self.validation_data 应该如何设置?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-04
    • 2020-09-03
    • 2022-01-15
    • 1970-01-01
    • 2013-09-22
    • 1970-01-01
    相关资源
    最近更新 更多