Мне нужно преобразовать модель resnet50 в модель CoreML. Обученная модель Keras работает правильно. Я пытался преобразовать его в Coreml, но вот ошибка, которую я получаю, используя coremltools:
ValueError: Keras layer '<class 'keras.layers.core.Lambda'>' not supported.
Кажется, у меня есть лямбда-функции в моей модели, и Coreml не поддерживает это ... но что я не делаю понять, откуда берутся эти лямбда-функции, поскольку я только что использовал стандартную сеть resnet50 для обучения передаче Я изменил только последний слой с 1000 плотностями на слой с 4 плотностями, вот мой код:
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
Я понятия не имею, откуда берутся лямбда-слои ... Есть идеи?
Для информации вот как проходит обучение:
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])
Спасибо за помощь
Edit1
А вот как я сохраняю модель:
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))