def discriminator(x, convolutional=True, filter_sizes=[5, 5, 5, 5], activation=tf.nn.relu, n_filters=[100, 100, 100, 100]): """Summary Parameters ---------- x : TYPE Description convolutional : bool, optional Description filter_sizes : list, optional Description activation : TYPE, optional Description n_filters : list, optional Description Returns ------- name : TYPE Description """ encoding = encoder( x=x, convolutional=convolutional, dimensions=n_filters, filter_sizes=filter_sizes, activation=activation) # flatten, then linear to 1 value res = utils.flatten(encoding['z'], name='flatten') if res.get_shape().as_list()[-1] > 1: res = utils.linear(res, 1)[0] return { 'logits': res, 'probs': tf.nn.sigmoid(res), 'Ws': encoding['Ws'], 'hs': encoding['hs'] }
def VAEGAN(input_shape=[None, 784], n_filters=[64, 64, 64], filter_sizes=[4, 4, 4], n_hidden=32, n_code=2, activation=tf.nn.tanh, convolutional=False, variational=False): """Summary Parameters ---------- input_shape : list, optional Description n_filters : list, optional Description filter_sizes : list, optional Description n_hidden : int, optional Description n_code : int, optional Description activation : TYPE, optional Description convolutional : bool, optional Description variational : bool, optional Description Returns ------- name : TYPE Description """ # network input / placeholders for train (bn) x = tf.placeholder(tf.float32, input_shape, 'x') z_samp = tf.placeholder(tf.float32, [None, n_code], 'z_samp') with tf.variable_scope('encoder'): encoding = encoder(x=x, n_hidden=n_hidden, convolutional=convolutional, dimensions=n_filters, filter_sizes=filter_sizes, activation=activation) with tf.variable_scope('variational'): z, z_mu, z_log_sigma, loss_z = variational_bayes(h=encoding['z'], n_code=n_code) shapes = encoding['shapes'].copy() shapes.reverse() n_filters_decoder = n_filters.copy() n_filters_decoder.reverse() n_filters_decoder += [input_shape[-1]] with tf.variable_scope('generator'): decoding_actual = decoder(z=z, shapes=shapes, n_hidden=n_hidden, convolutional=convolutional, dimensions=n_filters_decoder, filter_sizes=filter_sizes, activation=activation) with tf.variable_scope('generator', reuse=True): decoding_sampled = decoder(z=z_samp, shapes=shapes, n_hidden=n_hidden, convolutional=convolutional, dimensions=n_filters_decoder, filter_sizes=filter_sizes, activation=activation) with tf.variable_scope('discriminator'): D_real = discriminator(x, filter_sizes=filter_sizes, n_filters=n_filters, activation=activation) with tf.variable_scope('discriminator', reuse=True): D_fake = discriminator(decoding_actual['x_tilde'], filter_sizes=filter_sizes, n_filters=n_filters, activation=activation) with tf.variable_scope('discriminator', reuse=True): D_samp = discriminator(decoding_sampled['x_tilde'], filter_sizes=filter_sizes, n_filters=n_filters, activation=activation) with tf.variable_scope('loss'): # Weights influence of content/style of decoder gamma = tf.placeholder(tf.float32, name='gamma') # Discriminator_l Log Likelihood Loss loss_D_llike = 0 for h_fake, h_real in zip(D_fake['hs'][3:], D_real['hs'][3:]): loss_D_llike += tf.reduce_sum( 0.5 * tf.squared_difference(utils.flatten(h_fake), utils.flatten(h_real)), 1) # GAN Loss eps = 1e-12 loss_real = tf.reduce_sum(tf.log(D_real['probs'] + eps), 1) loss_fake = tf.reduce_sum(tf.log(1 - D_fake['probs'] + eps), 1) loss_samp = tf.reduce_sum(tf.log(1 - D_samp['probs'] + eps), 1) loss_GAN = (loss_real + loss_fake + loss_samp) / 3.0 loss_enc = tf.reduce_mean(loss_z + loss_D_llike) loss_gen = tf.reduce_mean(gamma * loss_D_llike - loss_GAN) loss_dis = -tf.reduce_mean(loss_GAN) return { 'x': x, 'z': z, 'x_tilde': decoding_actual['x_tilde'], 'z_samp': z_samp, 'x_tilde_samp': decoding_sampled['x_tilde'], 'loss_real': loss_real, 'loss_fake': loss_fake, 'loss_samp': loss_samp, 'loss_GAN': loss_GAN, 'loss_D_llike': loss_D_llike, 'loss_enc': loss_enc, 'loss_gen': loss_gen, 'loss_dis': loss_dis, 'gamma': gamma }
def encoder(x, n_hidden=None, dimensions=[], filter_sizes=[], convolutional=False, activation=tf.nn.relu, output_activation=tf.nn.sigmoid): """Summary Parameters ---------- x : TYPE Description n_hidden : None, optional Description dimensions : list, optional Description filter_sizes : list, optional Description convolutional : bool, optional Description activation : TYPE, optional Description output_activation : TYPE, optional Description Returns ------- name : TYPE Description """ if convolutional: x_tensor = utils.to_tensor(x) else: x_tensor = tf.reshape(tensor=x, shape=[-1, dimensions[0]]) dimensions = dimensions[1:] current_input = x_tensor Ws = [] hs = [] shapes = [] for layer_i, n_output in enumerate(dimensions): with tf.variable_scope(str(layer_i)): shapes.append(current_input.get_shape().as_list()) if convolutional: h, W = utils.conv2d(x=current_input, n_output=n_output, k_h=filter_sizes[layer_i], k_w=filter_sizes[layer_i], padding='SAME') else: h, W = utils.linear(x=current_input, n_output=n_output) h = activation(h) Ws.append(W) hs.append(h) current_input = h shapes.append(h.get_shape().as_list()) with tf.variable_scope('flatten'): flattened = utils.flatten(current_input) with tf.variable_scope('hidden'): if n_hidden: h, W = utils.linear(flattened, n_hidden, name='linear') h = activation(h) else: h = flattened return {'z': h, 'Ws': Ws, 'hs': hs, 'shapes': shapes}
def VAE(input_shape=[None, 784], n_filters=[64, 64, 64], filter_sizes=[4, 4, 4], n_hidden=32, n_code=2, activation=tf.nn.tanh, convolutional=False, variational=False): """Summary Parameters ---------- input_shape : list, optional Description n_filters : list, optional Description filter_sizes : list, optional Description n_hidden : int, optional Description n_code : int, optional Description activation : TYPE, optional Description convolutional : bool, optional Description variational : bool, optional Description Returns ------- name : TYPE Description """ # network input / placeholders for train (bn) x = tf.placeholder(tf.float32, input_shape, 'x') with tf.variable_scope('encoder'): encoding = encoder(x=x, n_hidden=n_hidden, convolutional=convolutional, dimensions=n_filters, filter_sizes=filter_sizes, activation=activation) if variational: with tf.variable_scope('variational'): z, z_mu, z_log_sigma, loss_z = variational_bayes(h=encoding['z'], n_code=n_code) else: z = encoding['z'] loss_z = None shapes = encoding['shapes'].copy() shapes.reverse() n_filters = n_filters.copy() n_filters.reverse() n_filters += [input_shape[-1]] with tf.variable_scope('generator'): decoding = decoder(z=z, shapes=shapes, n_hidden=n_hidden, dimensions=n_filters, filter_sizes=filter_sizes, convolutional=convolutional, activation=activation) x_tilde = decoding['x_tilde'] x_flat = utils.flatten(x) x_tilde_flat = utils.flatten(x_tilde) # -log(p(x|z)) loss_x = tf.reduce_sum(tf.squared_difference(x_flat, x_tilde_flat), 1) return { 'loss_x': loss_x, 'loss_z': loss_z, 'x': x, 'z': z, 'Ws': encoding['Ws'], 'hs': decoding['hs'], 'x_tilde': x_tilde }
def VAE(input_shape=[None, 784], n_filters=[64, 64, 64], filter_sizes=[4, 4, 4], n_hidden=32, n_code=2, activation=tf.nn.tanh, dropout=False, denoising=False, convolutional=False, variational=False): """(Variational) (Convolutional) (Denoising) Autoencoder. Uses tied weights. Parameters ---------- input_shape : list, optional Shape of the input to the network. e.g. for MNIST: [None, 784]. n_filters : list, optional Number of filters for each layer. If convolutional=True, this refers to the total number of output filters to create for each layer, with each layer's number of output filters as a list. If convolutional=False, then this refers to the total number of neurons for each layer in a fully connected network. filter_sizes : list, optional Only applied when convolutional=True. This refers to the ksize (height and width) of each convolutional layer. n_hidden : int, optional Only applied when variational=True. This refers to the first fully connected layer prior to the variational embedding, directly after the encoding. After the variational embedding, another fully connected layer is created with the same size prior to decoding. Set to 0 to not use an additional hidden layer. n_code : int, optional Only applied when variational=True. This refers to the number of latent Gaussians to sample for creating the inner most encoding. activation : function, optional Activation function to apply to each layer, e.g. tf.nn.relu dropout : bool, optional Whether or not to apply dropout. If using dropout, you must feed a value for 'keep_prob', as returned in the dictionary. 1.0 means no dropout is used. 0.0 means every connection is dropped. Sensible values are between 0.5-0.8. denoising : bool, optional Whether or not to apply denoising. If using denoising, you must feed a value for 'corrupt_prob', as returned in the dictionary. 1.0 means no corruption is used. 0.0 means every feature is corrupted. Sensible values are between 0.5-0.8. convolutional : bool, optional Whether or not to use a convolutional network or else a fully connected network will be created. This effects the n_filters parameter's meaning. variational : bool, optional Whether or not to create a variational embedding layer. This will create a fully connected layer after the encoding, if `n_hidden` is greater than 0, then will create a multivariate gaussian sampling layer, then another fully connected layer. The size of the fully connected layers are determined by `n_hidden`, and the size of the sampling layer is determined by `n_code`. Returns ------- model : dict { 'cost': Tensor to optimize. 'Ws': All weights of the encoder. 'x': Input Placeholder 'z': Inner most encoding Tensor (latent features) 'y': Reconstruction of the Decoder 'keep_prob': Amount to keep when using Dropout 'corrupt_prob': Amount to corrupt when using Denoising 'train': Set to True when training/Applies to Batch Normalization. } """ # network input / placeholders for train (bn) and dropout x = tf.placeholder(tf.float32, input_shape, 'x') phase_train = tf.placeholder(tf.bool, name='phase_train') keep_prob = tf.placeholder(tf.float32, name='keep_prob') corrupt_prob = tf.placeholder(tf.float32, [1]) if denoising: current_input = utils.corrupt(x) * corrupt_prob + x * (1 - corrupt_prob) # 2d -> 4d if convolution x_tensor = utils.to_tensor(x) if convolutional else x current_input = x_tensor Ws = [] shapes = [] # Build the encoder for layer_i, n_output in enumerate(n_filters): with tf.variable_scope('encoder/{}'.format(layer_i)): shapes.append(current_input.get_shape().as_list()) if convolutional: h, W = utils.conv2d( x=current_input, n_output=n_output, k_h=filter_sizes[layer_i], k_w=filter_sizes[layer_i]) else: h, W = utils.linear(x=current_input, n_output=n_output) h = activation(batch_norm(h, phase_train, 'bn' + str(layer_i))) if dropout: h = tf.nn.dropout(h, keep_prob) Ws.append(W) current_input = h shapes.append(current_input.get_shape().as_list()) with tf.variable_scope('variational'): if variational: dims = current_input.get_shape().as_list() flattened = utils.flatten(current_input) if n_hidden: h = utils.linear(flattened, n_hidden, name='W_fc')[0] h = activation(batch_norm(h, phase_train, 'fc/bn')) if dropout: h = tf.nn.dropout(h, keep_prob) else: h = flattened z_mu = utils.linear(h, n_code, name='mu')[0] z_log_sigma = 0.5 * utils.linear(h, n_code, name='log_sigma')[0] # Sample from noise distribution p(eps) ~ N(0, 1) epsilon = tf.random_normal(tf.stack([tf.shape(x)[0], n_code])) # Sample from posterior z = z_mu + tf.multiply(epsilon, tf.exp(z_log_sigma)) if n_hidden: h = utils.linear(z, n_hidden, name='fc_t')[0] h = activation(batch_norm(h, phase_train, 'fc_t/bn')) if dropout: h = tf.nn.dropout(h, keep_prob) else: h = z size = dims[1] * dims[2] * dims[3] if convolutional else dims[1] h = utils.linear(h, size, name='fc_t2')[0] current_input = activation(batch_norm(h, phase_train, 'fc_t2/bn')) if dropout: current_input = tf.nn.dropout(current_input, keep_prob) if convolutional: current_input = tf.reshape(current_input, tf.stack([ tf.shape(current_input)[0], dims[1], dims[2], dims[3] ])) else: z = current_input shapes.reverse() n_filters.reverse() Ws.reverse() n_filters += [input_shape[-1]] # %% # Decoding layers for layer_i, n_output in enumerate(n_filters[1:]): with tf.variable_scope('decoder/{}'.format(layer_i)): shape = shapes[layer_i + 1] if convolutional: h, W = utils.deconv2d( x=current_input, n_output_h=shape[1], n_output_w=shape[2], n_output_ch=shape[3], n_input_ch=shapes[layer_i][3], k_h=filter_sizes[layer_i], k_w=filter_sizes[layer_i]) else: h, W = utils.linear(x=current_input, n_output=n_output) h = activation(batch_norm(h, phase_train, 'dec/bn' + str(layer_i))) if dropout: h = tf.nn.dropout(h, keep_prob) current_input = h y = current_input x_flat = utils.flatten(x) y_flat = utils.flatten(y) # l2 loss loss_x = tf.reduce_sum(tf.squared_difference(x_flat, y_flat), 1) if variational: # variational lower bound, kl-divergence loss_z = -0.5 * tf.reduce_sum(1.0 + 2.0 * z_log_sigma - tf.square(z_mu) - tf.exp(2.0 * z_log_sigma), 1) # add l2 loss cost = tf.reduce_mean(loss_x + loss_z) else: # just optimize l2 loss cost = tf.reduce_mean(loss_x) return { 'cost': cost, 'Ws': Ws, 'x': x, 'z': z, 'y': y, 'keep_prob': keep_prob, 'corrupt_prob': corrupt_prob, 'train': phase_train }
def VAE(input_shape=[None, 784], n_filters=[64, 64, 64], filter_sizes=[4, 4, 4], n_hidden=32, n_code=2, activation=tf.nn.tanh, dropout=False, denoising=False, convolutional=False, variational=False): """(Variational) (Convolutional) (Denoising) Autoencoder. Uses tied weights. Parameters ---------- input_shape : list, optional Shape of the input to the network. e.g. for MNIST: [None, 784]. n_filters : list, optional Number of filters for each layer. If convolutional=True, this refers to the total number of output filters to create for each layer, with each layer's number of output filters as a list. If convolutional=False, then this refers to the total number of neurons for each layer in a fully connected network. filter_sizes : list, optional Only applied when convolutional=True. This refers to the ksize (height and width) of each convolutional layer. n_hidden : int, optional Only applied when variational=True. This refers to the first fully connected layer prior to the variational embedding, directly after the encoding. After the variational embedding, another fully connected layer is created with the same size prior to decoding. Set to 0 to not use an additional hidden layer. n_code : int, optional Only applied when variational=True. This refers to the number of latent Gaussians to sample for creating the inner most encoding. activation : function, optional Activation function to apply to each layer, e.g. tf.nn.relu dropout : bool, optional Whether or not to apply dropout. If using dropout, you must feed a value for 'keep_prob', as returned in the dictionary. 1.0 means no dropout is used. 0.0 means every connection is dropped. Sensible values are between 0.5-0.8. denoising : bool, optional Whether or not to apply denoising. If using denoising, you must feed a value for 'corrupt_prob', as returned in the dictionary. 1.0 means no corruption is used. 0.0 means every feature is corrupted. Sensible values are between 0.5-0.8. convolutional : bool, optional Whether or not to use a convolutional network or else a fully connected network will be created. This effects the n_filters parameter's meaning. variational : bool, optional Whether or not to create a variational embedding layer. This will create a fully connected layer after the encoding, if `n_hidden` is greater than 0, then will create a multivariate gaussian sampling layer, then another fully connected layer. The size of the fully connected layers are determined by `n_hidden`, and the size of the sampling layer is determined by `n_code`. Returns ------- model : dict { 'cost': Tensor to optimize. 'Ws': All weights of the encoder. 'x': Input Placeholder 'z': Inner most encoding Tensor (latent features) 'y': Reconstruction of the Decoder 'keep_prob': Amount to keep when using Dropout 'corrupt_prob': Amount to corrupt when using Denoising 'train': Set to True when training/Applies to Batch Normalization. } """ # network input / placeholders for train (bn) and dropout x = tf.placeholder(tf.float32, input_shape, 'x') phase_train = tf.placeholder(tf.bool, name='phase_train') keep_prob = tf.placeholder(tf.float32, name='keep_prob') corrupt_prob = tf.placeholder(tf.float32, [1]) if denoising: current_input = utils.corrupt(x) * corrupt_prob + x * (1 - corrupt_prob) # 2d -> 4d if convolution x_tensor = utils.to_tensor(x) if convolutional else x current_input = x_tensor Ws = [] shapes = [] # Build the encoder for layer_i, n_output in enumerate(n_filters): with tf.variable_scope('encoder/{}'.format(layer_i)): shapes.append(current_input.get_shape().as_list()) if convolutional: h, W = utils.conv2d(x=current_input, n_output=n_output, k_h=filter_sizes[layer_i], k_w=filter_sizes[layer_i]) else: h, W = utils.linear(x=current_input, n_output=n_output) h = activation(batch_norm(h, phase_train, 'bn' + str(layer_i))) if dropout: h = tf.nn.dropout(h, keep_prob) Ws.append(W) current_input = h shapes.append(current_input.get_shape().as_list()) with tf.variable_scope('variational'): if variational: dims = current_input.get_shape().as_list() flattened = utils.flatten(current_input) if n_hidden: h = utils.linear(flattened, n_hidden, name='W_fc')[0] h = activation(batch_norm(h, phase_train, 'fc/bn')) if dropout: h = tf.nn.dropout(h, keep_prob) else: h = flattened z_mu = utils.linear(h, n_code, name='mu')[0] z_log_sigma = 0.5 * utils.linear(h, n_code, name='log_sigma')[0] # Sample from noise distribution p(eps) ~ N(0, 1) epsilon = tf.random_normal(tf.stack([tf.shape(x)[0], n_code])) # Sample from posterior z = z_mu + tf.multiply(epsilon, tf.exp(z_log_sigma)) if n_hidden: h = utils.linear(z, n_hidden, name='fc_t')[0] h = activation(batch_norm(h, phase_train, 'fc_t/bn')) if dropout: h = tf.nn.dropout(h, keep_prob) else: h = z size = dims[1] * dims[2] * dims[3] if convolutional else dims[1] h = utils.linear(h, size, name='fc_t2')[0] current_input = activation(batch_norm(h, phase_train, 'fc_t2/bn')) if dropout: current_input = tf.nn.dropout(current_input, keep_prob) if convolutional: current_input = tf.reshape( current_input, tf.stack([ tf.shape(current_input)[0], dims[1], dims[2], dims[3] ])) else: z = current_input shapes.reverse() n_filters.reverse() Ws.reverse() n_filters += [input_shape[-1]] # %% # Decoding layers for layer_i, n_output in enumerate(n_filters[1:]): with tf.variable_scope('decoder/{}'.format(layer_i)): shape = shapes[layer_i + 1] if convolutional: h, W = utils.deconv2d(x=current_input, n_output_h=shape[1], n_output_w=shape[2], n_output_ch=shape[3], n_input_ch=shapes[layer_i][3], k_h=filter_sizes[layer_i], k_w=filter_sizes[layer_i]) else: h, W = utils.linear(x=current_input, n_output=n_output) h = activation(batch_norm(h, phase_train, 'dec/bn' + str(layer_i))) if dropout: h = tf.nn.dropout(h, keep_prob) current_input = h y = current_input x_flat = utils.flatten(x) y_flat = utils.flatten(y) # l2 loss loss_x = tf.reduce_sum(tf.squared_difference(x_flat, y_flat), 1) if variational: # variational lower bound, kl-divergence loss_z = -0.5 * tf.reduce_sum( 1.0 + 2.0 * z_log_sigma - tf.square(z_mu) - tf.exp(2.0 * z_log_sigma), 1) # add l2 loss cost = tf.reduce_mean(loss_x + loss_z) else: # just optimize l2 loss cost = tf.reduce_mean(loss_x) return { 'cost': cost, 'Ws': Ws, 'x': x, 'z': z, 'y': y, 'keep_prob': keep_prob, 'corrupt_prob': corrupt_prob, 'train': phase_train }
def encoder(x, dimensions=[], filter_sizes=[], convolutional=False, activation=tf.nn.relu, output_activation=tf.nn.sigmoid, reuse=False): """Encoder network codes input `x` to layers defined by dimensions. Parameters ---------- x : tf.Tensor Input to the encoder network, e.g. tf.Placeholder or tf.Variable dimensions : list, optional List of the number of neurons in each layer (convolutional=False) -or- List of the number of filters in each layer (convolutional=True), e.g. [100, 100, 100, 100] for a 4-layer deep network with 100 in each layer. filter_sizes : list, optional List of the size of the kernel in each layer, e.g.: [3, 3, 3, 3] is a 4-layer deep network w/ 3 x 3 kernels in every layer. convolutional : bool, optional Whether or not to use convolutional layers. activation : fn, optional Function for applying an activation, e.g. tf.nn.relu output_activation : fn, optional Function for applying an activation on the last layer, e.g. tf.nn.relu reuse : bool, optional For each layer's variable scope, whether to reuse existing variables. Returns ------- h : tf.Tensor Output tensor of the encoder """ # %% # ensure 2-d is converted to square tensor. if convolutional: x_tensor = utils.to_tensor(x) else: x_tensor = tf.reshape(tensor=x, shape=[-1, dimensions[0]]) dimensions = dimensions[1:] current_input = x_tensor for layer_i, n_output in enumerate(dimensions): with tf.variable_scope(str(layer_i), reuse=reuse): if convolutional: h, W = utils.conv2d( x=current_input, n_output=n_output, k_h=filter_sizes[layer_i], k_w=filter_sizes[layer_i], padding='SAME', reuse=reuse) else: h, W = utils.linear( x=current_input, n_output=n_output, reuse=reuse) output = activation(h) current_input = output flattened = utils.flatten(current_input, name='flatten', reuse=reuse) if output_activation is None: return flattened else: return output_activation(flattened)
def encoder(x, dimensions=[], filter_sizes=[], convolutional=False, activation=tf.nn.relu, output_activation=tf.nn.sigmoid, reuse=False): """Encoder network codes input `x` to layers defined by dimensions. Parameters ---------- x : tf.Tensor Input to the encoder network, e.g. tf.Placeholder or tf.Variable dimensions : list, optional List of the number of neurons in each layer (convolutional=False) -or- List of the number of filters in each layer (convolutional=True), e.g. [100, 100, 100, 100] for a 4-layer deep network with 100 in each layer. filter_sizes : list, optional List of the size of the kernel in each layer, e.g.: [3, 3, 3, 3] is a 4-layer deep network w/ 3 x 3 kernels in every layer. convolutional : bool, optional Whether or not to use convolutional layers. activation : fn, optional Function for applying an activation, e.g. tf.nn.relu output_activation : fn, optional Function for applying an activation on the last layer, e.g. tf.nn.relu reuse : bool, optional For each layer's variable scope, whether to reuse existing variables. Returns ------- h : tf.Tensor Output tensor of the encoder """ # %% # ensure 2-d is converted to square tensor. if convolutional: x_tensor = utils.to_tensor(x) else: x_tensor = tf.reshape(tensor=x, shape=[-1, dimensions[0]]) dimensions = dimensions[1:] current_input = x_tensor for layer_i, n_output in enumerate(dimensions): with tf.variable_scope(str(layer_i), reuse=reuse): if convolutional: h, W = utils.conv2d(x=current_input, n_output=n_output, k_h=filter_sizes[layer_i], k_w=filter_sizes[layer_i], padding='SAME', reuse=reuse) else: h, W = utils.linear(x=current_input, n_output=n_output, reuse=reuse) output = activation(h) current_input = output flattened = utils.flatten(current_input, name='flatten', reuse=reuse) if output_activation is None: return flattened else: return output_activation(flattened)
def VAEGAN(input_shape=[None, 784], n_filters=[64, 64, 64], filter_sizes=[4, 4, 4], n_hidden=32, n_code=2, activation=tf.nn.tanh, convolutional=False, variational=False): """Summary Parameters ---------- input_shape : list, optional Description n_filters : list, optional Description filter_sizes : list, optional Description n_hidden : int, optional Description n_code : int, optional Description activation : TYPE, optional Description convolutional : bool, optional Description variational : bool, optional Description Returns ------- name : TYPE Description """ # network input / placeholders for train (bn) x = tf.placeholder(tf.float32, input_shape, 'x') z_samp = tf.placeholder(tf.float32, [None, n_code], 'z_samp') with tf.variable_scope('encoder'): encoding = encoder( x=x, n_hidden=n_hidden, convolutional=convolutional, dimensions=n_filters, filter_sizes=filter_sizes, activation=activation) with tf.variable_scope('variational'): z, z_mu, z_log_sigma, loss_z = variational_bayes( h=encoding['z'], n_code=n_code) shapes = encoding['shapes'].copy() shapes.reverse() n_filters_decoder = n_filters.copy() n_filters_decoder.reverse() n_filters_decoder += [input_shape[-1]] with tf.variable_scope('generator'): decoding_actual = decoder( z=z, shapes=shapes, n_hidden=n_hidden, convolutional=convolutional, dimensions=n_filters_decoder, filter_sizes=filter_sizes, activation=activation) with tf.variable_scope('generator', reuse=True): decoding_sampled = decoder( z=z_samp, shapes=shapes, n_hidden=n_hidden, convolutional=convolutional, dimensions=n_filters_decoder, filter_sizes=filter_sizes, activation=activation) with tf.variable_scope('discriminator'): D_real = discriminator( x, filter_sizes=filter_sizes, n_filters=n_filters, activation=activation) with tf.variable_scope('discriminator', reuse=True): D_fake = discriminator( decoding_actual['x_tilde'], filter_sizes=filter_sizes, n_filters=n_filters, activation=activation) with tf.variable_scope('discriminator', reuse=True): D_samp = discriminator( decoding_sampled['x_tilde'], filter_sizes=filter_sizes, n_filters=n_filters, activation=activation) with tf.variable_scope('loss'): # Weights influence of content/style of decoder gamma = tf.placeholder(tf.float32, name='gamma') # Discriminator_l Log Likelihood Loss loss_D_llike = 0 for h_fake, h_real in zip(D_fake['hs'][3:], D_real['hs'][3:]): loss_D_llike += tf.reduce_sum(0.5 * tf.squared_difference( utils.flatten(h_fake), utils.flatten(h_real)), 1) # GAN Loss eps = 1e-12 loss_real = tf.reduce_sum(tf.log(D_real['probs'] + eps), 1) loss_fake = tf.reduce_sum(tf.log(1 - D_fake['probs'] + eps), 1) loss_samp = tf.reduce_sum(tf.log(1 - D_samp['probs'] + eps), 1) loss_GAN = (loss_real + loss_fake + loss_samp) / 3.0 loss_enc = tf.reduce_mean(loss_z + loss_D_llike) loss_gen = tf.reduce_mean(gamma * loss_D_llike - loss_GAN) loss_dis = -tf.reduce_mean(loss_GAN) return { 'x': x, 'z': z, 'x_tilde': decoding_actual['x_tilde'], 'z_samp': z_samp, 'x_tilde_samp': decoding_sampled['x_tilde'], 'loss_real': loss_real, 'loss_fake': loss_fake, 'loss_samp': loss_samp, 'loss_GAN': loss_GAN, 'loss_D_llike': loss_D_llike, 'loss_enc': loss_enc, 'loss_gen': loss_gen, 'loss_dis': loss_dis, 'gamma': gamma }
def encoder(x, n_hidden=None, dimensions=[], filter_sizes=[], convolutional=False, activation=tf.nn.relu, output_activation=tf.nn.sigmoid): """Summary Parameters ---------- x : TYPE Description n_hidden : None, optional Description dimensions : list, optional Description filter_sizes : list, optional Description convolutional : bool, optional Description activation : TYPE, optional Description output_activation : TYPE, optional Description Returns ------- name : TYPE Description """ if convolutional: x_tensor = utils.to_tensor(x) else: x_tensor = tf.reshape(tensor=x, shape=[-1, dimensions[0]]) dimensions = dimensions[1:] current_input = x_tensor Ws = [] hs = [] shapes = [] for layer_i, n_output in enumerate(dimensions): with tf.variable_scope(str(layer_i)): shapes.append(current_input.get_shape().as_list()) if convolutional: h, W = utils.conv2d( x=current_input, n_output=n_output, k_h=filter_sizes[layer_i], k_w=filter_sizes[layer_i], padding='SAME') else: h, W = utils.linear(x=current_input, n_output=n_output) h = activation(h) Ws.append(W) hs.append(h) current_input = h shapes.append(h.get_shape().as_list()) with tf.variable_scope('flatten'): flattened = utils.flatten(current_input) with tf.variable_scope('hidden'): if n_hidden: h, W = utils.linear(flattened, n_hidden, name='linear') h = activation(h) else: h = flattened return {'z': h, 'Ws': Ws, 'hs': hs, 'shapes': shapes}
def VAE(input_shape=[None, 784], n_filters=[64, 64, 64], filter_sizes=[4, 4, 4], n_hidden=32, n_code=2, activation=tf.nn.tanh, convolutional=False, variational=False): """Summary Parameters ---------- input_shape : list, optional Description n_filters : list, optional Description filter_sizes : list, optional Description n_hidden : int, optional Description n_code : int, optional Description activation : TYPE, optional Description convolutional : bool, optional Description variational : bool, optional Description Returns ------- name : TYPE Description """ # network input / placeholders for train (bn) x = tf.placeholder(tf.float32, input_shape, 'x') with tf.variable_scope('encoder'): encoding = encoder( x=x, n_hidden=n_hidden, convolutional=convolutional, dimensions=n_filters, filter_sizes=filter_sizes, activation=activation) if variational: with tf.variable_scope('variational'): z, z_mu, z_log_sigma, loss_z = variational_bayes( h=encoding['z'], n_code=n_code) else: z = encoding['z'] loss_z = None shapes = encoding['shapes'].copy() shapes.reverse() n_filters = n_filters.copy() n_filters.reverse() n_filters += [input_shape[-1]] with tf.variable_scope('generator'): decoding = decoder( z=z, shapes=shapes, n_hidden=n_hidden, dimensions=n_filters, filter_sizes=filter_sizes, convolutional=convolutional, activation=activation) x_tilde = decoding['x_tilde'] x_flat = utils.flatten(x) x_tilde_flat = utils.flatten(x_tilde) # -log(p(x|z)) loss_x = tf.reduce_sum(tf.squared_difference(x_flat, x_tilde_flat), 1) return { 'loss_x': loss_x, 'loss_z': loss_z, 'x': x, 'z': z, 'Ws': encoding['Ws'], 'hs': decoding['hs'], 'x_tilde': x_tilde }