Ejemplo n.º 1
0
class TrainingResult(Screen):
    def __init__(self, **kwargs):
        super(TrainingResult, self).__init__(**kwargs)
        contents = Builder.load_string(kv)
        self.add_widget(contents)
        self.ids = contents.ids

        # Bind the network
        self.network = NeuralNetwork(App.get_running_app())

        # Sample content
        # grid = self.ids.result_grid
        # for j in range(157):
        #     # First column: Actual image
        #     grid.add_widget(Image(source='face1.png'))
        #
        #     # Second column: Network's image reconstruction
        #     grid.add_widget(Image(source='face1.png'))
        #
        #     # Third column: Network Representation
        #     grid.add_widget(Label(text='mad', size_hint=(.5, .5)))
        #
        #     # Fourth column: Actual representation
        #     grid.add_widget(Label(text='happy', size_hint=(.5, .5)))
        #
        #     # Fifth column: correct/incorrect
        #     grid.add_widget(Label(text='1', size_hint=(.5, .5)))

        # Bind the buttons
        def back_pressed(instance):
            self.pause_training(instance)
            App.get_running_app().go_back()

        self.ids.back_button.bind(on_press=back_pressed)

        # Start the training thread when the screen is displayed
        self.bind(on_enter=self.start_training)

    # Manage network training
    def start_training(self, instance):
        Logger.info('Starting training')
        self.network.reset_training()
        self.resume_training(self)

    def resume_training(self, instance):
        Logger.info('Resuming training')
        self.clear_results()

        self.training_paused = False
        pause_button = self.ids.pause_button
        pause_button.text = 'Pause'
        pause_button.unbind(on_press=self.resume_training)
        pause_button.bind(on_press=self.pause_training)

        # Make sure the thread stops on application exit
        App.get_running_app().unbind(on_stop=self.pause_training)
        App.get_running_app().bind(on_stop=self.pause_training)

        threading.Thread(target=self._run_training).start()

    def pause_training(self, instance):
        self.training_paused = True
        pause_button = self.ids.pause_button
        pause_button.text = 'Resume'
        pause_button.unbind(on_press=self.pause_training)
        pause_button.bind(on_press=self.resume_training)

        self.display_results()

    def clear_results(self):
        '''Clears all children of the grid, except for the header labels.'''
        grid = self.ids.result_grid
        grid.clear_widgets()

    @mainthread
    def display_results(self):
        '''Shows the result of the training in the grid.'''
        grid = self.ids.result_grid

        predictions, reconstructions = self.network.predict_all()
        predictions_correct = predictions == self.network.targets
        for is_test, image, reconstruction, prediction, target, prediction_correct in \
                zip(self.network.idx_test, self.network.app.dataset['images'], reconstructions, predictions,
                    self.network.targets, predictions_correct):
            # First column: Actual image
            grid.add_widget(ResultImage(image))

            # Second column: Network's image reconstruction
            grid.add_widget(ResultImage(reconstruction))

            # Third column: Network Representation
            grid.add_widget(Label(text=self.network.target_names[prediction + 1], size_hint=(.5, .5)))

            # Fourth column: Actual representation
            grid.add_widget(Label(text=self.network.target_names[target + 1], size_hint=(.5, .5)))

            # Fifth column: correct/incorrect
            grid.add_widget(Label(text='%d' % prediction_correct, size_hint=(.5, .5)))

        self.ids.result_scrollview.disabled = False
        self.ids.table_header.disabled = False

    def _run_training(self):
        graph = self.ids.training_graph
        for epoch, epochs, rmse, cerr, is_last in self.network.resume_training():
            if (epoch % 10) == 1 or is_last:
                Logger.debug('epoch: %d, rmse shape: %s' % (epoch, str(rmse.shape)))
                graph.plot(epoch, epochs, rmse, cerr, self.network.minimum_rmse)

            if self.training_paused:
                break

        Logger.info('Exit training thread')
        self.display_results()