Assignment #4 - Neural Style Transfer

Jialu Gao (jialug)
2024 Spring, 16-726 Learning-based Image Synthesis

Description

In this project, we implement neural style transfer which can transfer specific contents to resemble a certain artistic style. For the first part, we will optimize random noise in content space to get familiar with optimizing pixels to content losses. For the second part, we will optimize random noise to match the textures of the style image. Then for the final part, we combine the first two steps and optimize some input image (initialized from random noise or content image) to match the artistic style of the style reference image.

 

For Bells & Whistles, I will first stylize the Poisson blended images from the previous homework. And then I will try using image editing methods for style transformation and compare the results.

Part 1:

Implementation

In this part, we will use content loss to reconstruct the content image from random noise.

Results

1. Report the effect of optimizing content loss at different layers

I am using the fallingwater.png as content image and trying to reconstruct the image using content loss only. The content loss measures the content distance between two images at some individual layer in the VGG19 feature layers. We first sample random noise as the original input image, and then optimize this input image in pixel space using the content loss. The content loss measures the MSE distance of the features after certain convolutional layers for the input image and the content image. By backpropagating through the loss, we are optimizing the input image to be more similar to the content image. To implement this loss, I insert a content_loss layer after the convolutional layers specified below.

 

Since the style image and content image should be of the same size, I am cropping all images to be size (512, 512).

 

Image 1
FallingWater
Conv2 Conv4
Image 1 Image 1
Conv6 Conv8
Image 1 Image 2

 

From the results we can observe that when the layer is the more shallow layers such as Conv2, the reconstruction is almost identical to the original image. When the layer is deeper, the reconstructed image have more noise.

 

I choose Conv4 as my favorite layer because it preserve decent content information and also removes some textures of the content image, which will be better for further style transfer.

2. Results with my favorite layer

With content loss inserted after Conv4, I use fallingwater.png and dancing.jpg as two content images and select two different seed to generate the initial noise as two input images, and optimize them with content loss.
Content Image Seed=42, Conv4 Seed=17, Conv4
Image 1 Image 1 Image 1
Image 1 Image 1 Image 2

 

For using random seed 42 and 17, the differences are minor for both content images and we can observe that both seeds preserve the structure of the content image very well. This demonstrate the model's robustness.

Part 2: Texture Synthesis

Implementation

In this part, we will implement style_loss to perform texture synthesis from random noise. We initialize the input image to be some random noise, and take a style image as reference where we want the input image to synthesize the textures of the style image. The style image and the input image is both fed through the VGG19 feature extrator, and after some specific convolutional layers, we measure the difference of the extracted features of the style image and the input image using Gram matrix. Then Gram matrix is a square matrix obtained by multiplying the featrure matrixx with its transpose, and can capture the statistical relationship between the two extracted features in terms of texture and pattern.

 

To implement the style_loss, I calculate the Gram matrix as described and calculate the MSE distance between that of the input image and the style image. The style_loss is inserted after each of the specified convolutional layers below.

Results

1. Report the effect of optimizing texture loss at different layers

For the configurations, I am only using the style loss with a weight of 100000, and a default num_steps=300. For random noise generation, I am using seed=42 to generate the noise as input image.

 

For the style image, I am using the frida_kahlo.jpeg and trying to learn the textures represented in this image.

 

Image 1
Frida Kahlo

 

Conv1 Conv2 Conv4
Image 1 Image 1 Image 1
Conv6 Conv8 Conv1-Conv5
Image 1 Image 1 Image 1

 

From the results, we can see that the shallow layers will lead to blurry textures that don't have enough resemblence to the reference style image. However, when the layer goes deeper, the noise level will also be too high to observe the textures. Therefore, I am selecting Conv1-Conv5 as the layers after which I insert the style_loss, and as shown in the table, this can lead to synthesized textures that well preserve the original texture information.

2. Results of different random noises

For generating different random noises, I am using seed=42 and seed=17 to get two input images and optimize them only with style loss for the style image picasso.jpg and frida_kahlo.jpeg.
Style Image seed=42, Conv1-Conv5 seed=17, Conv1-Conv5
Image 1 Image 1 Image 1
Image 1 Image 1 Image 1

 

We can observe that for different seeds, the synthesized textures are pretty similar with each other, which shows that our style_loss is robust enough to learn texture information from style images.

Part 3: Style Transfer

In this part, we are combining the first two steps and actually learn an input image from content image and style image to transfer that content image to be of similar style of the style image.

 

In my implementation, I am enabling style_loss and content_loss, and I make sure that the Gram matrix is normalized over feature pixels. From the previous experiments, I am using Conv4 for content_loss, and Conv1-5 for style_loss. The hyper-parameters that we need to tune is the content_weight and the style_weight for content_loss and style_loss separately.

 

Tune the Hyper-parameters

