python - AttributeError: 'list' object has no attribute 'rank' 将 Keras 模型转换为 CoreML 时
问题描述
我正在尝试将包含 GRU 层以生成莎士比亚文本的 Keras 模型转换为 coreml 模型,尽管当我尝试转换它时,我收到错误“AttributeError:'list' object has no attribute 'rank'”。我按照本网站上的说明进行操作。这是我的代码:
import tensorflow as tf
from tensorflow import keras
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import coremltools as ct
model = keras.models.load_model("checkpointshakespear.h5")
mlmodel = ct.convert(model)
这是我的模型层:
model = keras.models.Sequential([
keras.layers.GRU(128, return_sequences=True, input_shape=[None, max_id],
dropout=0.2, recurrent_dropout=0.2),
keras.layers.GRU(128, return_sequences=True,
dropout=0.2, recurrent_dropout=0.2),
keras.layers.TimeDistributed(keras.layers.Dense(max_id,
activation="softmax"))
])
model.compile(loss="sparse_categorical_crossentropy", optimizer="adam")
这是完整的错误:
Running TensorFlow Graph Passes: 100%|██████████| 5/5 [00:00<00:00, 9.78 passes/s]
Converting Frontend ==> MIL Ops: 0%| | 0/84 [00:00<?, ? ops/s]
Converting Frontend ==> MIL Ops: 0%| | 0/95 [00:00<?, ? ops/s]
Converting Frontend ==> MIL Ops: 0%| | 0/84 [00:00<?, ? ops/s]
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-2-8240f4ae502a> in <module>
6 import coremltools as ct
7 model = keras.models.load_model("checkpointshakespear.h5")
----> 8 mlmodel = ct.convert(model)
~/opt/anaconda3/lib/python3.7/site-packages/coremltools/converters/_converters_entry.py in convert(model, source, inputs, outputs, classifier_config, minimum_deployment_target, **kwargs)
256 outputs=outputs,
257 classifier_config=classifier_config,
--> 258 **kwargs
259 )
260
~/opt/anaconda3/lib/python3.7/site-packages/coremltools/converters/mil/converter.py in _convert(model, convert_from, convert_to, converter_registry, **kwargs)
118 backend_converter = backend_converter_type()
119
--> 120 prog = frontend_converter(model, **kwargs)
121 common_pass(prog)
122 out = backend_converter(prog, **kwargs)
~/opt/anaconda3/lib/python3.7/site-packages/coremltools/converters/mil/converter.py in __call__(self, *args, **kwargs)
50
51 tf2_loader = TF2Loader(*args, **kwargs)
---> 52 return tf2_loader.load()
53
54
~/opt/anaconda3/lib/python3.7/site-packages/coremltools/converters/mil/frontend/tensorflow/load.py in load(self)
78 )
79
---> 80 program = self._program_from_tf_ssa()
81 logging.debug("program:\n{}".format(program))
82 return program
~/opt/anaconda3/lib/python3.7/site-packages/coremltools/converters/mil/frontend/tensorflow2/load.py in _program_from_tf_ssa(self)
179
180 converter = TF2Converter(self._tf_ssa, **self.kwargs)
--> 181 return converter.convert()
182
183 def _populate_sub_graph_input_shapes(self, graph, graph_fns):
~/opt/anaconda3/lib/python3.7/site-packages/coremltools/converters/mil/frontend/tensorflow/converter.py in convert(self)
392 for g_name in self.graph_stack[1:]:
393 self.context.add_graph(g_name, self.tfssa.functions[g_name].graph)
--> 394 self.convert_main_graph(prog, graph)
395
396 # Apply TF frontend passes on Program. These passes are different
~/opt/anaconda3/lib/python3.7/site-packages/coremltools/converters/mil/frontend/tensorflow/converter.py in convert_main_graph(self, prog, graph)
337 for name in func_inputs.keys():
338 self.context.add(name, ssa_func.inputs[name])
--> 339 outputs = convert_graph(self.context, graph, self.outputs)
340 ssa_func.set_outputs(outputs)
341 prog.add_function("main", ssa_func)
~/opt/anaconda3/lib/python3.7/site-packages/coremltools/converters/mil/frontend/tensorflow/convert_utils.py in convert_graph(context, graph, outputs)
179 )
180 raise NotImplementedError(msg)
--> 181 _add_op(context, node)
182
183 if len(node.outputs) > 0:
~/opt/anaconda3/lib/python3.7/site-packages/coremltools/converters/mil/frontend/tensorflow2/ops.py in StatelessWhile(context, node)
98 return body_output_vars
99
--> 100 x = mb.while_loop(_cond=cond, _body=body, loop_vars=loop_vars, name=node.name)
101
102 # wraps x as tuple for get_tuple that always follow the while node.
~/opt/anaconda3/lib/python3.7/site-packages/coremltools/converters/mil/mil/ops/registry.py in add_op(cls, **kwargs)
60 @classmethod
61 def add_op(cls, **kwargs):
---> 62 return cls._add_op(op_cls, **kwargs)
63
64 setattr(Builder, op_type, add_op)
~/opt/anaconda3/lib/python3.7/site-packages/coremltools/converters/mil/mil/builder.py in _add_op(cls, op_cls, **kwargs)
188 new_op = op_cls(**kwargs)
189 curr_block()._insert_op_before(new_op, before_op=before_op)
--> 190 new_op.build_nested_blocks()
191 new_op.type_value_inference()
192 if len(new_op.outputs) == 1:
~/opt/anaconda3/lib/python3.7/site-packages/coremltools/converters/mil/mil/ops/defs/control_flow.py in build_nested_blocks(self)
302 v.consuming_blocks = list()
303
--> 304 block, exit_vars = self.build_block(block_inputs)
305
306 # Verify exit_vars has the same types as loop_vars
~/opt/anaconda3/lib/python3.7/site-packages/coremltools/converters/mil/mil/ops/defs/control_flow.py in build_block(self, block_inputs)
271 # Body func
272 body_func = self._body.val
--> 273 exit_vars = body_func(*block.inputs)
274
275 # Cond func:
~/opt/anaconda3/lib/python3.7/site-packages/coremltools/converters/mil/frontend/tensorflow2/ops.py in body(*loop_vars)
94 def body(*loop_vars):
95 context.stack_func_inputs(loop_vars)
---> 96 body_output_vars = convert_graph(context, body_graph)
97 context.unstack_func_inputs()
98 return body_output_vars
~/opt/anaconda3/lib/python3.7/site-packages/coremltools/converters/mil/frontend/tensorflow/convert_utils.py in convert_graph(context, graph, outputs)
179 )
180 raise NotImplementedError(msg)
--> 181 _add_op(context, node)
182
183 if len(node.outputs) > 0:
~/opt/anaconda3/lib/python3.7/site-packages/coremltools/converters/mil/frontend/tensorflow/ops.py in StridedSlice(context, node)
1351 squeeze_mask,
1352 ellipsis_mask,
-> 1353 new_axis_mask,
1354 )
1355
~/opt/anaconda3/lib/python3.7/site-packages/coremltools/converters/mil/frontend/tensorflow/ops.py in _pad_mask(x, begin, end, stride, begin_mask, end_mask, squeeze_mask, ellipsis_mask, new_axis_mask)
1257 x_rank = x.rank + new_dims
1258 else:
-> 1259 x_rank = x.rank
1260
1261 def pad_array(arr, max_rank, idx, default_value):
AttributeError: 'list' object has no attribute 'rank'
解决方案
看起来错误是由于recurrent_dropout 参数。删除此参数可解决错误。
另请注意,我已将 batch_size 参数添加到第一个 GRU 层。这是必要的,因为对于 RNN,CoreML 输入应该是 3 级(Seq、B、C)或 5 级(Seq、B、C、H、W)。
这是工作代码片段。
import tensorflow.keras as keras
import coremltools as ct
max_id = 1000
model = keras.models.Sequential([
keras.layers.GRU(128, return_sequences=True, input_shape=[None, max_id], batch_size=64,
dropout=0.2),
keras.layers.GRU(128, return_sequences=True,
dropout=0.2),
keras.layers.TimeDistributed(keras.layers.Dense(max_id,
activation="softmax"))
])
model.save('tf_keras_model.h5')
mlmodel = ct.convert('tf_keras_model.h5', source="tensorflow")
推荐阅读
- c++ - bash:g++:在 mac 上的 sublime 文本编辑器中找不到命令
- winbugs - WinBUGS 中的分位数功能
- python - 从 Python 子进程获取最新的流标准输出行
- svg - Blazor - 向 SVG 对象添加元素
- eclipse - 如何使用 Eclipse 调试 Kubernetes 部署的服务
- python - django.db.utils.IntegrityError:NOT NULL 约束失败:new__score_comment.post_id
- angular - 需要传递另一个值来更改事件
- docker - Bitbucket 管道 docker 图像标签在运行期间更改为图像摘要?
- reactjs - Docusaurus v2 项目的文档链接已损坏
- javascript - 如何在角度 6 的编辑模式下动态地在 ngFor 表中添加多行