Search code examples
pythonkerasgraphvizpydot

Issue with plot_model in keras and pydot


I have read similar questions - my error appears to be different since the solutions proposed do not solve my problem.

I am having trouble plotting graphs of keras models.

I have installed graphviz binaries using homebrew

I have installed graphviz python wrapper and pydot using pip (also tried with conda, since this seems to have been an issue in the past).

Using python 3.5

Running:

from keras.utils import plot_model plot_model(cnn_model, to_file='cnn_model.png')

I get the error:

ImportError: Failed to import pydot. You must install pydot and graphviz for pydotprint to work.

with the trace:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/Users/jusjosgra/anaconda/lib/python3.5/site-packages/keras/utils/vis_utils.py in _check_pydot()
     26         # so no specific class can be caught.
---> 27         raise ImportError('Failed to import pydot. You must install pydot'
     28                           ' and graphviz for `pydotprint` to work.')

AttributeError: 'NoneType' object has no attribute 'Dot'

During handling of the above exception, another exception occurred:

ImportError                               Traceback (most recent call last)
<ipython-input-450-82ff54d9260b> in <module>()
      1 from keras.utils import plot_model
----> 2 plot_model(cnn_model, to_file='cnn_model.png')

/Users/jusjosgra/anaconda/lib/python3.5/site-packages/keras/utils/vis_utils.py in plot_model(model, to_file, show_shapes, show_layer_names, rankdir)
    133     if not extension:
    134         extension = 'png'
--> 135     else:
    136         extension = extension[1:]
    137     dot.write(to_file, format=extension)

/Users/jusjosgra/anaconda/lib/python3.5/site-packages/keras/utils/vis_utils.py in model_to_dot(model, show_shapes, show_layer_names, rankdir)
     54     dot.set('rankdir', rankdir)
     55     dot.set('concentrate', True)
---> 56     dot.set_node_defaults(shape='record')
     57 
     58     if isinstance(model, Sequential):

/Users/jusjosgra/anaconda/lib/python3.5/site-packages/keras/utils/vis_utils.py in _check_pydot()
     29 
     30 
---> 31 def model_to_dot(model,
     32                  show_shapes=False,
     33                  show_layer_names=True,

I can successfully import pydot and graphviz independently.

There appears to be a history of bugs between keras and graphviz. Any ideas on a solution?


Solution

  • The error message is ambiguous: the exception could be raised also when pydot (or any of the forks mentioned in the module vis_utils) is successfully imported, but calling pydot.Dot.create fails. From https://github.com/keras-team/keras/blob/4eab0556d29f11ff41758d80c15d6457263f6a93/keras/utils/vis_utils.py:

    def _check_pydot():
        try:
            # Attempt to create an image of a blank graph
            # to check the pydot/graphviz installation.
            pydot.Dot.create(pydot.Dot())
        except Exception:
            # pydot raises a generic Exception here,
            # so no specific class can be caught.
            raise ImportError('Failed to import pydot. You must install pydot'
                              ' and graphviz for `pydotprint` to work.')
    

    and the method pydot.Dot.create attempts to call the executable dot (installed by GraphViz):

    https://github.com/erocarrera/pydot/blob/d6ac9e9244d1a882103422ac2b35ceef96f5dfe3/pydot.py#L1856

    If dot is not in the environment's PATH variable, then it is invisible to pydot, despite being present on the machine.

    Importing packages in a Python interpreter means that they are available under site-packages, or from wherever they were installed in development mode (e.g., with python setup.py develop, or with pip install -e .). Whether executables of GraphViz are on the path is a separate issue.

    Also, the Python package graphviz is unrelated to pydot, and not needed for using GraphViz via pydot. For more on this issue, please see:

    https://stackoverflow.com/a/47209738/1959808