Beispiel #1
0
    def evaluate(self,
                 epoch: int = -1,
                 writer=None,
                 tag: str = 'validation') -> Tuple[str, bool]:
        self.put_model_on_device()
        total_error = []
        #        for batch in tqdm(self.data_loader.get_data_batch(), ascii=True, desc='evaluate'):
        for batch in self.data_loader.get_data_batch():
            with torch.no_grad():
                predictions = self._net.forward(batch.observations,
                                                train=False)
                targets = data_to_tensor(batch.actions).type(
                    self._net.dtype).to(self._device)
                error = self._criterion(predictions, targets).mean()
                total_error.append(error)
        error_distribution = Distribution(total_error)
        self.put_model_back_to_original_device()
        if writer is not None:
            writer.write_distribution(error_distribution, tag)
            if self._config.store_output_on_tensorboard and (epoch % 30 == 0
                                                             or tag == 'test'):
                writer.write_output_image(predictions, f'{tag}/predictions')
                writer.write_output_image(targets, f'{tag}/targets')
                writer.write_output_image(torch.stack(batch.observations),
                                          f'{tag}/inputs')

        msg = f' {tag} {self._config.criterion} {error_distribution.mean: 0.3e} [{error_distribution.std:0.2e}]'

        best_checkpoint = False
        if self._lowest_validation_loss is None or error_distribution.mean < self._lowest_validation_loss:
            self._lowest_validation_loss = error_distribution.mean
            best_checkpoint = True
        return msg, best_checkpoint
    def train(self, epoch: int = -1, writer=None) -> str:
        self.put_model_on_device()
        total_error = []
        for batch in self.data_loader.sample_shuffled_batch():
            self._optimizer.zero_grad()
            targets = data_to_tensor(batch.actions).type(self._net.dtype).to(
                self._device)
            probabilities = self._net.forward_with_all_outputs(
                batch.observations, train=True)
            loss = self._criterion(probabilities[-1], targets).mean()
            for index, prob in enumerate(probabilities[:-1]):
                loss += self._criterion(prob, targets).mean()
            loss.mean().backward()
            if self._config.gradient_clip_norm != -1:
                nn.utils.clip_grad_norm_(self._net.parameters(),
                                         self._config.gradient_clip_norm)
            self._optimizer.step()
            self._net.global_step += 1
            total_error.append(loss.cpu().detach())
        self.put_model_back_to_original_device()

        error_distribution = Distribution(total_error)
        if writer is not None:
            writer.set_step(self._net.global_step)
            writer.write_distribution(error_distribution, 'training')
            if self._config.store_output_on_tensorboard and epoch % 30 == 0:
                for index, prob in enumerate(probabilities):
                    writer.write_output_image(prob,
                                              f'training/predictions_{index}')
                writer.write_output_image(targets, 'training/targets')
                writer.write_output_image(torch.stack(batch.observations),
                                          'training/inputs')
        return f' training {self._config.criterion} {error_distribution.mean: 0.3e} [{error_distribution.std:0.2e}]'
