We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Model serialization
This discussion started in #51, but as things can get complicated I decided to start another issue.

It seems to be a good idea to store weights for a model separately in an HDF5 file (or even a Numpy npy file, but HDF5 would be more portable). I wanted to compare how large is a serialized model with and without the weights, so I did the following test:

```
    model = Sequential()
    model.add(Dense(n_input, 2048, init='uniform', activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(2048, 2048, init='uniform', activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(2048, 2048, init='uniform', activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(2048, 2048, init='uniform', activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(2048, n_output, init='uniform', activation='linear'))
```

(the model is intentionally large!)

I then compiled the model, serialized it after compilation, and removed the weights and post-compilation Theano objects/functions as follows:

```
    for l in model.layers:
        weights.append(l.get_weights())
        l.params = []
        try:
            l.W = None
            l.b = None
        except ValueError:
            pass
    model.X = None
    model.y = None
    model.y_test = None
    model.y_train = None
    model._train  = None
    model._train_with_acc  = None
    model._test = None
    model._test_with_acc = None
    model._predict = None
```

The full compiled model ends up with 243 MB, and the cleaned-up model with 120 MB (which is exacly the same we would get from pickling the non-compiled models with the weight matrices deleted). Is there anything else we could remove to make the serialized model smaller?


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `keras/models.py`
Content:
```
1 from __future__ import absolute_import
2 from __future__ import print_function
3 import theano
4 import theano.tensor as T
5 import numpy as np
6 
7 from . import optimizers
8 from . import objectives
9 import time, copy
10 from .utils.generic_utils import Progbar
11 from six.moves import range
12 
13 def standardize_y(y):
14     if not hasattr(y, 'shape'):
15         y = np.asarray(y)
16     if len(y.shape) == 1:
17         y = np.reshape(y, (len(y), 1))
18     return y
19 
20 def make_batches(size, batch_size):
21     nb_batch = int(np.ceil(size/float(batch_size)))
22     return [(i*batch_size, min(size, (i+1)*batch_size)) for i in range(0, nb_batch)]
23 
24 class Sequential(object):
25     def __init__(self):
26         self.layers = []
27         self.params = []
28 
29     def add(self, layer):
30         self.layers.append(layer)
31         if len(self.layers) > 1:
32             self.layers[-1].connect(self.layers[-2])
33         self.params += [p for p in layer.params]
34 
35     def compile(self, optimizer, loss, class_mode="categorical"):
36         self.optimizer = optimizers.get(optimizer)
37         self.loss = objectives.get(loss)
38 
39         self.X = self.layers[0].input # input of model 
40         # (first layer must have an "input" attribute!)
41         self.y_train = self.layers[-1].output(train=True)
42         self.y_test = self.layers[-1].output(train=False)
43 
44         # output of model
45         self.y = T.matrix() # TODO: support for custom output shapes
46 
47         train_loss = self.loss(self.y, self.y_train)
48         test_score = self.loss(self.y, self.y_test)
49 
50         if class_mode == "categorical":
51             train_accuracy = T.mean(T.eq(T.argmax(self.y, axis=-1), T.argmax(self.y_train, axis=-1)))
52             test_accuracy = T.mean(T.eq(T.argmax(self.y, axis=-1), T.argmax(self.y_test, axis=-1)))
53 
54         elif class_mode == "binary":
55             train_accuracy = T.mean(T.eq(self.y, T.round(self.y_train)))
56             test_accuracy = T.mean(T.eq(self.y, T.round(self.y_test)))
57         else:
58             raise Exception("Invalid class mode:" + str(class_mode))
59         self.class_mode = class_mode
60 
61         updates = self.optimizer.get_updates(self.params, train_loss)
62 
63         self._train = theano.function([self.X, self.y], train_loss, 
64             updates=updates, allow_input_downcast=True)
65         self._train_with_acc = theano.function([self.X, self.y], [train_loss, train_accuracy], 
66             updates=updates, allow_input_downcast=True)
67         self._predict = theano.function([self.X], self.y_test, 
68             allow_input_downcast=True)
69         self._test = theano.function([self.X, self.y], test_score, 
70             allow_input_downcast=True)
71         self._test_with_acc = theano.function([self.X, self.y], [test_score, test_accuracy], 
72             allow_input_downcast=True)
73 
74     def train(self, X, y, accuracy=False):
75         y = standardize_y(y)
76         if accuracy:
77             return self._train_with_acc(X, y)
78         else:
79             return self._train(X, y)
80         
81 
82     def test(self, X, y, accuracy=False):
83         y = standardize_y(y)
84         if accuracy:
85             return self._test_with_acc(X, y)
86         else:
87             return self._test(X, y)
88 
89 
90     def fit(self, X, y, batch_size=128, nb_epoch=100, verbose=1,
91             validation_split=0., validation_data=None, shuffle=True, show_accuracy=False):
92         y = standardize_y(y)
93 
94         do_validation = False
95         if validation_data:
96             try:
97                 X_val, y_val = validation_data
98             except:
99                 raise Exception("Invalid format for validation data; provide a tuple (X_val, y_val).")
100             do_validation = True
101             y_val = standardize_y(y_val)
102             if verbose:
103                 print("Train on %d samples, validate on %d samples" % (len(y), len(y_val)))
104         else:
105             if 0 < validation_split < 1:
106                 # If a validation split size is given (e.g. validation_split=0.2)
107                 # then split X into smaller X and X_val,
108                 # and split y into smaller y and y_val.
109                 do_validation = True
110                 split_at = int(len(X) * (1 - validation_split))
111                 (X, X_val) = (X[0:split_at], X[split_at:])
112                 (y, y_val) = (y[0:split_at], y[split_at:])
113                 if verbose:
114                     print("Train on %d samples, validate on %d samples" % (len(y), len(y_val)))
115         
116         index_array = np.arange(len(X))
117         for epoch in range(nb_epoch):
118             if verbose:
119                 print('Epoch', epoch)
120                 progbar = Progbar(target=len(X), verbose=verbose)
121             if shuffle:
122                 np.random.shuffle(index_array)
123 
124             batches = make_batches(len(X), batch_size)
125             for batch_index, (batch_start, batch_end) in enumerate(batches):
126                 if shuffle:
127                     batch_ids = index_array[batch_start:batch_end]
128                 else:
129                     batch_ids = slice(batch_start, batch_end)
130                 X_batch = X[batch_ids]
131                 y_batch = y[batch_ids]
132 
133                 if show_accuracy:
134                     loss, acc = self._train_with_acc(X_batch, y_batch)
135                     log_values = [('loss', loss), ('acc.', acc)]
136                 else:
137                     loss = self._train(X_batch, y_batch)
138                     log_values = [('loss', loss)]
139 
140                 # validation
141                 if do_validation and (batch_index == len(batches) - 1):
142                     if show_accuracy:
143                         val_loss, val_acc = self.test(X_val, y_val, accuracy=True)
144                         log_values += [('val. loss', val_loss), ('val. acc.', val_acc)]
145                     else:
146                         val_loss = self.test(X_val, y_val)
147                         log_values += [('val. loss', val_loss)]
148                 
149                 # logging
150                 if verbose:
151                     progbar.update(batch_end, log_values)
152 
153             
154     def predict_proba(self, X, batch_size=128, verbose=1):
155         batches = make_batches(len(X), batch_size)
156         if verbose==1:
157             progbar = Progbar(target=len(X))
158         for batch_index, (batch_start, batch_end) in enumerate(batches):
159             X_batch = X[batch_start:batch_end]
160             batch_preds = self._predict(X_batch)
161 
162             if batch_index == 0:
163                 shape = (len(X),) + batch_preds.shape[1:]
164                 preds = np.zeros(shape)
165             preds[batch_start:batch_end] = batch_preds
166 
167             if verbose==1:
168                 progbar.update(batch_end)
169 
170         return preds
171 
172 
173     def predict_classes(self, X, batch_size=128, verbose=1):
174         proba = self.predict_proba(X, batch_size=batch_size, verbose=verbose)
175         if self.class_mode == "categorical":
176             return proba.argmax(axis=-1)
177         else:
178             return (proba>0.5).astype('int32')
179 
180 
181     def evaluate(self, X, y, batch_size=128, show_accuracy=False, verbose=1):
182         y = standardize_y(y)
183 
184         if show_accuracy:
185             tot_acc = 0.
186         tot_score = 0.
187 
188         batches = make_batches(len(X), batch_size)
189         if verbose:
190             progbar = Progbar(target=len(X), verbose=verbose)
191         for batch_index, (batch_start, batch_end) in enumerate(batches):
192             X_batch = X[batch_start:batch_end]
193             y_batch = y[batch_start:batch_end]
194 
195             if show_accuracy:
196                 loss, acc = self._test_with_acc(X_batch, y_batch)
197                 tot_acc += acc
198                 log_values = [('loss', loss), ('acc.', acc)]
199             else:
200                 loss = self._test(X_batch, y_batch)
201                 log_values = [('loss', loss)]
202             tot_score += loss
203 
204             # logging
205             if verbose:
206                 progbar.update(batch_end, log_values)
207 
208         if show_accuracy:
209             return tot_score/len(batches), tot_acc/len(batches)
210         else:
211             return tot_score/len(batches)
212 
213 
214                 
215 
216 
217 
218
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/keras/models.py b/keras/models.py
--- a/keras/models.py
+++ b/keras/models.py
@@ -211,7 +211,31 @@
             return tot_score/len(batches)
 
 
-                
-
+    def save_weights(self, filepath):
+        # Save weights from all layers to HDF5
+        import h5py
+        # FIXME: fail if file exists, or add option to overwrite!
+        f = h5py.File(filepath, 'w')
+        f.attrs['nb_layers'] = len(self.layers)
+        for k, l in enumerate(self.layers):
+            g = f.create_group('layer_{}'.format(k))
+            weights = l.get_weights()
+            g.attrs['nb_params'] = len(weights)
+            for n, param in enumerate(weights):
+                param_name = 'param_{}'.format(n)
+                param_dset = g.create_dataset(param_name, param.shape, dtype='float64')
+                param_dset[:] = param
+        f.flush()
+        f.close()
+
+    def load_weights(self, filepath):
+        # Loads weights from HDF5 file
+        import h5py
+        f = h5py.File(filepath)
+        for k in range(f.attrs['nb_layers']):
+            g = f['layer_{}'.format(k)]
+            weights = [g['param_{}'.format(p)] for p in range(g.attrs['nb_params'])]
+            self.layers[k].set_weights(weights)
+        f.close()

{"golden_diff": "diff --git a/keras/models.py b/keras/models.py\n--- a/keras/models.py\n+++ b/keras/models.py\n@@ -211,7 +211,31 @@\n             return tot_score/len(batches)\n \n \n-                \n-\n+    def save_weights(self, filepath):\n+        # Save weights from all layers to HDF5\n+        import h5py\n+        # FIXME: fail if file exists, or add option to overwrite!\n+        f = h5py.File(filepath, 'w')\n+        f.attrs['nb_layers'] = len(self.layers)\n+        for k, l in enumerate(self.layers):\n+            g = f.create_group('layer_{}'.format(k))\n+            weights = l.get_weights()\n+            g.attrs['nb_params'] = len(weights)\n+            for n, param in enumerate(weights):\n+                param_name = 'param_{}'.format(n)\n+                param_dset = g.create_dataset(param_name, param.shape, dtype='float64')\n+                param_dset[:] = param\n+        f.flush()\n+        f.close()\n+\n+    def load_weights(self, filepath):\n+        # Loads weights from HDF5 file\n+        import h5py\n+        f = h5py.File(filepath)\n+        for k in range(f.attrs['nb_layers']):\n+            g = f['layer_{}'.format(k)]\n+            weights = [g['param_{}'.format(p)] for p in range(g.attrs['nb_params'])]\n+            self.layers[k].set_weights(weights)\n+        f.close()\n", "issue": "Model serialization\nThis discussion started in #51, but as things can get complicated I decided to start another issue.\n\nIt seems to be a good idea to store weights for a model separately in an HDF5 file (or even a Numpy npy file, but HDF5 would be more portable). I wanted to compare how large is a serialized model with and without the weights, so I did the following test:\n\n```\n    model = Sequential()\n    model.add(Dense(n_input, 2048, init='uniform', activation='relu'))\n    model.add(Dropout(0.5))\n    model.add(Dense(2048, 2048, init='uniform', activation='relu'))\n    model.add(Dropout(0.5))\n    model.add(Dense(2048, 2048, init='uniform', activation='relu'))\n    model.add(Dropout(0.5))\n    model.add(Dense(2048, 2048, init='uniform', activation='relu'))\n    model.add(Dropout(0.5))\n    model.add(Dense(2048, n_output, init='uniform', activation='linear'))\n```\n\n(the model is intentionally large!)\n\nI then compiled the model, serialized it after compilation, and removed the weights and post-compilation Theano objects/functions as follows:\n\n```\n    for l in model.layers:\n        weights.append(l.get_weights())\n        l.params = []\n        try:\n            l.W = None\n            l.b = None\n        except ValueError:\n            pass\n    model.X = None\n    model.y = None\n    model.y_test = None\n    model.y_train = None\n    model._train  = None\n    model._train_with_acc  = None\n    model._test = None\n    model._test_with_acc = None\n    model._predict = None\n```\n\nThe full compiled model ends up with 243 MB, and the cleaned-up model with 120 MB (which is exacly the same we would get from pickling the non-compiled models with the weight matrices deleted). Is there anything else we could remove to make the serialized model smaller?\n\n", "before_files": [{"content": "from __future__ import absolute_import\nfrom __future__ import print_function\nimport theano\nimport theano.tensor as T\nimport numpy as np\n\nfrom . import optimizers\nfrom . import objectives\nimport time, copy\nfrom .utils.generic_utils import Progbar\nfrom six.moves import range\n\ndef standardize_y(y):\n    if not hasattr(y, 'shape'):\n        y = np.asarray(y)\n    if len(y.shape) == 1:\n        y = np.reshape(y, (len(y), 1))\n    return y\n\ndef make_batches(size, batch_size):\n    nb_batch = int(np.ceil(size/float(batch_size)))\n    return [(i*batch_size, min(size, (i+1)*batch_size)) for i in range(0, nb_batch)]\n\nclass Sequential(object):\n    def __init__(self):\n        self.layers = []\n        self.params = []\n\n    def add(self, layer):\n        self.layers.append(layer)\n        if len(self.layers) > 1:\n            self.layers[-1].connect(self.layers[-2])\n        self.params += [p for p in layer.params]\n\n    def compile(self, optimizer, loss, class_mode=\"categorical\"):\n        self.optimizer = optimizers.get(optimizer)\n        self.loss = objectives.get(loss)\n\n        self.X = self.layers[0].input # input of model \n        # (first layer must have an \"input\" attribute!)\n        self.y_train = self.layers[-1].output(train=True)\n        self.y_test = self.layers[-1].output(train=False)\n\n        # output of model\n        self.y = T.matrix() # TODO: support for custom output shapes\n\n        train_loss = self.loss(self.y, self.y_train)\n        test_score = self.loss(self.y, self.y_test)\n\n        if class_mode == \"categorical\":\n            train_accuracy = T.mean(T.eq(T.argmax(self.y, axis=-1), T.argmax(self.y_train, axis=-1)))\n            test_accuracy = T.mean(T.eq(T.argmax(self.y, axis=-1), T.argmax(self.y_test, axis=-1)))\n\n        elif class_mode == \"binary\":\n            train_accuracy = T.mean(T.eq(self.y, T.round(self.y_train)))\n            test_accuracy = T.mean(T.eq(self.y, T.round(self.y_test)))\n        else:\n            raise Exception(\"Invalid class mode:\" + str(class_mode))\n        self.class_mode = class_mode\n\n        updates = self.optimizer.get_updates(self.params, train_loss)\n\n        self._train = theano.function([self.X, self.y], train_loss, \n            updates=updates, allow_input_downcast=True)\n        self._train_with_acc = theano.function([self.X, self.y], [train_loss, train_accuracy], \n            updates=updates, allow_input_downcast=True)\n        self._predict = theano.function([self.X], self.y_test, \n            allow_input_downcast=True)\n        self._test = theano.function([self.X, self.y], test_score, \n            allow_input_downcast=True)\n        self._test_with_acc = theano.function([self.X, self.y], [test_score, test_accuracy], \n            allow_input_downcast=True)\n\n    def train(self, X, y, accuracy=False):\n        y = standardize_y(y)\n        if accuracy:\n            return self._train_with_acc(X, y)\n        else:\n            return self._train(X, y)\n        \n\n    def test(self, X, y, accuracy=False):\n        y = standardize_y(y)\n        if accuracy:\n            return self._test_with_acc(X, y)\n        else:\n            return self._test(X, y)\n\n\n    def fit(self, X, y, batch_size=128, nb_epoch=100, verbose=1,\n            validation_split=0., validation_data=None, shuffle=True, show_accuracy=False):\n        y = standardize_y(y)\n\n        do_validation = False\n        if validation_data:\n            try:\n                X_val, y_val = validation_data\n            except:\n                raise Exception(\"Invalid format for validation data; provide a tuple (X_val, y_val).\")\n            do_validation = True\n            y_val = standardize_y(y_val)\n            if verbose:\n                print(\"Train on %d samples, validate on %d samples\" % (len(y), len(y_val)))\n        else:\n            if 0 < validation_split < 1:\n                # If a validation split size is given (e.g. validation_split=0.2)\n                # then split X into smaller X and X_val,\n                # and split y into smaller y and y_val.\n                do_validation = True\n                split_at = int(len(X) * (1 - validation_split))\n                (X, X_val) = (X[0:split_at], X[split_at:])\n                (y, y_val) = (y[0:split_at], y[split_at:])\n                if verbose:\n                    print(\"Train on %d samples, validate on %d samples\" % (len(y), len(y_val)))\n        \n        index_array = np.arange(len(X))\n        for epoch in range(nb_epoch):\n            if verbose:\n                print('Epoch', epoch)\n                progbar = Progbar(target=len(X), verbose=verbose)\n            if shuffle:\n                np.random.shuffle(index_array)\n\n            batches = make_batches(len(X), batch_size)\n            for batch_index, (batch_start, batch_end) in enumerate(batches):\n                if shuffle:\n                    batch_ids = index_array[batch_start:batch_end]\n                else:\n                    batch_ids = slice(batch_start, batch_end)\n                X_batch = X[batch_ids]\n                y_batch = y[batch_ids]\n\n                if show_accuracy:\n                    loss, acc = self._train_with_acc(X_batch, y_batch)\n                    log_values = [('loss', loss), ('acc.', acc)]\n                else:\n                    loss = self._train(X_batch, y_batch)\n                    log_values = [('loss', loss)]\n\n                # validation\n                if do_validation and (batch_index == len(batches) - 1):\n                    if show_accuracy:\n                        val_loss, val_acc = self.test(X_val, y_val, accuracy=True)\n                        log_values += [('val. loss', val_loss), ('val. acc.', val_acc)]\n                    else:\n                        val_loss = self.test(X_val, y_val)\n                        log_values += [('val. loss', val_loss)]\n                \n                # logging\n                if verbose:\n                    progbar.update(batch_end, log_values)\n\n            \n    def predict_proba(self, X, batch_size=128, verbose=1):\n        batches = make_batches(len(X), batch_size)\n        if verbose==1:\n            progbar = Progbar(target=len(X))\n        for batch_index, (batch_start, batch_end) in enumerate(batches):\n            X_batch = X[batch_start:batch_end]\n            batch_preds = self._predict(X_batch)\n\n            if batch_index == 0:\n                shape = (len(X),) + batch_preds.shape[1:]\n                preds = np.zeros(shape)\n            preds[batch_start:batch_end] = batch_preds\n\n            if verbose==1:\n                progbar.update(batch_end)\n\n        return preds\n\n\n    def predict_classes(self, X, batch_size=128, verbose=1):\n        proba = self.predict_proba(X, batch_size=batch_size, verbose=verbose)\n        if self.class_mode == \"categorical\":\n            return proba.argmax(axis=-1)\n        else:\n            return (proba>0.5).astype('int32')\n\n\n    def evaluate(self, X, y, batch_size=128, show_accuracy=False, verbose=1):\n        y = standardize_y(y)\n\n        if show_accuracy:\n            tot_acc = 0.\n        tot_score = 0.\n\n        batches = make_batches(len(X), batch_size)\n        if verbose:\n            progbar = Progbar(target=len(X), verbose=verbose)\n        for batch_index, (batch_start, batch_end) in enumerate(batches):\n            X_batch = X[batch_start:batch_end]\n            y_batch = y[batch_start:batch_end]\n\n            if show_accuracy:\n                loss, acc = self._test_with_acc(X_batch, y_batch)\n                tot_acc += acc\n                log_values = [('loss', loss), ('acc.', acc)]\n            else:\n                loss = self._test(X_batch, y_batch)\n                log_values = [('loss', loss)]\n            tot_score += loss\n\n            # logging\n            if verbose:\n                progbar.update(batch_end, log_values)\n\n        if show_accuracy:\n            return tot_score/len(batches), tot_acc/len(batches)\n        else:\n            return tot_score/len(batches)\n\n\n                \n\n\n\n", "path": "keras/models.py"}], "after_files": [{"content": "from __future__ import absolute_import\nfrom __future__ import print_function\nimport theano\nimport theano.tensor as T\nimport numpy as np\n\nfrom . import optimizers\nfrom . import objectives\nimport time, copy\nfrom .utils.generic_utils import Progbar\nfrom six.moves import range\n\ndef standardize_y(y):\n    if not hasattr(y, 'shape'):\n        y = np.asarray(y)\n    if len(y.shape) == 1:\n        y = np.reshape(y, (len(y), 1))\n    return y\n\ndef make_batches(size, batch_size):\n    nb_batch = int(np.ceil(size/float(batch_size)))\n    return [(i*batch_size, min(size, (i+1)*batch_size)) for i in range(0, nb_batch)]\n\nclass Sequential(object):\n    def __init__(self):\n        self.layers = []\n        self.params = []\n\n    def add(self, layer):\n        self.layers.append(layer)\n        if len(self.layers) > 1:\n            self.layers[-1].connect(self.layers[-2])\n        self.params += [p for p in layer.params]\n\n    def compile(self, optimizer, loss, class_mode=\"categorical\"):\n        self.optimizer = optimizers.get(optimizer)\n        self.loss = objectives.get(loss)\n\n        self.X = self.layers[0].input # input of model \n        # (first layer must have an \"input\" attribute!)\n        self.y_train = self.layers[-1].output(train=True)\n        self.y_test = self.layers[-1].output(train=False)\n\n        # output of model\n        self.y = T.matrix() # TODO: support for custom output shapes\n\n        train_loss = self.loss(self.y, self.y_train)\n        test_score = self.loss(self.y, self.y_test)\n\n        if class_mode == \"categorical\":\n            train_accuracy = T.mean(T.eq(T.argmax(self.y, axis=-1), T.argmax(self.y_train, axis=-1)))\n            test_accuracy = T.mean(T.eq(T.argmax(self.y, axis=-1), T.argmax(self.y_test, axis=-1)))\n\n        elif class_mode == \"binary\":\n            train_accuracy = T.mean(T.eq(self.y, T.round(self.y_train)))\n            test_accuracy = T.mean(T.eq(self.y, T.round(self.y_test)))\n        else:\n            raise Exception(\"Invalid class mode:\" + str(class_mode))\n        self.class_mode = class_mode\n\n        updates = self.optimizer.get_updates(self.params, train_loss)\n\n        self._train = theano.function([self.X, self.y], train_loss, \n            updates=updates, allow_input_downcast=True)\n        self._train_with_acc = theano.function([self.X, self.y], [train_loss, train_accuracy], \n            updates=updates, allow_input_downcast=True)\n        self._predict = theano.function([self.X], self.y_test, \n            allow_input_downcast=True)\n        self._test = theano.function([self.X, self.y], test_score, \n            allow_input_downcast=True)\n        self._test_with_acc = theano.function([self.X, self.y], [test_score, test_accuracy], \n            allow_input_downcast=True)\n\n    def train(self, X, y, accuracy=False):\n        y = standardize_y(y)\n        if accuracy:\n            return self._train_with_acc(X, y)\n        else:\n            return self._train(X, y)\n        \n\n    def test(self, X, y, accuracy=False):\n        y = standardize_y(y)\n        if accuracy:\n            return self._test_with_acc(X, y)\n        else:\n            return self._test(X, y)\n\n\n    def fit(self, X, y, batch_size=128, nb_epoch=100, verbose=1,\n            validation_split=0., validation_data=None, shuffle=True, show_accuracy=False):\n        y = standardize_y(y)\n\n        do_validation = False\n        if validation_data:\n            try:\n                X_val, y_val = validation_data\n            except:\n                raise Exception(\"Invalid format for validation data; provide a tuple (X_val, y_val).\")\n            do_validation = True\n            y_val = standardize_y(y_val)\n            if verbose:\n                print(\"Train on %d samples, validate on %d samples\" % (len(y), len(y_val)))\n        else:\n            if 0 < validation_split < 1:\n                # If a validation split size is given (e.g. validation_split=0.2)\n                # then split X into smaller X and X_val,\n                # and split y into smaller y and y_val.\n                do_validation = True\n                split_at = int(len(X) * (1 - validation_split))\n                (X, X_val) = (X[0:split_at], X[split_at:])\n                (y, y_val) = (y[0:split_at], y[split_at:])\n                if verbose:\n                    print(\"Train on %d samples, validate on %d samples\" % (len(y), len(y_val)))\n        \n        index_array = np.arange(len(X))\n        for epoch in range(nb_epoch):\n            if verbose:\n                print('Epoch', epoch)\n                progbar = Progbar(target=len(X), verbose=verbose)\n            if shuffle:\n                np.random.shuffle(index_array)\n\n            batches = make_batches(len(X), batch_size)\n            for batch_index, (batch_start, batch_end) in enumerate(batches):\n                if shuffle:\n                    batch_ids = index_array[batch_start:batch_end]\n                else:\n                    batch_ids = slice(batch_start, batch_end)\n                X_batch = X[batch_ids]\n                y_batch = y[batch_ids]\n\n                if show_accuracy:\n                    loss, acc = self._train_with_acc(X_batch, y_batch)\n                    log_values = [('loss', loss), ('acc.', acc)]\n                else:\n                    loss = self._train(X_batch, y_batch)\n                    log_values = [('loss', loss)]\n\n                # validation\n                if do_validation and (batch_index == len(batches) - 1):\n                    if show_accuracy:\n                        val_loss, val_acc = self.test(X_val, y_val, accuracy=True)\n                        log_values += [('val. loss', val_loss), ('val. acc.', val_acc)]\n                    else:\n                        val_loss = self.test(X_val, y_val)\n                        log_values += [('val. loss', val_loss)]\n                \n                # logging\n                if verbose:\n                    progbar.update(batch_end, log_values)\n\n            \n    def predict_proba(self, X, batch_size=128, verbose=1):\n        batches = make_batches(len(X), batch_size)\n        if verbose==1:\n            progbar = Progbar(target=len(X))\n        for batch_index, (batch_start, batch_end) in enumerate(batches):\n            X_batch = X[batch_start:batch_end]\n            batch_preds = self._predict(X_batch)\n\n            if batch_index == 0:\n                shape = (len(X),) + batch_preds.shape[1:]\n                preds = np.zeros(shape)\n            preds[batch_start:batch_end] = batch_preds\n\n            if verbose==1:\n                progbar.update(batch_end)\n\n        return preds\n\n\n    def predict_classes(self, X, batch_size=128, verbose=1):\n        proba = self.predict_proba(X, batch_size=batch_size, verbose=verbose)\n        if self.class_mode == \"categorical\":\n            return proba.argmax(axis=-1)\n        else:\n            return (proba>0.5).astype('int32')\n\n\n    def evaluate(self, X, y, batch_size=128, show_accuracy=False, verbose=1):\n        y = standardize_y(y)\n\n        if show_accuracy:\n            tot_acc = 0.\n        tot_score = 0.\n\n        batches = make_batches(len(X), batch_size)\n        if verbose:\n            progbar = Progbar(target=len(X), verbose=verbose)\n        for batch_index, (batch_start, batch_end) in enumerate(batches):\n            X_batch = X[batch_start:batch_end]\n            y_batch = y[batch_start:batch_end]\n\n            if show_accuracy:\n                loss, acc = self._test_with_acc(X_batch, y_batch)\n                tot_acc += acc\n                log_values = [('loss', loss), ('acc.', acc)]\n            else:\n                loss = self._test(X_batch, y_batch)\n                log_values = [('loss', loss)]\n            tot_score += loss\n\n            # logging\n            if verbose:\n                progbar.update(batch_end, log_values)\n\n        if show_accuracy:\n            return tot_score/len(batches), tot_acc/len(batches)\n        else:\n            return tot_score/len(batches)\n\n\n    def save_weights(self, filepath):\n        # Save weights from all layers to HDF5\n        import h5py\n        # FIXME: fail if file exists, or add option to overwrite!\n        f = h5py.File(filepath, 'w')\n        f.attrs['nb_layers'] = len(self.layers)\n        for k, l in enumerate(self.layers):\n            g = f.create_group('layer_{}'.format(k))\n            weights = l.get_weights()\n            g.attrs['nb_params'] = len(weights)\n            for n, param in enumerate(weights):\n                param_name = 'param_{}'.format(n)\n                param_dset = g.create_dataset(param_name, param.shape, dtype='float64')\n                param_dset[:] = param\n        f.flush()\n        f.close()\n\n    def load_weights(self, filepath):\n        # Loads weights from HDF5 file\n        import h5py\n        f = h5py.File(filepath)\n        for k in range(f.attrs['nb_layers']):\n            g = f['layer_{}'.format(k)]\n            weights = [g['param_{}'.format(p)] for p in range(g.attrs['nb_params'])]\n            self.layers[k].set_weights(weights)\n        f.close()\n\n\n", "path": "keras/models.py"}]}