From 76756103ef6883e70a0379035cd539456b717aa9 Mon Sep 17 00:00:00 2001
From: JGlombitza <jonas.glombitza@rwth-aachen.de>
Date: Thu, 15 Feb 2018 16:40:14 +0100
Subject: [PATCH] remove unused functiony from utils add build_critic_training
 add build_generator_training

---
 AirShower_WGAN/ShowerGAN.py |  27 ++----
 AirShower_WGAN/utils.py     | 171 ++++++------------------------------
 2 files changed, 34 insertions(+), 164 deletions(-)

diff --git a/AirShower_WGAN/ShowerGAN.py b/AirShower_WGAN/ShowerGAN.py
index 7daf6ee..f879d90 100644
--- a/AirShower_WGAN/ShowerGAN.py
+++ b/AirShower_WGAN/ShowerGAN.py
@@ -16,7 +16,7 @@ import tensorflow as tf
 KTF.set_session(utils.get_session())  # Allows 2 jobs per GPU, Please do not change this during the tutorial
 log_dir="."
 
-EPOCHS = 10
+EPOCHS = 3
 GRADIENT_PENALTY_WEIGHT = 10
 BATCH_SIZE = 256
 NCR = 5
@@ -62,7 +62,7 @@ def build_generator(latent_size):
     outputs = Conv2D(1, (3, 3), padding='same', kernel_initializer='he_normal', activation='relu')(x)
     return Model(inputs=inputs, outputs=outputs, name='generator')
 
-
+# build critic
 def build_critic():
     critic = Sequential(name='critic')
     critic.add(Conv2D(64, (3, 3), padding='same', kernel_initializer='he_normal', input_shape=(9,9,1)))
@@ -79,6 +79,7 @@ def build_critic():
     critic.add(Dense(1))
     return critic
 
+
 generator = build_generator(latent_size)
 #plot_model(generator, to_file=log_dir + '/generator.png', show_shapes=True)
 critic = build_critic()
@@ -88,10 +89,7 @@ critic = build_critic()
 utils.make_trainable(critic, False)
 utils.make_trainable(generator, True)
 
-generator_in = Input(shape=(latent_size,))
-generator_out = generator(generator_in)
-critic_out = critic(generator_out)
-generator_training = Model(inputs=generator_in, outputs=critic_out)
+generator_training = utils.build_generator_graph(generator, critic, latent_size)
 generator_training.compile(optimizer=Adam(0.0001, beta_1=0.5, beta_2=0.9, decay=0.0), loss=[utils.wasserstein_loss])
 #plot_model(generator_training, to_file=log_dir + '/generator_training.png', show_shapes=True)
 
