Fix conflicts

This commit is contained in:
fchollet 2015-05-30 18:46:00 -07:00
commit b5c1ccab5a
7 changed files with 120 additions and 8 deletions

@ -38,4 +38,6 @@ pages:
- [preprocessing/sequence.md, Preprocessing, Sequence Preprocessing]
- [preprocessing/text.md, Preprocessing, Text Preprocessing]
- [preprocessing/image.md, Preprocessing, Image Preprocessing]
- [preprocessing/image.md, Preprocessing, Image Preprocessing]
- [utils/visualization.md, Utils, Visualization Utilities]

@ -39,8 +39,8 @@ model = keras.models.Sequential()
- __Return__: loss over the data, or tuple `(loss, accuracy)` if `accuracy=True`.
- __test__(X, y, accuracy=False): Single performance evaluation on one batch. if accuracy==False, return tuple (loss_on_batch, accuracy_on_batch). Else, return loss_on_batch.
- __Return__: loss over the data, or tuple `(loss, accuracy)` if `accuracy=True`.
- __save_weights__(fname): Store the weights of all layers to a HDF5 file.
- __load_weights__(fname): Sets the weights of a model, based to weights stored by __save_weights__. You can only __load_weights__ on a savefile from a model with an identical architecture. __load_weights__ can be called either before or after the __compile__ step.
- __save_weights__(fname, overwrite=False): Store the weights of all layers to a HDF5 file. If overwrite==False and the file already exists, an exception will be thrown.
- __load_weights__(fname): Sets the weights of a model, based to weights stored by __save__weights__. You can only __load__weights__ on a savefile from a model with an identical architecture. __load_weights__ can be called either before or after the __compile__ step.
__Examples__:

@ -0,0 +1,28 @@
## Grapher
Creates a visualization of the model structure using `pydot`.
```python
grapher = keras.utils.dot_utils.Grapher()
```
- __Methods__:
- __plot__(model, to_file): creates a graph visualizing the structure of `model` and writes it to `to_file`.
- __Arguments__:
- __model__: an instance of a Keras model (e.g. `Sequential`)
- __to_file__: the filename to save the visualization png to.
__Examples__:
```python
from keras.models import Sequential
from keras.layers.core import Dense, Activation
from keras.utils.dot_utils import Grapher
grapher = Grapher()
model = Sequential()
model.add(Dense(64, 2, init='uniform'))
model.add(Activation('softmax'))
grapher.plot(model, 'model.png')
```

@ -18,7 +18,7 @@ from keras.preprocessing.text import Tokenizer
'''
max_words = 10000
batch_size = 16
batch_size = 32
print("Loading data...")
(X_train, y_train), (X_test, y_test) = reuters.load_data(nb_words=max_words, test_split=0.2)
@ -51,7 +51,8 @@ model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam')
model.fit(X_train, Y_train, nb_epoch=4, batch_size=batch_size, verbose=1, show_accuracy=True, validation_split=0.1)
history = model.fit(X_train, Y_train, nb_epoch=3, batch_size=batch_size, verbose=1, show_accuracy=True, validation_split=0.1)
print(history)
score = model.evaluate(X_test, Y_test, batch_size=batch_size, verbose=1, show_accuracy=True)
print('Test score:', score[0])
print('Test accuracy:', score[1])

@ -382,10 +382,13 @@ class Sequential(Model):
self.layers[i].set_weights(weights[:nb_param])
weights = weights[nb_param:]
def save_weights(self, filepath):
def save_weights(self, filepath, overwrite=False):
# Save weights from all layers to HDF5
import h5py
# FIXME: fail if file exists, or add option to overwrite!
import os.path
# if file exists and should not be overwritten
if not overwrite and os.path.isfile(filepath):
raise IOError('%s already exists' % (filepath))
f = h5py.File(filepath, 'w')
f.attrs['nb_layers'] = len(self.layers)
for k, l in enumerate(self.layers):
@ -408,4 +411,4 @@ class Sequential(Model):
weights = [g['param_{}'.format(p)] for p in range(g.attrs['nb_params'])]
self.layers[k].set_weights(weights)
f.close()

51
keras/utils/dot_utils.py Normal file

@ -0,0 +1,51 @@
import pydot
from keras.layers.core import Merge
from keras.models import Model
from collections import Counter
class Grapher(object):
def __init__(self):
self.names = {}
self.class_counts = Counter()
def get_name(self, model):
"""
returns the name of the model instance. If model does not have a `name` attribute, then it will be assigned
a generic (and unique) identifier based on its class
"""
if hasattr(model, 'name'):
return model.name
clz = model.__class__.__name__
if model not in self.names:
self.class_counts[clz] += 1
self.names[model] = clz + str(self.class_counts[clz])
return self.names[model]
def add_edge(self, f, t, graph):
if f: graph.add_edge(pydot.Edge(f, t))
return t
def add_model(self, model, graph, parent=None):
"""
Recursively adds `model` and its components to the pydot graph
"""
this = self.get_name(model)
if isinstance(model, Model):
parent = self.add_edge(parent, this, graph)
for child in reversed(model.layers):
parent = self.add_model(child, graph, parent)
elif isinstance(model, Merge):
for child in model.models:
self.add_model(child, graph, this)
return self.add_edge(parent, this, graph)
else:
return self.add_edge(parent, this, graph)
def plot(self, model, to_file):
"""
creates a graph visualizing the structure of `model` and writes it to `to_file`
"""
graph = pydot.Dot(graph_type='graph')
self.add_model(model, graph)
graph.write_png(to_file)

27
test/test_dot_utils.py Normal file

@ -0,0 +1,27 @@
from keras.utils.dot_utils import Grapher
from keras.models import Sequential
from keras.layers.core import Dense, Activation, Merge, Flatten
from keras.layers.embeddings import Embedding
from keras.layers.recurrent import GRU
ent_lookup = Sequential()
ent_lookup.add(Embedding(10, 2))
ent_lookup.add(Flatten())
rel_lookup = Sequential()
rel_lookup.add(Embedding(20, 2))
rel_lookup.add(Flatten())
word_sequence = Sequential()
word_sequence.add(Embedding(10, 5))
word_sequence.add(GRU(5, 2))
model = Sequential()
model.add(Merge([word_sequence, ent_lookup, rel_lookup], mode='concat'))
model.add(Activation('relu'))
model.add(Dense(6, 2))
model.add(Activation('softmax'))
g = Grapher()
g.plot(model, 'mymodel.png')