Esempio n. 1
0
    def geometric_mean(self) -> tuple:
        '''
        Class method to calculate geometric mean of the dataset. 

        Returns:
            Geometric means for the three channels of the dataset images as a tuple.
        '''

        samples = self.file_reader()

        N = len(samples)

        channel_1_gm = channel_2_gm = channel_3_gm = 0.0

        print(
            "\nCalculating geometric mean of the \'{}\' dataset in \'{}\' color space..."
            .format(self.v_type, self.color_space))

        for ind in tqdm(iterable=range(N), desc="GM"):

            image = cv2.imread(samples[ind])
            image = cv2.resize(image, (self.image_size[0], self.image_size[1]))

            if self.color_space != "bgr":
                image = channels.change_channel(image,
                                                channel=self.color_space)

            if self.color_space == "gray":
                image = channels.change_channel(image, channel="bgr")

            channel_1 = np.reshape(image[:, :, 0], -1)
            channel_2 = np.reshape(image[:, :, 1], -1)
            channel_3 = np.reshape(image[:, :, 2], -1)

            channel_1 = np.array(channel_1, dtype=np.float)
            channel_2 = np.array(channel_2, dtype=np.float)
            channel_3 = np.array(channel_3, dtype=np.float)

            channel_1_mean = (np.sum(
                np.log(channel_1 + 1))) / channel_1.shape[0]
            channel_2_mean = (np.sum(
                np.log(channel_2 + 1))) / channel_2.shape[0]
            channel_3_mean = (np.sum(
                np.log(channel_3 + 1))) / channel_3.shape[0]

            channel_1_gm += channel_1_mean
            channel_2_gm += channel_2_mean
            channel_3_gm += channel_3_mean

        channel_1_mean = np.exp(channel_1_gm / N)
        channel_2_mean = np.exp(channel_2_gm / N)
        channel_3_mean = np.exp(channel_3_gm / N)

        geo_mean = tuple((channel_1_mean, channel_2_mean, channel_3_mean))

        return geo_mean
Esempio n. 2
0
    def arithmetic_mean(self) -> tuple:
        '''
        Class method to calculate arithmetic mean of the dataset. 

        Returns:
            Arithmetic means for the three channels of the dataset images as a tuple.
        '''

        samples = self.file_reader()

        N = len(samples)

        channel_1_am = channel_2_am = channel_3_am = 0.0

        print(
            "\nCalculating arithmetic mean of the \'{}\' dataset in \'{}\' color space..."
            .format(self.v_type, self.color_space))

        for ind in tqdm(iterable=range(N), desc="AM"):

            image = cv2.imread(samples[ind])
            image = cv2.resize(image, (self.image_size[0], self.image_size[1]))

            if self.color_space != "bgr":
                image = channels.change_channel(image,
                                                channel=self.color_space)

            if self.color_space == "gray":
                image = channels.change_channel(image, channel="bgr")

            channel_1 = np.reshape(image[:, :, 0], -1)
            channel_2 = np.reshape(image[:, :, 1], -1)
            channel_3 = np.reshape(image[:, :, 2], -1)

            channel_1_mean = channel_1.mean()
            channel_2_mean = channel_2.mean()
            channel_3_mean = channel_3.mean()

            channel_1_am += channel_1_mean
            channel_2_am += channel_2_mean
            channel_3_am += channel_3_mean

        channel_1_mean = channel_1_am / N
        channel_2_mean = channel_2_am / N
        channel_3_mean = channel_3_am / N

        arith_mean = tuple((channel_1_mean, channel_2_mean, channel_3_mean))

        return arith_mean
