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