Python MLModel可用于多阵列输出,但无法成功将输出更改为图像

Python MLModel可用于多阵列输出,但无法成功将输出更改为图像,python,keras,coreml,coremltools,mlmodel,Python,Keras,Coreml,Coremltools,Mlmodel,我使用coremltools 4.0将Keras模型转换为MLModel,但成功率有限 它可以工作,但只有当我使用MLMultiArray作为输出并转换为图像时。转换为图像所需的时间比推断所需的时间长;使它无法使用 如果我尝试更改MLModel规范以将图像用于输出,则运行预测时会出现以下错误: 无法将输出标识转换为图像: NSUnderlyingError=0x2809bad00{Error Domain=com.apple.CoreML Code=0“无效数组形状( 2048, 2048, 3

我使用coremltools 4.0将Keras模型转换为MLModel,但成功率有限

它可以工作,但只有当我使用MLMultiArray作为输出并转换为图像时。转换为图像所需的时间比推断所需的时间长;使它无法使用

如果我尝试更改MLModel规范以将图像用于输出,则运行预测时会出现以下错误:

无法将输出标识转换为图像:

NSUnderlyingError=0x2809bad00{Error Domain=com.apple.CoreML Code=0“无效数组形状( 2048, 2048, 3. )用于转换为灰度图像“

即使我已经为输出颜色指定了RGB:

输出{ 名称:“标识” 类型{ 图像类型{ 宽度:2048 身高:2048 色彩空间:RGB } } }

如果我使用多阵列(工作正常)Xcode报告:

输出:浮点32 1 x 2048 x 2048 x 3阵列

我怀疑问题是第一个维度,即批次号,但没有显示维度,因此我无法删除批次维度:

输出{ 姓名:“身份” 类型{ 多阵列类型{ 数据类型:FLOAT32 } } }

我认为我不能只向Keras Conv2D输出层添加输出形状,因为它有多个具有不同形状的入站节点。以下是输出形状:

>>> print(outputLayer.get_output_shape_at(0))
(None, None, None, 3)
>>> print(outputLayer.get_output_shape_at(1))
(1, 512, 512, 3)
>>> print(outputLayer.get_output_shape_at(2))
(1, 2048, 2048, 3)

>>> print(outputLayer.output)
Tensor("SR/Identity:0", shape=(None, None, None, 3), dtype=float32)
我认为coremltools混淆了通道的批处理,这就是为什么即使我指定RGB,它也试图创建灰度图像

知道怎么修吗

我有原始的Keras模型,但我不知道如何在没有批量标注的情况下指定形状。 以下是Keras模型层描述的开始和结束

__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
LR_input (InputLayer)           [(None, None, None,  0                                            
__________________________________________________________________________________________________
Pre_blocks_conv (Conv2D)        multiple             896         LR_input[0][0]                   
__________________________________________________________________________________________________
F_1_1_1 (Conv2D)                multiple             9248        Pre_blocks_conv[0][0]            

...                             multiple
...                             multiple

SR (Conv2D)                     multiple             84          PixelShuffle[0][0]               
==================================================================================================

在Core ML中,尺寸的顺序是(通道、高度、宽度),因此它希望看到3 x 2048 x 2048输出,而不是2048 x 2048 x 3


请注意,您还需要确保输出像素在[0,255]范围内,而不是[0,1]这可能就是你的Keras模型给你的。

谢谢Matthijs!我以为是这样的。有什么建议如何将其更改为Core ML所期望的吗?我是否需要一个辅助函数或输出在0-255范围内的东西?为了将通道放在正确的轴上,可能是pixelshuffle层所做的事情“错误”(从Core ML的角度来看)。对于0-255范围的输出,这取决于当前输出是什么。对于[0,1],只需在末尾添加一个乘法层(在Keras模型中最容易做到)。对于[-1,1],你需要两层:加1乘以127.5。你可以在这里找到你问题的答案:你也可以在下面找到我接受的答案。