首页 > 解决方案 > Keras:什么是“浅层结构”?

问题描述

在使用 Keras 和 Tensorflow 2.3.1 训练网络时,我收到以下错误消息:

TypeError: The two structures don't have the same sequence type. Input structure has type <class 'list'>, while shallow structure has type <class 'dict'>.

我可以猜测输入结构与在方法期间提供给keras.layers.Input()对象的数据类型有关fit()。但我无法猜测“浅层结构”是什么。

model.fit()调用方法时出现上述错误。在那里,我使用 TF 数据集来提供以下形式的元组:(input_data, {"target1": target1, "target1": target2})。因此,“输入结构”应该是一个字典,但它也可以被认为是列表。

我的问题是:在这种情况下,什么是“浅层结构”?

编辑#1:这是完整的回溯:

  File "<ipython-input-2-0c8f2fdd652d>", line 1, in <module>
    runfile('/Users/username/my_repo/my_trainer_R2.py', wdir='/Users/username/my_repo')
  File "/Users/username/Library/Application Support/JetBrains/Toolbox/apps/PyCharm-P/ch-0/203.5981.165/PyCharm 2020.3 EAP.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/pydev_umd.py", line 197, in runfile
    pydev_imports.execfile(filename, global_vars, local_vars)  # execute the script
  File "/Users/username/Library/Application Support/JetBrains/Toolbox/apps/PyCharm-P/ch-0/203.5981.165/PyCharm 2020.3 EAP.app/Contents/plugins/python/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "/Users/username/my_repo/my_trainer_R2.py", line 131, in <module>
    graph_builder.train_model(dataset_train_tuple, dataset_valid_tuple, n_epochs, n_batch_size, run_dir=run_dir, run_name=run_name, valid_dataset=pipeline_valid.get_dataset(), plotting_records=plotting_records[0])
  File "/Users/username/my_repo/graph_builder_R2.py", line 401, in train_model
    callbacks    = [early_stopping_cb, tensorboard_cb, checkpoint_cb, general_callbacks]
  File "/Users/username/.local/lib/python3.7/site-packages/tensorflow/python/keras/engine/training.py", line 108, in _method_wrapper
    return method(self, *args, **kwargs)
  File "/Users/username/.local/lib/python3.7/site-packages/tensorflow/python/keras/engine/training.py", line 1098, in fit
    tmp_logs = train_function(iterator)
  File "/Users/username/.local/lib/python3.7/site-packages/tensorflow/python/eager/def_function.py", line 780, in __call__
    result = self._call(*args, **kwds)
  File "/Users/username/.local/lib/python3.7/site-packages/tensorflow/python/eager/def_function.py", line 823, in _call
    self._initialize(args, kwds, add_initializers_to=initializers)
  File "/Users/username/.local/lib/python3.7/site-packages/tensorflow/python/eager/def_function.py", line 697, in _initialize
    *args, **kwds))
  File "/Users/username/.local/lib/python3.7/site-packages/tensorflow/python/eager/function.py", line 2855, in _get_concrete_function_internal_garbage_collected
    graph_function, _, _ = self._maybe_define_function(args, kwargs)
  File "/Users/username/.local/lib/python3.7/site-packages/tensorflow/python/eager/function.py", line 3213, in _maybe_define_function
    graph_function = self._create_graph_function(args, kwargs)
  File "/Users/username/.local/lib/python3.7/site-packages/tensorflow/python/eager/function.py", line 3075, in _create_graph_function
    capture_by_value=self._capture_by_value),
  File "/Users/username/.local/lib/python3.7/site-packages/tensorflow/python/framework/func_graph.py", line 986, in func_graph_from_py_func
    func_outputs = python_func(*func_args, **func_kwargs)
  File "/Users/username/.local/lib/python3.7/site-packages/tensorflow/python/eager/def_function.py", line 600, in wrapped_fn
    return weak_wrapped_fn().__wrapped__(*args, **kwds)
  File "/Users/username/.local/lib/python3.7/site-packages/tensorflow/python/framework/func_graph.py", line 973, in wrapper
    raise e.ag_error_metadata.to_exception(e)