Beispiel #3
0
    def train(self, epoch: int = -1, writer=None) -> str:
        self.put_model_on_device()
        total_error = []
        task_error = []
        domain_error = []
        for source_batch, target_batch in zip(self.data_loader.sample_shuffled_batch(),
                                              self.target_data_loader.sample_shuffled_batch()):
            self._optimizer.zero_grad()
            targets = data_to_tensor(source_batch.actions).type(self._net.dtype).to(self._device)
            # task loss
            predictions = self._net.forward(source_batch.observations, train=True)
            task_loss = (1 - self._config.epsilon) * self._criterion(predictions, targets).mean()

            # add domain adaptation loss
            domain_loss = self._config.epsilon * self._domain_adaptation_criterion(
                self._net.get_features(source_batch.observations, train=True),
                self._net.get_features(target_batch.observations, train=True))

            loss = task_loss + domain_loss
            loss.backward()
            if self._config.gradient_clip_norm != -1:
                nn.utils.clip_grad_norm_(self._net.parameters(),
                                         self._config.gradient_clip_norm)
            self._optimizer.step()
            self._net.global_step += 1
            task_error.append(task_loss.cpu().detach())
            domain_error.append(domain_loss.cpu().detach())
            total_error.append(loss.cpu().detach())
        self.put_model_back_to_original_device()

        if self._scheduler is not None:
            self._scheduler.step()

        task_error_distribution = Distribution(task_error)
        domain_error_distribution = Distribution(domain_error)
        total_error_distribution = Distribution(total_error)
        if writer is not None:
            writer.set_step(self._net.global_step)
            writer.write_distribution(task_error_distribution, 'training/task_error')
            writer.write_distribution(domain_error_distribution, 'training/domain_error')
            writer.write_distribution(total_error_distribution, 'training/total_error')
            if self._config.store_output_on_tensorboard and epoch % 30 == 0:
                writer.write_output_image(predictions, 'source/predictions')
                writer.write_output_image(targets, 'source/targets')
                writer.write_output_image(torch.stack(source_batch.observations), 'source/inputs')
                writer.write_output_image(self._net.forward(target_batch.observations, train=True),
                                          'target/predictions')
                writer.write_output_image(torch.stack(target_batch.observations), 'target/inputs')

        return f' training task: {self._config.criterion} {task_error_distribution.mean: 0.3e} ' \
               f'[{task_error_distribution.std:0.2e}]' \
               f' domain: {self._config.domain_adaptation_criterion} {domain_error_distribution.mean: 0.3e} ' \
               f'[{domain_error_distribution.std:0.2e}]'
    def train(self, epoch: int = -1, writer=None) -> str:
        self.put_model_on_device()
        total_error = []
        for batch in self.data_loader.sample_shuffled_batch():
            self._optimizer.zero_grad()
            targets = data_to_tensor(batch.actions).type(self._net.dtype).to(
                self._device)
            probabilities = self._net.forward_with_all_outputs(
                batch.observations, train=True)
            loss = self._criterion(probabilities[-1], targets).mean()
            for index, prob in enumerate(probabilities[:-1]):
                loss += self._criterion(prob, targets).mean()
            loss.mean().backward()
            if self._config.gradient_clip_norm != -1:
                nn.utils.clip_grad_norm_(self._net.parameters(),
                                         self._config.gradient_clip_norm)
            self._optimizer.step()
            self._net.global_step += 1
            total_error.append(loss.cpu().detach())
        self.put_model_back_to_original_device()

        error_distribution = Distribution(total_error)
        if writer is not None:
            writer.set_step(self._net.global_step)
            writer.write_distribution(error_distribution, 'training')
            if self._config.store_output_on_tensorboard and epoch % 30 == 0:
                for index, prob in enumerate(probabilities):
                    writer.write_output_image(prob,
                                              f'training/predictions_{index}')
                writer.write_output_image(targets, 'training/targets')
                writer.write_output_image(torch.stack(batch.observations),
                                          'training/inputs')
            if self._config.store_feature_maps_on_tensorboard and epoch % 30 == 0:
                outputs = self._net.forward_with_intermediate_outputs(
                    batch.observations, train=False)
                for i in range(4):  # store first 5 images of batch
                    for layer in ['x1', 'x2', 'x3', 'x4']:
                        feature_maps = outputs[layer][i].flatten(start_dim=0,
                                                                 end_dim=0)
                        title = f'feature_map/layer_{layer}/{i}'
                        # title += 'inds_' + '_'.join([str(v.item()) for v in winning_indices.indices])
                        # title += '_vals_' + '_'.join([f'{v.item():0.2f}' for v in winning_indices.values])
                        writer.write_output_image(feature_maps, title)
            writer.write_figure(tag='gradient',
                                figure=plot_gradient_flow(
                                    self._net.named_parameters()))
        return f' training {self._config.criterion} {error_distribution.mean: 0.3e} [{error_distribution.std:0.2e}]'