Esempio n. 3
0
    def standard_deviation(self, means=None, return_variance=False):
        '''
        Class method to calculate the standard deviation of the dataset.

        Args:
            means (tuple): Tuple of means of the three channels of the dataset images.
            return_variance (bool): Whether to return the variance of the dataset.

        Returns:
            A tuple with the standard deviaitons for the three channels of the dataset images.

        Raises:
            ValueError: When the entered value for `means` has inconsistent shape.
            TypeError: When the data type of `means` or `return_variance` does not match with the allowed ones.
        '''

        if len(means) != 3:
            raise ValueError(
                "Entered value for \'means\' must be a tuple with three entries of mean for the three respective channels."
            )
            exit(0)

        if not isinstance(means, Union[list, tuple]):
            raise TypeError(
                "Data type of the entered value for `means` does not match with either of the allowed data types i.e. `list` or `tuple`."
            )
            exit(0)

        if not isinstance(return_variance, bool):
            raise TypeError(
                "Data type of the entered value for `return_variance` does not match with the allowed data type i.e. `bool`."
            )
            exit(0)

        channel_1_mean = means[0]
        channel_2_mean = means[1]
        channel_3_mean = means[2]

        samples = self.file_reader()

        N = len(samples)

        channel_1_Sum_std = channel_2_Sum_std = channel_3_Sum_std = 0.0

        print(
            "\nCalculating standard deviation of the \'{}\' dataset in \'{}\' color space..."
            .format(self.v_type, self.color_space))

        for ind in tqdm(iterable=range(N), desc="SD"):

            image = cv2.imread(samples[ind])
            image = cv2.resize(image, (self.image_size[0], self.image_size[1]))

            if self.color_space != "bgr":
                image = channels.change_channel(image,
                                                channel=self.color_space)

            if self.color_space == "gray":
                image = channels.change_channel(image, channel="bgr")

            channel_1 = np.reshape(image[:, :, 0], -1)
            channel_2 = np.reshape(image[:, :, 1], -1)
            channel_3 = np.reshape(image[:, :, 2], -1)

            channel_1_diffs = channel_1 - channel_1_mean
            channel_1_SumOfSquares = np.sum(channel_1_diffs**2)

            channel_2_diffs = channel_2 - channel_2_mean
            channel_2_SumOfSquares = np.sum(channel_2_diffs**2)

            channel_3_diffs = channel_3 - channel_3_mean
            channel_3_SumOfSquares = np.sum(channel_3_diffs**2)

            channel_1_Sum_std += (1 /
                                  (N * self.image_size[0] * self.image_size[1])
                                  ) * channel_1_SumOfSquares
            channel_2_Sum_std += (1 /
                                  (N * self.image_size[0] * self.image_size[1])
                                  ) * channel_2_SumOfSquares
            channel_3_Sum_std += (1 /
                                  (N * self.image_size[0] * self.image_size[1])
                                  ) * channel_3_SumOfSquares

        variance_channel_1 = channel_1_Sum_std
        variance_channel_2 = channel_2_Sum_std
        variance_channel_3 = channel_3_Sum_std

        channel_1_std = np.sqrt(channel_1_Sum_std)
        channel_2_std = np.sqrt(channel_2_Sum_std)
        channel_3_std = np.sqrt(channel_3_Sum_std)

        variances = tuple(
            (variance_channel_1, variance_channel_2, variance_channel_3))
        stds = tuple((channel_1_std, channel_2_std, channel_3_std))

        if return_variance:

            return stds, variances

        else:

            return stds