TypeError: in user code:
    /Users/username/.local/lib/python3.7/site-packages/tensorflow/python/keras/engine/training.py:806 train_function  *
        return step_function(self, iterator)
    /Users/username/.local/lib/python3.7/site-packages/tensorflow/python/keras/engine/training.py:796 step_function  **
        outputs = model.distribute_strategy.run(run_step, args=(data,))
    /Users/username/.local/lib/python3.7/site-packages/tensorflow/python/distribute/distribute_lib.py:1211 run
        return self._extended.call_for_each_replica(fn, args=args, kwargs=kwargs)
    /Users/username/.local/lib/python3.7/site-packages/tensorflow/python/distribute/distribute_lib.py:2585 call_for_each_replica
        return self._call_for_each_replica(fn, args, kwargs)
    /Users/username/.local/lib/python3.7/site-packages/tensorflow/python/distribute/distribute_lib.py:2945 _call_for_each_replica
        return fn(*args, **kwargs)
    /Users/username/.local/lib/python3.7/site-packages/tensorflow/python/keras/engine/training.py:789 run_step  **
        outputs = model.train_step(data)
    /Users/username/.local/lib/python3.7/site-packages/tensorflow/python/keras/engine/training.py:759 train_step
        self.compiled_metrics.update_state(y, y_pred, sample_weight)
    /Users/username/.local/lib/python3.7/site-packages/tensorflow/python/keras/engine/compile_utils.py:388 update_state
        self.build(y_pred, y_true)
    /Users/username/.local/lib/python3.7/site-packages/tensorflow/python/keras/engine/compile_utils.py:319 build
        self._metrics, y_true, y_pred)
    /Users/username/.local/lib/python3.7/site-packages/tensorflow/python/util/nest.py:1139 map_structure_up_to
        **kwargs)
    /Users/username/.local/lib/python3.7/site-packages/tensorflow/python/util/nest.py:1221 map_structure_with_tuple_paths_up_to
        expand_composites=expand_composites)
    /Users/username/.local/lib/python3.7/site-packages/tensorflow/python/util/nest.py:825 assert_shallow_structure
        shallow_type=type(shallow_tree)))
    TypeError: The two structures don't have the same sequence type. Input structure has type <class 'list'>, while shallow structure has type <class 'dict'>.

标签: pythontensorflowkerastensorflow2.0tf.keras

解决方案


如果有人仍然有这个问题 - 它可以通过首先获得浅层然后根据您的需要进行修改来解决。

例子:

import tensorflow_datasets as tfds
ds = tfds.load('mnist', split='train', shuffle_files=True)

from tensorflow.python.data.ops import dataset_ops

dataset_ops.get_legacy_output_shapes(ds)

然后你可以修改输出:

{'image': TensorShape([28, 28, 1]), 'label': TensorShape([])}

至:

{'image': [28, 28, 1], 'label': []}

您可以在 padded_batch 中使用它来应用填充。在这种情况下,从 1 通道到 3。如果输入的一种大小具有可变长度,只需使用 None 代替固定数字,它将被填充到批处理中的最大大小(即 [28, 28, None] 如果你有此数据集中图像中的可变通道数):

list(ds.padded_batch(1,padded_shapes={'image': [28, 28, 3], 'label': []}).take(1))

结果:

[{'image': <tf.Tensor: shape=(1, 28, 28, 3), dtype=uint8, numpy=
  array([[[[0, 0, 0],
           [0, 0, 0],
           [0, 0, 0],
           ...,
           [0, 0, 0],
           [0, 0, 0],
           [0, 0, 0]],
  
          [[0, 0, 0],
           [0, 0, 0],
           [0, 0, 0],
           ...,
           [0, 0, 0],
           [0, 0, 0],
           [0, 0, 0]],
  
          [[0, 0, 0],
           [0, 0, 0],
           [0, 0, 0],
           ...,
           [0, 0, 0],
           [0, 0, 0],
           [0, 0, 0]],
  
          ...,
  
          [[0, 0, 0],
           [0, 0, 0],
           [0, 0, 0],
           ...,
           [0, 0, 0],
           [0, 0, 0],
           [0, 0, 0]],
  
          [[0, 0, 0],
           [0, 0, 0],
           [0, 0, 0],
           ...,
           [0, 0, 0],
           [0, 0, 0],
           [0, 0, 0]],
  
          [[0, 0, 0],
           [0, 0, 0],
           [0, 0, 0],
           ...,
           [0, 0, 0],
           [0, 0, 0],
           [0, 0, 0]]]], dtype=uint8)>,
  'label': <tf.Tensor: shape=(1,), dtype=int64, numpy=array([4])>}]

希望这会有所帮助。


推荐阅读