| 15 | |
| 16 | |
| 17 | class Optimizer(object): |
| 18 | def optimize(self, network): |
| 19 | loss_history = [] |
| 20 | for i in range(network.max_epochs): |
| 21 | if network.shuffle: |
| 22 | network.shuffle_dataset() |
| 23 | |
| 24 | start_time = time.time() |
| 25 | loss = self.train_epoch(network) |
| 26 | loss_history.append(loss) |
| 27 | if network.verbose: |
| 28 | msg = "Epoch:%s, train loss: %s" % (i, loss) |
| 29 | if network.log_metric: |
| 30 | msg += ", train %s: %s" % (network.metric_name, network.error()) |
| 31 | msg += ", elapsed: %s sec." % (time.time() - start_time) |
| 32 | logging.info(msg) |
| 33 | return loss_history |
| 34 | |
| 35 | def update(self, network): |
| 36 | """Performs an update of parameters.""" |
| 37 | raise NotImplementedError |
| 38 | |
| 39 | def train_epoch(self, network): |
| 40 | losses = [] |
| 41 | |
| 42 | # Create batch iterator |
| 43 | X_batch = batch_iterator(network.X, network.batch_size) |
| 44 | y_batch = batch_iterator(network.y, network.batch_size) |
| 45 | |
| 46 | batch = zip(X_batch, y_batch) |
| 47 | if network.verbose: |
| 48 | batch = tqdm( |
| 49 | batch, total=int(np.ceil(network.n_samples / network.batch_size)) |
| 50 | ) |
| 51 | |
| 52 | for X, y in batch: |
| 53 | loss = np.mean(network.update(X, y)) |
| 54 | self.update(network) |
| 55 | losses.append(loss) |
| 56 | |
| 57 | epoch_loss = np.mean(losses) |
| 58 | return epoch_loss |
| 59 | |
| 60 | def train_batch(self, network, X, y): |
| 61 | loss = np.mean(network.update(X, y)) |
| 62 | self.update(network) |
| 63 | return loss |
| 64 | |
| 65 | def setup(self, network): |
| 66 | """Creates additional variables. |
| 67 | Note: Must be called before optimization process.""" |
| 68 | raise NotImplementedError |
| 69 | |
| 70 | |
| 71 | class SGD(Optimizer): |
nothing calls this directly
no outgoing calls
no test coverage detected