{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Style Transfer Keras Sample\nThis notebook used Keras Code Example.<br/>\nhttps://keras.io/examples/generative/neural_style_transfer/","metadata":{"id":"Ew2u8xdYgS-G"}},{"cell_type":"code","source":"import numpy as np\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras.applications import vgg19","metadata":{"execution":{"iopub.status.busy":"2021-11-03T02:52:35.143226Z","iopub.execute_input":"2021-11-03T02:52:35.143742Z","iopub.status.idle":"2021-11-03T02:52:41.145882Z","shell.execute_reply.started":"2021-11-03T02:52:35.143642Z","shell.execute_reply":"2021-11-03T02:52:41.145074Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"content_path='https://storage.googleapis.com/kagglesdsdata/competitions/21755/1475600/photo_jpg/009ddaed1f.jpg?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=databundle-worker-v2%40kaggle-161607.iam.gserviceaccount.com%2F20211031%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20211031T130537Z&X-Goog-Expires=345599&X-Goog-SignedHeaders=host&X-Goog-Signature=9d47286638e7971fad55e71b1620ab409f3aae78e513d23aac5a7853efffa083d78681d728bdf05d8c128ba030d5408cf3cfe1cfa330d2c091cfbdb2843e5aa57507acbd5e251c237d44ba95ec395317f727b58acd8c765fc23e3b051c6f5d2fe4887b9edae7970f4290e27d3281b60447b3ffa7625414b8718b9bb60fb8ec05fc3d03c667240c4d2abaf3f4225a420f9a1bd7558a7d45367b2938ef15485adc0a8118022d9cfd952c866ded67591fae445821cf423ff0ac04a3c39f74a8d8e06f33302ce25441e12a6c93133cfc6e79bb8d74f8984a7b2ab85eab741c43b0ec54f4e81a0aeffa1844d21d9f4e8fbf0277af6a35cc058070bc3d1400af16f772'\nstyle_path='https://storage.googleapis.com/kagglesdsdata/competitions/21755/1475600/monet_jpg/0e3b3292da.jpg?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=databundle-worker-v2%40kaggle-161607.iam.gserviceaccount.com%2F20211101%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20211101T140027Z&X-Goog-Expires=345599&X-Goog-SignedHeaders=host&X-Goog-Signature=877fe59481f2744bd0a3d856808ca06e12a4b2f16a8dc3d1ef0b2a8a58ad10b2c8fdcf66240a23833076c93ec3cb2f919efa16517be1f48259357c7c8267b7cfa679859dfcb8f237bebc1f59eace3d0c4464a45560efe0e0626217832016715f80c2293dccd56e32e2abfde90f27c17ba785df611220b3a948c8ccc972c0b0a97ec28d25af176da5f763135864060445a8eed4e8921249d222f0a46f1acee6b632c1f3a92189c0ea2f85dd2424c59d9fb9b33e4ad5f7adc7740e82d295a47bde6a3f3b4a9a19b63f8e8c44e5ecc1813732da53e2b38338f7f35df1e8d4b263577dd6615633bd92b4dcf0b56b278af6e3e2717d1be9034f5b26177aeb935a8fd9'","metadata":{"execution":{"iopub.status.busy":"2021-11-03T01:11:16.176751Z","iopub.execute_input":"2021-11-03T01:11:16.177187Z","iopub.status.idle":"2021-11-03T01:11:16.182049Z","shell.execute_reply.started":"2021-11-03T01:11:16.177152Z","shell.execute_reply":"2021-11-03T01:11:16.181205Z"}},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_image_path = keras.utils.get_file(\"Content.jpg\", content_path)\nstyle_reference_image_path = keras.utils.get_file(\"Style.jpg\", style_path)\nresult_prefix = \"Stylized\"","metadata":{"execution":{"iopub.status.busy":"2021-11-03T02:52:41.153809Z","iopub.execute_input":"2021-11-03T02:52:41.154535Z","iopub.status.idle":"2021-11-03T02:52:41.640254Z","shell.execute_reply.started":"2021-11-03T02:52:41.154494Z","shell.execute_reply":"2021-11-03T02:52:41.638270Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Weights of the different loss components\ntotal_variation_weight = 1e-6\nstyle_weight = 1e-6\ncontent_weight = 2.5e-8\n\n# Dimensions of the generated picture.\nwidth, height = keras.preprocessing.image.load_img(base_image_path).size\nimg_nrows = 400\nimg_ncols = int(width * img_nrows / height)","metadata":{"id":"Jv83t7-lgS-G","execution":{"iopub.status.busy":"2021-11-03T02:52:41.641226Z","iopub.status.idle":"2021-11-03T02:52:41.641851Z","shell.execute_reply.started":"2021-11-03T02:52:41.641641Z","shell.execute_reply":"2021-11-03T02:52:41.641670Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Content image and Style Image","metadata":{"id":"WgZ5kbcbgS-I"}},{"cell_type":"code","source":"from IPython.display import Image, display\n\ndisplay(Image(base_image_path))\ndisplay(Image(style_reference_image_path))","metadata":{"id":"yaZiDF-JgS-I","execution":{"iopub.status.busy":"2021-11-03T02:52:41.642925Z","iopub.status.idle":"2021-11-03T02:52:41.643252Z","shell.execute_reply.started":"2021-11-03T02:52:41.643075Z","shell.execute_reply":"2021-11-03T02:52:41.643099Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Image preprocessing / deprocessing utilities\n","metadata":{"id":"eRzKeZg-gS-J"}},{"cell_type":"code","source":"def preprocess_image(image_path):\n    # Util function to open, resize and format pictures into appropriate tensors\n    img = keras.preprocessing.image.load_img(\n        image_path, target_size=(img_nrows, img_ncols)\n    )\n    img = keras.preprocessing.image.img_to_array(img)\n    img = np.expand_dims(img, axis=0)\n    img = vgg19.preprocess_input(img)\n    return tf.convert_to_tensor(img)\n\n\ndef deprocess_image(x):\n    # Util function to convert a tensor into a valid image\n    x = x.reshape((img_nrows, img_ncols, 3))\n    # Remove zero-center by mean pixel\n    x[:, :, 0] += 103.939\n    x[:, :, 1] += 116.779\n    x[:, :, 2] += 123.68\n    # 'BGR'->'RGB'\n    x = x[:, :, ::-1]\n    x = np.clip(x, 0, 255).astype(\"uint8\")\n    return x","metadata":{"id":"wk9zcqFBgS-K","execution":{"iopub.status.busy":"2021-11-03T02:52:41.644394Z","iopub.status.idle":"2021-11-03T02:52:41.644707Z","shell.execute_reply.started":"2021-11-03T02:52:41.644559Z","shell.execute_reply":"2021-11-03T02:52:41.644575Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def gram_matrix(x):\n    x = tf.transpose(x, (2, 0, 1))\n    features = tf.reshape(x, (tf.shape(x)[0], -1))\n    gram = tf.matmul(features, tf.transpose(features))\n    return gram\n\n\ndef style_loss(style, combination):\n    S = gram_matrix(style)\n    C = gram_matrix(combination)\n    channels = 3\n    size = img_nrows * img_ncols\n    return tf.reduce_sum(tf.square(S - C)) / (4.0 * (channels ** 2) * (size ** 2))\n\n\ndef content_loss(base, combination):\n    return tf.reduce_sum(tf.square(combination - base))\n\n\ndef total_variation_loss(x):\n    a = tf.square(\n        x[:, : img_nrows - 1, : img_ncols - 1, :] - x[:, 1:, : img_ncols - 1, :]\n    )\n    b = tf.square(\n        x[:, : img_nrows - 1, : img_ncols - 1, :] - x[:, : img_nrows - 1, 1:, :]\n    )\n    return tf.reduce_sum(tf.pow(a + b, 1.25))","metadata":{"id":"9AH1DhoYgS-M","execution":{"iopub.status.busy":"2021-11-03T02:52:41.645665Z","iopub.status.idle":"2021-11-03T02:52:41.645959Z","shell.execute_reply.started":"2021-11-03T02:52:41.645793Z","shell.execute_reply":"2021-11-03T02:52:41.645807Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = vgg19.VGG19(weights=\"imagenet\", include_top=False)\noutputs_dict = dict([(layer.name, layer.output) for layer in model.layers])\nfeature_extractor = keras.Model(inputs=model.inputs, outputs=outputs_dict)","metadata":{"id":"Modvp-JlgS-O","execution":{"iopub.status.busy":"2021-11-03T02:52:41.646898Z","iopub.status.idle":"2021-11-03T02:52:41.647392Z","shell.execute_reply.started":"2021-11-03T02:52:41.647220Z","shell.execute_reply":"2021-11-03T02:52:41.647238Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model","metadata":{"execution":{"iopub.status.busy":"2021-11-03T02:52:41.648298Z","iopub.status.idle":"2021-11-03T02:52:41.648602Z","shell.execute_reply.started":"2021-11-03T02:52:41.648446Z","shell.execute_reply":"2021-11-03T02:52:41.648462Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# List of layers to use for the style loss.\nstyle_layer_names = [\n    \"block1_conv1\",\n    \"block2_conv1\",\n    \"block3_conv1\",\n    \"block4_conv1\",\n    \"block5_conv1\",\n]\n# The layer to use for the content loss.\ncontent_layer_name = \"block5_conv2\"\n\n\ndef compute_loss(combination_image, base_image, style_reference_image):\n    input_tensor = tf.concat(\n        [base_image, style_reference_image, combination_image], axis=0\n    )\n    features = feature_extractor(input_tensor)\n\n    # Initialize the loss\n    loss = tf.zeros(shape=())\n\n    # Add content loss\n    layer_features = features[content_layer_name]\n    base_image_features = layer_features[0, :, :, :]\n    combination_features = layer_features[2, :, :, :]\n    loss = loss + content_weight * content_loss(\n        base_image_features, combination_features\n    )\n    # Add style loss\n    for layer_name in style_layer_names:\n        layer_features = features[layer_name]\n        style_reference_features = layer_features[1, :, :, :]\n        combination_features = layer_features[2, :, :, :]\n        sl = style_loss(style_reference_features, combination_features)\n        loss += (style_weight / len(style_layer_names)) * sl\n\n    # Add total variation loss\n    loss += total_variation_weight * total_variation_loss(combination_image)\n    return loss","metadata":{"id":"JE_iXiBXgS-P","execution":{"iopub.status.busy":"2021-11-03T02:52:41.649574Z","iopub.status.idle":"2021-11-03T02:52:41.649840Z","shell.execute_reply.started":"2021-11-03T02:52:41.649700Z","shell.execute_reply":"2021-11-03T02:52:41.649714Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"@tf.function\ndef compute_loss_and_grads(combination_image, base_image, style_reference_image):\n    with tf.GradientTape() as tape:\n        loss = compute_loss(combination_image, base_image, style_reference_image)\n    grads = tape.gradient(loss, combination_image)\n    return loss, grads","metadata":{"id":"5A69sovQgS-P","execution":{"iopub.status.busy":"2021-11-03T02:52:41.650919Z","iopub.status.idle":"2021-11-03T02:52:41.651212Z","shell.execute_reply.started":"2021-11-03T02:52:41.651052Z","shell.execute_reply":"2021-11-03T02:52:41.651067Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"optimizer = keras.optimizers.SGD(\n    keras.optimizers.schedules.ExponentialDecay(\n        initial_learning_rate=100.0, decay_steps=100, decay_rate=0.96\n    )\n)\n\nbase_image = preprocess_image(base_image_path)\nstyle_reference_image = preprocess_image(style_reference_image_path)\ncombination_image = tf.Variable(preprocess_image(base_image_path))\n\niterations = 1000\nfor i in range(1, iterations + 1):\n    loss, grads = compute_loss_and_grads(\n        combination_image, base_image, style_reference_image\n    )\n    optimizer.apply_gradients([(grads, combination_image)])\n    if i % 100 == 0:\n        print(\"Iteration %d: loss=%.2f\" % (i, loss))\n        img = deprocess_image(combination_image.numpy())\n        fname = result_prefix + \"_at_iteration_%d.png\" % i\n        keras.preprocessing.image.save_img(fname, img)\n","metadata":{"id":"I3ggeNBKgS-Q","execution":{"iopub.status.busy":"2021-11-03T02:52:41.651910Z","iopub.status.idle":"2021-11-03T02:52:41.652171Z","shell.execute_reply.started":"2021-11-03T02:52:41.652033Z","shell.execute_reply":"2021-11-03T02:52:41.652047Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"display(Image(result_prefix + \"_at_iteration_1000.png\"))","metadata":{"id":"mA8IGt-4gS-Q","execution":{"iopub.status.busy":"2021-11-03T02:52:41.653319Z","iopub.status.idle":"2021-11-03T02:52:41.653661Z","shell.execute_reply.started":"2021-11-03T02:52:41.653487Z","shell.execute_reply":"2021-11-03T02:52:41.653508Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Style Transfer TensorFlow Hub Sample<br/>\nhttps://www.kaggle.com/stpeteishii/style-transfer-tensorflow-hub-sample<br/>\nStyle Transfer Tensorflow Sample<br/>\nhttps://www.kaggle.com/stpeteishii/style-transfer-tensorflow-sample<br/>\nStyle Transfer Keras Sample<br/>\nhttps://www.kaggle.com/stpeteishii/style-transfer-keras-sample<br/>\nStyle Transfer Pytorch Sample<br/>\nhttps://www.kaggle.com/stpeteishii/style-transfer-pytorch-sample<br/>","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}