neural_style/neural_style_tensor/style_transfer.ipynb

1775 lines
4.5 MiB
Plaintext
Raw Normal View History

2024-02-23 19:22:37 +01:00
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "g_nWetWWd_ns"
},
"source": [
"##### Copyright 2018 The TensorFlow Authors."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"cellView": "form",
"execution": {
"iopub.execute_input": "2023-11-16T03:34:40.659665Z",
"iopub.status.busy": "2023-11-16T03:34:40.659217Z",
"iopub.status.idle": "2023-11-16T03:34:40.663044Z",
"shell.execute_reply": "2023-11-16T03:34:40.662455Z"
},
"id": "2pHVBk_seED1"
},
"outputs": [],
"source": [
"#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",
"# You may obtain a copy of the License at\n",
"#\n",
"# https://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "6msVLevwcRhm"
},
"source": [
"# Neural style transfer"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Ds4o1h4WHz9U"
},
"source": [
"<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://www.tensorflow.org/tutorials/generative/style_transfer\"><img src=\"https://www.tensorflow.org/images/tf_logo_32px.png\" />View on TensorFlow.org</a>\n",
" </td>\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://colab.research.google.com/github/tensorflow/docs/blob/master/site/en/tutorials/generative/style_transfer.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
" </td>\n",
" <td>\n",
" <a target=\"_blank\" href=\"https://github.com/tensorflow/docs/blob/master/site/en/tutorials/generative/style_transfer.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View on GitHub</a>\n",
" </td>\n",
" <td>\n",
" <a href=\"https://storage.googleapis.com/tensorflow_docs/docs/site/en/tutorials/generative/style_transfer.ipynb\"><img src=\"https://www.tensorflow.org/images/download_logo_32px.png\" />Download notebook</a>\n",
" </td>\n",
" <td>\n",
" <a href=\"https://tfhub.dev/google/magenta/arbitrary-image-stylization-v1-256/2\"><img src=\"https://www.tensorflow.org/images/hub_logo_32px.png\" />See TF Hub model</a>\n",
" </td>\n",
"</table>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "aDyGj8DmXCJI"
},
"source": [
"This tutorial uses deep learning to compose one image in the style of another image (ever wish you could paint like Picasso or Van Gogh?). This is known as *neural style transfer* and the technique is outlined in <a href=\"https://arxiv.org/abs/1508.06576\" class=\"external\">A Neural Algorithm of Artistic Style</a> (Gatys et al.). \n",
"\n",
"Note: This tutorial demonstrates the original style-transfer algorithm. It optimizes the image content to a particular style. Modern approaches train a model to generate the stylized image directly (similar to [CycleGAN](./cyclegan.ipynb)). This approach is much faster (up to 1000x).\n",
"\n",
"For a simple application of style transfer with a pretrained model from [TensorFlow Hub](https://tfhub.dev), check out the [Fast style transfer for arbitrary styles](https://www.tensorflow.org/hub/tutorials/tf2_arbitrary_image_stylization) tutorial that uses an [arbitrary image stylization model](https://tfhub.dev/google/magenta/arbitrary-image-stylization-v1-256/2). For an example of style transfer with [TensorFlow Lite](https://www.tensorflow.org/lite), refer to [Artistic style transfer with TensorFlow Lite](https://www.tensorflow.org/lite/examples/style_transfer/overview)."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "1b3XwN9V1nvR"
},
"source": [
"Neural style transfer is an optimization technique used to take two images—a *content* image and a *style reference* image (such as an artwork by a famous painter)—and blend them together so the output image looks like the content image, but “painted” in the style of the style reference image.\n",
"\n",
"This is implemented by optimizing the output image to match the content statistics of the content image and the style statistics of the style reference image. These statistics are extracted from the images using a convolutional network."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "28W8ggyO1KER"
},
"source": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "3kb_UJY-jCEl"
},
"source": [
"For example, lets take an image of this dog and Wassily Kandinsky's Composition 7:\n",
"\n",
"<img src=\"https://storage.googleapis.com/download.tensorflow.org/example_images/YellowLabradorLooking_new.jpg\" width=\"500px\"/>\n",
"\n",
"[Yellow Labrador Looking](https://commons.wikimedia.org/wiki/File:YellowLabradorLooking_new.jpg), from Wikimedia Commons by [Elf](https://en.wikipedia.org/wiki/User:Elf). License [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/deed.en)\n",
"\n",
"<img src=\"https://storage.googleapis.com/download.tensorflow.org/example_images/Vassily_Kandinsky%2C_1913_-_Composition_7.jpg\" width=\"500px\"/>\n",
"\n",
"\n",
"Now, what would it look like if Kandinsky decided to paint the picture of this Dog exclusively with this style? Something like this?\n",
"\n",
"<img src=\"https://tensorflow.org/tutorials/generative/images/stylized-image.png\" style=\"width: 500px;\"/>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "U8ajP_u73s6m"
},
"source": [
"## Setup\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "eqxUicSPUOP6"
},
"source": [
"### Import and configure modules"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:34:40.667189Z",
"iopub.status.busy": "2023-11-16T03:34:40.666636Z",
"iopub.status.idle": "2023-11-16T03:34:43.010101Z",
"shell.execute_reply": "2023-11-16T03:34:43.009437Z"
},
"id": "NyftRTSMuwue"
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2024-02-23 18:42:03.927415: I tensorflow/core/util/port.cc:113] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n",
"2024-02-23 18:42:03.955182: E external/local_xla/xla/stream_executor/cuda/cuda_dnn.cc:9261] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered\n",
"2024-02-23 18:42:03.955208: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:607] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered\n",
"2024-02-23 18:42:03.955840: E external/local_xla/xla/stream_executor/cuda/cuda_blas.cc:1515] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered\n",
"2024-02-23 18:42:03.960534: I tensorflow/core/platform/cpu_feature_guard.cc:182] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.\n",
"To enable the following instructions: AVX2 AVX512F AVX512_VNNI FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.\n",
"2024-02-23 18:42:04.492637: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT\n"
]
}
],
"source": [
"import os\n",
"import tensorflow as tf\n",
"# Load compressed models from tensorflow_hub\n",
"os.environ['TFHUB_MODEL_LOAD_FORMAT'] = 'COMPRESSED'"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:34:43.014828Z",
"iopub.status.busy": "2023-11-16T03:34:43.014014Z",
"iopub.status.idle": "2023-11-16T03:34:43.272013Z",
"shell.execute_reply": "2023-11-16T03:34:43.271331Z"
},
"id": "sc1OLbOWhPCO"
},
"outputs": [],
"source": [
"import IPython.display as display\n",
"\n",
"import matplotlib.pyplot as plt\n",
"import matplotlib as mpl\n",
"mpl.rcParams['figure.figsize'] = (12, 12)\n",
"mpl.rcParams['axes.grid'] = False\n",
"\n",
"import numpy as np\n",
"import PIL.Image\n",
"import time\n",
"import functools"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:34:43.276044Z",
"iopub.status.busy": "2023-11-16T03:34:43.275804Z",
"iopub.status.idle": "2023-11-16T03:34:43.279946Z",
"shell.execute_reply": "2023-11-16T03:34:43.279369Z"
},
"id": "GM6VEGrGLh62"
},
"outputs": [],
"source": [
"def tensor_to_image(tensor):\n",
" tensor = tensor*255\n",
" tensor = np.array(tensor, dtype=np.uint8)\n",
" if np.ndim(tensor)>3:\n",
" assert tensor.shape[0] == 1\n",
" tensor = tensor[0]\n",
" return PIL.Image.fromarray(tensor)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "oeXebYusyHwC"
},
"source": [
"Download images and choose a style image and a content image:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:34:43.283405Z",
"iopub.status.busy": "2023-11-16T03:34:43.283015Z",
"iopub.status.idle": "2023-11-16T03:34:43.428345Z",
"shell.execute_reply": "2023-11-16T03:34:43.427755Z"
},
"id": "wqc0OJHwyFAk"
},
"outputs": [],
"source": [
"content_path = tf.keras.utils.get_file('YellowLabradorLooking_new.jpg', 'https://storage.googleapis.com/download.tensorflow.org/example_images/YellowLabradorLooking_new.jpg')\n",
"style_path = tf.keras.utils.get_file('kandinsky5.jpg','https://storage.googleapis.com/download.tensorflow.org/example_images/Vassily_Kandinsky%2C_1913_-_Composition_7.jpg')"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "xE4Yt8nArTeR"
},
"source": [
"## Visualize the input"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "klh6ObK2t_vH"
},
"source": [
"Define a function to load an image and limit its maximum dimension to 512 pixels."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:34:43.431733Z",
"iopub.status.busy": "2023-11-16T03:34:43.431458Z",
"iopub.status.idle": "2023-11-16T03:34:43.436393Z",
"shell.execute_reply": "2023-11-16T03:34:43.435811Z"
},
"id": "3TLljcwv5qZs"
},
"outputs": [],
"source": [
"def load_img(path_to_img):\n",
" max_dim = 512\n",
" img = tf.io.read_file(path_to_img)\n",
" img = tf.image.decode_image(img, channels=3)\n",
" img = tf.image.convert_image_dtype(img, tf.float32)\n",
"\n",
" shape = tf.cast(tf.shape(img)[:-1], tf.float32)\n",
" long_dim = max(shape)\n",
" scale = max_dim / long_dim\n",
"\n",
" new_shape = tf.cast(shape * scale, tf.int32)\n",
"\n",
" img = tf.image.resize(img, new_shape)\n",
" img = img[tf.newaxis, :]\n",
" return img"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "2yAlRzJZrWM3"
},
"source": [
"Create a simple function to display an image:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:34:43.439757Z",
"iopub.status.busy": "2023-11-16T03:34:43.439222Z",
"iopub.status.idle": "2023-11-16T03:34:43.443101Z",
"shell.execute_reply": "2023-11-16T03:34:43.442492Z"
},
"id": "cBX-eNT8PAK_"
},
"outputs": [],
"source": [
"def imshow(image, title=None):\n",
" if len(image.shape) > 3:\n",
" image = tf.squeeze(image, axis=0)\n",
"\n",
" plt.imshow(image)\n",
" if title:\n",
" plt.title(title)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"chel_path = \"/home/aneta/.ipython/profile_default/neural_style_pytorch/images/chelm.jpg\""
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"owce_path = \"/home/aneta/.ipython/profile_default/neural_style_pytorch/images/owce.jpg\""
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:34:43.446483Z",
"iopub.status.busy": "2023-11-16T03:34:43.445917Z",
"iopub.status.idle": "2023-11-16T03:34:46.265458Z",
"shell.execute_reply": "2023-11-16T03:34:46.264530Z"
},
"id": "_UWQmeEaiKkP"
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2024-02-23 18:42:17.937760: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:01:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2024-02-23 18:42:17.958243: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:01:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2024-02-23 18:42:17.958276: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:01:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2024-02-23 18:42:17.962148: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:01:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2024-02-23 18:42:17.962188: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:01:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2024-02-23 18:42:17.962200: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:01:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2024-02-23 18:42:18.072362: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:01:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2024-02-23 18:42:18.072405: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:01:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2024-02-23 18:42:18.072411: I tensorflow/core/common_runtime/gpu/gpu_device.cc:2022] Could not identify NUMA node of platform GPU id 0, defaulting to 0. Your kernel may not have been built with NUMA support.\n",
"2024-02-23 18:42:18.072435: I external/local_xla/xla/stream_executor/cuda/cuda_executor.cc:887] could not open file to read NUMA node: /sys/bus/pci/devices/0000:01:00.0/numa_node\n",
"Your kernel may have been built without NUMA support.\n",
"2024-02-23 18:42:18.072452: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1929] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 1768 MB memory: -> device: 0, name: NVIDIA GeForce RTX 3050 Laptop GPU, pci bus id: 0000:01:00.0, compute capability: 8.6\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA90AAAGOCAYAAACKS2D2AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/H5lhTAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOy9e/xuVVUu/owx53q/Gzc3LyBCAoKKkaUJSqQoeeTsPF7CMm+fAjxiZmkWWmm/FMiETPFylEzTwoOYHv2oxw5l56T46VPSTT+R5aED3lITVBAQ2Pv7rjnH+P0xxphrvd99Ye8tt2oO3O693+/7rneuueZaez7jecYzSFUVPXr06NGjR48ePXr06NGjR4/bPfiuHkCPHj169OjRo0ePHj169Ojx7zU66O7Ro0ePHj169OjRo0ePHj3uoOigu0ePHj169OjRo0ePHj169LiDooPuHj169OjRo0ePHj169OjR4w6KDrp79OjRo0ePHj169OjRo0ePOyg66O7Ro0ePHj169OjRo0ePHj3uoOigu0ePHj169OjRo0ePHj169LiDooPuHj169OjRo0ePHj169OjR4w6KDrp79OjRo0ePHj169OjRo0ePOyg66O7Ro0ePHj169OjR424S55xzDojorh5Gjx49bsfooLtHjx49evTo0aNHj9uIz372s3j605+OI444Aps2bcJhhx2GU045BW95y1tW3nfeeefhIx/5yF0zyB3ERRddBCLC3/3d393VQ+nR4z9sdNDdo0ePHj169OjRo8cu4lOf+hSOP/54XHHFFXj+85+Pt771rTjzzDPBzHjzm9+88t67G+ju0aPHXR/5rh5Ajx49evTo0aNHjx5353jNa16DAw44AH/7t3+LAw88cOVn3/jGN+6aQfXo0ePfTHSmu0ePHj169OjRo0ePXcTnP/95fN/3fd92gBsADj744PZnIsItt9yCd7/73SAiEBHOOOMMXHbZZSAifPjDH97u8+9973tBRLj88st3OYb3vOc9OO6447DPPvvgXve6F571rGfhK1/5yl6dzxlnnIF9990X//Iv/4InP/nJ2HfffXHYYYfhwgsvBGBS+sc//vHYvHkzjjjiCLz3ve9d+fz111+Pl73sZfj+7/9+7Lvvvth///3xxCc+EVdcccV23/XlL38ZT33qU7F582YcfPDB+KVf+iX86Z/+KYgIn/zkJ1fe+9d//df40R/9URxwwAG4xz3ugcc97nH4y7/8y706xx497k7RQXePHj169OjRo0ePHruII444Ap/+9Kfxj//4j7t838UXX4y1tTWcdNJJuPjii3HxxRfjBS94AU4++WTc//73xyWXXLLdZy655BIcffTROPHEE3d63Ne85jU47bTT8KAHPQhveMMb8Iu/+Iv4+Mc/jsc+9rG44YYb9uqcaq144hOfiPvf//747d/+bRx55JF40YtehIsuugg/+qM/iuOPPx6vfe1rsd9+++G0007DF7/4xfbZL3zhC/jIRz6CJz/5yXjDG96AX/7lX8ZnP/tZPO5xj8O//uu/tvfdcsstePzjH48/+7M/wy/8wi/g//v//j986lOfwq/+6q9uN55PfOITeOxjH4ubbroJZ599Ns477zzccMMNePzjH4+/+Zu/2atz7NHjbhPao0ePHj169OjRo0ePncb//t//W1NKmlLSE088UX/lV35F//RP/1SXy+V27928ebOefvrp273+ile8QtfW1vSGG25or33jG9/QnLOeffbZ7bWzzz5b51v0L33pS5pS0te85jUrx/vsZz+rOeftXt8Yf/AHf6AA9G//9m/ba6effroC0PPOO6+99u1vf1v32WcfJSJ93/ve116/8sorFcDKGLdt26a11pXv+eIXv6hra2v6G7/xG+21Cy64QAHoRz7ykfba1q1b9SEPeYgC0Msuu0xVVUVEH/SgB+mWLVtURNp7b731Vn3AAx6gp5xyyi7PsUePu3t0prtHjx49evTo0aNHj13EKaecgssvvxxPfepTccUVV+C3f/u3sWXLFhx22GH46Ec/ulvHOO2007C+vo4PfvCD7bX3v//9KKXgp37qp3b6uQ996EMQETzjGc/At771rfbrkEMOwYMe9CBcdtlle31eZ555ZvvzgQceiGOOOQabN2/GM57xjPb6McccgwMPPBBf+MIX2mtra2tgNhhRa8V1112HfffdF8cccww+85nPtPd97GMfw2GHHYanPvWp7bVNmzbh+c9//so4/v7v/x5XXXUVnvOc5+C6665r53jLLbfgP/2n/4Q///M/h4js9Xn26HFXRzdS69GjR48ePXr06NHjNuKRj3wkPvShD2G5XOKKK67Ahz/8YbzxjW/E05/+dPz93/89jj322F1+/iEPeQge+chH4pJLLsHznvc8ACYt/6Ef+iE88IEP3OnnrrrqKqgqHvSgB+3w58Mw7NX5bNq0CQcddNDKawcccAC+53u+Z7s+4QcccAC+/e1vt7+LCN785jfjd37nd/DFL34Rtdb2s3vf+97tz1/+8pdx9NFHb3e8jed71VVXAQBOP/30nY73xhtvxD3vec/dPLsePe5e0UF3jx49evTo0aNHjx67GYvFAo985CPxyEc+Eg9+8IPx3Oc+Fx/4wAdw9tln3+ZnTzvtNLzkJS/BV7/6Vayvr+Ov/uqv8Na3vnWXnxEREBH+5E/+BCml7X6+77777tV57OhYu3pdVdufzzvvPLzyla/Ef/2v/xWvfvWrca973QvMjF/8xV/cK0Y6PvO6170OD3/4w3f4nr09zx497g7RQXePHj169OjRo0ePHnsRxx9/PADg61//enttI6s7j2c961k466yz8Id/+IfYunUrhmHAM5/5zF1+x9FHHw1VxQMe8AA8+MEPvn0G/l3GBz/4QfzIj/wI3vWud628fsMNN+A+97lP+/sRRxyBz33uc1DVlXm5+uqrVz539NFHAwD2339/POEJT7gDR96jx10Tvaa7R48ePXr06NGjR49dxGWXXbbC9Eb88R//MQCre47YvHnzTh3F73Of++CJT3wi3vOe9+CSSy7Bj/7oj66A1B3Fj//4jyOlhHPPPXe7Magqrrvuuj08m+8+UkrbjeUDH/gAvva1r628tmXLFnzta19bqXvftm0bfu/3fm/lfccddxyOPvpovP71r8fNN9+83fd985vfvB1H36PHnR+d6e7Ro0ePHj169OjRYxfx4he/GLfeeiue9rSn4SEPeQiWyyU+9alP4f3vfz+OPPJIPPe5z23vPe644/Bnf/ZneMMb3oBDDz0UD3jAA3DCCSe0n5922ml4+tOfDgB49atffZvfffTRR+M3f/M38YpXvAJf+tKXcOqpp2K//fbDF7/4RXz4wx/Gz/zMz+BlL3vZ7X/Su4gnP/nJ+I3f+A0897nPxQ//8A/js5/9LC655BIcddRRK+97wQtegLe+9a149rOfjZe85CW43/3uh0suuQSbNm0CMKkCmBnvfOc78cQnPhHf933fh+c+97k47LDD8LWvfQ2XXXYZ9t9/f/zRH/3RnXqOPXrcntFBd48ePXr06NGjR48eu4jXv/71+MAHPoA//uM/xjve8Q4sl0scfvjh+Lmf+zn8+q//Og488MD23je84Q34mZ/5Gfz6r/86tm7ditNPP30FdD/lKU/BPe95T4jIiqv3ruLlL385HvzgB+ONb3wjzj33XADA/e9/f/zn//yfd/sYt2f82q/9Gm655Ra8973vxfvf/3484hGPwKWXXoqXv/zlK+/bd9998YlPfAIvfvGL8eY3vxn77rsvTjvtNPzwD/8wfuInfqKBbwA4+eSTcfnll+PVr3413vrWt+Lmm2/GIYccghNOOAEveMEL7uxT7NHjdg3SHWllevTo0aNHjx49evTocbtHKQWHHnoonvKUp2xXE/0fJd70pjfhl37pl/DVr34Vhx122F09nB497vDoNd09evTo0aNHjx49etxJ8ZGPfATf/OY3cdppp93VQ7lTYuvWrSt/37ZtG97+9rfjQQ96UAfcPf7DRJeX9+jRo0ePHj169OhxB8df//Vf4x/+4R/w6le/Gj/
"text/plain": [
"<Figure size 1200x1200 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"content_image = load_img(owce_path)\n",
"style_image = load_img(chel_path)\n",
"\n",
"plt.subplot(1, 2, 1)\n",
"imshow(content_image, 'Content Image')\n",
"\n",
"plt.subplot(1, 2, 2)\n",
"imshow(style_image, 'Style Image')"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "YMzChXSlKTA2"
},
"source": [
"## Fast Style Transfer using TF-Hub\n",
"\n",
"This tutorial demonstrates the original style-transfer algorithm, which optimizes the image content to a particular style. Before getting into the details, let's see how the [TensorFlow Hub model](https://tfhub.dev/google/magenta/arbitrary-image-stylization-v1-256/2) does this:"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:34:46.276365Z",
"iopub.status.busy": "2023-11-16T03:34:46.275669Z",
"iopub.status.idle": "2023-11-16T03:34:55.327882Z",
"shell.execute_reply": "2023-11-16T03:34:55.327200Z"
},
"id": "iYSLexgRKSh-"
},
"outputs": [
{
"data": {
"image/jpeg": "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
"image/png": "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
"text/plain": [
"<PIL.Image.Image image mode=RGB size=512x288>"
]
},
"execution_count": 43,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import tensorflow_hub as hub\n",
"hub_model = hub.load('https://tfhub.dev/google/magenta/arbitrary-image-stylization-v1-256/2')\n",
"stylized_image = hub_model(tf.constant(content_image), tf.constant(style_image))[0]\n",
"tensor_to_image(stylized_image)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "GEwZ7FlwrjoZ"
},
"source": [
"## Define content and style representations\n",
"\n",
"Use the intermediate layers of the model to get the *content* and *style* representations of the image. Starting from the network's input layer, the first few layer activations represent low-level features like edges and textures. As you step through the network, the final few layers represent higher-level features—object parts like *wheels* or *eyes*. In this case, you are using the VGG19 network architecture, a pretrained image classification network. These intermediate layers are necessary to define the representation of content and style from the images. For an input image, try to match the corresponding style and content target representations at these intermediate layers.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "LP_7zrziuiJk"
},
"source": [
"Load a [VGG19](https://keras.io/api/applications/vgg/#vgg19-function) and test run it on our image to ensure it's used correctly:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:34:55.337831Z",
"iopub.status.busy": "2023-11-16T03:34:55.337587Z",
"iopub.status.idle": "2023-11-16T03:35:02.690946Z",
"shell.execute_reply": "2023-11-16T03:35:02.690299Z"
},
"id": "fMbzrr7BCTq0"
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2024-02-23 18:42:24.673107: I external/local_xla/xla/stream_executor/cuda/cuda_dnn.cc:454] Loaded cuDNN version 8902\n",
"2024-02-23 18:42:24.773440: I external/local_tsl/tsl/platform/default/subprocess.cc:304] Start cannot spawn child process: No such file or directory\n",
"2024-02-23 18:42:25.246989: I external/local_tsl/tsl/platform/default/subprocess.cc:304] Start cannot spawn child process: No such file or directory\n"
]
},
{
"data": {
"text/plain": [
"TensorShape([1, 1000])"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x = tf.keras.applications.vgg19.preprocess_input(content_image*255)\n",
"x = tf.image.resize(x, (224, 224))\n",
"vgg = tf.keras.applications.VGG19(include_top=True, weights='imagenet')\n",
"prediction_probabilities = vgg(x)\n",
"prediction_probabilities.shape"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"#vgg.summary()"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"#vgg.get_config()"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:35:02.694190Z",
"iopub.status.busy": "2023-11-16T03:35:02.693938Z",
"iopub.status.idle": "2023-11-16T03:35:02.758402Z",
"shell.execute_reply": "2023-11-16T03:35:02.757842Z"
},
"id": "1_FyCm0dYnvl"
},
"outputs": [
{
"data": {
"text/plain": [
"[('megalith', 0.761035),\n",
" ('king_penguin', 0.20216931),\n",
" ('ram', 0.014038121),\n",
" ('hay', 0.009777568),\n",
" ('bighorn', 0.0025387204)]"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"predicted_top_5 = tf.keras.applications.vgg19.decode_predictions(prediction_probabilities.numpy())[0]\n",
"[(class_name, prob) for (number, class_name, prob) in predicted_top_5]"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ljpoYk-0f6HS"
},
"source": [
"Now load a `VGG19` without the classification head, and list the layer names"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:35:02.761485Z",
"iopub.status.busy": "2023-11-16T03:35:02.761261Z",
"iopub.status.idle": "2023-11-16T03:35:03.621343Z",
"shell.execute_reply": "2023-11-16T03:35:03.620659Z"
},
"id": "Yh_AV6220ebD"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"input_2\n",
"block1_conv1\n",
"block1_conv2\n",
"block1_pool\n",
"block2_conv1\n",
"block2_conv2\n",
"block2_pool\n",
"block3_conv1\n",
"block3_conv2\n",
"block3_conv3\n",
"block3_conv4\n",
"block3_pool\n",
"block4_conv1\n",
"block4_conv2\n",
"block4_conv3\n",
"block4_conv4\n",
"block4_pool\n",
"block5_conv1\n",
"block5_conv2\n",
"block5_conv3\n",
"block5_conv4\n",
"block5_pool\n"
]
}
],
"source": [
"vgg = tf.keras.applications.VGG19(include_top=False, weights='imagenet')\n",
"\n",
"print()\n",
"for layer in vgg.layers:\n",
" print(layer.name)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Wt-tASys0eJv"
},
"source": [
"Choose intermediate layers from the network to represent the style and content of the image:\n"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:35:03.624855Z",
"iopub.status.busy": "2023-11-16T03:35:03.624612Z",
"iopub.status.idle": "2023-11-16T03:35:03.628342Z",
"shell.execute_reply": "2023-11-16T03:35:03.627754Z"
},
"id": "ArfX_6iA0WAX"
},
"outputs": [],
"source": [
"content_layers = ['block5_conv2'] \n",
"\n",
"style_layers = ['block1_conv1',\n",
" 'block2_conv1',\n",
" 'block3_conv1', \n",
" 'block4_conv1', \n",
" 'block5_conv1']\n",
"\n",
"num_content_layers = len(content_layers)\n",
"num_style_layers = len(style_layers)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "2o4nSwuN0U3X"
},
"source": [
"#### Intermediate layers for style and content\n",
"\n",
"So why do these intermediate outputs within our pretrained image classification network allow us to define style and content representations?\n",
"\n",
"At a high level, in order for a network to perform image classification (which this network has been trained to do), it must understand the image. This requires taking the raw image as input pixels and building an internal representation that converts the raw image pixels into a complex understanding of the features present within the image.\n",
"\n",
"This is also a reason why convolutional neural networks are able to generalize well: theyre able to capture the invariances and defining features within classes (e.g. cats vs. dogs) that are agnostic to background noise and other nuisances. Thus, somewhere between where the raw image is fed into the model and the output classification label, the model serves as a complex feature extractor. By accessing intermediate layers of the model, you're able to describe the content and style of input images."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Jt3i3RRrJiOX"
},
"source": [
"## Build the model \n",
"\n",
"The networks in `tf.keras.applications` are designed so you can easily extract the intermediate layer values using the Keras functional API.\n",
"\n",
"To define a model using the functional API, specify the inputs and outputs:\n",
"\n",
"`model = Model(inputs, outputs)`\n",
"\n",
"This following function builds a VGG19 model that returns a list of intermediate layer outputs:"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:35:03.631746Z",
"iopub.status.busy": "2023-11-16T03:35:03.631221Z",
"iopub.status.idle": "2023-11-16T03:35:03.635499Z",
"shell.execute_reply": "2023-11-16T03:35:03.634948Z"
},
"id": "nfec6MuMAbPx"
},
"outputs": [],
"source": [
"def vgg_layers(layer_names):\n",
" \"\"\" Creates a VGG model that returns a list of intermediate output values.\"\"\"\n",
" # Load our model. Load pretrained VGG, trained on ImageNet data\n",
" vgg = tf.keras.applications.VGG19(include_top=False, weights='imagenet')\n",
" vgg.trainable = False\n",
" \n",
" outputs = [vgg.get_layer(name).output for name in layer_names]\n",
"\n",
" model = tf.keras.Model([vgg.input], outputs)\n",
" return model"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "jbaIvZf5wWn_"
},
"source": [
"And to create the model:"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:35:03.638264Z",
"iopub.status.busy": "2023-11-16T03:35:03.638051Z",
"iopub.status.idle": "2023-11-16T03:35:05.887203Z",
"shell.execute_reply": "2023-11-16T03:35:05.886443Z"
},
"id": "LkyvPpBHSfVi"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"block1_conv1\n",
" shape: (1, 403, 512, 64)\n",
" min: 0.0\n",
" max: 743.2428\n",
" mean: 32.208652\n",
"\n",
"block2_conv1\n",
" shape: (1, 201, 256, 128)\n",
" min: 0.0\n",
" max: 2573.0193\n",
" mean: 134.44252\n",
"\n",
"block3_conv1\n",
" shape: (1, 100, 128, 256)\n",
" min: 0.0\n",
" max: 8561.582\n",
" mean: 103.2595\n",
"\n",
"block4_conv1\n",
" shape: (1, 50, 64, 512)\n",
" min: 0.0\n",
" max: 11601.054\n",
" mean: 451.57892\n",
"\n",
"block5_conv1\n",
" shape: (1, 25, 32, 512)\n",
" min: 0.0\n",
" max: 1913.4247\n",
" mean: 32.27252\n",
"\n"
]
}
],
"source": [
"style_extractor = vgg_layers(style_layers)\n",
"style_outputs = style_extractor(style_image*255)\n",
"\n",
"#Look at the statistics of each layer's output\n",
"for name, output in zip(style_layers, style_outputs):\n",
" print(name)\n",
" print(\" shape: \", output.numpy().shape)\n",
" print(\" min: \", output.numpy().min())\n",
" print(\" max: \", output.numpy().max())\n",
" print(\" mean: \", output.numpy().mean())\n",
" print()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "lGUfttK9F8d5"
},
"source": [
"## Calculate style\n",
"\n",
"The content of an image is represented by the values of the intermediate feature maps.\n",
"\n",
"It turns out, the style of an image can be described by the means and correlations across the different feature maps. Calculate a Gram matrix that includes this information by taking the outer product of the feature vector with itself at each location, and averaging that outer product over all locations. This Gram matrix can be calculated for a particular layer as:\n",
"\n",
"$$G^l_{cd} = \\frac{\\sum_{ij} F^l_{ijc}(x)F^l_{ijd}(x)}{IJ}$$\n",
"\n",
"This can be implemented concisely using the `tf.linalg.einsum` function:"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:35:05.890933Z",
"iopub.status.busy": "2023-11-16T03:35:05.890331Z",
"iopub.status.idle": "2023-11-16T03:35:05.895190Z",
"shell.execute_reply": "2023-11-16T03:35:05.894366Z"
},
"id": "HAy1iGPdoEpZ"
},
"outputs": [],
"source": [
"def gram_matrix(input_tensor):\n",
" result = tf.linalg.einsum('bijc,bijd->bcd', input_tensor, input_tensor)\n",
" input_shape = tf.shape(input_tensor)\n",
" num_locations = tf.cast(input_shape[1]*input_shape[2], tf.float32)\n",
" return result/(num_locations)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "pXIUX6czZABh"
},
"source": [
"## Extract style and content\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "1HGHvwlJ1nkn"
},
"source": [
"Build a model that returns the style and content tensors."
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:35:05.898313Z",
"iopub.status.busy": "2023-11-16T03:35:05.898052Z",
"iopub.status.idle": "2023-11-16T03:35:05.905039Z",
"shell.execute_reply": "2023-11-16T03:35:05.904179Z"
},
"id": "Sr6QALY-I1ja"
},
"outputs": [],
"source": [
"class StyleContentModel(tf.keras.models.Model):\n",
" def __init__(self, style_layers, content_layers):\n",
" super(StyleContentModel, self).__init__()\n",
" self.vgg = vgg_layers(style_layers + content_layers)\n",
" self.style_layers = style_layers\n",
" self.content_layers = content_layers\n",
" self.num_style_layers = len(style_layers)\n",
" self.vgg.trainable = False\n",
"\n",
" def call(self, inputs):\n",
" \"Expects float input in [0,1]\"\n",
" inputs = inputs*255.0\n",
" preprocessed_input = tf.keras.applications.vgg19.preprocess_input(inputs)\n",
" outputs = self.vgg(preprocessed_input)\n",
" style_outputs, content_outputs = (outputs[:self.num_style_layers],\n",
" outputs[self.num_style_layers:])\n",
"\n",
" style_outputs = [gram_matrix(style_output)\n",
" for style_output in style_outputs]\n",
"\n",
" content_dict = {content_name: value\n",
" for content_name, value\n",
" in zip(self.content_layers, content_outputs)}\n",
"\n",
" style_dict = {style_name: value\n",
" for style_name, value\n",
" in zip(self.style_layers, style_outputs)}\n",
"\n",
" return {'content': content_dict, 'style': style_dict}"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Xuj1o33t1edl"
},
"source": [
"When called on an image, this model returns the gram matrix (style) of the `style_layers` and content of the `content_layers`:"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:35:05.908129Z",
"iopub.status.busy": "2023-11-16T03:35:05.907892Z",
"iopub.status.idle": "2023-11-16T03:35:08.339329Z",
"shell.execute_reply": "2023-11-16T03:35:08.338644Z"
},
"id": "rkjO-DoNDU0A"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Styles:\n",
" block1_conv1\n",
" shape: (1, 64, 64)\n",
" min: 0.022261642\n",
" max: 44157.473\n",
" mean: 355.99878\n",
"\n",
" block2_conv1\n",
" shape: (1, 128, 128)\n",
" min: 0.0\n",
" max: 74937.36\n",
" mean: 11677.908\n",
"\n",
" block3_conv1\n",
" shape: (1, 256, 256)\n",
" min: 0.0\n",
" max: 379654.12\n",
" mean: 10265.242\n",
"\n",
" block4_conv1\n",
" shape: (1, 512, 512)\n",
" min: 0.0\n",
" max: 3333814.5\n",
" mean: 183739.55\n",
"\n",
" block5_conv1\n",
" shape: (1, 512, 512)\n",
" min: 0.0\n",
" max: 238887.22\n",
" mean: 2304.3767\n",
"\n",
"Contents:\n",
" block5_conv2\n",
" shape: (1, 18, 32, 512)\n",
" min: 0.0\n",
" max: 1443.7827\n",
" mean: 16.3132\n"
]
}
],
"source": [
"extractor = StyleContentModel(style_layers, content_layers)\n",
"\n",
"results = extractor(tf.constant(content_image))\n",
"\n",
"print('Styles:')\n",
"for name, output in sorted(results['style'].items()):\n",
" print(\" \", name)\n",
" print(\" shape: \", output.numpy().shape)\n",
" print(\" min: \", output.numpy().min())\n",
" print(\" max: \", output.numpy().max())\n",
" print(\" mean: \", output.numpy().mean())\n",
" print()\n",
"\n",
"print(\"Contents:\")\n",
"for name, output in sorted(results['content'].items()):\n",
" print(\" \", name)\n",
" print(\" shape: \", output.numpy().shape)\n",
" print(\" min: \", output.numpy().min())\n",
" print(\" max: \", output.numpy().max())\n",
" print(\" mean: \", output.numpy().mean())\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "y9r8Lyjb_m0u"
},
"source": [
"## Run gradient descent\n",
"\n",
"With this style and content extractor, you can now implement the style transfer algorithm. Do this by calculating the mean square error for your image's output relative to each target, then take the weighted sum of these losses.\n",
"\n",
"Set your style and content target values:"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:35:08.342604Z",
"iopub.status.busy": "2023-11-16T03:35:08.342348Z",
"iopub.status.idle": "2023-11-16T03:35:08.415356Z",
"shell.execute_reply": "2023-11-16T03:35:08.414749Z"
},
"id": "PgkNOnGUFcKa"
},
"outputs": [],
"source": [
"style_targets = extractor(style_image)['style']\n",
"content_targets = extractor(content_image)['content']"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "CNPrpl-e_w9A"
},
"source": [
"Define a `tf.Variable` to contain the image to optimize. To make this quick, initialize it with the content image (the `tf.Variable` must be the same shape as the content image):"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:35:08.418956Z",
"iopub.status.busy": "2023-11-16T03:35:08.418727Z",
"iopub.status.idle": "2023-11-16T03:35:08.423759Z",
"shell.execute_reply": "2023-11-16T03:35:08.423087Z"
},
"id": "J0vKxF8ZO6G8"
},
"outputs": [],
"source": [
"image = tf.Variable(content_image)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "M6L8ojmn_6rH"
},
"source": [
"Since this is a float image, define a function to keep the pixel values between 0 and 1:"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:35:08.426850Z",
"iopub.status.busy": "2023-11-16T03:35:08.426609Z",
"iopub.status.idle": "2023-11-16T03:35:08.429855Z",
"shell.execute_reply": "2023-11-16T03:35:08.429296Z"
},
"id": "kdgpTJwL_vE2"
},
"outputs": [],
"source": [
"def clip_0_1(image):\n",
" return tf.clip_by_value(image, clip_value_min=0.0, clip_value_max=1.0)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "MBU5RFpcAo7W"
},
"source": [
"Create an optimizer. The paper recommends LBFGS, but Adam works okay, too:"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:35:08.432914Z",
"iopub.status.busy": "2023-11-16T03:35:08.432699Z",
"iopub.status.idle": "2023-11-16T03:35:08.439251Z",
"shell.execute_reply": "2023-11-16T03:35:08.438680Z"
},
"id": "r4XZjqUk_5Eu"
},
"outputs": [],
"source": [
"opt = tf.keras.optimizers.Adam(learning_rate=0.02, beta_1=0.99, epsilon=1e-1)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "As-evbBiA2qT"
},
"source": [
"To optimize this, use a weighted combination of the two losses to get the total loss:"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:35:08.442444Z",
"iopub.status.busy": "2023-11-16T03:35:08.442228Z",
"iopub.status.idle": "2023-11-16T03:35:08.445095Z",
"shell.execute_reply": "2023-11-16T03:35:08.444539Z"
},
"id": "Dt4pxarvA4I4"
},
"outputs": [],
"source": [
"style_weight=1e-2\n",
"content_weight=1e4"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:35:08.447881Z",
"iopub.status.busy": "2023-11-16T03:35:08.447669Z",
"iopub.status.idle": "2023-11-16T03:35:08.451897Z",
"shell.execute_reply": "2023-11-16T03:35:08.451340Z"
},
"id": "0ggx2Na8oROH"
},
"outputs": [],
"source": [
"def style_content_loss(outputs):\n",
" style_outputs = outputs['style']\n",
" content_outputs = outputs['content']\n",
" style_loss = tf.add_n([tf.reduce_mean((style_outputs[name]-style_targets[name])**2) \n",
" for name in style_outputs.keys()])\n",
" style_loss *= style_weight / num_style_layers\n",
"\n",
" content_loss = tf.add_n([tf.reduce_mean((content_outputs[name]-content_targets[name])**2) \n",
" for name in content_outputs.keys()])\n",
" content_loss *= content_weight / num_content_layers\n",
" loss = style_loss + content_loss\n",
" return loss"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "vbF2WnP9BI5M"
},
"source": [
"Use `tf.GradientTape` to update the image."
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:35:08.454809Z",
"iopub.status.busy": "2023-11-16T03:35:08.454595Z",
"iopub.status.idle": "2023-11-16T03:35:08.458356Z",
"shell.execute_reply": "2023-11-16T03:35:08.457811Z"
},
"id": "0t0umkajFIuh"
},
"outputs": [],
"source": [
"@tf.function()\n",
"def train_step(image):\n",
" with tf.GradientTape() as tape:\n",
" outputs = extractor(image)\n",
" loss = style_content_loss(outputs)\n",
"\n",
" grad = tape.gradient(loss, image)\n",
" opt.apply_gradients([(grad, image)])\n",
" image.assign(clip_0_1(image))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "5FHMJq4UBRIQ"
},
"source": [
"Now run a few steps to test:"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:35:08.461299Z",
"iopub.status.busy": "2023-11-16T03:35:08.461085Z",
"iopub.status.idle": "2023-11-16T03:35:13.516037Z",
"shell.execute_reply": "2023-11-16T03:35:13.515351Z"
},
"id": "Y542mxi-O2a2"
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2024-02-23 18:43:23.674927: I external/local_xla/xla/service/service.cc:168] XLA service 0x7f88f61b4e70 initialized for platform CUDA (this does not guarantee that XLA will be used). Devices:\n",
"2024-02-23 18:43:23.674967: I external/local_xla/xla/service/service.cc:176] StreamExecutor device (0): NVIDIA GeForce RTX 3050 Laptop GPU, Compute Capability 8.6\n",
"2024-02-23 18:43:23.678877: I tensorflow/compiler/mlir/tensorflow/utils/dump_mlir_util.cc:269] disabling MLIR crash reproducer, set env var `MLIR_CRASH_REPRODUCER_DIRECTORY` to enable.\n",
"WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\n",
"I0000 00:00:1708710203.770091 50541 device_compiler.h:186] Compiled cluster using XLA! This line is logged at most once for the lifetime of the process.\n"
]
},
{
"data": {
"image/jpeg": "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
"image/png": "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
"text/plain": [
"<PIL.Image.Image image mode=RGB size=512x288>"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"train_step(image)\n",
"train_step(image)\n",
"train_step(image)\n",
"tensor_to_image(image)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "mNzE-mTbBVgY"
},
"source": [
"Since it's working, perform a longer optimization:"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:35:13.525306Z",
"iopub.status.busy": "2023-11-16T03:35:13.525049Z",
"iopub.status.idle": "2023-11-16T03:36:26.653022Z",
"shell.execute_reply": "2023-11-16T03:36:26.652370Z"
},
"id": "rQW1tXYoLbUS"
},
"outputs": [
{
"data": {
"image/jpeg": "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
"image/png": "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
"text/plain": [
"<PIL.Image.Image image mode=RGB size=512x288>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Train step: 1000\n",
"Total time: 69.4\n"
]
}
],
"source": [
"import time\n",
"start = time.time()\n",
"\n",
"epochs = 10\n",
"steps_per_epoch = 100\n",
"\n",
"step = 0\n",
"for n in range(epochs):\n",
" for m in range(steps_per_epoch):\n",
" step += 1\n",
" train_step(image)\n",
" print(\".\", end='', flush=True)\n",
" display.clear_output(wait=True)\n",
" display.display(tensor_to_image(image))\n",
" print(\"Train step: {}\".format(step))\n",
" \n",
"end = time.time()\n",
"print(\"Total time: {:.1f}\".format(end-start))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "GWVB3anJMY2v"
},
"source": [
"## Total variation loss\n",
"\n",
"One downside to this basic implementation is that it produces a lot of high frequency artifacts. Decrease these using an explicit regularization term on the high frequency components of the image. In style transfer, this is often called the *total variation loss*:"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:36:26.664062Z",
"iopub.status.busy": "2023-11-16T03:36:26.663812Z",
"iopub.status.idle": "2023-11-16T03:36:26.667988Z",
"shell.execute_reply": "2023-11-16T03:36:26.667377Z"
},
"id": "7szUUybCQMB3"
},
"outputs": [],
"source": [
"def high_pass_x_y(image):\n",
" x_var = image[:, :, 1:, :] - image[:, :, :-1, :]\n",
" y_var = image[:, 1:, :, :] - image[:, :-1, :, :]\n",
"\n",
" return x_var, y_var"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:36:26.670924Z",
"iopub.status.busy": "2023-11-16T03:36:26.670704Z",
"iopub.status.idle": "2023-11-16T03:36:27.714920Z",
"shell.execute_reply": "2023-11-16T03:36:27.714172Z"
},
"id": "Atc2oL29PXu_"
},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABHgAAAL8CAYAAACbAwK3AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/H5lhTAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOy9d7wlRZk+/lT3CTfOvTNMYphhgEGiIAqKCEhmQMEFQUQRgS8gLAIGMICLgLsrIguCmFjlNwRFJciqyyJKchHQVRFQCZKGPAMT79x0Qnf9/uiuPnXqVOw+5wboh89l7u2u8FZ6632fCk0opRQ5cuTIkSNHjhw5cuTIkSNHjhw5pi28yRYgR44cOXLkyJEjR44cOXLkyJEjRzbkBE+OHDly5MiRI0eOHDly5MiRI8c0R07w5MiRI0eOHDly5MiRI0eOHDlyTHPkBE+OHDly5MiRI0eOHDly5MiRI8c0R07w5MiRI0eOHDly5MiRI0eOHDlyTHPkBE+OHDly5MiRI0eOHDly5MiRI8c0R07w5MiRI0eOHDly5MiRI0eOHDlyTHPkBE+OHDly5MiRI0eOHDly5MiRI8c0R07w5MiRI0eOHDly5MiRI0eOHDlyTHPkBE+OHDly5MiRI0eOHDmmNY4//nhsttlmHUt/7733xt57792x9KeLDBONzTbbDMcff3yquBNRXxdccAEIIR3NI0cOF+QET44cHUCWyWgq4d577wUhBPfee++bWoaJxjXXXANCCJYvX+4cd6LqixCCCy64oKN55MiRI0eOqY0PfOAD6OnpwYYNG5RhjjnmGJRKJaxevTpzfq+88gouuOACPPzww5nT6hQ222wzEEJACIHneRgcHMQOO+yAT3ziE/jDH/7Q1ryman1QSnH99dfjve99LwYHB9HT04MddtgBX/nKVzAyMjLZ4uXI8YZGTvDkeEODOcp/+tOfpO/33ntvvPWtb51gqSYOX/3qV/Ff//VfHc+H1TP76erqwoIFC7B06VJ885vf1Bp+aXDDDTfg8ssvb2ua7cALL7yAU089FZttthnK5TLmzp2Lww47DPfff/9ki5YjR44cOXK0HccccwzGxsZw6623St+Pjo7i5z//OQ466CBstNFGmfN75ZVXcOGFF0oJje9///t48sknM+fRDuy00064/vrrcd111+Giiy7CPvvsg1/+8pd497vfjc9+9rNty0dXH5OFIAhw9NFH4+Mf/ziAaIfL5Zdfjp122gkXXngh3v3ud2PlypXW6T355JP4/ve/n0qWX//61/j1r3+dKm6OHNMVhckWIEeONyKefPJJeN7k86df/epXceSRR+Kwww6bkPy+8pWvYPPNN0etVsOKFStw77334tOf/jQuu+wy/OIXv8COO+7YlnxuuOEG/O1vf8OnP/3ptqTXDtx///143/veBwA46aSTsN1222HFihW45pprsOeee+KKK67AGWecYZXWsccei6OPPhrlctlZjve+970YGxtDqVRyjpsjR44cOXK44AMf+AD6+/txww03JA49j5///OcYGRnBMccckymfer2OMAy1YYrFYqY82olNNtkEH/vYx5qeXXzxxfjoRz+Kb3zjG3jLW96Cf/7nf54k6TqLr3/967jxxhtx9tln45JLLkmef+ITn8BRRx2Fww47DMcffzxuv/12ZRqUUoyPj6O7uzuVLcSQ20I53oyYfA80R443CCilGBsbAwCUy+UpZWhMFA4++GB87GMfwwknnIBzzjkHd9xxB+6880689tpr+MAHPpDUzxsNa9euxZFHHonu7m489NBDuPTSS3HiiSfiS1/6Eh599FHsscce+PSnP40HHnhAmw7btuz7Prq6ulKd6fY8D11dXVOCYMyRI0eOHG9sdHd344Mf/CDuuusuvPbaay3vb7jhBvT39+MDH/gAAGDdunX49Kc/jUWLFqFcLmPLLbfExRdf3ETeLF++HIQQ/Md//Acuv/xyLFmyBOVyGd/5znfwzne+EwBwwgknJLuGr7nmGgDyO3jCMMQVV1yBHXbYAV1dXZgzZw4OOuigpp3dy5Ytw7777ou5c+eiXC5ju+22w3e/+90211RUV9dffz1mzZqFf//3fweltEnOyy+/HNtvvz26urowb948nHLKKVi7dq0yvXvvvVdbH/fddx8+9KEPYdNNN0W5XMaiRYvwmc98psUWW7FiBU444QQsXLgQ5XIZG2+8Mf7pn/6p6Zj4+vXr8cQTT2D9+vXaMo6NjeGSSy7BVltthYsuuqjl/aGHHorjjjsOv/rVr/D73/8+eb7ZZpvhkEMOwR133IFddtkF3d3duOqqq5J34rUHjz76KPbaay90d3dj4cKF+Ld/+zcsW7as5Xi7eAcPO8Z+44034t///d+xcOFCdHV1Yb/99sPTTz/dlIdt/eXIMdWQewA5cgio1+v413/918Sg2GyzzXDuueeiUqk0hXOZjPjjS+IPPxHdfffd2HPPPdHb24vBwUH80z/9Ex5//PGmfNllbk8//TSOP/54DA4OYmBgACeccAJGR0eb8hwZGcG1116b5MVkev7553Haaadh6623Rnd3NzbaaCN86EMfSnXniwn77rsvzjvvPDz//PP44Q9/2PTuiSeewJFHHolZs2ahq6sLu+yyC37xi19o09t7771x22234fnnn0/KxQy6arWKL3/5y9h5550xMDCA3t5e7Lnnnrjnnnta0vnJT36CnXfeGf39/ZgxYwZ22GEHXHHFFU1hnnnmGTzzzDPGMl511VVYsWIFLrnkEixZsqTpXXd3d9IGX/nKV5Ln7Fjbb3/7W5x22mmYO3cuFi5c2PSOb48wDHHBBRdgwYIF6OnpwT777IPHHnuspa/J7uBhRxEfe+wx7LPPPujp6cEmm2yCr3/9602yutRfjhw5cuTIAUTHtOr1Om688cam52vWrMEdd9yBww8/HN3d3RgdHcVee+2FH/7wh/j4xz+Ob37zm9h9991xzjnnSI8tLVu2DFdeeSU+8YlP4NJLL8Xhhx+ezKOf+MQncP311yf3vKhw4oknJoTSxRdfjC9+8Yvo6upqIhe++93vYvHixTj33HNx6aWXYtGiRTjttNPw7W9/u0011EBfXx8OP/xwvPzyy3jssceS56eccgo+97nPYffdd8cVV1yBE044AT/60Y+wdOlS1Go1aVrbbruttj5uuukmjI6O4p//+Z9x5ZVXYunSpbjyyitbdlodccQRuPXWW3HCCSfgO9/5Ds4880xs2LABL7zwQhLm1ltvxbbbbqs8isfwu9/9DmvXrsVHP/pRFArygyIs///+7/9uev7kk0/iIx/5CA444ABcccUV2GmnnaTxX375Zeyzzz74+9//jnPOOQef+cxn8KMf/ajFhtPha1/7Gm699VacffbZOOecc/D73/++ZZeZbf3lyDHVkB/RyvGmwPr167Fq1aqW57JJ86STTsK1116LI488EmeddRb+8Ic/4KKLLsLjjz/eMrGxyeiUU07BySefjK233lqa//XXX9/y7F/+5V/w2muvoa+vDwBw55134uCDD8YWW2yBCy64AGNjY7jyyiux++6746GHHmpZlTrqqKOw+eab46KLLsJDDz2EH/zgB5g7dy4uvvjiJM+TTjoJ73rXu/CJT3wCABLy4Y9//CMeeOABHH300Vi4cCGWL1+O7373u9h7773x2GOPoaenx1Cjbjj22GNx7rnn4te//jVOPvlkAMDf//537L777thkk03wxS9+Eb29vbjxxhtx2GGH4ZZbbsHhhx8uTetLX/oS1q9fj5deegnf+MY3ACCpw6GhIfzgBz/ARz7yEZx88snYsGEDrr76aixduhT/93//lxgLv/nNb/CRj3wE++23X1Jfjz/+OO6//3586lOfSvLab7/9AMBIfP3yl79EV1cXjjrqKOn7zTffHHvssQfuvvtujI2Nobu7O3l32mmnYc6cOfjyl7+svXjwnHPOwde//nUceuihWLp0KR555BEsXboU4+PjWtkY1q5di4MOOggf/OAHcdRRR+Hmm2/GF77wBeywww44+OCDAdjXX44cOXLkyMGw7777YuO
"text/plain": [
"<Figure size 1400x1000 with 4 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"x_deltas, y_deltas = high_pass_x_y(content_image)\n",
"\n",
"plt.figure(figsize=(14, 10))\n",
"plt.subplot(2, 2, 1)\n",
"imshow(clip_0_1(2*y_deltas+0.5), \"Horizontal Deltas: Original\")\n",
"\n",
"plt.subplot(2, 2, 2)\n",
"imshow(clip_0_1(2*x_deltas+0.5), \"Vertical Deltas: Original\")\n",
"\n",
"x_deltas, y_deltas = high_pass_x_y(image)\n",
"\n",
"plt.subplot(2, 2, 3)\n",
"imshow(clip_0_1(2*y_deltas+0.5), \"Horizontal Deltas: Styled\")\n",
"\n",
"plt.subplot(2, 2, 4)\n",
"imshow(clip_0_1(2*x_deltas+0.5), \"Vertical Deltas: Styled\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "lqHElVgBkgkz"
},
"source": [
"This shows how the high frequency components have increased.\n",
"\n",
"Also, this high frequency component is basically an edge-detector. You can get similar output from the Sobel edge detector, for example:"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:36:27.743198Z",
"iopub.status.busy": "2023-11-16T03:36:27.742554Z",
"iopub.status.idle": "2023-11-16T03:36:28.398290Z",
"shell.execute_reply": "2023-11-16T03:36:28.397633Z"
},
"id": "HyvqCiywiUfL"
},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABHcAAAFXCAYAAAAoO6KKAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/H5lhTAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOy9eZguRXk2flcv7zrr2Q8HOCCoCBFJUAkiggsguESjcQlXROJCPhU16ucVzE+FSxOixqhRQjQxYEw0QbNovkRxjTGKiYmCK3hAdjjbzJn1nXfp7vr9UVXd1f32UtXd7zszx74vDjPTXctT+/PcT1U1oZRSVKhQoUKFChUqVKhQoUKFChUqVNiUMNZbgAoVKlSoUKFChQoVKlSoUKFChQr5UZE7FSpUqFChQoUKFSpUqFChQoUKmxgVuVOhQoUKFSpUqFChQoUKFSpUqLCJUZE7FSpUqFChQoUKFSpUqFChQoUKmxgVuVOhQoUKFSpUqFChQoUKFSpUqLCJUZE7FSpUqFChQoUKFSpUqFChQoUKmxgVuVOhQoUKFSpUqFChQoUKFSpUqLCJUZE7FSpUqFChQoUKFSpUqFChQoUKmxgVuVOhQoUKFSpUqFChQoUKFSpUqLCJUZE7FSpsIJxwwgl4+ctfvt5iFMa///u/gxCCf//3fx973ieccAKe/exnl5omIQRXX311qWnG4cYbbwQhBPfcc8/I86pQoUKFChUqAC9/+ctxwgknjCz9888/H+eff/7I0k+C0Cn+53/+p7Q0r776ahBCSksvDUeLTlyhwjhRkTsVKsQga0E8//zz8Uu/9Etjlmp8+MM//EP88z//81jy+uEPf4gXvvCF2Lt3LxqNBvbs2YMLLrgAH/7wh8eSf4UKFSpUqFBhvHjuc5+LVquF5eXlxDCXXnoparUa5ubmCuf30EMP4eqrr8att95aOK1Rod/v40Mf+hB++Zd/GVNTU5iZmcFpp52GV7/61bj99tvXW7wKFSpsAlTkToUKGwh33HEH/uIv/mK9xRgbufPtb38bj3/843HbbbfhVa96FT7ykY/gla98JQzDwIc+9KGR51+hQoUKFSpUGD8uvfRSrK2t4Z/+6Z9i33c6HXzuc5/DM5/5TGzdurVwfg899BCuueaaWHLnL/7iL3DHHXcUzqMoXvCCF+DNb34zfumXfgl/9Ed/hGuuuQZPecpT8IUvfAHf+c531lu8ChUqbAJY6y1AhQq/6KCUotvtotlsol6vr7c4Y8Uf/MEfYHp6Gt/97ncxMzMTenfw4MH1EapChQoVKlSoMFI897nPxeTkJD71qU/hZS972dD7z33uc1hdXcWll15aKB/HceB5XmoY27YL5VEGvvvd7+L//b//hz/4gz/A2972ttC7j3zkI1hYWFgfwSpUqLCpUO3cqVChJDiOg3e961046aSTUK/XccIJJ+Btb3sber1eKJy4E+bmm2/G4x//eDSbTXz0ox/138nniwkhif/ke1m+9rWv4dxzz0W73cbMzAx+7dd+DT/96U9D+Ypz0nfeeSde/vKXY2ZmBtPT07j88svR6XRCea6uruITn/iEn5eQ6d5778VrXvMaPPrRj0az2cTWrVvxG7/xG7nviLnrrrtw2mmnDRE7ALBjx47Q36r1K/ClL30JZ5xxBhqNBk499VT84z/+41CYhYUFvPGNb8Rxxx2Her2Ok08+Ge95z3syFcE03H777XjhC1+ILVu2oNFo4PGPfzw+//nPD4X78Y9/jKc97WloNps49thj8e53vzs2X8/zcPXVV+OYY45Bq9XCU5/6VPzkJz+JPYuuWp6/+7u/w5lnnonJyUlMTU3hsY99bLVTqkKFChUqjA3NZhO//uu/jq9+9auxzpxPfepTmJycxHOf+1wAauvbPffcA0II/viP/xgf/OAHfX3hz/7sz/CEJzwBAHD55Zf7us2NN94IIP7OHc/z8KEPfQiPfexj0Wg0sH37djzzmc8MHde/4YYb8LSnPQ07duxAvV7Hqaeeiuuvvz5Xfdx1110AgHPOOWfonWmaQ7uXvv/97+Piiy/G1NQUJiYm8PSnPz1xd0+n08EVV1yBrVu3YmpqCi972ctw5MiRoXBf+MIXfF1ycnISz3rWs/DjH/84V3kAVocf/OAHcdppp6HRaGDnzp244oorhvKmlOLd7343jj32WF/PScr3Bz/4Ac4777yQ7nTDDTfE3leoUp79+/fj8ssvx7HHHot6vY7du3fj137t16q7DytsWlQ7dypUSMHi4iIOHz489HwwGAw9e+UrX4lPfOITeOELX4g3v/nN+K//+i9ce+21+OlPfzq07fiOO+7AS1/6UlxxxRV41atehUc/+tGx+X/yk58cevb//X//Hw4ePIiJiQkAwFe+8hVcfPHFeMQjHoGrr74aa2tr+PCHP4xzzjkH3/ve94YUlhe96EU48cQTce211+J73/se/vIv/xI7duzAe97zHj/PV77ylXjiE5+IV7/61QCAk046CQDzLH3729/GS17yEhx77LG45557cP311+P888/HT37yE7RarYwaDWPv3r245ZZb8KMf/SjzDiOd+t23bx9e/OIX43d+53dw2WWX4YYbbsBv/MZv4Itf/CIuuOACAEzZOe+88/Dggw/iiiuuwPHHH49vf/vbuOqqq/Dwww/jgx/8oFZZAEbYnHPOOdizZw9+7/d+D+12GzfddBOe97zn4R/+4R/w/Oc/HwBTJp761KfCcRw/3Mc+9jE0m82hNK+66iq8973vxXOe8xxcdNFFuO2223DRRReh2+2GwqmW58tf/jJe+tKX4ulPf7rf5j/96U/xrW99C294wxu0y1yhQoUKFSrkwaWXXopPfOITuOmmm/C6173Ofz4/P4+bb74ZL33pS9FsNrXX6xtuuAHdbhevfvWrUa/X8fznPx/Ly8t4xzvegVe/+tU499xzAQBPetKTEmV7xStegRtvvBEXX3wxXvnKV8JxHHzzm9/Ed77zHTz+8Y8HAFx//fU47bTT8NznPheWZeFf/uVf8JrXvAae5+G1r32tVl3s3bsXAPC3f/u3OOecc2BZySbaj3/8Y5x77rmYmprCW9/6Vti2jY9+9KM4//zz8Y1vfANnnXVWKPzrXvc6zMzM4Oqrr8Ydd9yB66+/Hvfee6//8QuA6X6XXXYZLrroIrznPe9Bp9PB9ddfjyc/+cn4/ve/n+vC6SuuuAI33ngjLr/8crz+9a/H3XffjY985CP4/ve/j29961v+jql3vOMdePe7341LLrkEl1xyCb73ve/hwgsvRL/fD6X34IMP4qlPfSoIIbjqqqvQbrfxl3/5l7G73lXL84IXvAA//vGPceWVV+KEE07AwYMH8eUvfxn33XffSC/ZrlBhZKAVKlQYwg033EABpP477bTT/PC33norBUBf+cpXhtJ5y1veQgHQr33ta/6zvXv3UgD0i1/84lC+e/fupZdddlmiXO9973spAPrXf/3X/rMzzjiD7tixg87NzfnPbrvtNmoYBn3Zy17mP3vnO99JAdDf/u3fDqX5/Oc/n27dujX0rN1ux8rR6XSGnt1yyy1DMn3961+nAOjXv/71xLJQSumXvvQlapomNU2Tnn322fStb30rvfnmm2m/3w+Fy1O///AP/+A/W1xcpLt376a//Mu/7D9717veRdvtNv3Zz34WSvP3fu/3qGma9L777vOfAaDvfOc7U8tCKaVPf/rT6WMf+1ja7Xb9Z57n0Sc96Un0kY98pP/sjW98IwVA/+u//st/dvDgQTo9PU0B0LvvvptSSun+/fupZVn0ec97Xiifq6++mgIItZFqed7whjfQqakp6jhOZnkqVKhQoUKFUcFxHLp792569tlnh57/+Z//OQVAb775Zkqp+vp29913UwB0amqKHjx4MBT2u9/9LgVAb7jhhiE5LrvsMrp3717/76997WsUAH39618/FNbzPP/3OJ3ooosuoo94xCNCz8477zx63nnnDVdAJN3zzjuPAqA7d+6kL33pS+l1111H77333qGwz3ve82itVqN33XWX/+yhhx6ik5OT9ClPeYr/TOiyZ55
"text/plain": [
"<Figure size 1400x1000 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.figure(figsize=(14, 10))\n",
"\n",
"sobel = tf.image.sobel_edges(content_image)\n",
"plt.subplot(1, 2, 1)\n",
"imshow(clip_0_1(sobel[..., 0]/4+0.5), \"Horizontal Sobel-edges\")\n",
"plt.subplot(1, 2, 2)\n",
"imshow(clip_0_1(sobel[..., 1]/4+0.5), \"Vertical Sobel-edges\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "vv5bKlSDnPP7"
},
"source": [
"The regularization loss associated with this is the sum of the squares of the values:"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:36:28.410709Z",
"iopub.status.busy": "2023-11-16T03:36:28.410447Z",
"iopub.status.idle": "2023-11-16T03:36:28.414372Z",
"shell.execute_reply": "2023-11-16T03:36:28.413690Z"
},
"id": "mP-92lXMIYPn"
},
"outputs": [],
"source": [
"def total_variation_loss(image):\n",
" x_deltas, y_deltas = high_pass_x_y(image)\n",
" return tf.reduce_sum(tf.abs(x_deltas)) + tf.reduce_sum(tf.abs(y_deltas))"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:36:28.417541Z",
"iopub.status.busy": "2023-11-16T03:36:28.417005Z",
"iopub.status.idle": "2023-11-16T03:36:28.426670Z",
"shell.execute_reply": "2023-11-16T03:36:28.426108Z"
},
"id": "s4OYBUX2KQ25"
},
"outputs": [
{
"data": {
"text/plain": [
"56826.945"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"total_variation_loss(image).numpy()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "pu2hJ8zOKMc1"
},
"source": [
"That demonstrated what it does. But there's no need to implement it yourself, TensorFlow includes a standard implementation:"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:36:28.430127Z",
"iopub.status.busy": "2023-11-16T03:36:28.429584Z",
"iopub.status.idle": "2023-11-16T03:36:28.436614Z",
"shell.execute_reply": "2023-11-16T03:36:28.436039Z"
},
"id": "YQjWW04NKLfJ"
},
"outputs": [
{
"data": {
"text/plain": [
"array([56826.945], dtype=float32)"
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tf.image.total_variation(image).numpy()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "nTessd-DCdcC"
},
"source": [
"## Re-run the optimization\n",
"\n",
"Choose a weight for the `total_variation_loss`:"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:36:28.439704Z",
"iopub.status.busy": "2023-11-16T03:36:28.439220Z",
"iopub.status.idle": "2023-11-16T03:36:28.442092Z",
"shell.execute_reply": "2023-11-16T03:36:28.441561Z"
},
"id": "tGeRLD4GoAd4"
},
"outputs": [],
"source": [
"total_variation_weight=30"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "kG1-T4kJsoAv"
},
"source": [
"Now include it in the `train_step` function:"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:36:28.445174Z",
"iopub.status.busy": "2023-11-16T03:36:28.444649Z",
"iopub.status.idle": "2023-11-16T03:36:28.452936Z",
"shell.execute_reply": "2023-11-16T03:36:28.452367Z"
},
"id": "BzmfcyyYUyWq"
},
"outputs": [],
"source": [
"@tf.function()\n",
"def train_step(image):\n",
" with tf.GradientTape() as tape:\n",
" outputs = extractor(image)\n",
" loss = style_content_loss(outputs)\n",
" loss += total_variation_weight*tf.image.total_variation(image)\n",
"\n",
" grad = tape.gradient(loss, image)\n",
" opt.apply_gradients([(grad, image)])\n",
" image.assign(clip_0_1(image))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "lcLWBQChsutQ"
},
"source": [
"Reinitialize the image-variable and the optimizer:"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:36:28.455824Z",
"iopub.status.busy": "2023-11-16T03:36:28.455522Z",
"iopub.status.idle": "2023-11-16T03:36:28.460788Z",
"shell.execute_reply": "2023-11-16T03:36:28.460227Z"
},
"id": "a-dPRr8BqexB"
},
"outputs": [],
"source": [
"opt = tf.keras.optimizers.Adam(learning_rate=0.02, beta_1=0.99, epsilon=1e-1)\n",
"image = tf.Variable(content_image)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "BEflRstmtGBu"
},
"source": [
"And run the optimization:"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-16T03:36:28.463940Z",
"iopub.status.busy": "2023-11-16T03:36:28.463420Z",
"iopub.status.idle": "2023-11-16T03:37:43.245043Z",
"shell.execute_reply": "2023-11-16T03:37:43.244317Z"
},
"id": "q3Cc3bLtoOWy"
},
"outputs": [
{
"data": {
"image/jpeg": "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
"image/png": "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
"text/plain": [
"<PIL.Image.Image image mode=RGB size=512x288>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Train step: 1000\n",
"Total time: 71.3\n"
]
}
],
"source": [
"import time\n",
"start = time.time()\n",
"\n",
"epochs = 10\n",
"steps_per_epoch = 100\n",
"\n",
"step = 0\n",
"for n in range(epochs):\n",
" for m in range(steps_per_epoch):\n",
" step += 1\n",
" train_step(image)\n",
" print(\".\", end='', flush=True)\n",
" display.clear_output(wait=True)\n",
" display.display(tensor_to_image(image))\n",
" print(\"Train step: {}\".format(step))\n",
"\n",
"end = time.time()\n",
"print(\"Total time: {:.1f}\".format(end-start))"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<tf.Variable 'Variable:0' shape=(1, 422, 512, 3) dtype=float32, numpy=\n",
"array([[[[5.2192467e-01, 3.5730761e-01, 4.3012524e-01],\n",
" [5.2258748e-01, 3.5042602e-01, 4.2847326e-01],\n",
" [5.2142912e-01, 3.3703288e-01, 4.6795484e-01],\n",
" ...,\n",
" [3.5259786e-01, 2.0069836e-01, 0.0000000e+00],\n",
" [3.7858683e-01, 8.8987187e-02, 0.0000000e+00],\n",
" [3.7882906e-01, 8.8669561e-02, 0.0000000e+00]],\n",
"\n",
" [[5.2074802e-01, 3.5717541e-01, 4.3073651e-01],\n",
" [5.2213031e-01, 3.5292444e-01, 4.2814627e-01],\n",
" [5.1997304e-01, 3.3482769e-01, 4.7205076e-01],\n",
" ...,\n",
" [3.5210976e-01, 2.1672039e-01, 0.0000000e+00],\n",
" [3.9774185e-01, 9.4535254e-02, 0.0000000e+00],\n",
" [4.0475607e-01, 9.9769264e-02, 0.0000000e+00]],\n",
"\n",
" [[5.2096248e-01, 4.2476922e-01, 5.6723040e-01],\n",
" [5.1835060e-01, 3.7873101e-01, 5.5380058e-01],\n",
" [5.1772678e-01, 3.3783364e-01, 5.5342436e-01],\n",
" ...,\n",
" [3.5153681e-01, 2.9214185e-01, 0.0000000e+00],\n",
" [4.0174142e-01, 2.9518455e-01, 0.0000000e+00],\n",
" [4.1466421e-01, 2.9645365e-01, 9.2595583e-06]],\n",
"\n",
" ...,\n",
"\n",
" [[7.7451438e-01, 6.1107898e-01, 4.9147427e-01],\n",
" [7.9484630e-01, 5.3058982e-01, 4.9114281e-01],\n",
" [5.5543298e-01, 5.2111608e-01, 4.6575382e-01],\n",
" ...,\n",
" [4.6427000e-01, 5.5372471e-01, 5.6248754e-01],\n",
" [2.1076988e-01, 3.1807196e-01, 5.5500793e-01],\n",
" [2.0806797e-01, 3.1826279e-01, 5.5626237e-01]],\n",
"\n",
" [[5.5564922e-01, 5.2309209e-01, 4.7513846e-01],\n",
" [5.5392897e-01, 5.2152395e-01, 4.7580311e-01],\n",
" [5.5371583e-01, 5.1829290e-01, 4.6731946e-01],\n",
" ...,\n",
" [4.6132144e-01, 5.4868215e-01, 5.6376553e-01],\n",
" [1.7865986e-01, 2.9668301e-01, 5.6151551e-01],\n",
" [1.6780509e-01, 2.9647833e-01, 5.6041163e-01]],\n",
"\n",
" [[5.5324817e-01, 5.2326709e-01, 4.7086918e-01],\n",
" [5.5364186e-01, 5.2139556e-01, 4.7007531e-01],\n",
" [5.5321431e-01, 5.1366639e-01, 4.7087216e-01],\n",
" ...,\n",
" [4.6121120e-01, 5.4781228e-01, 5.6475556e-01],\n",
" [1.7181176e-01, 2.9641071e-01, 5.6171346e-01],\n",
" [1.7033017e-01, 2.9690620e-01, 5.5929840e-01]]]], dtype=float32)>"
]
},
"execution_count": 44,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"image"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "tNlwRXagxQZk"
},
"source": [
"## Learn more\n",
"\n",
"This tutorial demonstrates the original style-transfer algorithm. For a simple application of style transfer check out this [tutorial](https://www.tensorflow.org/hub/tutorials/tf2_arbitrary_image_stylization) to learn more about how to use the arbitrary image style transfer model from [TensorFlow Hub](https://tfhub.dev)."
]
}
],
"metadata": {
"accelerator": "GPU",
"colab": {
"collapsed_sections": [],
"name": "style_transfer.ipynb",
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
}
},
"nbformat": 4,
"nbformat_minor": 0
}