You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/models.rst
+41-49Lines changed: 41 additions & 49 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,19 +12,18 @@ We include three `examples`_ for you to try: a model trained on the `MNIST`_ dat
12
12
13
13
If you built your model with Keras using a `Sequential`_ model, you should be more or less good to go. If you used Tensorflow, you'll need to manually specify the entry and exit points [#]_.
14
14
15
-
You can specify the backend (Tensorflow or Keras) using the ``PICASSO_BACKEND_ML`` setting. The allowed values are ``tensorflow`` or ``keras`` (see :doc:`settings`).
16
-
17
15
Your model data
18
16
===============
19
17
20
-
You can specify the data directory with the ``PICASSO_DATA_DIR`` setting. This directory should contain the Keras or Tensorflow checkpoint files. If multiple checkpoints are found, the latest one will be used (see example `Keras model code`_).
18
+
You can specify the data directory with the ``MODEL_LOAD_ARGS.data_dir`` setting (see :doc:`settings`). This directory should contain the Keras or Tensorflow checkpoint files. If multiple checkpoints are found, the latest one will be used (see example `Keras model code`_).
21
19
22
20
Utility functions
23
21
=================
24
22
25
23
In addition to the graph and weight information of the model itself, you'll need to define a few functions to help the visualization interact with user input, and interpret raw output from your computational graph. These are arbitrary python functions, and their locations can be specified in the :doc:`settings`.
26
24
27
-
We'll draw from the `Keras MNIST example`_ for this guide.
25
+
We'll draw from the `Keras MNIST example`_ for this guide. All custom models
26
+
from the relevant model: either ``KerasModel`` or ``TensorflowModel``.
28
27
29
28
Preprocessor
30
29
------------
@@ -33,39 +32,29 @@ The preprocessor takes images uploaded to the webapp and converts them into arra
33
32
34
33
.. code-block:: python3
35
34
36
-
MNIST_DIM = (28, 28)
37
-
38
-
def preprocess(targets):
39
-
image_arrays = []
40
-
for target in targets:
41
-
im = target.convert('L')
42
-
im = im.resize(MNIST_DIM, Image.ANTIALIAS)
43
-
arr = np.array(im)
44
-
image_arrays.append(arr)
45
-
46
-
all_targets = np.array(image_arrays)
47
-
return all_targets.reshape(len(all_targets),
48
-
MNIST_DIM[0],
49
-
MNIST_DIM[1], 1).astype('float32') / 255
50
-
51
-
Specifically, we have to convert an arbitrary input color image to a float array of the input size specified with ``MNIST_DIM``.
35
+
import numpy as np
36
+
from PIL import Image
37
+
38
+
from picasso.models.keras import KerasModel
52
39
53
-
Postprocessor
54
-
-------------
40
+
MNIST_DIM = (28, 28)
55
41
56
-
For some visualizations, it's useful to convert a flat representation back into an array with the same shape as the original image.
42
+
class KerasMNISTModel(KerasModel):
57
43
58
-
.. code-block:: python3
44
+
def preprocess(self, raw_inputs):
45
+
image_arrays = []
46
+
for target in targets:
47
+
im = target.convert('L')
48
+
im = im.resize(MNIST_DIM, Image.ANTIALIAS)
49
+
arr = np.array(im)
50
+
image_arrays.append(arr)
59
51
60
-
def postprocess(output_arr):
61
-
images = []
62
-
for row in output_arr:
63
-
im_array = row.reshape(MNIST_DIM)
64
-
images.append(im_array)
52
+
all_targets = np.array(image_arrays)
53
+
return all_targets.reshape(len(all_targets),
54
+
MNIST_DIM[0],
55
+
MNIST_DIM[1], 1).astype('float32') / 255
65
56
66
-
return images
67
-
68
-
This therefore takes an arbitrary array (with the same number of total entries as the image array) and reshapes it back.
57
+
Specifically, we have to convert an arbitrary input color image to a float array of the input size specified with ``MNIST_DIM``.
69
58
70
59
Class Decoder
71
60
-------------
@@ -74,24 +63,27 @@ Class probabilities are usually returned in an array. For any visualization whe
74
63
75
64
.. code-block:: python3
76
65
77
-
def prob_decode(probability_array, top=5):
78
-
results = []
79
-
for row in probability_array:
80
-
entries = []
81
-
for i, prob in enumerate(row):
82
-
entries.append({'index': i,
83
-
'name': str(i),
84
-
'prob': prob})
66
+
class KerasMNISTModel(KerasModel):
85
67
86
-
entries = sorted(entries,
87
-
key=itemgetter('prob'),
88
-
reverse=True)[:top]
68
+
...
69
+
70
+
def decode_prob(self, class_probabilities):
71
+
results = []
72
+
for row in class_probabilities:
73
+
entries = []
74
+
for i, prob in enumerate(row):
75
+
entries.append({'index': i,
76
+
'name': str(i),
77
+
'prob': prob})
89
78
90
-
for entry in entries:
91
-
entry['prob'] = '{:.3f}'.format(entry['prob'])
92
-
results.append(entries)
79
+
entries = sorted(entries,
80
+
key=itemgetter('prob'),
81
+
reverse=True)[:self.top_probs]
93
82
94
-
return results
83
+
for entry in entries:
84
+
entry['prob'] = '{:.3f}'.format(entry['prob'])
85
+
results.append(entries)
86
+
return results
95
87
96
88
``results`` is then a list of dicts in the format ``[{'index': class_index, 'name': class_name, 'prob': class_probability}, ...]``. In the case of the MNIST dataset, the index is the same as the class name (digits 0-9).
97
89
@@ -103,9 +95,9 @@ Class probabilities are usually returned in an array. For any visualization whe
@@ -34,7 +32,7 @@ and ``picasso/templates/FunViz.html``:
34
32
your visualization html goes here
35
33
{% endblock %}
36
34
37
-
Some explanation for the ``FunViz`` class in ``fun_viz.py``: All visualizations should inherit from :class:`~picasso.visualizations.__init__.BaseVisualization` (see `code <BaseVisualization>`_). You must implement the ``__init__`` method, and it should accept one argument, ``model``. ``model`` will be an instance of a child class of `Model`_, which provides an interface to the machine learning backend. You can also add a description which will display on the landing page.
35
+
Some explanation for the ``FunViz`` class in ``fun_viz.py``: All visualizations should inherit from :class:`~picasso.visualizations.base.__init__.BaseVisualization`. You can also add a description which will display on the landing page.
38
36
39
37
Some explanation for ``FunViz.html``: The web app is uses `Flask`_, which uses `Jinja2`_ templating. This explains the funny ``{% %}`` delimiters. The ``{% extends "result.html" %}`` just tells the your page to inherit from a boilerplate. All your html should sit within the ``vis`` block.
40
38
@@ -53,16 +51,14 @@ Add visualization logic
53
51
Our visualization should actually do something. It's just going to compute the class probabilities and pass them back along to the web app. So we'll add:
54
52
55
53
.. code-block:: python3
56
-
:emphasize-lines: 11-21
54
+
:emphasize-lines: 9-21
57
55
58
-
from picasso.visualizations import BaseVisualization
56
+
from picasso.visualizations.base import BaseVisualization
@@ -311,20 +307,19 @@ Similarly, there is an ``outputs/`` folder (not shown in this example). Its pat
311
307
Add some settings
312
308
=================
313
309
314
-
Maybe we'd like the user to be able to limit the number of classes shown. We can easily do this by adding a ``settings`` property to the ``FunViz`` class.
310
+
Maybe we'd like the user to be able to limit the number of classes shown. We can easily do this by adding an ``ALLOWED_SETTINGS`` property to the ``FunViz`` class.
315
311
316
312
.. code-block:: python3
317
-
:emphasize-lines: 5, 21
313
+
:emphasize-lines: 6, 20
318
314
319
315
from picasso.visualizations import BaseVisualization
0 commit comments