Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
# mlpredict

A python package to predict the execution time for one forward and backward pass a deep learning model.
A python package to predict the execution time for one forward and backward pass a deep neural network.

To improve the underlying machine learning model see https://github.com/CDECatapult/ml-performance-prediction.

To install mlpredict run

mlpredict can be installed by executing
``` bash
pip install -r requirements.txt
```
and
``` bash
python setup.py install
```
from the root directory.
Expand All @@ -18,7 +17,7 @@ The mlpredict API can be used to create representations of deep neural networks
### Create a model representations
To build the representation of a deep neural network from scratch create an instance of the dnn class
``` python
dnn_repr = mlpredict.api.new_dnn(input_dimension,input_size)
dnn_repr = mlpredict.api.dnn(input_dimension,input_size)
```
and add layers
``` python
Expand All @@ -33,7 +32,7 @@ and the current network architecture can be displayed
dnn_repr.describe()
```

A completed model can be saved to a .json file using
Finally, a model can be saved to a .json file using
``` python
dnn_repr.save(filename)
```
Expand All @@ -44,9 +43,9 @@ For a full working example see the jupyter notebook https://github.com/CDECatap
### Import existing model representations
Exiting model representations can be imported using
```python
dnn_repr = mlpredict.api.import_default(filename)
dnn_repr = mlpredict.api.import_default(dnn_object)
```
An imported representation can be modified and saved as described above in **Create a model representations**.
`dnn_object` can be either the path to a previously created .json file (see above) or the name of a default model (at the moment only`'VGG16'`). An imported representation can be modified and saved as described above in the section **Create a model representations**.


