ClassificationKeras launching

Hello,

I’m new to ROOT so I’m sorry if the answer is obvious.
In the past days I have tried some TMVA tutorial files, they have all worked expect the python files. I have tried to launch the ClassificationKeras.py as I would launch TMVAClassification.C (i.e root -l ClassificationKeras.py). I assume, from all the error: invalid preprocessing directive’s I get, this is not the way to launch it. I assume it probably needs to be launched via pyroot? Any advice would be welcome.

Cheers.

ROOT Version: 6.22.08
Platform: Ubuntu 20.04.2.0

The good thing is I figured how to launch the .py file, sadly now i have this problem

pyroot ClassificationKeras.py
Traceback (most recent call last):
  File "ClassificationKeras.py", line 17, in <module>
    from keras.models import Sequential
  File "/snap/root-framework/121/usr/local/lib/ROOT/_facade.py", line 121, in _importhook
    return _orig_ihook(name, *args, **kwds)
ModuleNotFoundError: No module named 'keras'

Thanks for any help in advance

Hey,

The snap package has a unqiue way of launching pyroot, with the pyroot binary. Internally this is just a normal python distribution. In other ROOT packages, you’d call python directly.

Beyond this, there are two other problems here.

Firstly, the snap doesn’t actually come bundled with TensorFlow/Keras, I’ve been debating whether to include it for a while, the main issue being Tensorflow/Keras is massive relative to the current size of the snap, I was capable of making the snap fit into 350mb of hard disk trivially, with Tensorflow it’ll shoot up from its current size of 500MB to about 1GB, and CUDA in the future will probably push this further. Regardless, I think I’ll concede here and just bundle it regardless because of the sheer utility the package provides.

The other problem is, from what I recall the way of actually using Keras has changed and a lot of the tutorials are currently still outdated, and you might need to edit the file to use

import tensorflow as tf
from tensorflow import keras

To compensate for package changes upstream.

I’ll post back in an hour or two when I’ve uploaded a new version of the snap that includes TF by default, and I’ll also post a cheeky way of including arbitrary Python packages without rebuilding the snap entirely for the benefit of those who might be interested.

Sorry for the delay, I’m still actively working on this. There’s been a few problems with snap quirks and recompiling ROOT 10 times in a row can take a while!

I’ve made good progress but the tutorials themselves do seem to be heavily tailored for an older version of Keras, I’m wondering if any of the other ROOTers here happen to know which version of Keras is recommended for v6.22, because as is none of the tutorials will work because they don’t match the latest upstream interfaces, and I don’t know whether to just bundle the latest TF/Keras and expect users to try tutorials outside the ROOT directory or pin to an older version of TF/Keras instead, though my inclination is the latter.

Edit: I’ve updated the snap, if you run sudo snap refresh it’ll now include Keras 2.4 and Tensorflow 2.4 and I’m reasonably confident these are working in CPU mode. The tutorials don’t work, however I assume that someone else might be able to chime in to give some examples that are more suitable than the ones bundled in the tutorial directory.

1 Like

Thank you very much. I’m sorry for the fuss I caused :sweat_smile:.
You also mentioned a way to include arbitrary Python packages? I understand if it’s too complicated to explain in a forum post.
Thank you again.
Have a great rest of the day!

No worries, it’s been on the to-do list for a while so it’s good that I’ve put some work into it :slight_smile:

It’s not that it’s complicated but that it’s not always guaranteed to work, for various reasons, but certain packages might be ideal for it, stuff like beautifulsoup or requests for example would probably work fine.

Internally Python has a list of folders to search for its packages, you can simply add to this list and it’ll try to use them, which means something like this is valid

import sys
import os
os.system("pip install requests -t pyroot_extras")
# It might be pip3, I'm somewhat forgetful ^
sys.path.append("pyroot_extras")

And you could then make .rootlogin.py entries in $HOME/snap/root-framework/current/.rootlogin.py that would automatically append this everytime you open PyROOT for example.

Importantly, you’re just telling pip to put the modules in your home folder and python to look for them there, -t for --target

As I say, it won’t work for everything and it won’t be managed by snap itself with means updates could break them, but it might be better than rebuilding the entire ROOT snap itself for people who need just the odd couple of extras.

Thank you very much for the help.
I just want to let you know that I’ve seen that the code for ClassificationKeras.py has changed for root 6.24 i.e:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation
from tensorflow.keras.optimizers import SGD

has been added. I thought since it seems to be the latest version it might work. I’ve got the following error:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: cannot import name 'tensorflow_backend' from 'keras.backend' (/snap/root-framework/123/lib/python3.8/site-packages/keras/backend.py)

