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
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
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
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
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()