1

I have created a neural network in Keras using the InceptionV3 pretrained model:

base_model = applications.inception_v3.InceptionV3(weights='imagenet', include_top=False)

# add a global spatial average pooling layer
x = base_model.output
x = GlobalAveragePooling2D()(x)

# let's add a fully-connected layer
x = Dense(2048, activation='relu')(x)
x = Dropout(0.5)(x)
predictions = Dense(len(labels_list), activation='sigmoid')(x)

I trained the model successfully and want to following image: https://i.stack.imgur.com/N43F9.jpg. Therefore, the image is cropped to 299x299 and normalized (just devided by 255):

def img_to_array(img, data_format='channels_last', dtype='float32'):
    if data_format not in {'channels_first', 'channels_last'}:
        raise ValueError('Unknown data_format: %s' % data_format)
    # Numpy array x has format (height, width, channel)
    # or (channel, height, width)
    # but original PIL image has format (width, height, channel)
    x = np.asarray(img, dtype=dtype)
    if len(x.shape) == 3:
        if data_format == 'channels_first':
            x = x.transpose(2, 0, 1)
    elif len(x.shape) == 2:
        if data_format == 'channels_first':
            x = x.reshape((1, x.shape[0], x.shape[1]))
        else:
            x = x.reshape((x.shape[0], x.shape[1], 1))
    else:
        raise ValueError('Unsupported image shape: %s' % (x.shape,))
    return x
def load_image_as_array(path):
    if pil_image is not None:
        _PIL_INTERPOLATION_METHODS = {
            'nearest': pil_image.NEAREST,
            'bilinear': pil_image.BILINEAR,
            'bicubic': pil_image.BICUBIC,
        }
        # These methods were only introduced in version 3.4.0 (2016).
        if hasattr(pil_image, 'HAMMING'):
            _PIL_INTERPOLATION_METHODS['hamming'] = pil_image.HAMMING
        if hasattr(pil_image, 'BOX'):
            _PIL_INTERPOLATION_METHODS['box'] = pil_image.BOX
        # This method is new in version 1.1.3 (2013).
        if hasattr(pil_image, 'LANCZOS'):
            _PIL_INTERPOLATION_METHODS['lanczos'] = pil_image.LANCZOS

    with open(path, 'rb') as f:
        img = pil_image.open(io.BytesIO(f.read()))
        width_height_tuple = (IMG_HEIGHT, IMG_WIDTH)
        resample = _PIL_INTERPOLATION_METHODS['nearest']
        img = img.resize(width_height_tuple, resample)
    return img_to_array(img, data_format=K.image_data_format())

img_array = load_image_as_array('https://i.stack.imgur.com/N43F9.jpg')
img_array = img_array/255

Then I predict it with the trained model in Keras:

predict(img_array.reshape(1,img_array.shape[0],img_array.shape[1],img_array.shape[2]))

The result is the following:

array([[0.02083278, 0.00425783, 0.8858412 , 0.17453966, 0.2628744 ,
        0.00428194, 0.2307986 , 0.01038828, 0.07561868, 0.00983179,
        0.09568241, 0.03087404, 0.00751176, 0.00651798, 0.03731382,
        0.02220723, 0.0187968 , 0.02018479, 0.3416505 , 0.00586909,
        0.02030778, 0.01660049, 0.00960067, 0.02457979, 0.9711478 ,
        0.00666443, 0.01468313, 0.0035468 , 0.00694743, 0.03057212,
        0.00429407, 0.01556832, 0.03173089, 0.01407397, 0.35166138,
        0.00734553, 0.0508953 , 0.00336689, 0.0169737 , 0.07512951,
        0.00484502, 0.01656419, 0.01643038, 0.02031735, 0.8343202 ,
        0.02500874, 0.02459189, 0.01325032, 0.00414564, 0.08371573,
        0.00484318]], dtype=float32)

The important point is that it has four values with a value greater than 0.8:

>>> y[y>=0.8]
array([0.9100583 , 0.96635956, 0.91707945, 0.9711707 ], dtype=float32))

Now I have converted my network to .pb and imported it in an android project. I wanted to predict the same image in android. Therefore I also resize the image and normalize it like I did in Python by using the following code:

// Resize image:
InputStream imageStream = getAssets().open("test3.jpg");
Bitmap bitmap = BitmapFactory.decodeStream(imageStream);
Bitmap resized_image = utils.processBitmap(bitmap,299);

and then normalize by using the following function:

public static float[] normalizeBitmap(Bitmap source,int size){

    float[] output = new float[size * size * 3];

    int[] intValues = new int[source.getHeight() * source.getWidth()];

    source.getPixels(intValues, 0, source.getWidth(), 0, 0, source.getWidth(), source.getHeight());
    for (int i = 0; i < intValues.length; ++i) {
        final int val = intValues[i];
        output[i * 3] = Color.blue(val) / 255.0f;
        output[i * 3 + 1] =  Color.green(val) / 255.0f;
        output[i * 3 + 2] = Color.red(val) / 255.0f ;
    }
    return output;
}

But in java I get other values. None of the four indices has a value greater than 0.8.
The value of the four indices are between 0.1 and 0.4!!!
I have checked my code several times, but I don't understand why in android I don't get the same values for the same image? Any idea or hint?

Rahul Gaur
  • 1,661
  • 1
  • 13
  • 29
Code Pope
  • 5,075
  • 8
  • 26
  • 68
  • how about raw pixel values when u read them ? in both python environment and in Java ? – venkata krishnan Feb 10 '20 at 01:51
  • @venkatakrishnan You mean using `BufferedImage` in java? What do you mean with raw pixel values? How can I do that in java? – Code Pope Feb 10 '20 at 02:01
  • Yes. The for inference you should use the same interval you used for training. And for training you should normalize your images. This results in faster convergence. Therefore, we have to divide by 255. And I have done this in Python Keras and achieve great results. I don't know why the results in android are different by the same model. – Code Pope Feb 10 '20 at 02:15
  • Maybe [this](https://stackoverflow.com/questions/39649292/imageio-reading-slightly-different-rgb-values-than-other-methods) will help? – Scary Wombat Feb 10 '20 at 02:32
  • what i meant by raw pixels is the RGB values, when you read the images. https://alvinalexander.com/blog/post/java/getting-rgb-values-for-each-pixel-in-image-using-java-bufferedi this might help. the basic difference in the RGB value for python environment and the java environment might give us some idea of where we are missing the trick – venkata krishnan Feb 10 '20 at 02:56
  • @ScaryWombat thanks for link. But it seems that answers just imply that there is not solution for this problem. Isn't it? – Code Pope Feb 10 '20 at 03:09

0 Answers0