### Predict execution time using mlpredict
Expand All @@ -57,4 +56,4 @@ time_total, layer, time_layer = dnn_repr.predict(gpu,
optimizer,
batchsize)
```
returns the total execution time, the layers and the time per layer. For a complete working example see https://github.com/CDECatapult/mlpredict/blob/master/notebooks/Full_model_prediction.ipynb
returns the total execution time, the layers and the time per layer. Here, `gpu` can be a .json file with the keys 'bandwidth', 'cores', and 'clock' or the name of a default GPU ('V100', 'P100', 'M60', 'K80', 'K40', or '1080Ti'). For a complete working example see https://github.com/CDECatapult/mlpredict/blob/master/notebooks/Full_model_prediction.ipynb
11 changes: 1 addition & 10 deletions notebooks/Create_new_dnn.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
}
],
"source": [
"VGG16 = mlpredict.api.dnn(input_dimension=3, input_size=224)\n",
"VGG16 = mlpredict.api.Dnn(input_dimension=3, input_size=224)\n",
"\n",
"\n",
"VGG16.add_layer('Convolution', 'conv1_1', kernelsize=3, channels_out=64, \n",
Expand Down Expand Up @@ -179,15 +179,6 @@
"source": [
"VGG16.save('models/VGG16.json')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
Expand Down
40 changes: 19 additions & 21 deletions notebooks/Full_model_prediction.ipynb

Large diffs are not rendered by default.

16 changes: 7 additions & 9 deletions src/mlpredict/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from mlpredict.import_tools import import_gpu


class dnn(dict):
class Dnn(dict):
"""Class for deep neural network architecture"""

def __init__(self, input_dimension, input_size):
Expand All @@ -17,14 +17,14 @@ def __init__(self, input_dimension, input_size):
self['input']['size'] = input_size

def save(self, path):
"""Save dnn to path"""
"""Save Dnn to path"""
if not os.path.isdir(os.path.dirname(path)):
os.mkdir(os.path.dirname(path))
with open(path, 'w') as json_file:
json.dump(self, json_file, indent=4)

def describe(self):
"""Prints a description of of the class instance"""
"""Prints a description of the class instance"""
print('%d layer network\n' % (len(self['layers'])))
print('Input size %dx%dx%d\n'
% (self['input']['size'], self['input']['size'],
Expand Down Expand Up @@ -76,9 +76,8 @@ def add_layer(self, layer_type, layer_name, **kwargs):
(kwargs['padding'].lower() == 'valid')
* (kwargs['kernelsize'] - 1))
output_size = (
(input_size -
padding_reduction) /
kwargs['strides'])
(input_size - padding_reduction)
/ kwargs['strides'])

self['layers'][new_layer]['matsize'] = input_size
self['layers'][new_layer]['kernelsize'] = kwargs['kernelsize']
Expand All @@ -95,9 +94,8 @@ def add_layer(self, layer_type, layer_name, **kwargs):
(kwargs['padding'].lower() == 'valid')
* (kwargs['pool_size'] - 1))
output_size = (
(input_size -
padding_reduction) /
kwargs['strides'])
(input_size - padding_reduction)
/ kwargs['strides'])

self['layers'][new_layer]['pool_size'] = kwargs['pool_size']
self['layers'][new_layer]['strides'] = kwargs['strides']
Expand Down
35 changes: 21 additions & 14 deletions src/mlpredict/import_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import json
import pkg_resources

import mlpredict.api
import mlpredict


class DnnImportError(Exception):
Expand All @@ -25,9 +25,11 @@ def __init__(self, message):


def import_dnn(dnn_obj):
"""Import dnn. Tries local definition first
"""Import dnn definition from local file or mlpredict.
Tries local definition first.
Returns:
net: instance of class dnn"""
net: instance of class Dnn
"""
if os.path.isfile(dnn_obj):
net = import_dnn_file(dnn_obj)
else:
Expand All @@ -36,9 +38,10 @@ def import_dnn(dnn_obj):


def import_dnn_default(dnn_name):
"""Import dnn from default path
"""Import dnn from default path (mlpredict).
Returns:
net: instance of class dnn"""
net: instance of class Dnn
"""
try:
dnn_file = pkg_resources.resource_filename(
'mlpredict', 'dnn_architecture/%s.json'
Expand All @@ -52,11 +55,11 @@ def import_dnn_default(dnn_name):


def import_dnn_file(dnn_file):
"""Import dnn from local path
"""Import dnn from local path.
Returns:
net: instance of class dnn"""

net = mlpredict.api.dnn(0, 0)
net: instance of class Dnn
"""
net = mlpredict.api.Dnn(0, 0)
with open(dnn_file) as json_data:
tmpdict = json.load(json_data)
try:
Expand All @@ -68,9 +71,11 @@ def import_dnn_file(dnn_file):


def import_gpu(gpu_obj):
"""Import gpu definition. Tries local definition first
"""Import gpu definition from local file or mlpredict.
Tries local definition first.
Returns:
gpu_stats"""
gpu_stats
"""
if os.path.isfile(gpu_obj):
gpu_stats = import_gpu_file(gpu_obj)
else:
Expand All @@ -79,9 +84,10 @@ def import_gpu(gpu_obj):


def import_gpu_default(gpu_name):
"""Import gpu definition from default path
"""Import gpu definition from default path (mlpredict).
Returns:
gpu_stats"""
gpu_stats
"""
try:
gpu_file = pkg_resources.resource_filename(
'mlpredict', 'GPUs/%s.json' % gpu_name)
Expand All @@ -95,7 +101,8 @@ def import_gpu_default(gpu_name):
def import_gpu_file(gpu_file):
"""Import gpu definition from local path
Returns:
gpu_stats"""
gpu_stats
"""
with open(gpu_file) as json_data:
gpu_stats = json.load(json_data)
if not all(key in gpu_stats.keys() for key in ['bandwidth','cores', 'clock']):
Expand Down
44 changes: 23 additions & 21 deletions src/mlpredict/prediction.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def predict_walltime(model,
Args:
model: Deep neural network architecture, instance of the model class
model_file: tensorflow model
sklearn: skleran scaler
sklearn: sklearn scaler
batchsize (int)
optimizer (string)
bandwidth: GPU memory bandwidth in GB/s (int)
Expand Down Expand Up @@ -62,6 +62,7 @@ def get_input_features(
bandwidth,
cores,
clock):
"""Generates fetaure dictionary to be used with mlpredict"""

padding_reduction = ((dictionary['padding'].lower() == 'valid')
* (dictionary['kernelsize'] - 1))
Expand All @@ -86,26 +87,27 @@ def get_input_features(
* elements_output
* dictionary['channels_out'])

features = np.array([batchsize,
dictionary['matsize']**2,
dictionary['kernelsize']**2,
dictionary['channels_in'],
dictionary['channels_out'],
(1 if dictionary['padding'].lower() == 'same' else 0),
dictionary['strides'],
dictionary['use_bias'],
(1 if optimizer.lower() == 'sgd' else 0),
(1 if optimizer.lower() == 'adadelta' else 0),
(1 if optimizer.lower() == 'adagrad' else 0),
(1 if optimizer.lower() == 'momentum' else 0),
(1 if optimizer.lower() == 'adam' else 0),
(1 if optimizer.lower() == 'rmsprop' else 0),
(1 if dictionary['activation'].lower() == 'relu' else 0),
(1 if dictionary['activation'].lower() == 'tanh' else 0),
(1 if dictionary['activation'].lower() == 'sigmoid' else 0),
bandwidth,
cores,
clock])
features = np.array([
batchsize,
dictionary['matsize']**2,
dictionary['kernelsize']**2,
dictionary['channels_in'],
dictionary['channels_out'],
(1 if dictionary['padding'].lower() == 'same' else 0),
dictionary['strides'],
dictionary['use_bias'],
(1 if optimizer.lower() == 'sgd' else 0),
(1 if optimizer.lower() == 'adadelta' else 0),
(1 if optimizer.lower() == 'adagrad' else 0),
(1 if optimizer.lower() == 'momentum' else 0),
(1 if optimizer.lower() == 'adam' else 0),
(1 if optimizer.lower() == 'rmsprop' else 0),
(1 if dictionary['activation'].lower() == 'relu' else 0),
(1 if dictionary['activation'].lower() == 'tanh' else 0),
(1 if dictionary['activation'].lower() == 'sigmoid' else 0),
bandwidth,
cores,
clock])

features = scaler.transform(features.reshape(1, -1))
return features