Recently, I was looking for a way to dynamically switch Keras backend between Theano and TensorFlow while working with Jupyter notebooks; I thought that there must be a way to work with multiple Keras configuration files, but this proved not to be the case.
My issue was that, while I am mainly working with Theano, I wanted a quick and painless way to start a Jupyter notebook with TensorFlow backend instead. And while Keras provides the KERAS_BACKEND
environment variable, there is still the issue of image dimension ordering, which is handled differently in Theano and TensorFlow, and cannot be set with a command line flag like KERAS_BACKEND
; and image dimension ordering is already the source of endless confusion and frustration, especially among beginners (check the “A quick note on image_dim_ordering” section in this post).
Recalling the profiles functionality of IPython, my first thought was to build two different profiles for use with Theano and TensorFlow respectively, but, as I was soon to discover, the profiles functionality did not survive the migration from IPython to Jupyter.
Eventually, I figured out the solution, employing the startup files functionality of IPython which, surprisingly enough, works along with Jupyter, too. So, here is a complete demonstration of the issue and the solution.
As I said, in my situation Keras is by default configured to work with Theano, so here is the content of my ~/.keras/keras.json file:
{ "image_dim_ordering": "th", "epsilon": 1e-07, "floatx": "float32", "backend": "theano" }
We can start Jupyter with TensorFLow backend for Keras using the flag KERAS_BACKEND=tensorflow
in the command line:
$ KERAS_BACKEND=tensorflow jupyter notebook --no-browser --ip 192.10.10.221
but, as shown below, the image dimension ordering is still set to 'th'
(for Theano):
The solution is to write a small Python script keras_init.py that will always run at Jupyter startup; it will check the backend and, if it is set to TensorFlow, it will configure accordingly the image dimension ordering:
import keras K = keras.backend.backend() if K=='tensorflow': keras.backend.set_image_dim_ordering('tf')
For the script to run at Jupyter startup, it suffices to put it in our ~/.ipython/profile_default/startup/ directory.
Now, let’s start again Jupyter notebook with KERAS_BACKEND=tensorflow
flag in the command line, and verify that all settings are correct:
Finally, let’s confirm that when launching Jupyter notebook without any Keras flag, both the backend and image dimension ordering are correctly set for Theano:
Summary
To summarize, here are the steps in order to be able to dynamically switch between a default Theano backend for Keras and TensorFlow in your Jupyter notebooks:
- Copy the keras_init.py script shown above to your ~/.ipython/profile_default/startup/ directory
- For working with TensorFlow backend, include theĀ
KERAS_BACKEND=tensorflow
flag in the command line when launching Jupyter - For working with Theano backend, simply launch Jupyter as usually (without flags)
Of course, it is straightforward to adapt the approach shown above for the opposite situation, i.e. when working with TensorFlow backend by default but you want to occasionally switch to Theano.
As always, comments and remarks most welcome.-
- Streaming data from Raspberry Pi to Oracle NoSQL via Node-RED - February 13, 2017
- Dynamically switch Keras backend in Jupyter notebooks - January 10, 2017
- sparklyr: a test drive on YARN - November 7, 2016
Thanks! This is really useful.
I’ve mentioned your solution at my article about switching backends in Keras, here: http://www.codesofinterest.com/2016/11/switching-between-tensorflow-and-theano.html
Thanks – glad you found it useful!
[…] solved: from keras import backend # https://www.nodalpoint.com/switch-keras-backend/ # Dynamically switch keras backend to theano […]
To really dynamically change the framework use the following code in the cell:
# Select the framework
import os
import sys
# Select the backend
#os.environ[“KERAS_BACKEND”] = “theano”
os.environ[“KERAS_BACKEND”] = “tensorflow”
# Un-load the old module
for mod in sys.modules.keys():
if mod.startswith(‘keras.’):
del sys.modules[mod]
del sys.modules[“eras”]
# Import the required modules
import keras
Thanks Jordan.
The idea was exactly to avoid the necessity of carrying such “preamble” code snippets in each & every notebook. And your suggestion still needs some lines in order to address the image ordering parameter…