Beispiel #5
0
    def train(self, epoch: int = -1, writer=None) -> str:
        self.put_model_on_device()
        total_error = []
        #        for batch in tqdm(self.data_loader.sample_shuffled_batch(), ascii=True, desc='train'):
        for batch in self.data_loader.sample_shuffled_batch():
            self._optimizer.zero_grad()
            targets = data_to_tensor(batch.actions).type(self._net.dtype).to(
                self._device)
            if self._config.add_KL_divergence_loss:
                predictions, mean, std = self._net.forward_with_distribution(
                    batch.observations, train=True)
            else:
                predictions = self._net.forward(batch.observations, train=True)

            loss = self._criterion(predictions, targets).mean()
            if self._config.add_KL_divergence_loss:
                # https://arxiv.org/pdf/1312.6114.pdf
                KL_loss = -0.5 * torch.sum(1 + std.pow(2).log() - mean.pow(2) -
                                           std.pow(2))
                loss += KL_loss

            loss.backward()
            if self._config.gradient_clip_norm != -1:
                nn.utils.clip_grad_norm_(self._net.parameters(),
                                         self._config.gradient_clip_norm)
            self._optimizer.step()
            self._net.global_step += 1
            total_error.append(loss.cpu().detach())
        self.put_model_back_to_original_device()

        if self._scheduler is not None:
            self._scheduler.step()

        error_distribution = Distribution(total_error)
        if writer is not None:
            writer.set_step(self._net.global_step)
            writer.write_distribution(error_distribution, 'training')
            if self._config.add_KL_divergence_loss:
                writer.write_scalar(KL_loss, 'KL_divergence')
            if self._config.store_output_on_tensorboard and epoch % 30 == 0:
                writer.write_output_image(predictions, 'training/predictions')
                writer.write_output_image(targets, 'training/targets')
                writer.write_output_image(torch.stack(batch.observations),
                                          'training/inputs')
        return f' training {self._config.criterion} {error_distribution.mean: 0.3e} [{error_distribution.std:0.2e}]'
Beispiel #6
0
    def train(self, epoch: int = -1, writer=None) -> str:
        self.put_model_on_device()
        total_error = []
        task_error = []
        domain_error = []
        for source_batch, target_batch in zip(self.data_loader.sample_shuffled_batch(),
                                              self.target_data_loader.sample_shuffled_batch()):
            self._optimizer.zero_grad()
            targets = data_to_tensor(source_batch.actions).type(self._net.dtype).to(self._device)

            # deep supervision loss
            probabilities = self._net.forward_with_all_outputs(source_batch.observations, train=True)
            task_loss = self._criterion(probabilities[-1], targets).mean()
            for index, prob in enumerate(probabilities[:-1]):
                task_loss += self._criterion(prob, targets).mean()
            task_loss *= (1 - self._config.epsilon)

            # add domain adaptation loss on distribution of output pixels at each output
            domain_loss = sum([self._domain_adaptation_criterion(sp.flatten().unsqueeze(1), tp.flatten().unsqueeze(1))
                               for sp, tp in zip(self._net.forward_with_all_outputs(source_batch.observations,
                                                                                    train=True),
                                                 self._net.forward_with_all_outputs(target_batch.observations,
                                                                                    train=True))
                               ]) * self._config.epsilon

            loss = task_loss + domain_loss
            loss.backward()
            if self._config.gradient_clip_norm != -1:
                nn.utils.clip_grad_norm_(self._net.parameters(),
                                         self._config.gradient_clip_norm)
            self._optimizer.step()
            self._net.global_step += 1
            task_error.append(task_loss.cpu().detach().numpy())
            domain_error.append(domain_loss.cpu().detach().numpy())
            total_error.append(loss.cpu().detach().numpy())

        self.put_model_back_to_original_device()

        if self._scheduler is not None:
            self._scheduler.step()

        task_error_distribution = Distribution(task_error)
        domain_error_distribution = Distribution(domain_error)
        total_error_distribution = Distribution(total_error)
        if writer is not None:
            writer.set_step(self._net.global_step)
            writer.write_distribution(task_error_distribution, 'training/task_error')
            writer.write_distribution(domain_error_distribution, 'training/domain_error')
            writer.write_distribution(total_error_distribution, 'training/total_error')
            if self._config.store_output_on_tensorboard and epoch % 30 == 0:
                writer.write_output_image(probabilities[-1], 'source/predictions')
                writer.write_output_image(targets, 'source/targets')
                writer.write_output_image(torch.stack(source_batch.observations), 'source/inputs')
                writer.write_output_image(self._net.forward(target_batch.observations, train=False),
                                          'target/predictions')
                writer.write_output_image(torch.stack(target_batch.observations), 'target/inputs')
            if self._config.store_feature_maps_on_tensorboard and epoch % 30 == 0:
                for name, batch in zip(['source', 'target'], [source_batch, target_batch]):
                    outputs = self._net.forward_with_intermediate_outputs(batch.observations, train=False)
                    for i in range(4):  # store first 5 images of batch
                        for layer in ['x1', 'x2', 'x3', 'x4']:
                            feature_maps = outputs[layer][i].flatten(start_dim=0, end_dim=0)
                            title = f'feature_map/{name}/layer_{layer}/{i}'
                            # title += 'inds_' + '_'.join([str(v.item()) for v in winning_indices.indices])
                            # title += '_vals_' + '_'.join([f'{v.item():0.2f}' for v in winning_indices.values])
                            writer.write_output_image(feature_maps, title)
        return f' task {self._config.criterion} ' \
               f'{task_error_distribution.mean: 0.3e} ' \
               f'[{task_error_distribution.std:0.2e}] ' \
               f' domain {self._config.domain_adaptation_criterion} ' \
               f'{domain_error_distribution.mean: 0.3e} ' \
               f'[{domain_error_distribution.std: 0.2e}]'
