{"cells":[{"cell_type":"markdown","id":"c5a47d2f","metadata":{"id":"c5a47d2f"},"source":["# Transfer stylu\n"]},{"cell_type":"code","execution_count":null,"id":"6a607d86","metadata":{"id":"6a607d86"},"outputs":[],"source":["#1 Import bibliotek\n","import tensorflow as tf\n","from tensorflow.keras.applications import VGG16\n","from tensorflow.keras.applications.vgg16 import preprocess_input\n","from tensorflow.keras.models import Model\n","import numpy as np\n","import matplotlib.pyplot as plt\n","from PIL import Image"]},{"cell_type":"code","source":["#2 Funkcja ładująca grafikę\n"],"metadata":{"id":"qikHrkugoYi9"},"id":"qikHrkugoYi9","execution_count":null,"outputs":[]},{"cell_type":"code","source":["#3 Przetwarzanie obrazu\n","def preprocess(image):\n","    image = tf.convert_to_tensor(image, dtype=tf.float32)\n","    return preprocess_input(image)\n","\n","\n","def gram_matrix(tensor):\n","    result = tf.linalg.einsum('bijc,bijd->bcd', tensor, tensor)\n","    input_shape = tf.shape(tensor)\n","    num_locations = tf.cast(input_shape[1] * input_shape[2], tf.float32)\n","    return result / num_locations"],"metadata":{"id":"2DThYo4RoZM0"},"id":"2DThYo4RoZM0","execution_count":null,"outputs":[]},{"cell_type":"code","source":["#4 Wczytanie obrazów stylu i treści\n"],"metadata":{"id":"hDyB2BlNoZXU"},"id":"hDyB2BlNoZXU","execution_count":null,"outputs":[]},{"cell_type":"code","source":["#5 Wybór warstw stylu i treści\n"],"metadata":{"id":"GND7GBrSo4Fq"},"id":"GND7GBrSo4Fq","execution_count":null,"outputs":[]},{"cell_type":"code","source":["#6 Budowa modelu i ekstrakcja cech\n","vgg = VGG16(include_top=False, weights='imagenet')\n","vgg.trainable = False\n","outputs = [vgg.get_layer(name).output for name in layer_names]\n","extractor_model = Model(inputs=vgg.input, outputs=outputs)\n","\n","def extract_features(image):\n","    if image.ndim == 3:\n","        image = tf.expand_dims(image, axis=0)\n","    image = preprocess(image)\n","    outputs = extractor_model(image)\n","    return {name: output for name, output in zip(layer_names, outputs)}\n","\n","style_targets = extract_features(style_image)\n","content_targets = extract_features(content_image)\n","style_grams = {name: gram_matrix(style_targets[name]) for name in style_layers}\n","\n","\n","#7 Inicjalizacja modelu\n","image = tf.Variable(content_image / 255.0)\n","style_weight = 1e4\n","content_weight = 10\n","opt = tf.optimizers.Adam(learning_rate=0.02)\n","\n","#8 Funkcja treningu\n","def train_step(image):\n","    with tf.GradientTape() as tape:\n","        outputs = extract_features(image * 255.0)\n","        content_output = outputs[content_layer]\n","        style_output = {name: outputs[name] for name in style_layers}\n","\n","        content_loss = tf.reduce_mean((content_output - content_targets[content_layer]) ** 2)\n","        style_loss = tf.add_n([\n","            tf.reduce_mean((gram_matrix(style_output[name]) - style_grams[name]) ** 2)\n","            for name in style_layers\n","        ])\n","\n","        total_loss = style_weight * style_loss + content_weight * content_loss\n","\n","    grad = tape.gradient(total_loss, image)\n","    opt.apply_gradients([(grad, image)])\n","    image.assign(tf.clip_by_value(image, 0.0, 1.0))"],"metadata":{"id":"JqAXdeLuTd2T"},"id":"JqAXdeLuTd2T","execution_count":null,"outputs":[]},{"cell_type":"code","source":["#9 Trening\n"],"metadata":{"id":"puIPNPxyo_qP"},"id":"puIPNPxyo_qP","execution_count":null,"outputs":[]},{"cell_type":"code","source":["#10 Wyświetlenie wyników\n"],"metadata":{"id":"ZY7-QR2Oo_zC"},"id":"ZY7-QR2Oo_zC","execution_count":null,"outputs":[]},{"cell_type":"code","source":[],"metadata":{"id":"tCbMw8cbo_55"},"id":"tCbMw8cbo_55","execution_count":null,"outputs":[]}],"metadata":{"colab":{"provenance":[]},"language_info":{"name":"python"},"kernelspec":{"name":"python3","display_name":"Python 3"}},"nbformat":4,"nbformat_minor":5}