Spaces:
Running
Running
| # Install gradio | |
| # Import necessary libs | |
| import tensorflow as tf | |
| import keras | |
| import numpy as np | |
| # Load the VGG19 model | |
| from keras.applications.vgg19 import VGG19 | |
| from keras.applications.vgg19 import preprocess_input, decode_predictions | |
| model = VGG19(include_top=False, weights='imagenet') | |
| # Define style layers and content layers for VGG19 | |
| content_layers = 'block5_conv2' | |
| style_layers = ['block1_conv1', | |
| 'block2_conv1', | |
| 'block3_conv1', | |
| 'block4_conv1', | |
| 'block5_conv1'] | |
| num_content_layers = len(content_layers) | |
| num_style_layers = len(style_layers) | |
| # Model for extracting style feature | |
| style_model = keras.Model(inputs=model.input, outputs=[model.get_layer(name).output for name in style_layers], name='Style_model') | |
| # Model for extracting content feature | |
| content_model = keras.Model(inputs=model.input, outputs=model.get_layer(content_layers).output, name='Content_model') | |
| # Style model summary | |
| print(f'Style model: {style_model.name}') | |
| style_model.summary() | |
| # Content model summary | |
| print(f'Content model: {content_model.name}') | |
| content_model.summary() | |
| # Compute content loss | |
| def content_loss(gen, content_img): | |
| return tf.reduce_sum(tf.square(content_img - gen)) | |
| # Gram matrix | |
| def gram_matrix(image): | |
| # Reshape image to 2-D array | |
| channel = image.shape[-1] # Number of channels | |
| a = tf.reshape(image, [-1, channel]) | |
| # Compute Gram matrix corresponding to the input image | |
| dimension = a.shape[0] # Dimension M*N of an MxNxc image | |
| return tf.matmul(a, a, transpose_a=True) / tf.cast(dimension, tf.float32) | |
| # Style loss | |
| def style_loss(gen, style_img): | |
| total_loss = 0. | |
| for i in range(len(gen)): | |
| gen_gram = gram_matrix(gen[i]) | |
| style_gram = gram_matrix(style_img[i]) | |
| # Compute style loss | |
| total_loss += tf.reduce_sum(tf.square(gen_gram-style_gram))/4 | |
| return total_loss | |
| # Training parameter | |
| lr = 10. | |
| optimizer = keras.optimizers.Adam(lr) | |
| alpha = 1e-7 | |
| beta = 1e-10 | |
| style_weight = len(style_layers) | |
| # Train step | |
| def train_step(image, process_content_image, process_style_image): | |
| with tf.GradientTape() as tape: | |
| # Calculate content loss | |
| gen_content_feature = content_model(image) | |
| content_feature = content_model(process_content_image) | |
| loss_content = content_loss(gen_content_feature, content_feature) | |
| # Calculate style loss | |
| gen_style_feature = style_model(image) | |
| style_feature = style_model(process_style_image) | |
| loss_style = style_loss(gen_style_feature, style_feature) | |
| # Calculate total loss | |
| total_loss = alpha*loss_content + beta*loss_style/style_weight | |
| # Calculate gradient | |
| grad = tape.gradient(total_loss, image) | |
| # Apply gradient | |
| optimizer.apply_gradients([(grad, image)]) | |
| # Return loss for visualize | |
| return total_loss | |
| # Deprocess image | |
| def deprocess_image(x): | |
| # Util function to convert a tensor into a valid image | |
| x = x.reshape((256,256,3)) | |
| # Remove zero-center by mean pixel | |
| x[:, :, 0] += 103.939 | |
| x[:, :, 1] += 116.779 | |
| x[:, :, 2] += 123.68 | |
| # 'BGR'->'RGB' | |
| x = x[:, :, ::-1] | |
| x = np.clip(x, 0, 255).astype("uint8") | |
| return x | |
| def load_image(image, RESO=256): | |
| image = tf.image.convert_image_dtype(image, tf.float32) * 255 | |
| image = tf.image.resize(image,[RESO, RESO],method=tf.image.ResizeMethod.BICUBIC) | |
| image = tf.expand_dims(preprocess_input(image), 0) | |
| return image | |
| def style_transfer(content_image, style_image, step=100): | |
| process_content_image = load_image(content_image) | |
| process_style_image = load_image(style_image) | |
| generate_image = tf.Variable(process_content_image, trainable=True) | |
| for step in range(1, step+1): | |
| # Train step | |
| loss = train_step(generate_image, process_content_image, process_style_image) | |
| return deprocess_image(generate_image[0].numpy()) | |
| import gradio as gr | |
| demo = gr.Interface( | |
| fn=style_transfer, | |
| inputs=[gr.Image(label='Input Image'), gr.Image(label='Style Image'), gr.Slider(10, 200, 50, step=10, label='Step', show_label=True)], | |
| outputs=gr.Image(label='Style Transfer Image'), | |
| ) | |
| demo.launch(debug=True, share=True) |