Here I try to tune the hyper-parameters of the loss weights. For implementation, I am initializing the input image as the content image and then perform the optimization. For hyper-parameters, I am using content_weight=1, and altering style_weight to see if which value will lead to better performance.

 

Content Image Style Image
Image 1 Image 1

 

 

Style_weight=100 Style_weight=1000 Style_weight=10000
Image 1 Image 1 Image 1
Style_weight=100000 Style_weight=200000 Style_weight=500000
Image 1 Image 1 Image 1

 

As shown in the table, we can see that with smaller style_weight, the generated image will look very similar to the content image and doesn't capture the style. For larger style_weight, the image will look too different in terms of structure to the content image. Therefore, I choose 100000 and sometimes 200000 as the optimal hyper-parameter for the following experiments.

 

3 * 3 Table Results

Here I report the results that are optimized from two content images mixing with two style images accordingly. I have also included the content and style image in the table.

 

Content Image\Style Image Image 1 Image 1 Image 1
Image 1 Image 1 Image 1 Image 1
Image 1 Image 1 Image 1 Image 1
Image 1 Image 1 Image 1 Image 1

 

 

 

From Random Noise as Input

Image 1 Image 1 Image 1
Random Noise Input Image 1 Image 1 Image 1
Content Image Input Image 1 Image 1 Image 1
Random Noise Input Image 1 Image 1 Image 1
Content Image Input Image 1 Image 1 Image 1

 

From the results above, we can see that style transfer from a noise image leads to lower quality in generated image as the image is more blurry and with more noise. In contrast, the image initialized through the content image has better quality and preserves more details of the content image.

 

For the computational efficiency, with num_stepe=10, the random noise initialization takes about 17 seconds on average, and the content image initialization takes 14 seconds on average. This is because when we initialize the input image with the content image, the gap for the content_loss optimization is smaller and we don't need to perform a lot of optimizations on the pixels as we would from scratch if we use random noise as initialization.

 

Results on My Own Images

Here I present several of my own images as the content image and perform style transfer with the style images.

 

Content Image Style Image Output Image
Image 1 Image 1 Image 1
Image 1 Image 1 Image 1
Image 1 Image 1 Image 1
Image 1 Image 1 Image 1
Image 1 Image 1 Image 1
Image 1 Image 1 Image 1

 

 

Bells & Whistles

1. Stylize the Poisson blended images

I select two samples generate in Assignment 2 where we use Poisson blending to fuse two images together, and perform style transfer. The results are shown in the following table.

 

Content Image Style Image Output Image
Image 1 Image 1 Image 1
Image 1 Image 1 Image 1
Image 1 Image 1 Image 1
Image 1 Image 1 Image 1
Image 1 Image 1 Image 1
Image 1 Image 1 Image 1

 

 

2. Image Editing Models for Style Transfer

Recent years, we have a lot of generation models that are trained with huge amounts of data, and can generate stylized images given text prompts. Based on these generation models, there are also image editing models that can condition the generated images on some input image and text prompt.

 

InstructPix2pix is one of the most recent work that can perform image editing in an end-to-end fashion without any fine-tuning. Therefore, I am testing the InstructPix2pix model's performance on the style transfer task.

 

For the prompt for InstructPix2pix, I am using "Make it a picasso painting." and "Turn this into the style of starry night of Van Gogh."

 

Target Style Content Image InstructPix2pix Output Style Transfer Output
Picasso Painting Image 1 Image 1 Image 1
Picasso Painting Image 1 Image 1 Image 1
Picasso Painting Image 1 Image 1 Image 1
Picasso Painting Image 1 Image 1 Image 1
Van Gogh Starry Night Image 1 Image 1 Image 1
Van Gogh Starry Night Image 1 Image 1 Image 1
Van Gogh Starry Night Image 1 Image 1 Image 1
Van Gogh Starry Night Image 1 Image 1 Image 1

 

From the results, we can observe that InstructPix2pix have troubles keeping the original structure of the content image, but can apply the style changes most of the time. While the style transfer method we implemented always keep the original structure and details of the content image, it sometimes cannot make obvious or significant style transfer. Moreover, one of the advantage of InstructPix2pix is that, we don't actually need a reference image to perform the style transfer. Although text descriptions have ambiguitiy, it is much easier to collect.

 

For computation statistics, the inference time for InstructPix2pix on A4500 is 15-16 seconds on average, which is about the same as running style transfer with 10 optimization steps. But the memory requirement for InstructPix2pix is about 18GB, while the requirement for style transfer is much smaller.

 

Overall, the end-to-end models usually have less guarantee on the output image structures, but generally are more creative and more prone to make huge changes. The style_loss and content_loss guided style transfer have more guarantee in the generated image's resemblence to the content image, and generally will pick up exactly the textural details of the provided style image.