<jupyter_start><jupyter_text>SRGAN (Super-Resolution Generative Adversarial Network)A tensorflow implementation of "Photo-Realistic Single Image Super-Resolution Using a Generative Adversarial Network" paper (https://arxiv.org/abs/1609.04802). This implementation is quite different from original paper. The differences are as followings:1. MNIST data set is used for convenience.2. Replaced MSE loss with GAN using tuple input for discriminator.3. Used sub-pixel CNN instead of deconvolution. (see : http://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Shi_Real-Time_Single_Image_CVPR_2016_paper.pdf)The existing CNN based super-resolution skill mainly use MSE loss and this makes super-resolved images look blurry. If we replace MSE loss with gradients from GAN, we may prevent the blurry artifacts of the super-resolved images and this is the key idea of this paper. CreditsCredits for this code goes to https://github.com/buriburisuri/.<jupyter_code>import sugartensor as tf
import numpy as np
# set log level to debug
tf.sg_verbosity(10)
# hyper parameters
batch_size = 32
# MNIST input tensor (with QueueRunner)
data = tf.sg_data.Mnist(batch_size=batch_size)

# input images
x = data.train.image

# low resolution image
x_small = tf.image.resize_bicubic(x, (14, 14))
x_nearest = tf.image.resize_images(x_small, (28, 28), tf.image.ResizeMethod.NEAREST_NEIGHBOR)

# generator labels (all ones)
y = tf.ones(batch_size, dtype=tf.sg_floatx)

# discriminator labels (half 1s, half 0s)
y_disc = tf.concat([y, y * 0], 0, name='concat')
# generator network
with tf.sg_context(name='generator', act='relu', bn=True):
    gen = (x_small
           .sg_conv(dim=32)
           .sg_conv()
           .sg_conv(dim=4, act='sigmoid', bn=False)
           .sg_periodic_shuffle(factor=2))
    
# add image summary
tf.sg_summary_image(gen)
# input image pairs
x_real_pair = tf.concat([x_nearest, x], 3, name='concat')
x_fake_pair = tf.concat([x_nearest, gen], 3, name='concat')
# create discriminator & recognizer

# create real + fake image input
xx = tf.concat([x_real_pair, x_fake_pair], 0, name='concat')

with tf.sg_context(name='discriminator', size=4, stride=2, act='leaky_relu'):
    # discriminator part
    disc = (xx.sg_conv(dim=64)
              .sg_conv(dim=128)
              .sg_flatten()
              .sg_dense(dim=1024)
              .sg_dense(dim=1, act='linear')
              .sg_squeeze())
# loss and train ops
loss_disc = tf.reduce_mean(disc.sg_bce(target=y_disc))  # discriminator loss
loss_gen = tf.reduce_mean(disc.sg_reuse(input=x_fake_pair).sg_bce(target=y))  # generator loss

train_disc = tf.sg_optim(loss_disc, lr=0.0001, category='discriminator')  # discriminator train ops
train_gen = tf.sg_optim(loss_gen, lr=0.001, category='generator')  # generator train ops
# training

# def alternate training func
@tf.sg_train_func
def alt_train(sess, opt):
    l_disc = sess.run([loss_disc, train_disc])[0]  # training discriminator
    l_gen = sess.run([loss_gen, train_gen])[0]  # training generator
    return np.mean(l_disc) + np.mean(l_gen)

# do training
alt_train(log_interval=10, max_ep=20, ep_size=data.train.num_batch, early_stop=False)<jupyter_output>INFO:tensorflow:Restoring parameters from asset/train/model.ckpt-17385
{'fraction_non_alphanumeric': 0.11029185867895545, 'fraction_numerical': 0.02304147465437788, 'mean_word_length': 4.633217993079585, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, 'https://': 2, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '89874', 'license': 'MIT', 'n_tokens_mistral': 1168, 'n_tokens_neox': 1092, 'n_words': 283, 'path': 'section_3/02_srgan/train.ipynb', 'repo_name': 'PacktPublishing/Hands-on-Artificial-Intelligence-with-TensorFlow', 'size': '3255'}