Классификация CoreML не выполняется, когда модель конвертируется из Keras в CoreML с несколькими class_labels - PullRequest
0 голосов
/ 22 января 2020

Я пытаюсь создать модель для приложения iOS, над которым я работаю. Я тренирую это, используя Керас. Затем преобразуйте его в CoreML, используя coremltools.

При обучении он знает, что у меня есть два класса: кошки и собаки. И это хорошо тренируется. После этого я конвертирую его и передаю class_labels в виде списка: ["cat", "dog"]. В приложении это не работает.

Показывает ошибку: "The VNCoreMLTransform request failed". Если я оставлю только один class_label, он будет работать нормально, а также классифицируется.

Я пытаюсь выяснить, где я что-то не так сделал.

Керас:

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')

1 Ответ

0 голосов
/ 22 января 2020

Я думаю, что проблема в том, что конвертер CoreML не знает, что двоичная классификация может означать один выходной нейрон, который может представлять две метки, поэтому я думаю, что у вас есть два варианта:

  • Удалить метки класса параметр, и пусть модель выдает одно значение, а затем вы выполняете некоторую постобработку, чтобы преобразовать вывод модели в метки класса (тоже устанавливая порог).
  • Вы обучаете бинарную модель классификации с двумя выходными нейронами и softmax Активация, которая должна хорошо работать с конвертером CoreML и вашими метками классов.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...