Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different results for tensorflowjs and keras on same model and tensor

I trained a CNN model on some images following the example of https://blog.keras.io/building-powerful-image-classification-models-using-very-little-data.html. My model code is identical, I just trained it on another image dataset: also for classification between two classes.

The results are what you'd expect on the training set: images are classified correctly either 0 or 1.

I saved the model in a tensorflowjs-friendly format following the "Alternative: Use the Python API to export directly to TF.js Layers format" section of https://js.tensorflow.org/tutorials/import-keras.html

However when I try to access the results in an html page with javascript I get 1 for pretty much every image (or close to it): even if the image gives 0 in Keras.

I have even saved an image as a tensor in JSON and I get 0 in Keras and 1 in TensorflowJS. Is this a bug or have I made a mistake somewhere ?

Here is my code in TensorflowJS to access the json:

<html>
  <head>
    <!-- Load TensorFlow.js -->
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]"></script>

    <script>
      // https://stackoverflow.com/a/18324384/2730032
      function callAjax(url, callback){
        var xmlhttp;
        // compatible with IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function(){
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
                callback(xmlhttp.responseText);
            }
        }
        xmlhttp.open("GET", url, true);
        xmlhttp.send();
      }

      tf.loadModel('/model.json').then(model => {
        callAjax('/tensor.json', res => {
          arr = JSON.parse(res);
          const example = tf.tensor(arr).reshape([1, 150, 150, 3]);
          const prediction = model.predict(example);
          prediction.data().then(res => {
            console.log('PREDICTION JS', res[0]);
          })
        });
      })
    </script>
  </head>
  <body>
  </body>
</html>

And here is my python code for the same:

import json
import numpy as np
import tensorflowjs as tfjs

model = tfjs.converters.load_keras_model('model.json')

with open('tensor.json', 'r') as f:
    r = json.load(f)
arr = np.array([np.array([np.array(v) for v in l]) for l in r])
print('PREDICTION PYTHON', model.predict(arr[np.newaxis,...])[0][0])

I get PREDICTION JS 1 and PREDICTION PYTHON 0.0, for exactly the same data and the same model: does anybody see any issue in my code ?

EDIT1: I'm on Xubuntu 18.04.1 LTS and use the following software versions:

Python 3.6.6
Keras 2.2.4
tensorflow 1.11.0
tensorflowjs 0.6.2
numpy 1.15.2

EDIT2: I opened the following issue https://github.com/tensorflow/tfjs/issues/776 and it has since been fixed.

like image 740
Ixio Avatar asked Oct 06 '18 22:10

Ixio


2 Answers

Upgrading to the latest version of tfjs (currently 0.13.3) solves the issue. More context to the question can be viewed here and there

<script src="https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]"></script>
like image 111
edkeveked Avatar answered Oct 05 '22 08:10

edkeveked


Similar issue here on Mac 10.15, TF 2.3, Python 3.8, plain JavaScript TFJS 2.6.0, webserver: python3 -m http.server

Results of inference would always remain around 0.5 on all units on a large, deep, CNN + RNN Keras network.

Solution: Do not use tensorflowjs_converter for .h5 to TFJS conversion

tensorflowjs_wizard lets you switch off numerical compression, providing almost identical results as Python TF2.3 (in my case up to 6 digits on final layer).

like image 36
Joolean Avatar answered Oct 05 '22 08:10

Joolean