Tensorflow: несовместимые формы для модели tflite и выходного массива

#python #tensorflow #keras #tf.keras

#python #tensorflow #keras #tf.keras

Вопрос:

Я следую довольно простому руководству tf.keras по созданию классификатора двоичных изображений. Затем я преобразовал готовую модель в файл .tflite, который я пытаюсь включить в приложение для Android.

Код, создающий последовательную модель tf.keras.

 import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D
from tensorflow.keras.layers import Activation, Dropout, Flatten, Dense
from tensorflow.keras import backend as K
from tensorflow.keras.callbacks import TensorBoard, ReduceLROnPlateau
from sklearn.utils import class_weight
import numpy as np


# dimensions of our images.====================================================================================================
img_width, img_height = 200, 200

train_data_dir = 'augmentedImg/200/training_data'#=============================================================================
validation_data_dir = 'augmentedImg/200/validation_data'#=============================================================================
nb_train_samples = 9009
nb_validation_samples = 2252
epochs = 100
batch_size = 32

layer_size = 64

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(layer_size, (3, 3), input_shape=input_shape))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

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

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

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

model.add(Flatten())

#model.add(Dropout(0.5))

model.add(Dense(1))
model.add(Activation('sigmoid'))

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

# this is the augmentation configuration we will use for training
train_datagen = ImageDataGenerator(
    rescale=1. / 255,
    rotation_range=90,
    width_shift_range=0.1,
    height_shift_range=0.1,
    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),
    color_mode='grayscale',
    batch_size=batch_size,
    class_mode='binary')

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

class_weights = class_weight.compute_class_weight(
               'balanced',
                np.unique(train_generator.classes), 
                train_generator.classes)

model.fit_generator(
    train_generator,
    class_weight=class_weights,
    steps_per_epoch=nb_train_samples // batch_size,
    epochs=epochs,
    validation_data=validation_generator,
    validation_steps=nb_validation_samples# // batch_size,
    #callbacks=[tensorboard, reduce_lr]
    )

model.save_weights('model.h5')
print("End of program")
  

Преобразование кода в модель tflite:

 import tensorflow as tf

converter = tf.lite.TFLiteConverter.from_keras_model_file("models/1Data_aug_200x200.h5")
tflite_model = converter.convert()
open("models/convertedModels/1Data_aug_200x200.tflite", "wb").write(tflite_model)
  

Затем я вызываю ‘run’ для модели, передавая ByteBuffer (изображение, подлежащее классификации) и выходной массив.

Выходной массив:

 private float[][] labelProbArray = new float[1][numLabels]; //numLabels=2
  

Однако при вызове tflite.run(imgData, labelProbArray); я получаю сообщение об ошибке.

java.lang.IllegalArgumentException: Cannot copy between a TensorFlowLite tensor with shape [1, 1] and a Java object with shape [1, 2].

Должен ли тензор также иметь форму [1,2]? Или есть альтернатива, где я могу просто вернуть предсказанный класс и вероятность?

Комментарии:

1. нам нужен воспроизводимый код или, по крайней мере, указатель на ваш учебник..

2. Вы говорите, что это двоичный классификатор изображений , тогда он должен иметь форму вывода как [ 1 , 1]. Двоичный классификатор имеет только один выходной узел. Попробуйте изменить значение меток num на 1.

3. @ShubhamPanchal Я пробовал это, все, что было возвращено, было десятичным (например, 0,016182696). Нет указаний на то, какой класс был предсказан, и если это показатель достоверности, он не кажется очень высоким. Документации по этому поводу также не так много