簡體   English   中英

預訓練的keras模型在android中重現相同的結果

[英]Pretrained keras model is returing the same result in android

我在Keras中創建了圖像分類器,后來我將模型保存為pb格式以在android中使用。

但是,在python代碼中,它可以正確分類圖像。 但是在android中,無論我提供什么圖像作為輸入,輸出始終是相同的。

這就是我訓練模型的方式

rom keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense

# Initialising the CNN
classifier = Sequential()

# Step 1 - Convolution
classifier.add(Conv2D(32, (3, 3), input_shape = (64, 64, 3), activation = 'relu'))

# Step 2 - Pooling
classifier.add(MaxPooling2D(pool_size = (2, 2)))

# Adding a second convolutional layer
classifier.add(Conv2D(32, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))

# Step 3 - Flattening
classifier.add(Flatten())

# Step 4 - Full connection
classifier.add(Dense(units = 128, activation = 'relu'))
classifier.add(Dense(units = 1, activation = 'sigmoid'))

# Compiling the CNN
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])

# Part 2 - Fitting the CNN to the images

from keras.preprocessing.image import ImageDataGenerator

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

test_datagen = ImageDataGenerator(rescale = 1./255)

training_set = train_datagen.flow_from_directory('dataset/training_set',
                                                 target_size = (64, 64),
                                                 batch_size = 32,
                                                 class_mode = 'binary')

test_set = test_datagen.flow_from_directory('dataset/test_set',
                                            target_size = (64, 64),
                                            batch_size = 32,
                                            class_mode = 'binary')

classifier.fit_generator(training_set,
                         steps_per_epoch = 8000,
                         epochs = 25,
                         validation_data = test_set,
                         validation_steps = 2000)
classifier.summary()
classifier.save('saved_model.h5')

后來我通過使用這個將keras模型( saved_model.h5 )轉換為張量流模型

這就是我轉換位圖浮點數組的方式

    public static float[] getPixels(Bitmap bitmap) {

        final int IMAGE_SIZE = 64;

        int[] intValues = new int[IMAGE_SIZE * IMAGE_SIZE];
        float[] floatValues = new float[IMAGE_SIZE * IMAGE_SIZE * 3];

        if (bitmap.getWidth() != IMAGE_SIZE || bitmap.getHeight() != IMAGE_SIZE) {
            // rescale the bitmap if needed
            bitmap = ThumbnailUtils.extractThumbnail(bitmap, IMAGE_SIZE, IMAGE_SIZE);
        }

        bitmap.getPixels(intValues, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());

        for (int i = 0; i < intValues.length; ++i) {
            final int val = intValues[i];
        // bitwise shifting - without our image is shaped [1, 64, 64, 1] but we need [1, 168, 168, 3]
            floatValues[i * 3 + 2] = Color.red(val) / 255.0f;
            floatValues[i * 3 + 1] = Color.green(val) / 255.0f;
            floatValues[i * 3] = Color.blue(val) / 255.0f;
        }
        return floatValues;
    }

后來,我嘗試使用android中的tensorflow對圖像進行分類,如下所示。

TensorFlowInferenceInterface tensorFlowInferenceInterface; 
tensorFlowInferenceInterface = new TensorFlowInferenceInterface(getAssets(),"model.pb");
float[] output = new float[2];
tensorFlowInferenceInterface.feed("conv2d_11_input",
                getPixels(bitmap), 1,64,64,3);
tensorFlowInferenceInterface.run(new String[]{"dense_12/Sigmoid"});
tensorFlowInferenceInterface.fetch("dense_12/Sigmoid",output);

無論我給output圖像是[1,0]

有什么我想念的嗎?

Color.red(int)Color.blue(int)Color.green(int)返回的顏色分量是[0,255]范圍內的整數(請參閱doc )。 使用ImageDataGenerator讀取圖像時,也會發生同樣的事情。 但是,正如我在評論部分所述,在預測階段,您需要執行與訓練階段相同的預處理步驟。 您正在訓練中按1./255縮放圖像像素(使用ImageDataGenerator rescale = 1./255 ),因此,根據我提到的第一點,這也必須在預測中完成:

floatValues[i * 3 + 2] = Color.red(val) / 255.0;
floatValues[i * 3 + 1] = Color.green(val) / 255.0;
floatValues[i * 3] = Color.blue(val) / 255.0;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM