Tuesday, May 9, 2017

image_data_format vs. image_dim_ordering in Keras v2

If you have been using Keras for some time, then you would probably know the image_dim_ordering parameter of Keras. Specially, if you switch between TensorFlow and Theano backends frequently when using Keras.

When I first started using Keras for image classification, most of my experiments failed because I have set the image_dim_ordering incorrectly. Learning from my mistakes, last year I did a post on what image_dim_ordering is and why is it important.

The keras.json file houses the configuration options for Keras
The keras.json file houses the configuration options for Keras


In short, image_dim_ordering instructed Keras to properly rearrange the image data structure when passing to the backend:
Both TensorFlow and Theano expects 4D tensors of image data as input. But, while TensorFlow expects its structure/shape to be (samples, rows, cols, channels), Theano expects it to be (samples, channels, rows, cols). So, setting the image_dim_ordering to 'tf' made Keras use the TensorFlow ordering, while setting it to 'th' made it Theano ordering.

At least, that's how it used to work.

But recently, if you have updated to the latest version of Keras, you might have run into issues with the dimension ordering, even if you're sure that you set the image_dim_ordering correctly.

You may have gotten errors like,
 ValueError: The shape of the input to "Flatten" is not fully defined (got (0, 7,  
  50). Make sure to pass a complete "input_shape" or "batch_input_shape" argument  
  to the first layer in your model.  

It may seem to you that Keras has started to ignore your image_dim_ordering setting.

And you're right.


Keras is ignoring the image_dim_ordering setting, because with Keras v2 (v2.0.4 being the latest at the time of this writing) the name of the parameter has been changed.

Now you set it using the image_data_format parameter.

image_data_format can be set to "channels_last" or "channels_first", which corresponds to the TensorFlow or Theano dimension orders respectively.

i.e. When using TensorFlow, you now set your keras.json like this,
 {  
   "image_data_format": "channels_last",  
   "epsilon": 1e-07,   
   "floatx": "float32",   
   "backend": "tensorflow"  
 }  

For Theano, you need to set it like this,
 {  
   "image_data_format": "channels_first",  
   "epsilon": 1e-07,   
   "floatx": "float32",   
   "backend": "theano"  
 }  

You can check which data format is set by using,
 keras.backend.image_data_format()  

The problem that occurs most frequently when upgrading to Keras v2 is that the older version of keras.json file remains (with the older image_dim_ordering parameter). If you install Keras v2 on a fresh system, then Keras will create the keras.json with the updated image_data_format.

To avoid the issue, you can delete your existing keras.json file when upgrading Keras (and let it create a new one), or you can update your file manually as I mentioned above.



On a side note,
You can basically keep both the old and new parameters in your keras.json and Keras wouldn't complain,

e.g.
 {  
   "image_dim_ordering": "th",   
   "image_data_format": "channels_first",  
   "epsilon": 1e-07,   
   "floatx": "float32",   
   "backend": "theano"  
 }  

This would work, but I wouldn't recommend it. It may cause issues later on if you forget to update one parameter when switching the backend.

Related links:
https://keras.io/backend/ 

Build Deeper: The Path to Deep Learning

Learn the bleeding edge of AI in the most practical way: By getting hands-on with Python, TensorFlow, Keras, and OpenCV. Go a little deeper...

Get your copy now!





1 comment:

  1. Thank you for your post. If I have a dataset which is prepared for theano, the shape of training data will be (samples, channels, rows, cols) just like you mentioned. If I changed the backend from theano to tensoflow, do I need to change my training data's shape to (samples, rows, cols, channels) before loading into my program, then do the others? or load the training date first, then reshape to (samples, rows, cols, channels), then do the others?

    ReplyDelete