Esempio n. 4
0
    def am_gm_hm(self):
        '''
        Class method to calculate all the three means (arithmetic, geometric and harmonic) of the dataset in a single run. 
        
        Returns:
            Three tuples for the arithmetic, geometric and harmonic means for the three channels of the dataset images.
        '''

        samples = self.file_reader()

        N = len(samples)

        channel_1_am = channel_2_am = channel_3_am = 0.0
        channel_1_gm = channel_2_gm = channel_3_gm = 0.0
        channel_1_hm = channel_2_hm = channel_3_hm = 0.0

        print(
            "\nCalculating arithmetic, geometric, and harmonic means of the \'{}\' dataset in \'{}\' color space..."
            .format(self.v_type, self.color_space))

        for ind in tqdm(iterable=range(N), desc="AM_GM_HM"):

            image = cv2.imread(samples[ind])
            image = cv2.resize(image, (self.image_size[0], self.image_size[1]))

            if self.color_space != "bgr":
                image = channels.change_channel(image,
                                                channel=self.color_space)

            if self.color_space == "gray":
                image = channels.change_channel(image, channel="bgr")

            channel_1 = np.reshape(image[:, :, 0], -1)
            channel_2 = np.reshape(image[:, :, 1], -1)
            channel_3 = np.reshape(image[:, :, 2], -1)

            channel_1 = np.array(channel_1, dtype=np.float)
            channel_2 = np.array(channel_2, dtype=np.float)
            channel_3 = np.array(channel_3, dtype=np.float)

            ##### AM #####
            channel_1_mean_am = channel_1.mean()
            channel_2_mean_am = channel_2.mean()
            channel_3_mean_am = channel_3.mean()

            channel_1_am += channel_1_mean_am
            channel_2_am += channel_2_mean_am
            channel_3_am += channel_3_mean_am

            ##### GM #####
            channel_1_mean_gm = (np.sum(
                np.log(channel_1 + 1))) / channel_1.shape[0]
            channel_2_mean_gm = (np.sum(
                np.log(channel_2 + 1))) / channel_2.shape[0]
            channel_3_mean_gm = (np.sum(
                np.log(channel_3 + 1))) / channel_3.shape[0]

            channel_1_gm += channel_1_mean_gm
            channel_2_gm += channel_2_mean_gm
            channel_3_gm += channel_3_mean_gm

            ##### HM #####
            channel_1_mean_hm = (np.sum(
                np.reciprocal(channel_1 + 1))) / channel_1.shape[0]
            channel_2_mean_hm = (np.sum(
                np.reciprocal(channel_2 + 1))) / channel_2.shape[0]
            channel_3_mean_hm = (np.sum(
                np.reciprocal(channel_3 + 1))) / channel_3.shape[0]

            channel_1_hm += channel_1_mean_hm
            channel_2_hm += channel_2_mean_hm
            channel_3_hm += channel_3_mean_hm

        channel_1_AM = channel_1_am / N
        channel_2_AM = channel_2_am / N
        channel_3_AM = channel_3_am / N

        channel_1_GM = np.exp(channel_1_gm / N)
        channel_2_GM = np.exp(channel_2_gm / N)
        channel_3_GM = np.exp(channel_3_gm / N)

        channel_1_HM = N / channel_1_hm
        channel_2_HM = N / channel_2_hm
        channel_3_HM = N / channel_3_hm

        arith_mean = tuple((channel_1_AM, channel_2_AM, channel_3_AM))
        geome_mean = tuple((channel_1_GM, channel_2_GM, channel_3_GM))
        harmo_mean = tuple((channel_1_HM, channel_2_HM, channel_3_HM))

        return arith_mean, geome_mean, harmo_mean
