diff --git a/architectures/utils/NN_gen_building_blocks.py b/architectures/utils/NN_gen_building_blocks.py index b0958e7..19b8b17 100644 --- a/architectures/utils/NN_gen_building_blocks.py +++ b/architectures/utils/NN_gen_building_blocks.py @@ -518,6 +518,98 @@ output = layer.forward(output, reuse, is_training) + if i==len(self.d_dense_layers)-2: + feature_output=output + + if i==len(self.d_dense_layers)-1: + output_mb=self.mb_layer.forward(output, + reuse, + is_training) + # print('After dense layer_%i' %i) + # print('Shape', output.get_shape()) + + activation = tf.reshape(output_mb, (-1, self.num_kernels, self.kernel_dim)) + diffs = tf.expand_dims(activation, 3) - tf.expand_dims( + tf.transpose(activation, [1, 2, 0]), 0) + + eps = tf.expand_dims(tf.eye(tf.shape(X)[0], dtype=np.float32), 1) + abs_diffs = tf.reduce_sum(tf.abs(diffs), 2) + eps + minibatch_features = tf.reduce_sum(tf.exp(-abs_diffs), 2) + print('minibatch features shape', minibatch_features.get_shape()) + output=tf.concat([output, minibatch_features], 1) + + logits = self.d_final_layer.forward(output, + reuse, + is_training) + print('Feature output shape', feature_output.get_shape()) + print('Logits shape', logits.get_shape()) + + return logits, feature_output + +class dense_Discriminator_minibatch(object): + + def __init__(self, X, d_sizes, d_name): + + self.num_kernels=10 + self.kernel_dim=8 + + _, dim_H, dim_W, n_C = X.get_shape().as_list() + mi = dim_W*dim_H*n_C + + print('Dense Network architecture detected for discriminator '+ d_name) + + with tf.variable_scope('discriminator_'+d_name) as scope: + #building discriminator dense layers + + count=0 + self.d_dense_layers = [] + + for i, (mo, apply_batch_norm, keep_prob, act_f, w_init) in enumerate(d_sizes['dense_layers']): + + name = 'd_dense_layer_%s' %count + #print(name) + count +=1 + + layer = DenseLayer(name, mi, mo, + apply_batch_norm, keep_prob, + act_f, w_init) + + self.d_dense_layers.append(layer) + mi = mo + if i == len(d_sizes['dense_layers'])-1: + name = "mb_disc_layer" + self.mb_layer = DenseLayer(name, mi, self.num_kernels*self.kernel_dim, False, + keep_prob=1, act_f=lambda x:x, w_init=tf.truncated_normal_initializer(stddev=0.02)) + #final logistic layer + + name = 'd_dense_layer_%s' %count + w_init_last = d_sizes['readout_layer_w_init'] + #print(name) + # + self.d_final_layer = DenseLayer(name, mi + self.num_kernels , 1, + False, keep_prob=1, + act_f=lambda x: x, w_init=w_init_last) + + self.d_name=d_name + + + def d_forward(self, X, reuse = None, is_training=True): + + print('Discriminator_'+self.d_name) + #print('Convolution') + + output = X + print('Input shape ', X.get_shape()) + + output = tf.contrib.layers.flatten(output) + #print('After flatten shape', output.get_shape()) + + for i, layer in enumerate(self.d_dense_layers): + #print('Dense weights %i' %i) + #print(layer.W.get_shape()) + output = layer.forward(output, + reuse, + is_training) if i==len(self.d_dense_layers)-1: feature_output=output @@ -1749,6 +1841,7 @@ self.g_enc_conv_layers.append(layer) mi = mo + mi = mi + self.latent_dims dec_dims_H = [output_dim_H] dec_dims_W = [output_dim_W] @@ -1787,7 +1880,214 @@ self.g_dec_conv_layers.append(layer) mi = mo + #mi = mi + self.latent_dims + if deconv_count > 1: + name = 'g_deconv_layer_%s' %deconv_count + #print(name) + + layer = DeconvLayer( + name, 2*mi+ self.latent_dims, mo, [dec_dims_H[deconv_count], dec_dims_W[deconv_count]], + filter_sz, stride, apply_batch_norm, keep_prob, + act_f, w_init + ) + self.g_dec_conv_layers.append(layer) + mi = mo + #mi = mi + self.latent_dims + + assert conv_count==deconv_count, '\n Number of convolutional and deconvolutional layers do not coincide in \n encoder and decoder part of generator '+g_name + + # self.g_dims_H = dec_dims_H + # self.g_dims_W = dims_W + self.conv_count=conv_count + self.deconv_count=deconv_count + self.g_name=g_name + + def g_forward(self, X, z, reuse=None, is_training=True): + + + print('Generator_'+self.g_name) + + output=conv_concat(X,z, self.latent_dims) + + print('Input for generator encoded shape', X.get_shape()) + + skip_conv_outputs=[] + #convolutional encoder layers + + for i, layer in enumerate(self.g_enc_conv_layers, 1): + output = layer.forward(output, + reuse, + is_training) + skip_conv_outputs.append(output) + output=conv_concat(output, z, self.latent_dims) + + print('After conv layer%i' %i) + print('shape: ', output.get_shape()) + + assert i == self.conv_count + + if (output.get_shape().as_list()[1], output.get_shape().as_list()[2]) != (1, 1): + output = tf.reshape( + output, + [-1, 1, 1, self.n_C_last] + ) + + print('Output of generator encoder, \n and input for generator decoder shape', output.get_shape()) + + for i, layer in enumerate(self.g_dec_conv_layers[:-1], 1): + + skip_layer=self.conv_count - i + if i > 1: + #print('After deconv layer %i' %i) + #print('main path', output.get_shape()) + #print('secondary path', skip_conv_outputs[skip_layer].get_shape()) + output = tf.concat([output, skip_conv_outputs[skip_layer]], axis =3) + #print('After concat shape', output.get_shape()) + + output = layer.forward(output, + reuse, + is_training) + output = conv_concat(output, z, self.latent_dims) + print('After deconv layer %i' %i) + print('Shape', output.get_shape()) + output = tf.concat([output, skip_conv_outputs[skip_layer-1]], axis =3) + output = self.g_dec_conv_layers[-1].forward(output, + reuse, + is_training) + assert i + 1 == self.deconv_count + + print('Generator output shape', output.get_shape()) + return output + + # def g_forward_noise(self, X, z, reuse=None, is_training=True): + + + # print('Encoder_'+self.g_name) + + # output = X + + # print('Input for generator encoded shape', X.get_shape()) + + # skip_conv_outputs=[] + # #convolutional encoder layers + + # for i, layer in enumerate(self.g_enc_conv_layers, 1): + # output = layer.forward(output, + # reuse, + # is_training) + + # skip_conv_outputs.append(output) + # #print('After conv layer%i' %i) + # #print('shape: ', output.get_shape()) + + # assert i == self.conv_count + + # if (output.get_shape().as_list()[1], output.get_shape().as_list()[2]) != (1, 1): + # output = tf.reshape( + # output, + # [-1, 1, 1, self.n_C_last] + # ) + + # print('Output of generator encoder, \n and input for generator decoder shape', output.get_shape()) + + # for i, layer in enumerate(self.g_dec_conv_layers, 1): + + # skip_layer=self.conv_count - i + # if i > 1: + # #print('After deconv layer %i' %i) + # #print('main path', output.get_shape()) + # #print('secondary path', skip_conv_outputs[skip_layer].get_shape()) + # output = tf.concat([output, skip_conv_outputs[skip_layer]], axis =3) + # #print('After concat shape', output.get_shape()) + # output = layer.forward(output, + # reuse, + # is_training) + + # # print('After deconv layer %i' %i) + # # print('Shape', output.get_shape()) + + # assert i == self.deconv_count + + # print('Generator output shape', output.get_shape()) + # return output + +#same as pix2pixGenerator with input noise +class bicycleGenerator_old(object): + + def __init__(self, X, output_dim_H, output_dim_W, g_sizes_enc, g_sizes_dec, g_name): + + _, input_dim_H, input_dim_W, input_n_C = X.get_shape().as_list() + + enc_dims_H=[input_dim_H] + enc_dims_W=[input_dim_W] + enc_dims_nC=[input_n_C] + + output_n_C=input_n_C + self.latent_dims = g_sizes_enc['latent_dims'] + mi = input_n_C + self.latent_dims + + with tf.variable_scope('generator_'+g_name) as scope: + + #building generator encoder convolutional layers + self.g_enc_conv_layers =[] + enc_dims=[] + for conv_count, (mo, filter_sz, stride, apply_batch_norm, keep_prob, act_f, w_init) in enumerate(g_sizes_enc['conv_layers'], 1): + + name = "g_conv_layer_%s" % conv_count + layer = ConvLayer(name, mi, mo, + filter_sz, stride, + apply_batch_norm, keep_prob, + act_f, w_init) + + input_dim_H = int(np.ceil(float(input_dim_H)/stride)) + input_dim_W = int(np.ceil(float(input_dim_W)/stride)) + + enc_dims_H.append(input_dim_H) + enc_dims_W.append(input_dim_W) + enc_dims_nC.append(mo) + self.g_enc_conv_layers.append(layer) + + mi = mo + + dec_dims_H = [output_dim_H] + dec_dims_W = [output_dim_W] + + #building generator decoder deconvolutional layers + #calculate outputsize for each deconvolution step + for _, _, stride, _, _, _, _ in reversed(g_sizes_dec['deconv_layers']): + + output_dim_H = int(np.ceil(float(output_dim_H)/stride)) + output_dim_W = int(np.ceil(float(output_dim_W)/stride)) + + dec_dims_H.append(output_dim_H) + dec_dims_W.append(output_dim_W) + + dec_dims_H = list(reversed(dec_dims_H)) + dec_dims_W = list(reversed(dec_dims_W)) + + self.g_dec_conv_layers=[] + + #number of channels of last convolution and of first transposed convolution + # the layer will be reshaped to have dimensions [?, 1, 1, mi*enc_dims_W[-1]*enc_dims_H[-1]] + mi=mi*enc_dims_W[-1]*enc_dims_H[-1] + self.n_C_last=mi + + for deconv_count, (mo, filter_sz, stride, apply_batch_norm, keep_prob, act_f, w_init) in enumerate(g_sizes_dec['deconv_layers'], 1): + + if deconv_count == 1: + name = 'g_deconv_layer_%s' %deconv_count + #print(name) + + layer = DeconvLayer( + name, mi, mo, [dec_dims_H[deconv_count], dec_dims_W[deconv_count]], + filter_sz, stride, apply_batch_norm, keep_prob, + act_f, w_init + ) + + self.g_dec_conv_layers.append(layer) + mi = mo + #mi = mi + self.latent_dims if deconv_count > 1: name = 'g_deconv_layer_%s' %deconv_count #print(name) @@ -1800,7 +2100,7 @@ self.g_dec_conv_layers.append(layer) mi = mo - + #mi = mi + self.latent_dims assert conv_count==deconv_count, '\n Number of convolutional and deconvolutional layers do not coincide in \n encoder and decoder part of generator '+g_name @@ -1810,18 +2110,12 @@ self.deconv_count=deconv_count self.g_name=g_name - def g_forward(self, X, z, reuse=None, is_pretraining=None, is_training=True): + def g_forward(self, X, z, reuse=None, is_training=True): - if is_pretraining: - z=X - elif not is_pretraining: - z = tf.reshape(z, [tf.shape(X)[0], 1, 1, self.latent_dims]) - z = tf.tile(z, [1, tf.shape(X)[1], tf.shape(X)[2], 1]) print('Generator_'+self.g_name) - output = X - output=tf.concat([X,z], axis=3) + output=conv_concat(X,z, self.latent_dims) print('Input for generator encoded shape', X.get_shape()) @@ -1832,10 +2126,10 @@ output = layer.forward(output, reuse, is_training) - skip_conv_outputs.append(output) - #print('After conv layer%i' %i) - #print('shape: ', output.get_shape()) + + print('After conv layer%i' %i) + print('shape: ', output.get_shape()) assert i == self.conv_count @@ -1856,18 +2150,69 @@ #print('secondary path', skip_conv_outputs[skip_layer].get_shape()) output = tf.concat([output, skip_conv_outputs[skip_layer]], axis =3) #print('After concat shape', output.get_shape()) + output = layer.forward(output, reuse, is_training) - - # print('After deconv layer %i' %i) - # print('Shape', output.get_shape()) + print('After deconv layer %i' %i) + print('Shape', output.get_shape()) assert i == self.deconv_count - print('Generator output shape', output.get_shape()) return output + # def g_forward_noise(self, X, z, reuse=None, is_training=True): + + + # print('Encoder_'+self.g_name) + + # output = X + + # print('Input for generator encoded shape', X.get_shape()) + + # skip_conv_outputs=[] + # #convolutional encoder layers + + # for i, layer in enumerate(self.g_enc_conv_layers, 1): + # output = layer.forward(output, + # reuse, + # is_training) + + # skip_conv_outputs.append(output) + # #print('After conv layer%i' %i) + # #print('shape: ', output.get_shape()) + + # assert i == self.conv_count + + # if (output.get_shape().as_list()[1], output.get_shape().as_list()[2]) != (1, 1): + # output = tf.reshape( + # output, + # [-1, 1, 1, self.n_C_last] + # ) + + # print('Output of generator encoder, \n and input for generator decoder shape', output.get_shape()) + + # for i, layer in enumerate(self.g_dec_conv_layers, 1): + + # skip_layer=self.conv_count - i + # if i > 1: + # #print('After deconv layer %i' %i) + # #print('main path', output.get_shape()) + # #print('secondary path', skip_conv_outputs[skip_layer].get_shape()) + # output = tf.concat([output, skip_conv_outputs[skip_layer]], axis =3) + # #print('After concat shape', output.get_shape()) + # output = layer.forward(output, + # reuse, + # is_training) + + # # print('After deconv layer %i' %i) + # # print('Shape', output.get_shape()) + + # assert i == self.deconv_count + + # print('Generator output shape', output.get_shape()) + # return output + #(residual) conditional generator, label injected at every step class condGenerator(object): def __init__(self, dim_y, dim_H, dim_W, g_sizes, g_name): @@ -2204,8 +2549,8 @@ def __init__(self, X, e_sizes, e_name): - latent_dims = e_sizes['z'] - + latent_dims = e_sizes['latent_dims'] + X=tf.contrib.layers.flatten(X) _, mi = X.get_shape().as_list() with tf.variable_scope('encoder'+e_name) as scope: @@ -2243,7 +2588,8 @@ def e_forward(self, X, reuse = None, is_training=False): - output=X + output=tf.contrib.layers.flatten(X) + for layer in self.e_layers: output = layer.forward(output, reuse, is_training)