【问题标题】:Can not convert Resnet model trained with Keras to CoreML model无法将使用 Keras 训练的 Resnet 模型转换为 CoreML 模型
【发布时间】:2020-05-21 13:10:24
【问题描述】:

我需要将 resnet50 模型转换为 CoreML 模型。 训练的 Keras 模型工作正常。我尝试将其转换为 Coreml,但这是我使用 coremltools 时遇到的错误:

ValueError: Keras layer '<class 'keras.layers.core.Lambda'>' not supported.

我的模型中似乎有 lambda 函数,Coreml 不支持它......但是我不明白这些 lambda 函数的来源,因为我只是使用标准 resnet50 网络进行迁移学习。我只将最后的 1000-dense 层更改为 4-dense 层,这是我的代码:

from keras.applications.resnet50 import ResNet50, preprocess_input

full_imagenet_model = ResNet50(weights='imagenet')

output = full_imagenet_model.layers[-2].output
base_model = Model(full_imagenet_model.input, output)

top_model = Sequential()
top_model.add(Dense(4, input_dim=2048, activation='softmax'))
top_model.compile(optimizer=Adam(lr=1e-4),
                  loss='categorical_crossentropy', metrics=['accuracy'])

model = Model(base_model.input, top_model(base_model.output))

这是模型摘要的开始和结束:

__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_1 (InputLayer)            (None, 224, 224, 3)  0                                            
__________________________________________________________________________________________________
conv1_pad (ZeroPadding2D)       (None, 230, 230, 3)  0           input_1[0][0]                    
__________________________________________________________________________________________________
conv1 (Conv2D)                  (None, 112, 112, 64) 9472        conv1_pad[0][0]                  
__________________________________________________________________________________________________
bn_conv1 (BatchNormalization)   (None, 112, 112, 64) 256         conv1[0][0]                      
__________________________________________________________________________________________________
activation_1 (Activation)       (None, 112, 112, 64) 0           bn_conv1[0][0]                   
__________________________________________________________________________________________________
pool1_pad (ZeroPadding2D)       (None, 114, 114, 64) 0           activation_1[0][0]               
__________________________________________________________________________________________________
max_pooling2d_1 (MaxPooling2D)  (None, 56, 56, 64)   0           pool1_pad[0][0]                  
__________________________________________________________________________________________________
res2a_branch2a (Conv2D)         (None, 56, 56, 64)   4160        max_pooling2d_1[0][0]            
________________________________________________________________________________________________

(...)           
__________________________________________________________________________________
add_16 (Add)                    (None, 7, 7, 2048)   0           bn5c_branch2c[0][0]              
                                                                 activation_46[0][0]              
__________________________________________________________________________________________________
activation_49 (Activation)      (None, 7, 7, 2048)   0           add_16[0][0]                     
__________________________________________________________________________________________________
avg_pool (GlobalAveragePooling2 (None, 2048)         0           activation_49[0][0]              
__________________________________________________________________________________________________
sequential_1 (Sequential)       (None, 4)            8196        avg_pool[0][0]                   
==================================================================================================
Total params: 23,595,908
Trainable params: 23,542,788
Non-trainable params: 53,120

奇怪的是,当我加载我训练的模型并调用摘要时,我得到的是:

__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_3 (InputLayer)            (None, 224, 224, 3)  0                                            
__________________________________________________________________________________________________
lambda_3 (Lambda)               (None, 224, 224, 3)  0           input_3[0][0]                    
__________________________________________________________________________________________________
lambda_4 (Lambda)               (None, 224, 224, 3)  0           input_3[0][0]                    
__________________________________________________________________________________________________
model_5 (Model)                 (None, 4)            23595908    lambda_3[0][0]                   
                                                                 lambda_4[0][0]                   
__________________________________________________________________________________________________
sequential_2 (Concatenate)      (None, 4)            0           model_5[1][0]                    
                                                                 model_5[2][0]                    
==================================================================================================
Total params: 23,595,908
Trainable params: 23,542,788
Non-trainable params: 53,120

我不知道 lambda 层是从哪里来的……知道吗?

有关信息,以下是培训的完成方式:

opt = Adam(lr=1e-3)

parallel_model = multi_gpu_model(model, gpus=2)

parallel_model.compile(optimizer=opt, loss='categorical_crossentropy',
              metrics=['accuracy'])

history = parallel_model.fit_generator(train_flow, train_flow.n // train_flow.batch_size,
                              epochs=200,
                              validation_data=val_flow,
                              validation_steps=val_flow.n,
                              callbacks=[clr, tensorboard, cb_checkpointer, cb_early_stopper])

感谢您的帮助

编辑1

这是我保存模型的方法:

from tensorflow.python.keras.callbacks import EarlyStopping, ModelCheckpoint
from pyimagesearch.clr_callback import CyclicLR

cb_early_stopper = EarlyStopping(monitor = 'val_acc', patience = 30)
cb_checkpointer = ModelCheckpoint(filepath = 'SAVED_MODELS/EPOCH:50_DataAug:Yes_Monitor:val-acc_DB2.hdf5', monitor = 'val_acc', save_best_only = True, mode = 'auto')
tensorboard = TensorBoard(log_dir="logs/{}".format('model_EPOCH:50_DataAug:Yes_Monitor:val-acc_DB2'))
clr = CyclicLR(
        mode=CLR_METHOD,
        base_lr=MIN_LR,
        max_lr=MAX_LR,
        step_size= STEP_SIZE * (train_flow.n // train_flow.batch_size))

【问题讨论】:

  • 你是如何保存模型的?请添加该代码
  • 嗨,Matias,刚刚使用请求的代码编辑了我的帖子。谢谢。

标签: keras coreml coremltools


【解决方案1】:

好的,我想我找到了问题所在。我发布的代码遗漏了关于用于训练的 multi_gpu_model 的部分。

问题是使用 multi_gpu 在摘要中创建 lambdas 函数以在并行中加载数据。

我现在正在寻找在 coremltools 中实现 lambda 函数。

【讨论】:

    猜你喜欢
    • 2020-01-24
    • 1970-01-01
    • 2017-12-15
    • 2020-09-30
    • 2019-01-12
    • 2017-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多