| 2089 | ' without calling `model.compile` after ?', 1) |
| 2090 | |
| 2091 | def _make_train_function(self): |
| 2092 | has_recompiled = self._recompile_weights_loss_and_weighted_metrics() |
| 2093 | self._check_trainable_weights_consistency() |
| 2094 | if isinstance(self.optimizer, list): |
| 2095 | raise ValueError('The `optimizer` in `compile` should be a single ' |
| 2096 | 'optimizer.') |
| 2097 | # If we have re-compiled the loss/weighted metric sub-graphs then create |
| 2098 | # train function even if one exists already. This is because |
| 2099 | # `_feed_sample_weights` list has been updated on re-copmpile. |
| 2100 | if getattr(self, 'train_function', None) is None or has_recompiled: |
| 2101 | # Restore the compiled trainable state. |
| 2102 | current_trainable_state = self._get_trainable_state() |
| 2103 | self._set_trainable_state(self._compiled_trainable_state) |
| 2104 | |
| 2105 | inputs = (self._feed_inputs + |
| 2106 | self._feed_targets + |
| 2107 | self._feed_sample_weights) |
| 2108 | if not isinstance(K.symbolic_learning_phase(), int): |
| 2109 | inputs += [K.symbolic_learning_phase()] |
| 2110 | |
| 2111 | with K.get_graph().as_default(): |
| 2112 | with K.name_scope('training'): |
| 2113 | # Training updates |
| 2114 | updates = self.optimizer.get_updates( |
| 2115 | params=self._collected_trainable_weights, loss=self.total_loss) |
| 2116 | # Unconditional updates |
| 2117 | updates += self.get_updates_for(None) |
| 2118 | # Conditional updates relevant to this model |
| 2119 | updates += self.get_updates_for(self.inputs) |
| 2120 | |
| 2121 | metrics = self._get_training_eval_metrics() |
| 2122 | metrics_tensors = [ |
| 2123 | m._call_result for m in metrics if hasattr(m, '_call_result') # pylint: disable=protected-access |
| 2124 | ] |
| 2125 | |
| 2126 | with K.name_scope('training'): |
| 2127 | # Gets loss and metrics. Updates weights at each call. |
| 2128 | fn = K.function( |
| 2129 | inputs, [self.total_loss] + metrics_tensors, |
| 2130 | updates=updates, |
| 2131 | name='train_function', |
| 2132 | **self._function_kwargs) |
| 2133 | setattr(self, 'train_function', fn) |
| 2134 | |
| 2135 | # Restore the current trainable state |
| 2136 | self._set_trainable_state(current_trainable_state) |
| 2137 | |
| 2138 | def _make_test_function(self): |
| 2139 | has_recompiled = self._recompile_weights_loss_and_weighted_metrics() |