It might just be that I’m using code written for root 6.24 and running root 6.22, but thought I would just let you know for the off-chance it being a bug.
On the plus side it actually started to load and add variables.

Could you provide some code that produces the error?

/snap/root-framework/123/lib/python3.8/site-packages/keras/backend.py is simply from tensorflow.keras.backend import * ; on my machine with the same revision of the snap as you I get this:

ubuntu@pardonable-sunbird:~$ pyroot
Python 3.8.5 (default, Jul 28 2020, 12:59:40)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ROOT
>>> import tensorflow
2021-03-28 23:44:41.138184: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /var/lib/snapd/lib/gl:/var/lib/snapd/lib/gl32:/var/lib/snapd/void:/snap/root-framework/123/usr/local/lib:/snap/root-framework/123/lib:/snap/root-framework/123/usr/lib:/snap/root-framework/123/lib/x86_64-linux-gnu:/snap/root-framework/123/usr/lib/x86_64-linux-gnu:/snap/root-framework/123/usr/lib/x86_64-linux-gnu/dri
2021-03-28 23:44:41.138235: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.
>>> import keras
>>> from tensorflow.keras.backend import *
>>>

Unfortunately I’m not knowledgable in how TF/Keras/ROOT fundamentally fit together, it could quite possibly be my fault so hopefully someone might be able to shine a light as we go back into the work week; however I can’t reproduce the issue at the moment.

Hello,

for the code I used, it’s just the code from ROOT: tutorials/tmva/keras/ClassificationKeras.py Source File .Just I changed the part where it used the default file because it was throwing up a null point error when trying to load ‘TreeS’. Nevertheless I used a MVA file I was provided to analyse it.
And for your code snippet, I’ve tried every command and no error occurred

pyroot
Python 3.8.5 (default, Jul 28 2020, 12:59:40) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ROOT
>>> import tensorflow
2021-03-29 00:58:22.304986: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /var/lib/snapd/lib/gl:/var/lib/snapd/lib/gl32:/var/lib/snapd/void:/snap/root-framework/123/usr/local/lib:/snap/root-framework/123/lib:/snap/root-framework/123/usr/lib:/snap/root-framework/123/lib/x86_64-linux-gnu:/snap/root-framework/123/usr/lib/x86_64-linux-gnu:/snap/root-framework/123/usr/lib/x86_64-linux-gnu/dri
2021-03-29 00:58:22.305017: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.
>>> import keras
>>> from tensorflow.keras.backend import *
>>> quit()

It’s getting late here, so I’m sorry that I won’t be of much help until tomorrow.

The null pointer is caused by the curl command, the server is using a HTTP redirect and curl isn’t folllowing it, you can fix that specific issue by replacing the bit under #load data with

call(['curl', '-O', 'http://root.cern.ch/files/tmva_class_example.root', '-L'])

Otherwise, I do get the same error as you, I’ve tried playing about with it a bit. Placing from tensorflow.keras.backend import * after the end of the other imports doesn’t cause the problem, the exact line causing the problem is

factory.BookMethod(dataloader, TMVA.Types.kPyKeras, 'PyKeras',
                   'H:!V:VarTransform=D,G:FilenameModel=model.h5:NumEpochs=20:BatchSize=32')

If someone chimes in with a recommendation for specific versions of Tensorflow/Keras that are known to work I can rebuild the package with them, but I’ve tried searching for hints and can’t find any. Hopefully an expert will come along soon (as a reminder because this thread is getting a bit long, the snap is currently using ROOT 6.22.8 with - tensorflow 2.4.1 and Keras 2.4.3)

Hi,
There is an issue getting the file with curl in the ClassificationKeras.py tutorial.
It should use https instead of http.
The correct command is:

# Load data                                                                                                                                                                             
if not isfile('tmva_class_example.root'):                                                                                                                                               
    call(['curl', '-O', 'https://root.cern.ch/files/tmva_class_example.root'])    

You can also forget about curl and do:

data = TFile.Open('http://root.cern.ch/files/tmva_class_example.root')  

I will submit a PR fixing ths

Lorenzo

Hello again,

found this forum post New version of Keras and conflict with TMVA!
I don’t know if it will help but if someone is watching just to let him know that the error has occurred before.
It does say “Keras 2.3.0 ok”

Funnily I’m compiling a version with Keras 2.3 as you’ve sent this :stuck_out_tongue:

I’ve just tried it without the Keras package at all, the import failure goes away but the code still doesn’t run. Taking a look into the backend, I see there’s basically a comment that says Keras 2.4 is just never going to work. There also seems to be an option that implies that it might be toggable to use tf.keras internally but I’m not sure exactly how to trigger it. Regardless, I might have some good news soonish.

1 Like