Beispiel #7
0
    def _train_main_network(self, epoch: int = -1, writer=None) -> str:
        deeply_supervised_error = []
        discriminator_error = []
        for sim_batch, real_batch in zip(
                self.data_loader.sample_shuffled_batch(),
                self.target_data_loader.sample_shuffled_batch()):
            self._optimizer.zero_grad()

            # normal deep supervision loss
            targets = data_to_tensor(sim_batch.actions).type(
                self._net.dtype).to(self._device)
            probabilities = self._net.forward_with_all_outputs(
                sim_batch.observations, train=True)
            loss = self._criterion(probabilities[-1], targets).mean()
            for index, prob in enumerate(probabilities[:-1]):
                loss += self._criterion(prob, targets).mean()
            deeply_supervised_error.append(loss.mean().cpu().detach())

            # adversarial loss on discriminator data
            network_outputs = torch.cat(
                self._net.forward_with_all_outputs(
                    real_batch.observations, train=True)).unsqueeze(dim=1)
            discriminator_loss = self._net.discriminate(network_outputs,
                                                        train=False).mean()
            #results = self._net.forward_with_intermediate_outputs(real_batch.observations, train=True)
            #feature_maps =

            # combine losses with epsilon weight
            loss *= (1 - self._config.epsilon)
            loss += self._config.epsilon * discriminator_loss
            loss.mean().backward()
            discriminator_error.append(
                discriminator_loss.mean().cpu().detach())
            # clip gradients
            if self._config.gradient_clip_norm != -1:
                nn.utils.clip_grad_norm_(self._net.parameters(),
                                         self._config.gradient_clip_norm)
            self._optimizer.step()

        supervised_error_distribution = Distribution(deeply_supervised_error)
        discriminator_error_distribution = Distribution(discriminator_error)
        if writer is not None:
            writer.write_distribution(supervised_error_distribution,
                                      'training_loss_from_deep_supervision')
            writer.write_distribution(discriminator_error_distribution,
                                      'training_loss_from_discriminator')
            if self._config.store_output_on_tensorboard and epoch % 30 == 0:
                for index, prob in enumerate(probabilities):
                    writer.write_output_image(prob,
                                              f'training/predictions_{index}')
                writer.write_output_image(targets, 'training/targets')
                writer.write_output_image(torch.stack(sim_batch.observations),
                                          'training/inputs')
            for index, prob in enumerate(
                    self._net.forward_with_all_outputs(real_batch.observations,
                                                       train=False)):
                writer.write_output_image(prob, f'real/predictions_{index}')
            writer.write_output_image(torch.stack(real_batch.observations),
                                      'real/inputs')
        return f' Training: supervision {self._config.criterion} {supervised_error_distribution.mean: 0.3e} ' \
               f'[{supervised_error_distribution.std:0.2e}]' \
               f' discriminator {discriminator_error_distribution.mean: 0.3e} ' \
               f'[{discriminator_error_distribution.std:0.2e}]'