创建 CoreML LRCN 模型

Creating a CoreML LRCN model

您好,在此先感谢您或提供的任何帮助或指导!

我的问题源于 Apple 的 CoreML 文档站点上 posted 的一篇文章。这篇文章的主题在 WWDC 2017 的讲座中也有涉及,我觉得它很有趣。我最近 post 提出了一个问题,该问题与我正在从事的同一项目的一部分有关,并且很容易解决;然而,随着我进一步深入这项工作,我发现自己并不了解该模型的一部分是如何实施的。

首先,我有一个在 Keras 中构建的模型,它有一个 Tensorflow 后端,它在时间分布式包装器中使用卷积层。在卷积部分之后,单个 LSTM 层连接到密集层作为输出。目标是创建多对多结构,对填充的图像序列中的每个项目进行分类。我将 post 下面模型的代码。

我训练和部署这个网络的计划可能会在未来提出其他问题,但如果它们造成麻烦,我会单独提出一个 post。它涉及使用时间分布式包装器进行训练,然后将其从模型中剥离并在 CoreML 转换时加载包装层的权重,因为时间分布式包装器不能很好地与 CoreML 配合使用。

我的问题是:

在上述文章中(以及我在 GitHub 上找到的一个 CormeML 示例项目),实现非常巧妙。由于 CoreML(或至少是常用转换器)不支持图像序列作为输入,因此一次输入一个图像,并且 LSTM 状态作为输出与输入图像的预测一起传出网络。对于序列中的下一张图像,用户将图像连同前一个时间步长的 LSTM 状态一起传递,这样模型就可以 "pick up where it left off" 可以这么说并将单个输入作为一个序列来处理。它有点形成 LSTM 状态的循环(这在 Apple 文章中有更详细的介绍)。现在,对于实际问题部分...

这是如何在像 Keras 这样的库中实现的?到目前为止,我已经成功地使用函数 API 和 LSTM 层上的 "return_state" 设置输出 LSTM 状态,并将其路由到辅助输出。很简单。没那么简单(至少对我而言),是如何将该状态传递回网络以进行下一次预测。我查看了 LSTM 层的源代码和文档,但没有看到任何作为状态输入跳出的内容。我唯一能想到的就是可能使 LSTM 层成为它自己的模型并使用 "initial_state" 来设置它,但是基于我发现的 Keras GitHub 上的 post,看起来模型需要一个自定义调用函数,我不确定如何将它应用到 CoreML 中。仅供参考,我计划将隐藏状态和单元状态循环进出模型,除非这不是必需的,并且只应使用隐藏状态,如 Apple 的模型所示。

再次感谢。始终感谢提供的任何帮助!

我现在的模型是这样的:

image_input = Input(shape=(max_sequence_length, 224, 224, 3))
hidden_state_input = Input(shape=((None, 256)))
cell_state_input = Input(shape=((None, 256)))

convolutional_1 = TimeDistributed(Conv2D(64, (3, 3), activation='relu', data_format = 'channels_last'))(image_input)
pooling_1 = TimeDistributed(MaxPooling2D((2, 2), strides=(1, 1)(convolutional_1)

convolutional_2 = TimeDistributed(Conv2D(128, (4,4), activation='relu'))(pooling_1)
pooling_2 = TimeDistributed(MaxPooling2D((2, 2), strides=(2, 2)))(convolutional_2)

convolutional_3 = TimeDistributed(Conv2D(256, (4,4), activation='relu'))(pooling_2)
pooling_3 = TimeDistributed(MaxPooling2D((2, 2), strides=(2, 2)))(convolutional_3)

flatten_1 = TimeDistributed(Flatten())(pooling_3)
dropout_1 = TimeDistributed(Dropout(0.5))(flatten_1)

lstm_1, state_h, state_c = LSTM(256, return_sequences=True, return_state=True, stateful=False, dropout=0.5)(dropout_1)

dense_1 = TimeDistributed(Dense(num_classes, activation='sigmoid'))(lstm_1)

model = Model(inputs = [image_input, hidden_state_input, cell_state_input], outputs = [dense_1, state_h, state_c])

Link 苹果文章: https://developer.apple.com/documentation/coreml/core_ml_api/making_predictions_with_a_sequence_of_inputs

Link 到 GitHub 回购与使用类似方法的示例模型: https://github.com/akimach/GestureAI-CoreML-iOS

Link 转Keras GitHub post 关于自定义调用函数: https://github.com/keras-team/keras/issues/2995

事实证明,coremltools 转换器会在转换过程中自动添加状态输入和输出。

Keras 转换器 _topology.py,第 215 行供参考。