【问题标题】:CoreML classification fails when model is converted from Keras to CoreML with multiple class_labels当模型从 Keras 转换为具有多个 class_labels 的 CoreML 时,CoreML 分类失败
【发布时间】:2020-05-08 09:50:10
【问题描述】:

我正在尝试为我正在开发的 iOS 应用程序制作模型。我使用 Keras 训练它。然后使用 coremltools 将其转换为 CoreML。

在训练时,它知道我有两个班级:猫和狗。 它训练得很好。之后,我将其转换并将 class_labels 作为列表传递:["cat", "dog"]。在应用程序中它不起作用。

显示错误:"The VNCoreMLTransform request failed"。如果我只留下一个class_label,它可以正常工作并且也可以分类。

我正在试图找出我做错了什么。

Keras:

img_width, img_height = 224, 224

train_data_dir = 'data/train'
validation_data_dir = 'data/validate'
nb_train_samples = 1000
nb_validation_samples = 20
epochs = 10
batch_size = 10

if K.image_data_format() == 'channels_first': 
    input_shape = (3, img_width, img_height) 
else: 
    input_shape = (img_width, img_height, 3) 

model = Sequential() 
model.add(Conv2D(32, (2, 2), input_shape = input_shape)) 
model.add(Activation('relu')) 
model.add(MaxPooling2D(pool_size =(2, 2))) 

model.add(Conv2D(32, (2, 2))) 
model.add(Activation('relu')) 
model.add(MaxPooling2D(pool_size =(2, 2))) 

model.add(Conv2D(64, (2, 2))) 
model.add(Activation('relu')) 
model.add(MaxPooling2D(pool_size =(2, 2))) 

model.add(Flatten()) 
model.add(Dense(64)) 
model.add(Activation('relu')) 
model.add(Dropout(0.5)) 
model.add(Dense(1)) 
model.add(Activation('sigmoid')) 

model.compile(loss = 'binary_crossentropy', 
                optimizer = 'rmsprop', 
                metrics = ['accuracy']) 

train_datagen = ImageDataGenerator( 
                rescale = 1. / 255, 
                 shear_range = 0.2, 
                  zoom_range = 0.2, 
            horizontal_flip = True) 

test_datagen = ImageDataGenerator(rescale = 1. / 255) 

train_generator = train_datagen.flow_from_directory(train_data_dir, 
                              target_size =(img_width, img_height), 
                     batch_size = batch_size, class_mode ='binary') 

validation_generator = test_datagen.flow_from_directory( 
                                    validation_data_dir, 
                   target_size =(img_width, img_height), 
          batch_size = batch_size, class_mode ='binary') 

model.fit_generator(train_generator, 
    steps_per_epoch = nb_train_samples // batch_size, 
    epochs = epochs, validation_data = validation_generator, 
    validation_steps = nb_validation_samples // batch_size) 

model.save('model_saved.h5')

转换器:

converted_model = coremltools.converters.keras.convert('model_saved.h5', 
                                                        input_names = 'image',
                                                        image_input_names = 'image',
                                                        output_names=['classLabelProbs'],
                                                        class_labels = ['cat', 'dog'])

#converted_model = coremltools.converters.keras.convert("model.h5")                  
converted_model.save('myModel.mlmodel')

【问题讨论】:

    标签: python tensorflow keras coreml coremltools


    【解决方案1】:

    我认为问题在于 CoreML 转换器不知道二进制分类可能意味着一个输出神经元可以代表两个标签,所以我认为您有两种选择:

    • 移除类标签参数并让模型输出单个值,然后进行一些后处理将模型输出转换为类标签(也设置阈值)。
    • 您训练了一个具有两个输出神经元和softmax 激活的二元分类模型,它应该可以与 CoreML 转换器和您的类标签一起正常工作。

    【讨论】:

    • 很抱歉,因为工作忙,回答迟了。我不知道我将如何做第一步,所以我专注于另一个。我是 keras 的新手,所以我的问题是在训练我的模型时如何设置两个输出神经元。作为参考,我使用了本指南和其中的代码:geeksforgeeks.org/python-image-classification-using-keras 我只更改了 save_weights 以仅保存,因为我不能仅将权重转换为 coreML。
    【解决方案2】:

    我遇到了同样的问题,终于可以自己想办法了。

    1. 2 个单位的Densesoftmax 激活
    .
    .
    .
    model.add(Dense(2, activation='softmax'))
    .
    .
    
    1. binary_crossentropycategorical_crossentropy
    model.compile(..... loss='binary_crossentropy'.....)
    

    祝你好运!

    【讨论】:

      猜你喜欢
      • 2017-12-10
      • 2020-01-24
      • 2019-03-23
      • 2017-11-12
      • 2017-11-30
      • 2017-11-23
      • 2017-12-09
      • 2020-11-06
      • 2020-11-28
      相关资源
      最近更新 更多