Hi,
The TMVA Keras interface works both with tf.keras and keras standalone version (<=2.3).
2.3 is the last version of Keras, as independent of Tensorflow.

I am a bit confused by all the messages. What is the error are you getting ?

Lorenzo

1 Like

To try keep it brief since this thread is getting confusing,

The snap is currently using ROOT 6.22.8, I am trying to give it a suitable environment for users to use the TMVA Keras interface but the current attempts have failed. I have full control over the users Python environment and can upgrade and downgrade it at will, but I’m simply not sure what specific packages and their versions to include. So far I’ve tried Tensorflow 2.4 + Keras 2.4, Tensorflow 2.4 without Keras, and Tensorflow 2.4 and Keras 2.3; all three of these have had seperate issues.

On Johns side, there’s the problems with the API’s changing over time which is adding to the complications, but at the moment I can’t guarantee the snap is actually stable regarding Keras to assume it’s problems with the tutorials exclusively.

So if there’s some exact package versions you could recommend, I can force all the users to have that specific configuration, and then presumably the problem is just adapting to the API differences. The specific errors for each combination of packages and tutorial used change substantially, if there’s a specific one you’d like to know about let me know.

Thanks for the help :slight_smile:

HI,

The PyMVA in ROOT 6.22.8 should support both Keras 2.3 and Tensorflow.Keras (tensorflow version > 2.0)
I think you should recommend people using tensorflow.keras for 6.22 and use add the option when booking the method, tf.keras=True. For example:

factory.BookMethod(dataloader, TMVA.Types.kPyKeras, 'PyKeras',
                   'H:!V:VarTransform=D,G:FilenameModel=model.h5:NumEpochs=20:BatchSize=32:tf.keras=True')

Note that the tutorials in tutorials/tmva/keras have been updated only for ROOT 6.24 to work with tensorflow keras.

If you are getting an error, please share your code and let me know the version you are using ?

Best regards

Lorenzo

1 Like

Thank you very much for the help Lorenzo, with Tensorflow 2.4, and Keras 2.3, adding the tf.keras=True attribute makes the 6.24 tutorial work.

I’ll work on uploading this to the snap store now so John can get on with using it.

#!/usr/bin/env python
## \file
## \ingroup tutorial_tmva_keras
## \notebook -nodraw
## This tutorial shows how to do classification in TMVA with neural networks
## trained with keras.
##
## \macro_code
##
## \date 2017
## \author TMVA Team

from ROOT import TMVA, TFile, TTree, TCut
from subprocess import call
from os.path import isfile

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation
from tensorflow.keras.optimizers import SGD

# Setup TMVA
TMVA.Tools.Instance()
TMVA.PyMethodBase.PyInitialize()

output = TFile.Open('TMVA.root', 'RECREATE')
factory = TMVA.Factory('TMVAClassification', output,
                       '!V:!Silent:Color:DrawProgressBar:Transformations=D,G:AnalysisType=Classification')

# Load data
if not isfile('tmva_class_example.root'):
    call(['curl', '-O', 'https://root.cern.ch/files/tmva_class_example.root'])

data = TFile.Open('tmva_class_example.root')
signal = data.Get('TreeS')
background = data.Get('TreeB')

dataloader = TMVA.DataLoader('dataset')
for branch in signal.GetListOfBranches():
    dataloader.AddVariable(branch.GetName())

dataloader.AddSignalTree(signal, 1.0)
dataloader.AddBackgroundTree(background, 1.0)
dataloader.PrepareTrainingAndTestTree(TCut(''),
                                      'nTrain_Signal=4000:nTrain_Background=4000:SplitMode=Random:NormMode=NumEvents:!V')

# Generate model

# Define model
model = Sequential()
model.add(Dense(64, activation='relu', input_dim=4))
model.add(Dense(2, activation='softmax'))

# Set loss and optimizer
model.compile(loss='categorical_crossentropy',
              optimizer=SGD(lr=0.01), metrics=['accuracy', ])

# Store model to file
model.save('model.h5')
model.summary()

# Book methods
factory.BookMethod(dataloader, TMVA.Types.kFisher, 'Fisher',
                   '!H:!V:Fisher:VarTransform=D,G')
factory.BookMethod(dataloader, TMVA.Types.kPyKeras, 'PyKeras',
                   'H:!V:VarTransform=D,G:FilenameModel=model.h5:NumEpochs=20:BatchSize=32:tf.keras=True')

# Run training, test and evaluation
factory.TrainAllMethods()
factory.TestAllMethods()
factory.EvaluateAllMethods()

Edit: it’s live now, run sudo snap refresh and hopefully revision 125 will work absolutely fine with the snippet above

2 Likes