@@ -99,14 +97,8 @@ generator_training.compile(optimizer=Adam(0.0001, beta_1=0.5, beta_2=0.9, decay=
 utils.make_trainable(critic, True)
 utils.make_trainable(generator, False)
 
-generator_in_critic_training = Input(shape=(latent_size,), name="noise")
-shower_in_critic_training = Input(shape=(9,9,1), name='shower_maps')
-generator_out_critic_training = generator(generator_in_critic_training)
-out_critic_training_gen = critic(generator_out_critic_training)
-out_critic_training_shower = critic(shower_in_critic_training)
-averaged_batch = RandomWeightedAverage(name='Average')([generator_out_critic_training, shower_in_critic_training])
-averaged_batch_out = critic(averaged_batch)
-critic_training = Model(inputs=[generator_in_critic_training, shower_in_critic_training], outputs=[out_critic_training_gen, out_critic_training_shower, averaged_batch_out])
+
+critic_training, averaged_batch = utils.build_critic_graph(generator, critic, latent_size, batch_size=BATCH_SIZE)
 gradient_penalty = partial(utils.gradient_penalty_loss, averaged_batch=averaged_batch, penalty_weight=GRADIENT_PENALTY_WEIGHT)
 gradient_penalty.__name__ = 'gradient_penalty'
 critic_training.compile(optimizer=Adam(0.0001, beta_1=0.5, beta_2=0.9, decay=0.0), loss=[utils.wasserstein_loss, utils.wasserstein_loss, gradient_penalty])
@@ -115,7 +107,7 @@ critic_training.compile(optimizer=Adam(0.0001, beta_1=0.5, beta_2=0.9, decay=0.0
 # For Wassersteinloss
 positive_y = np.ones(BATCH_SIZE)
 negative_y = -positive_y
-dummy = np.zeros(BATCH_SIZE) # keras throws an error when calculating a loss withuot having a label -> needed for using the gradient penalty loss
+dummy = np.zeros(BATCH_SIZE) # keras throws an error when calculating a loss without having a label -> needed for using the gradient penalty loss
 
 generator_loss = []
 critic_loss = []
@@ -136,9 +128,8 @@ for epoch in range(EPOCHS):
         generator_loss.append(generator_training.train_on_batch([noise_batch], [positive_y]))
         print "generator loss:", generator_loss[-1]
 
-utils.plot_loss(critic_loss, name="critic", iterations_per_epoch=iterations_per_epoch, NCR=NCR, log_dir=log_dir, bins_per_epoch=3)
-utils.plot_loss(generator_loss, name="generator", iterations_per_epoch=iterations_per_epoch, log_dir=log_dir, bins_per_epoch=3)
-
+utils.plot_loss(critic_loss, name="critic", log_dir=log_dir)
+utils.plot_loss(generator_loss, name="generator",log_dir=log_dir)
 
 # plot some generated figures
 generated_map = generator.predict(np.random.randn(BATCH_SIZE, latent_size))
diff --git a/AirShower_WGAN/utils.py b/AirShower_WGAN/utils.py
index 4702374..ef1772c 100644
--- a/AirShower_WGAN/utils.py
+++ b/AirShower_WGAN/utils.py
@@ -8,13 +8,15 @@ import matplotlib
 matplotlib.use('Agg')
 import matplotlib.pyplot as plt
 
+
 def get_session(gpu_fraction=0.40):
-    ''' Allocate only a fraction of the GPU RAM - (1080 GTX 8Gb)'''
+    ''' Allocate only a fraction of the GPU RAM - (1080 GTX 8Gb). Please do not change the fraction during the tutorial!'''
     gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=gpu_fraction)
     return tf.Session(config=tf.ConfigProto(gpu_options=gpu_options))
 
 
 def ReadInData(filenames):
+    '''Reads in the trainings data'''
     N = 100000 *len(filenames)
     a = 100000
     shower_maps = np.zeros(N*9*9*1).reshape(N,9,9,1)
@@ -26,36 +28,8 @@ def ReadInData(filenames):
     return shower_maps, Energy
 
 
-def ang2vec(phi, zenith):
-    """ Get 3-vector from spherical angles.
-    Args:
-        phi (array): azimuth (pi, -pi), 0 points in x-direction, pi/2 in y-direction
-        zenith (array): zenith (0, pi), 0 points in z-direction
-    Returns:
-        array of 3-vectors
-    """
-    x = np.sin(zenith) * np.cos(phi)
-    y = np.sin(zenith) * np.sin(phi)
-    z = np.cos(zenith)
-    return np.array([x, y, z]).T
-
-
-def vec2ang(v):
-    '''Calculates phi and theta for given shower axis'''
-    x, y, z = np.asarray(v).T
-    phi = np.arctan2(y, x)
-    theta = np.pi/2 - np.arctan2(z, (x**2 + y**2)**.5)
-    return np.rad2deg(phi), np.rad2deg(theta)
-
-
-def DenselyConnectedConv(z, nfilter):
-    ''' Densely Connected SeparableConvolution2D Layer'''
-    c = Conv2D(nfilter, (3, 3), padding = 'same', activation='relu', kernel_initializer='he_normal')(z)
-    return concatenate([z, c], axis=-1)
-
-
 def make_trainable(model, trainable):
-    ''' Freezes/unfreezes the weights in the given model '''
+    ''' Freezes/unfreezes the weights in the given model for each layer'''
     for layer in model.layers:
         model.trainable=trainable
     model.trainable=trainable
@@ -69,14 +43,13 @@ def rectangular_array(n=9):
 
 def wasserstein_loss(y_true, y_pred):
     """Calculates the Wasserstein loss - critic maximises the distance between its output for real and generated samples.
-    To achieve this generated samples have the label -1 and real samples the label 1. Multiplying the outputs by the labels results to the wasserstein loss"""
+    To achieve this generated samples have the label -1 and real samples the label 1. Multiplying the outputs by the labels results to the wasserstein loss via the Kantorovich-Rubinstein duality"""
     return K.mean(y_true * y_pred)
 
 
 def gradient_penalty_loss(y_true, y_pred, averaged_batch, penalty_weight):
     """Calculates the gradient penalty (for details see arXiv:1704.00028v3).
-    The 1-Lipschitz constraint for improved WGANs is enforced by adding a term which penalizes if the gradient norm in the critic unequal to 1.
-    (With this loss we penalize gradients with respect to the input of the averaged samples.)"""
+    The 1-Lipschitz constraint for improved WGANs is enforced by adding a term to the loss which penalizes if the gradient norm in the critic unequal to 1"""
     gradients = K.gradients(K.sum(y_pred), averaged_batch)
     gradient_l2_norm = K.sqrt(K.sum(K.square(gradients)))
     gradient_penalty = penalty_weight * K.square(1 - gradient_l2_norm)
@@ -94,103 +67,43 @@ class RandomWeightedAverage(_Merge):
         return (weights * inputs[0]) + ((1 - weights) * inputs[1])
 
 
-def build_generator_graph(generator, critic, conditioner, latent_size, energy_in=1):
+def build_generator_graph(generator, critic, latent_size):
+    '''Builds the graph for training the generator part of the improved WGAN'''
     generator_in = Input(shape=(latent_size,))
-    generator_in_energy_label = Input(shape=(energy_in,))
-    generator_out = generator([generator_in, generator_in_energy_label])
+    generator_out = generator([generator_in])
     critic_out = critic(generator_out)
-    energy_rec_out = conditioner(generator_out)
-    return Model(inputs=[generator_in, generator_in_energy_label], outputs=[critic_out, energy_rec_out])
+    return Model(inputs=[generator_in], outputs=[critic_out])
 
 
-def build_critic_graph(generator, critic, conditioner, latent_size, energy_in, batch_size=1):
+def build_critic_graph(generator, critic, latent_size, batch_size=1):
+    '''Builds the graph for training the critic part of the improved WGAN'''
     generator_in_critic_training = Input(shape=(latent_size,), name="noise")
-    generator_in_critic_training_energy_label = Input(shape=(energy_in,), name="energy_label")
     shower_in_critic_training = Input(shape=(9,9,1), name='shower_maps')
-    generator_out_critic_training = generator([generator_in_critic_training, generator_in_critic_training_energy_label])
+    generator_out_critic_training = generator([generator_in_critic_training])
     out_critic_training_gen = critic(generator_out_critic_training)
     out_critic_training_shower = critic(shower_in_critic_training)
     averaged_batch = RandomWeightedAverage(batch_size, name='Average')([generator_out_critic_training, shower_in_critic_training])
     averaged_batch_out = critic(averaged_batch)
-    rec_out = conditioner(shower_in_critic_training)
-    return Model(inputs=[generator_in_critic_training, shower_in_critic_training, generator_in_critic_training_energy_label], outputs=[out_critic_training_gen, out_critic_training_shower, averaged_batch_out, rec_out]), averaged_batch
-
-
-def plot_loss_wasserstein(loss, log_dir = ".", name="", iterations_per_epoch=10, NCR=1, Rec_scaling=1):
-    fig, ax1 = plt.subplots(1, figsize=(10,5))
-    epoch = np.arange(len(loss))
-    loss = np.array(loss)
-    plt.plot(epoch, loss[:,1] + loss[:,2] + loss[:,3], color='red', markersize=12, label=r'$Wasserstein$')
-    plt.legend(loc='upper right',prop={'size':10})
-    ax1.set_xlabel(r'$Iterations$')
-    ax1.set_ylabel(r'$Loss$')
-    ax1.set_ylim(-2, 2)
-    fig.savefig(log_dir + '/%s_Loss_wasserstein.png' %name, dpi=480)
-    plt.plot(epoch, loss[:,4]*Rec_scaling, color='orange', markersize=12, label=r'$Reconstruction$')
-    plt.close('all')
-
-
-def plot_loss_reco(loss, log_dir = ".", name="", iterations_per_epoch=10, NCR=1, Rec_scaling=1):
-    fig, ax1 = plt.subplots(1, figsize=(10,4))
-    epoch = np.arange(len(loss))
-    loss = np.array(loss)
-    plt.plot(epoch, loss[:,2], color='orange', markersize=12, label=r'$Reconstruction$')
-    plt.legend(loc='upper right',prop={'size':10})
-    ax1.set_xlabel(r'$Iterations$')
-    ax1.set_ylabel(r'$Loss$')
-    ax1.set_yscale("log", nonposy='clip')
-    fig.savefig(log_dir + '/%s_Loss_reco.png' %name, dpi=480)
-    plt.close('all')
+    return Model(inputs=[generator_in_critic_training, shower_in_critic_training], outputs=[out_critic_training_gen, out_critic_training_shower, averaged_batch_out]), averaged_batch
 
 
-def plot_loss(loss, log_dir = ".", name="", iterations_per_epoch=10, NCR=1, Rec_scaling=1):
+def plot_loss(loss, log_dir = ".", name=""):
+    """Plot the traings curve"""
     fig, ax1 = plt.subplots(1, figsize=(10,4))
     epoch = np.arange(len(loss))
     loss = np.array(loss)
     try:
-        plt.plot(epoch, loss[:,0], color='red', markersize=12, label=r'$Total$')
-        plt.plot(epoch, loss[:,1] + loss[:,2], color='green', label=r'$Wasserstein$', linestyle='dashed')
-        plt.plot(epoch, loss[:,3], color='royalblue', markersize=12, label=r'$Gradient$', linestyle='dashed')
-        plt.plot(epoch, Rec_scaling*loss[:,4], color='orange', markersize=12, label=r'$Reconstrucion$', linestyle='dashed')
+        plt.plot(epoch, loss[:,0], color='red', markersize=12, label=r'Total')
+        plt.plot(epoch, loss[:,1] + loss[:,2], color='green', label=r'Wasserstein', linestyle='dashed')
+        plt.plot(epoch, loss[:,3], color='royalblue', markersize=12, label=r'GradientPenalty', linestyle='dashed')
     except:
-        plt.plot(epoch, loss[:,0], color='red', markersize=12, label=r'$Total$')
+        plt.plot(epoch, loss[:], color='red', markersize=12, label=r'Total')
 
     plt.legend(loc='upper right',prop={'size':10})
-    ax1.set_xlabel(r'$Iterations$')
-    ax1.set_ylabel(r'$Cost \Theta (MSE)$')
-    ax1.set_ylim(-2, 2)
-    fig.savefig(log_dir + '/%s_Loss.png' %name, dpi=480)
-    plt.close('all')
-
-
-def plot_array_scatter(values, label, axis, vmin=0):
-    """Plot a map *values* for an detector array specified by *v_stations*. """
-    xd, yd = rectangular_array()
-    filter = values!=0
-    filter[5,5] = True
-    axis.scatter(xd[~filter], yd[~filter], c = 'grey', s = 220, alpha=0.1, label="silent")
-    circles = axis.scatter(xd[filter], yd[filter], c = values[filter], s = 200, alpha=1, label="loud", vmin=vmin)
-    cbar = plt.colorbar(circles, ax=axis)
-    cbar.set_label(label + ' [a.u.]')
-    axis.grid(True)
-    axis.set_title(label + ' footprint', fontsize=10)
-    axis.set_aspect('equal')
-    axis.set_xlim(-5, 5)
-    axis.set_ylim(-5, 5)
-    axis.set_xlabel('x [km]')
-    axis.set_ylabel('y [km]')
-
-
-def plot_showermaps(footprint, log_dir='.', title='', epoch=''):
-    """ Plots the time and signal footprint in one figure """
-    fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(10,4))
-    fig.subplots_adjust(left=0, bottom=0.13)
-    plot_array_scatter(footprint[:,:,0], label = 'time', axis=ax1, vmin=1)
-    plot_array_scatter(footprint[:,:,1], label = 'signal', axis=ax2)
-    plt.suptitle(title + ' ' + str(epoch), fontsize=16)
-    plt.tight_layout()
-    plt.legend(bbox_to_anchor=(0.59, 0.12, 0, 0.0), bbox_transform=plt.gcf().transFigure, ncol=2)
-    fig.savefig(log_dir + '/%s_shower_map.png' %epoch, dpi=140)
+    ax1.set_xlabel(r'Iterations')
+    ax1.set_ylabel(r'Loss')
+    ax1.set_ylim(-1, 3)
+    fig.savefig(log_dir + '/%s_Loss.png' %name, dpi=120)
     plt.close('all')
 
 
@@ -229,39 +142,5 @@ def plot_multiple_signalmaps(footprint, log_dir='.', title='', epoch='', nrows=2
     plt.tight_layout()
     fig.subplots_adjust(left=0.02, top=0.95)
     plt.suptitle(title + ' ' + str(epoch), fontsize=12)
-    fig.savefig(log_dir + '/%s_signal_maps.png' %epoch, dpi=140)
+    fig.savefig(log_dir + '/%s_signal_maps.png' %epoch, dpi=120)
     plt.close('all')
-
-
-def plot_energy_histos(y_true, y_pred, log_dir, name):
-    ''' Plottingfunction to evaluate the reconstruction of the cosmic ray energy
-        plots: predicted Energy against MC Energy and the energy dependence of the relative energy resolution (embedded)'''
-    y_true = y_true.reshape(y_true.shape[0],1)
-    reco = y_true-y_pred
-    # Embedding plot
-    fig, ax1 = plt.subplots(1)
-    ax1.scatter(y_true, y_pred, s = 2, color='royalblue', alpha=.90)
-    ax1.set_xlabel(r'$Energy_{Input}\;[EeV]$')
-    ax1.set_ylabel(r'$Energy_{DNN}\;[EeV]$')
-    left, bottom, width, height = [0.23, 0.6, 0.3, 0.26] # Links Oben
-    ax1.text(0.95,0.2, r"$\mu = $ %.3f" % np.mean(reco) + " [EeV]" + "\n" + "$\sigma = $ %.3f" % np.std(reco) + " [EeV]", verticalalignment = 'top', horizontalalignment = 'right', transform=ax1.transAxes, backgroundcolor='w')
-    ax1.plot([np.min(y_true), np.max(y_true)], [np.min(y_true), np.max(y_true)], color='red')
-    fig.savefig(log_dir + '/%s_Energy_reconstruction.png' %name, dpi=140)
-    return reco
-
-def plot_energy_histos_real(y_true, y_pred, log_dir, name):
-    ''' Plottingfunction to evaluate the reconstruction of the cosmic ray energy
-        plots: predicted Energy against MC Energy and the energy dependence of the relative energy resolution (embedded)'''
-    y_true = y_true.reshape(y_true.shape[0],1)
-    reco = y_true-y_pred
-    # Embedding plot
-    fig, ax1 = plt.subplots(1)
-    ax1.scatter(y_true, y_pred, s = 2, color='royalblue', alpha=.90)
-    ax1.set_xlabel(r'$Energy_{MC}\;[EeV]$')
-    ax1.set_ylabel(r'$Energy_{DNN}\;[EeV]$')
-    left, bottom, width, height = [0.23, 0.6, 0.3, 0.26] # Links Oben
-    ax1.text(0.95,0.2, r"$\mu = $ %.3f" % np.mean(reco) + " [EeV]" + "\n" + "$\sigma = $ %.3f" % np.std(reco) + " [EeV]", verticalalignment = 'top', horizontalalignment = 'right', transform=ax1.transAxes, backgroundcolor='w')
-    ax1.plot([np.min(y_true), np.max(y_true)], [np.min(y_true), np.max(y_true)], color='red')
-    fig.savefig(log_dir + '/%s_Energy_reconstruction.png' %name, dpi=140)
-    return reco
-
-- 
GitLab