创建 CoreML LRCN 模型

Posted

技术标签:

【中文标题】创建 CoreML LRCN 模型【英文标题】:Creating a CoreML LRCN model 【发布时间】:2018-07-07 15:18:54 【问题描述】:

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

我的问题源于 Apple 的 CoreML 文档网站上发布的一篇文章。这篇文章的主题也在 WWDC 2017 的讲座中介绍过,我觉得它很有趣。我最近发布了一个问题,该问题与我正在从事的同一个项目的一部分有关,并且很容易解决;但是,随着我进一步深入研究,我发现自己不了解该模型的一部分是如何实现的。

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

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

我的问题是这样的:

在上述文章(以及我在 GitHub 上找到的 CormeML 示例项目)中,实现非常巧妙。由于 CoreML(或至少是 stock 转换器)不支持图像序列作为输入,因此一次输入一个图像,并且 LSTM 状态与输入图像的预测一起作为输出从网络传递出去。对于序列中的下一个图像,用户传递图像以及前一个时间步的 LSTM 状态,因此模型可以“从中断的地方继续”,可以说并将单个输入作为序列处理。它在某种程度上形成了 LSTM 状态的循环(Apple 文章中对此进行了更详细的介绍)。现在,对于实际的问题部分......

这是如何在像 Keras 这样的库中实现的?到目前为止,我已经成功地使用功能 API 和 LSTM 层上的“return_state”设置输出 LSTM 状态,并将其路由到辅助输出。很简单。不是那么简单(至少对我来说),是如何将该状态传递回网络以进行下一次预测。我查看了 LSTM 层的源代码和文档,没有看到任何作为状态输入跳出的内容。我唯一能想到的就是可能使 LSTM 层成为自己的模型并使用“initial_state”来设置它,但是根据我发现的 Keras GitHub 上的一篇文章,似乎模型需要自定义调用功能,我不确定如何将其用于 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])

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

通过使用类似方法的示例模型链接到 GitHub 存储库: https://github.com/akimach/GestureAI-CoreML-ios

关于自定义调用函数的 Keras GitHub 帖子链接: https://github.com/keras-team/keras/issues/2995

【问题讨论】:

【参考方案1】:

原来 coremltools 转换器会在转换过程中自动添加状态输入和输出。

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

【讨论】:

以上是关于创建 CoreML LRCN 模型的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Turi Create 创建的 CoreML 模型转换为 Keras?

如何将 CoreML 模型添加到 Swift 包中?

继续训练 CoreML 模型

从远程源加载重型 CoreML 模型

CoreML 模型预测不同于训练

如何将使用 Mask Rcnn 在自定义对象检测上创建蒙版图像的 Keras 模型转换为 CoreML 模型以在 iOS 应用程序中使用?