def test_rescale_compress_lossless_maps(self): """Tests the function `rescale_compress_lossless_maps` in the file "lossless/compression.py". The test is successful if, when using the binary probabilities saved at "lossless/pseudo_data/binary_probabilities_scale_compress_invalid_0.npy", the program raises `RuntimeError` of type 4. This must also occur when using the binary probabilities saved at "lossless/pseudo_data/binary_probabilities_scale_compress_invalid_1.npy". However, when using the binary probabilities saved at "lossless/pseudo_data/binary_probabilities_scale_compress_valid.npy", the program should not raise any exception. """ height_map = 96 width_map = 48 bin_widths_test = numpy.array([1.5, 1.5, 1.5], dtype=numpy.float32) # In "lossless/pseudo_data/binary_probabilities_scale_compress_invalid_0.npy", # several binary probabilities are equal to `nan` # but the associated binary decisions may occur. # In "lossless/pseudo_data/binary_probabilities_scale_compress_invalid_1.npy", # several binary probabilities are either negative # or larger than 1. path_to_binary_probabilities = 'lossless/pseudo_data/binary_probabilities_scale_compress_valid.npy' print('The binary probabilities at "{}" are used.'.format( path_to_binary_probabilities)) # The optional argument `loc` of the function # `numpy.random.normal` is set to 0.0 as the # data must be centered. centered_data_0 = numpy.random.normal(loc=0., scale=5., size=(1, height_map, width_map, 1)).astype(numpy.float32) centered_data_1 = numpy.random.normal(loc=0., scale=0.2, size=(1, height_map, width_map, 1)).astype(numpy.float32) centered_data_2 = numpy.random.normal(loc=0., scale=0.5, size=(1, height_map, width_map, 1)).astype(numpy.float32) centered_data = numpy.concatenate( (centered_data_0, centered_data_1, centered_data_2), axis=3) expanded_centered_quantized_data = tls.quantize_per_map( centered_data, bin_widths_test) centered_quantized_data = numpy.squeeze( expanded_centered_quantized_data, axis=0) nb_bits = lossless.compression.rescale_compress_lossless_maps( centered_quantized_data, bin_widths_test, path_to_binary_probabilities) print('Number of bits in the bitstream: {}'.format(nb_bits))
def test_quantize_per_map(self): """Tests the function `quantize_per_map`. The test is successful if, for each map of data, the map of quantized data is consistent with the quantization bin width. """ data = numpy.random.normal(loc=0., scale=5., size=(2, 1, 3, 2)).astype(numpy.float32) bin_widths = numpy.array([1., 10.], dtype=numpy.float32) quantized_data = tls.quantize_per_map(data, bin_widths) print('1st map of data after being flattened:') print(data[:, :, :, 0].flatten()) print('1st quantization bin width: {}'.format(bin_widths[0])) print('1st map of quantized data after being flattened:') print(quantized_data[:, :, :, 0].flatten()) print('2nd map of data after being flattened:') print(data[:, :, :, 1].flatten()) print('2nd quantization bin width: {}'.format(bin_widths[1])) print('2nd map of quantized data after being flattened:') print(quantized_data[:, :, :, 1].flatten())
def test_rate_3d(self): """Tests the function `rate_3d`. The test is successful if the rate computed by the function is close to the approximate theoretical rate. """ h_in = 768 w_in = 512 height_map = 256 width_map = 256 bin_widths = numpy.array([0.2, 0.5], dtype=numpy.float32) expanded_latent_float32 = numpy.random.normal(loc=0., scale=1., size=(1, height_map, width_map, 2)).astype(numpy.float32) expanded_quantized_latent_float32 = tls.quantize_per_map(expanded_latent_float32, bin_widths) quantized_latent_float32 = numpy.squeeze(expanded_quantized_latent_float32, axis=0) rate = tls.rate_3d(quantized_latent_float32, bin_widths, h_in, w_in) # The formula below is derived from the # theorem 8.3.1 in the book "Elements of information theory", # 2nd edition, written by Thomas M. Cover and Joy A. Thomas. # Warning! The quantization in this theorem is not the # uniform scalar quantization. But, the two quantizations # get close as the quantization bin width tends to 0. approx_theoretical_entropy = -numpy.log2(bin_widths[0]) \ - numpy.log2(bin_widths[1]) \ + (numpy.log(2.*numpy.pi) + 1.)/numpy.log(2.) approx_theoretical_rate = approx_theoretical_entropy*height_map*width_map/(h_in*w_in) print('Rate computed by the function: {}'.format(rate)) print('Approximate theoretical rate: {}'.format(approx_theoretical_rate))
def mask_maps(y_float32, sess, isolated_decoder, bin_widths, idx_unmasked_map, map_mean, height_crop, width_crop, paths): """Masks all the latent variable feature maps except one. All the latent variable feature maps except one are masked. Then, the latent variable feature maps are quantized. Finally, the quantized latent variable feature maps are passed through the decoder of the entropy autoencoder. Parameters ---------- y_float32 : numpy.ndarray 4D array with data-type `numpy.float32`. Latent variables. `y_float32[i, :, :, j]` is the jth latent variable feature map of the ith example. sess : Session Session that runs the graph. isolated_decoder : IsolatedDecoder Decoder of the entropy autoencoder. The graph of the decoder is built to process one example at a time. bin_widths : numpy.ndarray 1D array with data-type `numpy.float32`. Quantization bin widths at the end of the training. idx_unmasked_map : int Index of the unmasked latent variable feature map. map_mean : numpy.ndarray 1D array with data-type `numpy.float32`. Latent variable feature map means. height_crop : int Height of the crop of the decoder output. width_crop : int Width of the crop of the decoder output. paths : list The ith string in this list is the path to the ith saved crop of the decoder output. Each path ends with ".png". Raises ------ ValueError If `len(paths)` is not equal to `y_float32.shape[0]`. """ if len(paths) != y_float32.shape[0]: raise ValueError('`len(paths)` is not equal to `y_float32.shape[0]`.') # The same latent variable feature map is # iteratively overwritten in the loop below. masked_y_float32 = numpy.tile(numpy.reshape(map_mean, (1, 1, 1, y_float32.shape[3])), (1, y_float32.shape[1], y_float32.shape[2], 1)) for i in range(y_float32.shape[0]): masked_y_float32[0, :, :, idx_unmasked_map] = y_float32[i, :, :, idx_unmasked_map] quantized_y_float32 = tls.quantize_per_map(masked_y_float32, bin_widths) reconstruction_float32 = sess.run( isolated_decoder.node_reconstruction, feed_dict={isolated_decoder.node_quantized_y:quantized_y_float32} ) reconstruction_uint8 = numpy.squeeze(tls.cast_bt601(reconstruction_float32), axis=(0, 3)) tls.save_image(paths[i], reconstruction_uint8[0:height_crop, 0:width_crop])
def activate_latent_variable(sess, isolated_decoder, h_in, w_in, bin_widths, row_activation, col_activation, idx_map_activation, activation_value, map_mean, height_crop, width_crop, path_to_crop): """Activates one latent variable and deactivates the others. One latent variable is activated and the others are deactivated. Then, the latent variable feature maps are quantized. Finally, the quantized latent variable feature maps are passed through the decoder of the entropy autoencoder. Parameters ---------- sess : Session Session that runs the graph. isolated_decoder : IsolatedDecoder Decoder of the entropy autoencoder. The graph of the decoder is built to process one example at a time. h_in : int Height of the images returned by the isolated decoder. w_in : int Width of the images returned by the isolated decoder. bin_widths : numpy.ndarray 1D array with data-type `numpy.float32`. Quantization bin widths at the end of the training. row_activation : int Row of the activated latent variable in the latent variable feature map of index `idx_map_activation`. col_activation : int Column of the activated latent variable in the latent variable feature map of index `idx_map_activation`. idx_map_activation : int Index of the latent variable feature map containing the activated latent variable. activation_value : float Activation value. map_mean : numpy.ndarray 1D array with data-type `numpy.float32`. Latent variable feature map means. height_crop : int Height of the crop of the decoder output. width_crop : int Width of the crop of the decoder output. path_to_crop : str Path to the saved crop of the decoder output. The path ends with ".png". Raises ------ ValueError If `row_activation` is not strictly positive. ValueError If `col_activation` is not strictly positive. """ if row_activation <= 0: raise ValueError('`row_activation` is not strictly positive.') if col_activation <= 0: raise ValueError('`col_activation` is not strictly positive.') y_float32 = numpy.tile(numpy.reshape(map_mean, (1, 1, 1, csts.NB_MAPS_3)), (1, h_in//csts.STRIDE_PROD, w_in//csts.STRIDE_PROD, 1)) y_float32[0, row_activation, col_activation, idx_map_activation] = activation_value quantized_y_float32 = tls.quantize_per_map(y_float32, bin_widths) reconstruction_float32 = sess.run( isolated_decoder.node_reconstruction, feed_dict={isolated_decoder.node_quantized_y:quantized_y_float32} ) reconstruction_uint8 = numpy.squeeze(tls.cast_bt601(reconstruction_float32), axis=(0, 3)) # The ratio between the feature map height and the # decoded image height is equal to `csts.STRIDE_PROD`. row_offset = (row_activation - 1)*csts.STRIDE_PROD col_offset = (col_activation - 1)*csts.STRIDE_PROD tls.save_image(path_to_crop, reconstruction_uint8[row_offset:row_offset + height_crop, col_offset:col_offset + width_crop])
def test_compress_lossless_maps(self): """Tests the function `compress_lossless_maps` in the file "lossless/compression.py". The test is successful if, for each centered quantized latent variable feature map, the coding cost computed by the function is slightly larger than the approximate theoretical coding cost. """ height_map = 384 width_map = 384 bin_widths_test = numpy.array([0.5, 0.25], dtype=numpy.float32) laplace_scales = numpy.array([0.5, 3.], dtype=numpy.float32) # Note that the binary probabilities saved at # "lossless/pseudo_data/binary_probabilities_compress_maps_0.npy" # and those saved at # "lossless/pseudo_data/binary_probabilities_compress_maps_1.npy" # are specific to the two Laplace distributions # below. This means that the binary probabilities # must be modified if `laplace_scales` is modified. paths_to_binary_probabilities = [ 'lossless/pseudo_data/binary_probabilities_compress_maps_0.npy', 'lossless/pseudo_data/binary_probabilities_compress_maps_1.npy' ] centered_data_0 = numpy.random.laplace(loc=0., scale=laplace_scales[0].item(), size=(1, height_map, width_map, 1)).astype(numpy.float32) centered_data_1 = numpy.random.laplace(loc=0., scale=laplace_scales[1].item(), size=(1, height_map, width_map, 1)).astype(numpy.float32) centered_data = numpy.concatenate((centered_data_0, centered_data_1), axis=3) expanded_centered_quantized_data = tls.quantize_per_map( centered_data, bin_widths_test) centered_quantized_data = numpy.squeeze( expanded_centered_quantized_data, axis=0) tiled_bin_widths = numpy.tile( numpy.reshape(bin_widths_test, (1, 1, 2)), (height_map, width_map, 1)) ref_int16 = tls.cast_float_to_int16(centered_quantized_data / tiled_bin_widths) (rec_int16_0, nb_bits_each_map_0) = \ lossless.compression.compress_lossless_maps(ref_int16, paths_to_binary_probabilities[0]) numpy.testing.assert_equal( ref_int16, rec_int16_0, err_msg= 'The test fails as the lossless compression alters the signed integers.' ) (rec_int16_1, nb_bits_each_map_1) = \ lossless.compression.compress_lossless_maps(ref_int16, paths_to_binary_probabilities[1]) numpy.testing.assert_equal( ref_int16, rec_int16_1, err_msg= 'The test fails as the lossless compression alters the signed integers.' ) # The formula below is derived from the # theorem 8.3.1 in the book "Elements of information theory", # 2nd edition, written by Thomas M. Cover and Joy A. Thomas. # Warning! The quantization in this theorem is not the # uniform scalar quantization. But, the two quantizations # get close as the quantization bin width tends to 0. approx_theoretical_entropies = -numpy.log2(bin_widths_test) + ( numpy.log(2. * laplace_scales) + 1.) / numpy.log(2.) print('B0 denotes the binary probabilities saved at "{}".'.format( paths_to_binary_probabilities[0])) print('B1 denotes the binary probabilities saved at "{}".'.format( paths_to_binary_probabilities[1])) print('\n1st centered quantized latent variable feature map.') print('Approximate theoretical coding cost: {} bits.'.format( approx_theoretical_entropies[0] * height_map * width_map)) print('Coding cost computed by the function via B0: {} bits.'.format( nb_bits_each_map_0[0])) print('Coding cost computed by the function via B1: {} bits.'.format( nb_bits_each_map_1[0])) print('\n2nd centered quantized latent variable feature map.') print('Approximate theoretical coding cost: {} bits.'.format( approx_theoretical_entropies[1] * height_map * width_map)) print('Coding cost computed by the function via B0: {} bits.'.format( nb_bits_each_map_0[1])) print('Coding cost computed by the function via B1: {} bits.'.format( nb_bits_each_map_1[1]))
def vary_gamma_fix_bin_widths(reference_uint8, bin_width_init, idxs_training, gammas_scaling, batch_size, path_to_checking_r, list_rotation, positions_top_left): """Computes a series of pairs (rate, PSNR). Several entropy autoencoders, each trained with a different scaling coefficient, are considered. At training time, the quantization bin widths were fixed. For each scaling coefficient, for each luminance image, the pair (rate, PSNR) associated to the compression of the luminance image via the entropy autoencoder trained with the scaling coefficient is computed. Parameters ---------- reference_uint8 : numpy.ndarray 3D array with data-type `numpy.uint8`. Luminance images. `reference_uint8[i, :, :]` is the ith luminance image. bin_width_init : float Value of the quantization bin widths at the beginning of the 1st training. In this function, the quantization bin widths are the same at training time and at test time. idxs_training : numpy.ndarray 1D array with data-type `numpy.int32`. Its ith element is the training phase index of the entropy autoencoder trained with the ith scaling coefficient. gammas_scaling : numpy.ndarray 1D array with data-type `numpy.float64`. Scaling coefficients. batch_size : int Size of the mini-batches for encoding and decoding via the entropy autoencoders. path_to_checking_r : str Path to the folder containing the luminance images before/after being compressed via entropy autoencoders. list_rotation : list Each integer in this list is the index of a rotated luminance image. positions_top_left : numpy.ndarray 2D array with data-type `numpy.int32`. This array is dedicated to visualization. `positions_top_left[:, i]` contains the row and the column of the image pixel at the top-left of the ith crop of each luminance image after being compressed via entropy autoencoders. Returns ------- tuple numpy.ndarray 2D array with data-type `numpy.float64`. The element at the position [i, j] in this array is the rate associated to the compression of the jth luminance image via the entropy autoencoder trained with the ith scaling coefficient. numpy.ndarray 2D array with data-type `numpy.float64`. The element at the position [i, j] in this array is the PSNR associated to the compression of the jth luminance image via the entropy autoencoder trained with the ith scaling coefficient. Raises ------ ValueError If `gammas_scaling.size` is not equal to `idxs_training.size`. """ nb_points = gammas_scaling.size if idxs_training.size != nb_points: raise ValueError( '`gammas_scaling.size` is not equal to `idxs_training.size`.') (nb_images, h_in, w_in) = reference_uint8.shape rate = numpy.zeros((nb_points, nb_images)) psnr = numpy.zeros((nb_points, nb_images)) for i in range(nb_points): gamma_scaling = gammas_scaling[i].item() idx_training = idxs_training[i].item() suffix = '{0}_{1}'.format(tls.float_to_str(bin_width_init), tls.float_to_str(gamma_scaling)) path_to_nb_itvs_per_side_load = 'eae/results/{0}/nb_itvs_per_side_{1}.pkl'.format( suffix, idx_training) path_to_restore = 'eae/results/{0}/model_{1}.ckpt'.format( suffix, idx_training) path_to_storage = os.path.join( path_to_checking_r, 'reconstruction_vary_gamma_fix_bin_widths', suffix) if not os.path.isdir(path_to_storage): os.makedirs(path_to_storage) # Every time `gamma_scaling` changes, a new # entropy autoencoder is created. entropy_ae = EntropyAutoencoder(batch_size, h_in, w_in, bin_width_init, gamma_scaling, path_to_nb_itvs_per_side_load, False) with tf.Session() as sess: entropy_ae.initialization(sess, path_to_restore) y_float32 = eae.batching.encode_mini_batches( numpy.expand_dims(reference_uint8, axis=3), sess, entropy_ae, batch_size) # `bin_widths` are the quantization bin widths # at training time. bin_widths = entropy_ae.get_bin_widths() # The graph of the entropy autoencoder is destroyed. tf.reset_default_graph() # Every time `gamma_scaling` changes, a new # decoder is created. isolated_decoder = IsolatedDecoder(batch_size, h_in, w_in, False) quantized_y_float32 = tls.quantize_per_map(y_float32, bin_widths) with tf.Session() as sess: isolated_decoder.initialization(sess, path_to_restore) expanded_reconstruction_uint8 = eae.batching.decode_mini_batches( quantized_y_float32, sess, isolated_decoder, batch_size) # The elements of `reconstruction_uint8` span # the range [|16, 235|]. reconstruction_uint8 = numpy.squeeze(expanded_reconstruction_uint8, axis=3) # The graph of the decoder is destroyed. tf.reset_default_graph() for j in range(nb_images): rate[i, j] = tls.rate_3d(quantized_y_float32[j, :, :, :], bin_widths, h_in, w_in) psnr[i, j] = tls.psnr_2d(reference_uint8[j, :, :], reconstruction_uint8[j, :, :]) paths = [ os.path.join(path_to_storage, 'reconstruction_{}.png'.format(j)) ] paths += [ os.path.join( path_to_storage, 'reconstruction_{0}_crop_{1}.png'.format(j, index_crop)) for index_crop in range(positions_top_left.shape[1]) ] tls.visualize_rotated_luminance(reconstruction_uint8[j, :, :], j in list_rotation, positions_top_left, paths) return (rate, psnr)
def fix_gamma(reference_uint8, bin_width_init, multipliers, idx_training, gamma_scaling, batch_size, are_bin_widths_learned, is_lossless, path_to_checking_r, list_rotation, positions_top_left): """Computes a series of pairs (rate, PSNR). A single entropy autoencoder is considered. At training time, the quantization bin widths were either fixed or learned. For each multiplier, the quantization bin widths at the end of the training are multiplied by the multiplier, yielding a set of test quantization bin widths. Then, for each set of test quantization bin widths, for each luminance image, the pair (rate, PSNR) associated to the compression of the luminance image via the single entropy autoencoder and the set of test quantization bin widths is computed. Parameters ---------- reference_uint8 : numpy.ndarray 3D array with data-type `numpy.uint8`. Luminance images. `reference_uint8[i, :, :]` is the ith luminance image. bin_width_init : float Value of the quantization bin widths at the beginning of the 1st training. multipliers : numpy.ndarray 1D array with data-type `numpy.float32`. Multipliers. idx_training : int Training phase index of the single entropy autoencoder. gamma_scaling : float Scaling coefficient of the single entropy autoencoder. batch_size : int Size of the mini-batches for encoding and decoding via the single entropy autoencoder. are_bin_widths_learned : bool Were the quantization bin widths learned at training time? is_lossless : bool Are the quantized latent variables coded losslessly? path_to_checking_r : str Path to the folder containing the luminance images before/after being compressed via the single entropy autoencoder. list_rotation : list Each integer in this list is the index of a rotated luminance image. positions_top_left : numpy.ndarray 2D array with data-type `numpy.int32`. This array is dedicated to visualization. `positions_top_left[:, i]` contains the row and the column of the image pixel at the top-left of the ith crop of each luminance image after being compressed via the single entropy autoencoder. Returns ------- tuple numpy.ndarray 2D array with data-type `numpy.float64`. The element at the position [i, j] in this array is the rate associated to the compression of the jth luminance image via the single entropy autoencoder and the ith set of test quantization bin widths. numpy.ndarray 2D array with data-type `numpy.float64`. The element at the position [i, j] in this array is the PSNR associated to the compression of the jth luminance image via the single entropy autoencoder and the ith set of test quantization bin widths. """ nb_points = multipliers.size (nb_images, h_in, w_in) = reference_uint8.shape rate = numpy.zeros((nb_points, nb_images)) psnr = numpy.zeros((nb_points, nb_images)) if are_bin_widths_learned: suffix = 'learning_bw_{0}_{1}'.format(tls.float_to_str(bin_width_init), tls.float_to_str(gamma_scaling)) else: suffix = '{0}_{1}'.format(tls.float_to_str(bin_width_init), tls.float_to_str(gamma_scaling)) path_to_nb_itvs_per_side_load = 'eae/results/{0}/nb_itvs_per_side_{1}.pkl'.format( suffix, idx_training) path_to_restore = 'eae/results/{0}/model_{1}.ckpt'.format( suffix, idx_training) if is_lossless: path_to_vis = os.path.join(path_to_checking_r, 'reconstruction_fix_gamma', suffix, 'lossless') else: path_to_vis = os.path.join(path_to_checking_r, 'reconstruction_fix_gamma', suffix, 'approx') path_to_stats = 'lossless/results/{0}/training_index_{1}/'.format( suffix, idx_training) path_to_map_mean = os.path.join(path_to_stats, 'map_mean.npy') # A single entropy autoencoder is created. entropy_ae = EntropyAutoencoder(batch_size, h_in, w_in, bin_width_init, gamma_scaling, path_to_nb_itvs_per_side_load, are_bin_widths_learned) with tf.Session() as sess: entropy_ae.initialization(sess, path_to_restore) y_float32 = eae.batching.encode_mini_batches( numpy.expand_dims(reference_uint8, axis=3), sess, entropy_ae, batch_size) # `bin_widths` are the quantization bin widths # at the end of the training. bin_widths = entropy_ae.get_bin_widths() # The graph of the entropy autoencoder is destroyed. tf.reset_default_graph() # A single decoder is created. isolated_decoder = IsolatedDecoder(batch_size, h_in, w_in, are_bin_widths_learned) # `array_nb_deads[i, j]` stores the number of dead feature # maps at the rate of index i for the luminance image of # index j. array_nb_deads = numpy.zeros((nb_points, nb_images), dtype=numpy.int32) # `map_mean[i]` is the approximate mean of the latent # variable feature map of index i. It was computed on # the extra set. map_mean = numpy.load(path_to_map_mean) tiled_map_mean = numpy.tile( map_mean, (nb_images, y_float32.shape[1], y_float32.shape[2], 1)) # `idx_map_exception` was also computed on the extra set. if is_lossless: with open(os.path.join(path_to_stats, 'idx_map_exception.pkl'), 'rb') as file: idx_map_exception = pickle.load(file) centered_y_float32 = y_float32 - tiled_map_mean with tf.Session() as sess: isolated_decoder.initialization(sess, path_to_restore) for i in range(nb_points): multiplier = multipliers[i].item() str_multiplier = tls.float_to_str(multiplier) bin_widths_test = multiplier * bin_widths centered_quantized_y_float32 = tls.quantize_per_map( centered_y_float32, bin_widths_test) # For a given luminance image, if at least a coefficient # of a feature map is different from 0.0, this feature map # is viewed as not dead. array_nb_deads[i, :] = tls.count_nb_deads( centered_quantized_y_float32) off_centered_quantized_y_float32 = centered_quantized_y_float32 + tiled_map_mean expanded_reconstruction_uint8 = eae.batching.decode_mini_batches( off_centered_quantized_y_float32, sess, isolated_decoder, batch_size) # The elements of span `reconstruction_uint8` # the range [|16, 235|]. reconstruction_uint8 = numpy.squeeze(expanded_reconstruction_uint8, axis=3) # The binary probabilities were also computed # on the extra set. if is_lossless: path_to_binary_probabilities = os.path.join( path_to_stats, 'binary_probabilities_{}.npy'.format(str_multiplier)) path_to_storage = os.path.join( path_to_vis, 'multiplier_{}'.format(str_multiplier)) if not os.path.isdir(path_to_storage): os.makedirs(path_to_storage) for j in range(nb_images): if is_lossless: nb_bits = lossless.compression.rescale_compress_lossless_maps( centered_quantized_y_float32[j, :, :, :], bin_widths_test, path_to_binary_probabilities, idx_map_exception=idx_map_exception) rate[i, j] = float(nb_bits) / (h_in * w_in) else: rate[i, j] = tls.rate_3d( centered_quantized_y_float32[j, :, :, :], bin_widths_test, h_in, w_in) psnr[i, j] = tls.psnr_2d(reference_uint8[j, :, :], reconstruction_uint8[j, :, :]) paths = [ os.path.join(path_to_storage, 'reconstruction_{}.png'.format(j)) ] paths += [ os.path.join( path_to_storage, 'reconstruction_{0}_crop_{1}.png'.format( j, index_crop)) for index_crop in range(positions_top_left.shape[1]) ] tls.visualize_rotated_luminance(reconstruction_uint8[j, :, :], j in list_rotation, positions_top_left, paths) # The graph of the decoder is destroyed. tf.reset_default_graph() path_to_directory_nb_dead = os.path.join(path_to_vis, 'nb_dead') if not os.path.isdir(path_to_directory_nb_dead): os.makedirs(path_to_directory_nb_dead) plot_nb_dead_feature_maps(rate, array_nb_deads, [ os.path.join(path_to_directory_nb_dead, 'nb_dead_{}.png'.format(i)) for i in range(nb_images) ]) return (rate, psnr)
def compute_binary_probabilities(y_float32, bin_widths_test, map_mean, truncated_unary_length): """Computes the binary probabilities associated to each latent variable feature map. Parameters ---------- y_float32 : numpy.ndarray 4D array with data-type `numpy.float32`. Latent variable feature maps. `y_float32[i, :, :, j]` is the jth latent variable feature map of the ith example. bin_widths_test : numpy.ndarray 1D array with data-type `numpy.float32`. Test quantization bin widths. map_mean : numpy.ndarray 1D array with data-type `numpy.float32`. Latent variable feature map means. truncated_unary_length : int Length of the truncated unary prefix. Returns ------- numpy.ndarray 2D array with data-type `numpy.float64`. Binary probabilities. The element at the position [i, j] in this array is the probability the jth binary decision is 0 in the truncated unary prefix associated to the ith absolute centered-quantized latent variable feature map. """ (nb_images, height_map, width_map, nb_maps) = y_float32.shape centered_y_float32 = y_float32 - numpy.tile( map_mean, (nb_images, height_map, width_map, 1)) centered_quantized_y_float32 = tls.quantize_per_map( centered_y_float32, bin_widths_test) cumulated_zeros = numpy.zeros((nb_maps, truncated_unary_length), dtype=numpy.int64) cumulated_ones = numpy.zeros((nb_maps, truncated_unary_length), dtype=numpy.int64) for i in range(nb_maps): (cumulated_zeros[i, :], cumulated_ones[i, :]) = \ count_binary_decisions(numpy.absolute(centered_quantized_y_float32[:, :, :, i]), bin_widths_test[i].item(), truncated_unary_length) total = cumulated_zeros + cumulated_ones # For the ith absolute centered-quantized latent # variable feature map, if the jth binary decision # never occurs, `binary_probabilities[i, j]` # is equal to `numpy.nan`. with numpy.errstate(invalid='ignore'): binary_probabilities = cumulated_zeros.astype( numpy.float64) / total.astype(numpy.float64) # If a binary decision never occurs, the # probability this binary decision is 0 # is set to 0.5. binary_probabilities[numpy.isnan(binary_probabilities)] = 0.5 binary_probabilities[binary_probabilities == 0.] = 0.01 binary_probabilities[binary_probabilities == 1.] = 0.99 return binary_probabilities