{"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 Tensorflow Sample\nThis notebook reffered to Tensorflow Tutorials 'Neural style transfer'<br/>\nhttps://github.com/tensorflow/docs/blob/master/site/en/tutorials/generative/style_transfer.ipynb","metadata":{"id":"6msVLevwcRhm"}},{"cell_type":"markdown","source":"### Import and configure modules","metadata":{"id":"eqxUicSPUOP6"}},{"cell_type":"code","source":"import os\nimport numpy as np\nimport PIL.Image\nimport time\nimport functools\nimport tensorflow as tf\nimport IPython.display as display\nimport matplotlib.pyplot as plt\nimport matplotlib as mpl\nmpl.rcParams['figure.figsize'] = (12, 12)\nmpl.rcParams['axes.grid'] = False","metadata":{"id":"sc1OLbOWhPCO","execution":{"iopub.status.busy":"2021-11-03T03:08:03.043433Z","iopub.execute_input":"2021-11-03T03:08:03.043937Z","iopub.status.idle":"2021-11-03T03:08:03.050671Z","shell.execute_reply.started":"2021-11-03T03:08:03.043874Z","shell.execute_reply":"2021-11-03T03:08:03.049819Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","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)","metadata":{"id":"GM6VEGrGLh62","execution":{"iopub.status.busy":"2021-11-03T03:08:03.052297Z","iopub.execute_input":"2021-11-03T03:08:03.052799Z","iopub.status.idle":"2021-11-03T03:08:03.073Z","shell.execute_reply.started":"2021-11-03T03:08:03.052719Z","shell.execute_reply":"2021-11-03T03:08:03.071834Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"content_path0='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_path0='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-03T03:08:03.074502Z","iopub.execute_input":"2021-11-03T03:08:03.075126Z","iopub.status.idle":"2021-11-03T03:08:03.087329Z","shell.execute_reply.started":"2021-11-03T03:08:03.075075Z","shell.execute_reply":"2021-11-03T03:08:03.086589Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"content_path = tf.keras.utils.get_file(\"Content.jpg\", content_path0)\nstyle_path = tf.keras.utils.get_file(\"Style.jpg\", style_path0)","metadata":{"execution":{"iopub.status.busy":"2021-11-03T03:08:03.090033Z","iopub.execute_input":"2021-11-03T03:08:03.090569Z","iopub.status.idle":"2021-11-03T03:08:04.422031Z","shell.execute_reply.started":"2021-11-03T03:08:03.09052Z","shell.execute_reply":"2021-11-03T03:08:04.420989Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","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","metadata":{"id":"3TLljcwv5qZs","execution":{"iopub.status.busy":"2021-11-03T03:08:04.423893Z","iopub.execute_input":"2021-11-03T03:08:04.424422Z","iopub.status.idle":"2021-11-03T03:08:04.433Z","shell.execute_reply.started":"2021-11-03T03:08:04.424372Z","shell.execute_reply":"2021-11-03T03:08:04.432093Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","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)","metadata":{"id":"cBX-eNT8PAK_","execution":{"iopub.status.busy":"2021-11-03T03:08:04.434475Z","iopub.execute_input":"2021-11-03T03:08:04.434834Z","iopub.status.idle":"2021-11-03T03:08:04.461099Z","shell.execute_reply.started":"2021-11-03T03:08:04.434806Z","shell.execute_reply":"2021-11-03T03:08:04.459988Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"content_image = load_img(content_path)\nstyle_image = load_img(style_path)\n\nplt.subplot(1, 2, 1)\nimshow(content_image, 'Content Image')\n\nplt.subplot(1, 2, 2)\nimshow(style_image, 'Style Image')","metadata":{"id":"_UWQmeEaiKkP","execution":{"iopub.status.busy":"2021-11-03T03:08:04.462678Z","iopub.execute_input":"2021-11-03T03:08:04.46389Z","iopub.status.idle":"2021-11-03T03:08:05.340068Z","shell.execute_reply.started":"2021-11-03T03:08:04.46385Z","shell.execute_reply":"2021-11-03T03:08:05.339163Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x = tf.keras.applications.vgg19.preprocess_input(content_image*255)\nx = tf.image.resize(x, (224, 224))\nvgg = tf.keras.applications.VGG19(include_top=True, weights='imagenet')\nprediction_probabilities = vgg(x)\nprediction_probabilities.shape","metadata":{"id":"fMbzrr7BCTq0","execution":{"iopub.status.busy":"2021-11-03T03:08:05.341276Z","iopub.execute_input":"2021-11-03T03:08:05.34156Z","iopub.status.idle":"2021-11-03T03:08:10.771786Z","shell.execute_reply.started":"2021-11-03T03:08:05.341528Z","shell.execute_reply":"2021-11-03T03:08:10.770959Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","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]","metadata":{"id":"1_FyCm0dYnvl","execution":{"iopub.status.busy":"2021-11-03T03:08:10.772833Z","iopub.execute_input":"2021-11-03T03:08:10.773091Z","iopub.status.idle":"2021-11-03T03:08:10.803702Z","shell.execute_reply.started":"2021-11-03T03:08:10.773064Z","shell.execute_reply":"2021-11-03T03:08:10.802878Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vgg = tf.keras.applications.VGG19(include_top=False, weights='imagenet')\n\nprint()\nfor layer in vgg.layers:\n  print(layer.name)","metadata":{"id":"Yh_AV6220ebD","execution":{"iopub.status.busy":"2021-11-03T03:08:10.805041Z","iopub.execute_input":"2021-11-03T03:08:10.805337Z","iopub.status.idle":"2021-11-03T03:08:11.686504Z","shell.execute_reply.started":"2021-11-03T03:08:10.805298Z","shell.execute_reply":"2021-11-03T03:08:11.685598Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Choose intermediate layers from the network to represent the style and content of the image:\n","metadata":{"id":"Wt-tASys0eJv"}},{"cell_type":"code","source":"content_layers = ['block5_conv2'] \n\nstyle_layers = ['block1_conv1',\n                'block2_conv1',\n                'block3_conv1', \n                'block4_conv1', \n                'block5_conv1']\n\nnum_content_layers = len(content_layers)\nnum_style_layers = len(style_layers)","metadata":{"id":"ArfX_6iA0WAX","execution":{"iopub.status.busy":"2021-11-03T03:08:11.687757Z","iopub.execute_input":"2021-11-03T03:08:11.687999Z","iopub.status.idle":"2021-11-03T03:08:11.693666Z","shell.execute_reply.started":"2021-11-03T03:08:11.68797Z","shell.execute_reply":"2021-11-03T03:08:11.692697Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","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","metadata":{"id":"nfec6MuMAbPx","execution":{"iopub.status.busy":"2021-11-03T03:08:11.694897Z","iopub.execute_input":"2021-11-03T03:08:11.695166Z","iopub.status.idle":"2021-11-03T03:08:11.706167Z","shell.execute_reply.started":"2021-11-03T03:08:11.695128Z","shell.execute_reply":"2021-11-03T03:08:11.705334Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"style_extractor = vgg_layers(style_layers)\nstyle_outputs = style_extractor(style_image*255)\n\n#Look at the statistics of each layer's output\nfor 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()","metadata":{"id":"LkyvPpBHSfVi","execution":{"iopub.status.busy":"2021-11-03T03:08:11.70952Z","iopub.execute_input":"2021-11-03T03:08:11.710068Z","iopub.status.idle":"2021-11-03T03:08:14.230345Z","shell.execute_reply.started":"2021-11-03T03:08:11.710024Z","shell.execute_reply":"2021-11-03T03:08:14.229368Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","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)","metadata":{"id":"HAy1iGPdoEpZ","execution":{"iopub.status.busy":"2021-11-03T03:08:14.231991Z","iopub.execute_input":"2021-11-03T03:08:14.232294Z","iopub.status.idle":"2021-11-03T03:08:14.237865Z","shell.execute_reply.started":"2021-11-03T03:08:14.232252Z","shell.execute_reply":"2021-11-03T03:08:14.236996Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","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}","metadata":{"id":"Sr6QALY-I1ja","execution":{"iopub.status.busy":"2021-11-03T03:08:14.23929Z","iopub.execute_input":"2021-11-03T03:08:14.23953Z","iopub.status.idle":"2021-11-03T03:08:14.531808Z","shell.execute_reply.started":"2021-11-03T03:08:14.239499Z","shell.execute_reply":"2021-11-03T03:08:14.530555Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"extractor = StyleContentModel(style_layers, content_layers)\n\nresults = extractor(tf.constant(content_image))\n\nprint('Styles:')\nfor 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\nprint(\"Contents:\")\nfor 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","metadata":{"id":"rkjO-DoNDU0A","execution":{"iopub.status.busy":"2021-11-03T03:08:14.535852Z","iopub.execute_input":"2021-11-03T03:08:14.536146Z","iopub.status.idle":"2021-11-03T03:08:17.307555Z","shell.execute_reply.started":"2021-11-03T03:08:14.536115Z","shell.execute_reply":"2021-11-03T03:08:17.306434Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"style_targets = extractor(style_image)['style']\ncontent_targets = extractor(content_image)['content']","metadata":{"id":"PgkNOnGUFcKa","execution":{"iopub.status.busy":"2021-11-03T03:08:17.309612Z","iopub.execute_input":"2021-11-03T03:08:17.310138Z","iopub.status.idle":"2021-11-03T03:08:21.817603Z","shell.execute_reply.started":"2021-11-03T03:08:17.310094Z","shell.execute_reply":"2021-11-03T03:08:21.81651Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image = tf.Variable(content_image)","metadata":{"id":"J0vKxF8ZO6G8","execution":{"iopub.status.busy":"2021-11-03T03:08:21.819039Z","iopub.execute_input":"2021-11-03T03:08:21.820531Z","iopub.status.idle":"2021-11-03T03:08:21.826528Z","shell.execute_reply.started":"2021-11-03T03:08:21.820494Z","shell.execute_reply":"2021-11-03T03:08:21.825657Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def clip_0_1(image):\n  return tf.clip_by_value(image, clip_value_min=0.0, clip_value_max=1.0)","metadata":{"id":"kdgpTJwL_vE2","execution":{"iopub.status.busy":"2021-11-03T03:08:21.827977Z","iopub.execute_input":"2021-11-03T03:08:21.828964Z","iopub.status.idle":"2021-11-03T03:08:23.878762Z","shell.execute_reply.started":"2021-11-03T03:08:21.828743Z","shell.execute_reply":"2021-11-03T03:08:23.877291Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"opt = tf.optimizers.Adam(learning_rate=0.02, beta_1=0.99, epsilon=1e-1)","metadata":{"id":"r4XZjqUk_5Eu","execution":{"iopub.status.busy":"2021-11-03T03:08:23.881241Z","iopub.execute_input":"2021-11-03T03:08:23.881797Z","iopub.status.idle":"2021-11-03T03:08:23.893679Z","shell.execute_reply.started":"2021-11-03T03:08:23.881743Z","shell.execute_reply":"2021-11-03T03:08:23.892811Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"style_weight=1e-2\ncontent_weight=1e4","metadata":{"id":"Dt4pxarvA4I4","execution":{"iopub.status.busy":"2021-11-03T03:08:23.895394Z","iopub.execute_input":"2021-11-03T03:08:23.895618Z","iopub.status.idle":"2021-11-03T03:08:23.9083Z","shell.execute_reply.started":"2021-11-03T03:08:23.895592Z","shell.execute_reply":"2021-11-03T03:08:23.906649Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","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","metadata":{"id":"0ggx2Na8oROH","execution":{"iopub.status.busy":"2021-11-03T03:08:23.911061Z","iopub.execute_input":"2021-11-03T03:08:23.911663Z","iopub.status.idle":"2021-11-03T03:08:23.926281Z","shell.execute_reply.started":"2021-11-03T03:08:23.911619Z","shell.execute_reply":"2021-11-03T03:08:23.925185Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"@tf.function()\ndef 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))","metadata":{"id":"0t0umkajFIuh","execution":{"iopub.status.busy":"2021-11-03T03:08:23.928172Z","iopub.execute_input":"2021-11-03T03:08:23.928564Z","iopub.status.idle":"2021-11-03T03:08:23.94154Z","shell.execute_reply.started":"2021-11-03T03:08:23.928534Z","shell.execute_reply":"2021-11-03T03:08:23.940128Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_step(image)\ntrain_step(image)\ntrain_step(image)\ntensor_to_image(image)","metadata":{"id":"Y542mxi-O2a2","execution":{"iopub.status.busy":"2021-11-03T03:08:23.944106Z","iopub.execute_input":"2021-11-03T03:08:23.944361Z","iopub.status.idle":"2021-11-03T03:08:38.64878Z","shell.execute_reply.started":"2021-11-03T03:08:23.944334Z","shell.execute_reply":"2021-11-03T03:08:38.647646Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import time\nstart = time.time()\n\nepochs = 10\nsteps_per_epoch = 100\n\nstep = 0\nfor 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  \nend = time.time()\nprint(\"Total time: {:.1f}\".format(end-start))","metadata":{"id":"rQW1tXYoLbUS","execution":{"iopub.status.busy":"2021-11-03T03:08:38.650552Z","iopub.execute_input":"2021-11-03T03:08:38.650847Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","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","metadata":{"id":"7szUUybCQMB3","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x_deltas, y_deltas = high_pass_x_y(content_image)\n\nplt.figure(figsize=(14, 10))\nplt.subplot(2, 2, 1)\nimshow(clip_0_1(2*y_deltas+0.5), \"Horizontal Deltas: Original\")\n\nplt.subplot(2, 2, 2)\nimshow(clip_0_1(2*x_deltas+0.5), \"Vertical Deltas: Original\")\n\nx_deltas, y_deltas = high_pass_x_y(image)\n\nplt.subplot(2, 2, 3)\nimshow(clip_0_1(2*y_deltas+0.5), \"Horizontal Deltas: Styled\")\n\nplt.subplot(2, 2, 4)\nimshow(clip_0_1(2*x_deltas+0.5), \"Vertical Deltas: Styled\")","metadata":{"id":"Atc2oL29PXu_","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(14, 10))\n\nsobel = tf.image.sobel_edges(content_image)\nplt.subplot(1, 2, 1)\nimshow(clip_0_1(sobel[..., 0]/4+0.5), \"Horizontal Sobel-edges\")\nplt.subplot(1, 2, 2)\nimshow(clip_0_1(sobel[..., 1]/4+0.5), \"Vertical Sobel-edges\")","metadata":{"id":"HyvqCiywiUfL","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","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))","metadata":{"id":"mP-92lXMIYPn","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"total_variation_loss(image).numpy()","metadata":{"id":"s4OYBUX2KQ25","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tf.image.total_variation(image).numpy()","metadata":{"id":"YQjWW04NKLfJ","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"total_variation_weight=30","metadata":{"id":"tGeRLD4GoAd4","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"@tf.function()\ndef 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))","metadata":{"id":"BzmfcyyYUyWq","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image = tf.Variable(content_image)","metadata":{"id":"a-dPRr8BqexB","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import time\nstart = time.time()\n\nepochs = 10\nsteps_per_epoch = 100\n\nstep = 0\nfor 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\nend = time.time()\nprint(\"Total time: {:.1f}\".format(end-start))","metadata":{"id":"q3Cc3bLtoOWy","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"file_name = 'stylized-image.png'\ntensor_to_image(image).save(file_name)\n\ntry:\n  from google.colab import files\nexcept ImportError:\n   pass\nelse:\n  files.download(file_name)","metadata":{"id":"SSH6OpyyQn7w","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":[]}]}