Esempio n. 5
0
    def fit(self,
            publish_summaries=True,
            save_checkpoints=True,
            interval_of_checkpoints=5,
            save_outputs=True,
            output_interval=5,
            max_keep_checkpoints=10):
        '''
        Execute the built graph. For now it is only capable of fitting over our dataset.

        Args:
            publish_summaries(bool): Whether to write summaries of training to be visualized in Tensorboard. Set the path for summaries in `paths.json` file. Default: True
            save_checkpoints(bool): Whether to save model training checkpoints. Helpful when you want to restart the training or while testing the model. Default: True
            interval_of_checkpoints(int): Interval in terms of epochs to save the model checkpoints at. Default: 5
            save_outputs(bool): Whether to save the model outputs or not. Default: True
            output_interval(int): Interval in terms of epochs to save model outputs at. Default: 5
            max_keep_checkpoints(int): Number of checkpoints to store. As new checkpoints come, the old ones will be deleted. Default: 10

        Returns:
            Nothing
        '''

        ########################################## GPU_GROWTH #########################################

        tf_config = tf.ConfigProto()
        tf_config.gpu_options.allow_growth = True

        ###################################### LOSS FUNCTION(S) #######################################

        main_train_loss = tf.reduce_mean(
            self.available_loss_functions[self.loss_function](
                y_true=self.Y,
                y_pred=self.layer_outputs[list(self.layer_outputs)[-1]]))

        ########################################## SUMMARIES ##########################################

        if publish_summaries:
            summaries = []
            summaries.append(tf.summary.scalar('Loss', main_train_loss))
            for layer_num in range(1, self.number_of_layers + 1):
                # kernels, biases = {}, {}
                # kernels['Layer_' + str(layer_num)] = tf.get_default_graph().get_tensor_by_name('Layer_' + str(layer_num) + '_dense/kernel:0')
                # biases['Layer_' + str(layer_num)] = tf.get_default_graph().get_tensor_by_name('Layer_' + str(layer_num) + '_dense/bias:0')
                summaries.append(
                    tf.summary.histogram(
                        'Layer_' + str(layer_num) + 'dense_kernel',
                        tf.get_default_graph().get_tensor_by_name(
                            'Layer_' + str(layer_num) + '_dense/kernel:0')))
                summaries.append(
                    tf.summary.histogram(
                        'Layer_' + str(layer_num) + 'dense_bias',
                        tf.get_default_graph().get_tensor_by_name(
                            'Layer_' + str(layer_num) + '_dense/bias:0')))
            merged_summary = tf.summary.merge(summaries)

        ########################################## OPTIMIZER ##########################################

        if self.optimizer == 'adagradDA':
            global_step = tf.compat.v1.train.get_global_step()
            train_step = self.available_optimizers['adagradDA'](
                learning_rate=self.learning_rate,
                global_step=global_step).minimize(loss=main_train_loss)
        else:
            train_step = self.available_optimizers[self.optimizer](
                learning_rate=self.learning_rate).minimize(
                    loss=main_train_loss)

        extra_update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)

        with tf.Session(config=tf_config) as sess:
            init = tf.global_variables_initializer()
            sess.run(init)

            image_names = bg.image_names_generator()
            batches = len(image_names) // self.batch_size

            writer = tf.summary.FileWriter(
                os.path.join(self.paths['path_to_tensorflow_data'], self.name,
                             'Tensorflow/LOGS/'))
            writer.add_graph(sess.graph)

            if save_checkpoints:
                saver = tf.train.Saver(max_to_keep=max_keep_checkpoints)

            for epoch in range(1, self.epochs + 1):
                for batch_num in range(1, batches + 1):

                    train_batch = bg.batch_generator(
                        image_names,
                        batch_size=self.batch_size,
                        image_size=self.image_size)

                    train_batch_gray = change_channel(
                        batch=train_batch, channel=self.channel_of_input)

                    train_batch_reshaped = np.reshape(train_batch,
                                                      (self.batch_size, -1))
                    train_batch_gray_reshaped = np.reshape(
                        train_batch_gray, (self.batch_size, -1))

                    feed_dict_train = {
                        self.X: train_batch_gray_reshaped,
                        self.Y: train_batch_reshaped,
                        self.is_training: True,
                        self.keep_prob: self.dropout_keep_prob
                    }
                    _, _, loss = sess.run(
                        [train_step, extra_update_ops, main_train_loss],
                        feed_dict=feed_dict_train)

                    if publish_summaries:
                        s = sess.run(merged_summary, feed_dict=feed_dict_train)
                        writer.add_summary(s, epoch)
                        writer.flush()

                    print('Epoch: {}/{} - Batch: {}/{}        Loss: {}'.format(
                        epoch, self.epochs, batch_num, batches, loss))

                    if save_outputs:

                        if epoch % output_interval == 0 and batch_num == 1:
                            out_ = sess.run(self.layer_outputs[list(
                                self.layer_outputs)[-1]],
                                            feed_dict=feed_dict_train)
                            out_reshaped = np.reshape(
                                out_, (self.batch_size, self.image_size[0],
                                       self.image_size[1], 3))
                            out_reshaped = np.clip(out_reshaped * 255, 0, 255)
                            out_reshaped = out_reshaped.astype(np.uint8)

                            random_index = random.randint(
                                0, self.batch_size - 1)
                            input_sample = cv2.cvtColor(
                                train_batch_gray[random_index],
                                cv2.COLOR_GRAY2BGR)

                            final_image = np.concatenate([
                                input_sample, train_batch[random_index],
                                out_reshaped[random_index]
                            ],
                                                         axis=1)

                            output_path = os.path.join(
                                self.paths["model_output_paths"], self.name,
                                'OUTPUTS/')

                            try:
                                if not os.path.exists(output_path):
                                    os.mkdir(output_path)
                            except OSError:
                                raise OSError(
                                    'Could not make directory to save model outputs.'
                                )

                            cv2.imwrite(
                                output_path + 'Output_epoch_' + str(epoch) +
                                '_.jpg', final_image)

                    if save_checkpoints:
                        if epoch % interval_of_checkpoints == 0 and batch_num == 1:
                            checkpoint_path = os.path.join(
                                self.paths['path_to_tensorflow_data'],
                                self.name, 'Tensorflow/Checkpoints/')
                            saver.save(
                                sess,
                                checkpoint_path + 'Epoch_{}'.format(epoch))

            writer.close()