{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":3362,"databundleVersionId":31148,"sourceType":"competition"},{"sourceId":14127666,"sourceType":"datasetVersion","datasetId":9001512}],"dockerImageVersionId":31193,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import tensorflow as tf\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nimport os\n\n# --- НАЛАШТУВАННЯ MULTI-GPU ---\ntry:\n    # Створюємо стратегію розподілення\n    strategy = tf.distribute.MirroredStrategy()\n    print(f'Кількість знайдених пристроїв: {strategy.num_replicas_in_sync}')\n    \n    # Автоматичне налаштування буфера даних\n    AUTOTUNE = tf.data.AUTOTUNE\n    \n    # Збільшуємо розмір батчу, оскільки у нас 2 GPU\n    # Якщо для 1 GPU було 64, то для 2 ставимо 128 (64 * 2)\n    BATCH_SIZE_PER_REPLICA = 64\n    GLOBAL_BATCH_SIZE = BATCH_SIZE_PER_REPLICA * strategy.num_replicas_in_sync\n    \nexcept Exception as e:\n    print(f\"Помилка ініціалізації TPU/GPU: {e}\")\n    # Fallback на звичайний режим, якщо GPU немає\n    strategy = tf.distribute.get_strategy() \n    GLOBAL_BATCH_SIZE = 64\n\nprint(f\"Глобальний розмір батчу: {GLOBAL_BATCH_SIZE}\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-12-12T18:27:05.788228Z","iopub.execute_input":"2025-12-12T18:27:05.788920Z","iopub.status.idle":"2025-12-12T18:27:30.421756Z","shell.execute_reply.started":"2025-12-12T18:27:05.788894Z","shell.execute_reply":"2025-12-12T18:27:30.421094Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Проект 1: CNN для Класифікації Зображень (CIFAR-10)","metadata":{}},{"cell_type":"code","source":"# --- ПРОЕКТ 1: CIFAR-10 Multi-GPU ---\nfrom tensorflow.keras.datasets import cifar10\nfrom tensorflow.keras.utils import to_categorical\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense, Conv2D, MaxPool2D, Flatten, Dropout, BatchNormalization\n\n# 1. Дані\n(x_train, y_train), (x_test, y_test) = cifar10.load_data()\nx_train = x_train.astype('float32') / 255.0\nx_test = x_test.astype('float32') / 255.0\ny_cat_train = to_categorical(y_train, 10)\ny_cat_test = to_categorical(y_test, 10)\n\n# 2. Створення моделі в контексті Multi-GPU\nwith strategy.scope():\n    model = Sequential([\n        Conv2D(32, (3,3), padding='same', activation='relu', input_shape=(32,32,3)),\n        BatchNormalization(),\n        Conv2D(32, (3,3), padding='same', activation='relu'),\n        BatchNormalization(),\n        MaxPool2D(pool_size=(2,2)),\n        Dropout(0.3),\n\n        Conv2D(64, (3,3), padding='same', activation='relu'),\n        BatchNormalization(),\n        Conv2D(64, (3,3), padding='same', activation='relu'),\n        BatchNormalization(),\n        MaxPool2D(pool_size=(2,2)),\n        Dropout(0.4),\n\n        Flatten(),\n        Dense(512, activation='relu'),\n        Dropout(0.5),\n        Dense(10, activation='softmax')\n    ])\n    \n    model.compile(loss='categorical_crossentropy', \n                  optimizer='adam', \n                  metrics=['accuracy'])\n\n# 3. Навчання (з використанням глобального батчу)\nhistory = model.fit(x_train, y_cat_train, \n                    epochs=8, \n                    batch_size=GLOBAL_BATCH_SIZE,\n                    validation_data=(x_test, y_cat_test))\n\n# --- ВІЗУАЛІЗАЦІЯ РЕЗУЛЬТАТІВ ---\ndef visualize_results(model, x_test, y_test, num_samples=15):\n    class_names = ['plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']\n    \n    # Випадковий вибір\n    indices = np.random.choice(len(x_test), num_samples, replace=False)\n    x_sample = x_test[indices]\n    y_true = y_test[indices]\n    \n    # Передбачення\n    predictions = model.predict(x_sample, batch_size=GLOBAL_BATCH_SIZE)\n    pred_labels = np.argmax(predictions, axis=1)\n    \n    # Побудова сітки\n    plt.figure(figsize=(15, 8))\n    for i in range(num_samples):\n        plt.subplot(3, 5, i+1)\n        plt.imshow(x_sample[i])\n        \n        true_label = class_names[y_true[i][0]]\n        pred_label = class_names[pred_labels[i]]\n        \n        # Колір тексту: Зелений якщо вірно, Червоний якщо помилка\n        col = 'green' if true_label == pred_label else 'red'\n        \n        plt.title(f\"T: {true_label}\\nP: {pred_label}\", color=col, fontsize=12, fontweight='bold')\n        plt.axis('off')\n    plt.tight_layout()\n    plt.show()\n\nprint(\"\\n--- Результати розпізнавання ---\")\nvisualize_results(model, x_test, y_test)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-12T17:03:02.384882Z","iopub.execute_input":"2025-12-12T17:03:02.385353Z","iopub.status.idle":"2025-12-12T17:04:40.767344Z","shell.execute_reply.started":"2025-12-12T17:03:02.385332Z","shell.execute_reply":"2025-12-12T17:04:40.766681Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Проект 2: Реальні Зображення та Аугментація","metadata":{}},{"cell_type":"code","source":"# --- ПРОЕКТ 2: Multi-GPU + TF.Data Pipeline ---\nimport zipfile\nfrom sklearn.model_selection import train_test_split\nfrom tensorflow.keras import layers, models\n\n# 1. Швидке розпакування (якщо ще не зроблено)\nif not os.path.exists('/kaggle/working/train'):\n    with zipfile.ZipFile('/kaggle/input/dogs-vs-cats/train.zip', 'r') as zip_ref:\n        zip_ref.extractall('/kaggle/working/')\n\n# 2. Підготовка DataFrame\nbase_dir = '/kaggle/working/train'\nfilenames = os.listdir(base_dir)\nfilepaths = [os.path.join(base_dir, f) for f in filenames]\nlabels = [1 if 'dog' in f else 0 for f in filenames] # 1=Dog, 0=Cat\n\ndf = pd.DataFrame({'filepath': filepaths, 'label': labels})\ndf['label'] = df['label'].astype('float32') # Важливо для TF\ntrain_df, val_df = train_test_split(df, test_size=0.2, random_state=42)\n\n# 3. Створення Efficient Pipeline\nIMG_SIZE = (128, 128)\n\ndef process_img(filepath, label):\n    img = tf.io.read_file(filepath)\n    img = tf.image.decode_jpeg(img, channels=3)\n    img = tf.image.resize(img, IMG_SIZE)\n    return img, label\n\ndef get_dataset(dataframe, shuffle=False):\n    ds = tf.data.Dataset.from_tensor_slices((dataframe['filepath'].values, dataframe['label'].values))\n    ds = ds.map(process_img, num_parallel_calls=AUTOTUNE)\n    if shuffle:\n        ds = ds.shuffle(buffer_size=2000)\n    ds = ds.batch(GLOBAL_BATCH_SIZE, drop_remainder=False) \n    ds = ds.prefetch(buffer_size=AUTOTUNE)\n    return ds\n\ntrain_ds = get_dataset(train_df, shuffle=True)\nval_ds = get_dataset(val_df)\n\n# 4. Модель Multi-GPU\nwith strategy.scope():\n    model = models.Sequential([\n        layers.Input(shape=(128, 128, 3)),\n        # GPU Augmentation layers\n        layers.Rescaling(1./255),\n        layers.RandomFlip(\"horizontal\"),\n        layers.RandomRotation(0.1),\n        \n        layers.Conv2D(32, (3, 3), activation='relu'),\n        layers.MaxPooling2D((2, 2)),\n        \n        layers.Conv2D(64, (3, 3), activation='relu'),\n        layers.MaxPooling2D((2, 2)),\n        \n        layers.Conv2D(128, (3, 3), activation='relu'),\n        layers.MaxPooling2D((2, 2)),\n        \n        layers.Flatten(),\n        layers.Dense(512, activation='relu'),\n        layers.Dropout(0.5),\n        layers.Dense(1, activation='sigmoid')\n    ])\n    \n    model.compile(optimizer='adam',\n                  loss='binary_crossentropy',\n                  metrics=['accuracy'])\n\n# 5. Навчання\nhistory = model.fit(train_ds, validation_data=val_ds, epochs=10)\n\n# --- ВІЗУАЛІЗАЦІЯ ПЕРЕДБАЧЕНЬ ---\ndef show_predictions(dataset, model, num=10):\n    # Беремо 1 батч з датасету\n    imgs, labels = next(iter(dataset))\n    preds = model.predict(imgs)\n    \n    plt.figure(figsize=(15, 6))\n    for i in range(num):\n        if i >= len(imgs): break\n        ax = plt.subplot(2, 5, i + 1)\n        \n        # Картинка (повертаємо з тензора в numpy)\n        img_np = imgs[i].numpy().astype(\"uint8\")\n        plt.imshow(img_np)\n        \n        # Логіка\n        is_dog_pred = preds[i][0] > 0.5\n        is_dog_true = labels[i] == 1.0\n        \n        conf = preds[i][0] if is_dog_pred else 1 - preds[i][0]\n        pred_text = \"Dog\" if is_dog_pred else \"Cat\"\n        true_text = \"Dog\" if is_dog_true else \"Cat\"\n        \n        col = 'green' if is_dog_pred == is_dog_true else 'red'\n        \n        plt.title(f\"True: {true_text}\\nPred: {pred_text} ({conf:.1%})\", color=col)\n        plt.axis(\"off\")\n    plt.tight_layout()\n    plt.show()\n\nprint(\"Візуалізація роботи моделі:\")\nshow_predictions(val_ds, model)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-12T17:04:40.768094Z","iopub.execute_input":"2025-12-12T17:04:40.768341Z","iopub.status.idle":"2025-12-12T17:07:25.303311Z","shell.execute_reply.started":"2025-12-12T17:04:40.768303Z","shell.execute_reply":"2025-12-12T17:07:25.302398Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Проект 3: RNN/LSTM - Прогноз Часового Ряду","metadata":{}},{"cell_type":"code","source":"# --- ПРОЕКТ 3: RNN Multi-GPU (True Forecasting - Fixed) ---\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import LSTM, Dense, Input\n\n# Очищення пам'яті перед запуском\ntf.keras.backend.clear_session()\n\n# --- 0. НАЛАШТУВАННЯ (Страхування від помилок) ---\ntry:\n    strategy = tf.distribute.MirroredStrategy()\n    print(f'Кількість GPU: {strategy.num_replicas_in_sync}')\n    GLOBAL_BATCH_SIZE = 128 \nexcept:\n    strategy = tf.distribute.get_strategy()\n    GLOBAL_BATCH_SIZE = 64\n\n# --- 1. ГЕНЕРАЦІЯ ДАНИХ ---\nx = np.linspace(0, 100, 2000) \ny = np.sin(x)\n\nsplit_index = 1600 \ntrain_data = y[:split_index]\ntest_data = y[split_index:] \n\n# --- 2. ПІДГОТОВКА DATASET ---\nlength = 50 \n\ndef create_dataset(dataset, look_back=50):\n    dataX, dataY = [], []\n    for i in range(len(dataset) - look_back):\n        a = dataset[i:(i + look_back)]\n        dataX.append(a)\n        dataY.append(dataset[i + look_back])\n    return np.array(dataX), np.array(dataY)\n\nx_train, y_train = create_dataset(train_data, length)\n\n# Решейп [Samples, Time Steps, Features]\nx_train = np.reshape(x_train, (x_train.shape[0], x_train.shape[1], 1))\n\n# Створення tf.data.Dataset\ntrain_ds = tf.data.Dataset.from_tensor_slices((x_train, y_train))\ntrain_ds = train_ds.shuffle(1000).batch(GLOBAL_BATCH_SIZE, drop_remainder=True).prefetch(tf.data.AUTOTUNE)\n\nprint(f\"Форма тренувальних даних: {x_train.shape}\")\n\n# --- 3. НАВЧАННЯ (Multi-GPU Model) ---\nprint(\"Створення тренувальної моделі...\")\nwith strategy.scope():\n    model_train = Sequential([\n        Input(shape=(length, 1)), # Keras 3 стиль\n        LSTM(64, return_sequences=False),\n        Dense(1)\n    ])\n    model_train.compile(optimizer='adam', loss='mse')\n\nprint(\"Починаємо навчання на GPU...\")\nmodel_train.fit(train_ds, epochs=10, verbose=1)\n\n# --- 4. СТВОРЕННЯ МОДЕЛІ ДЛЯ ПРОГНОЗУ (Inference Model) ---\n\nprint(\"Копіювання ваг у модель для прогнозування...\")\ninference_model = Sequential([\n    Input(shape=(length, 1)),\n    LSTM(64, return_sequences=False),\n    Dense(1)\n])\n\ninference_model.set_weights(model_train.get_weights())\n\nforecast_steps = 400 \ncurrent_batch = train_data[-length:] \ncurrent_batch = current_batch.reshape((1, length, 1)) \n\nforecast_predictions = []\n\nprint(f\"Генеруємо прогноз на {forecast_steps} кроків...\")\n\nfor i in range(forecast_steps):\n    current_pred = inference_model.predict(current_batch, verbose=0)[0]\n    \n    forecast_predictions.append(current_pred)\n    \n    current_batch = np.append(current_batch[:, 1:, :], [[current_pred]], axis=1)\n\n# --- 6. ВІЗУАЛІЗАЦІЯ ---\nplt.figure(figsize=(14, 7))\n\n# Кінець тренувальних даних\nplt.plot(np.arange(1400, split_index), train_data[1400:], label='Training Data (End)', color='blue')\n\n# Реальне майбутнє (Ground Truth)\ntrue_future_idx = np.arange(split_index, split_index + len(test_data))\nplt.plot(true_future_idx, test_data, label='True Future', color='green', alpha=0.5)\n\n# Наш прогноз\nforecast_idx = np.arange(split_index, split_index + forecast_steps)\nplt.plot(forecast_idx, forecast_predictions, label='RNN Auto-regressive Forecast', color='red', linestyle='--', linewidth=2)\n\nplt.title(\"RNN True Forecasting (Multi-GPU Training -> Single Inference)\")\nplt.xlabel(\"Time Steps\")\nplt.legend()\nplt.grid(True)\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-12T18:30:11.440928Z","iopub.execute_input":"2025-12-12T18:30:11.441768Z","iopub.status.idle":"2025-12-12T18:30:39.974515Z","shell.execute_reply.started":"2025-12-12T18:30:11.441738Z","shell.execute_reply":"2025-12-12T18:30:39.973847Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Проект 4: NLP - Генерація Тексту (Шекспір)","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\nimport numpy as np\nimport os\nimport time\n\n# --- 1. АВТОМАТИЧНИЙ ПОШУК ТА ЗАВАНТАЖЕННЯ ФАЙЛУ ---\ndirectory = '/kaggle/input/kobzar'\ntext_file = None\n\n# Шукаємо файл у папці\nfor root, dirs, files in os.walk(directory):\n    for file in files:\n        if file.endswith(\".txt\"):\n            text_file = os.path.join(root, file)\n            break\n\nif text_file:\n    print(f\"Знайдено файл: {text_file}\")\n    # Читаємо файл (обов'язково utf-8 для кирилиці)\n    text = open(text_file, 'rb').read().decode(encoding='utf-8')\n    print(f\"Довжина тексту: {len(text)} символів\")\nelse:\n    print(\"Помилка: Текстовий файл (.txt) не знайдено у папці!\")\n    # Якщо файл не знайдено, зупиняємо виконання\n    raise FileNotFoundError(\"Перевірте структуру датасету\")\n\n# Подивимось на перші рядки\nprint(\"\\n--- ПРИКЛАД ТЕКСТУ ---\")\nprint(text[:200])\n\n# --- 2. ПІДГОТОВКА ДАНИХ ---\n# Створюємо словник унікальних символів (а, б, в, г, ґ...)\nvocab = sorted(set(text))\nprint(f'\\nУнікальних символів: {len(vocab)}')\n\nchar2idx = {u:i for i, u in enumerate(vocab)}\nidx2char = np.array(vocab)\ntext_as_int = np.array([char2idx[c] for c in text])\n\n# Нарізка на шматки (seq_length)\nseq_length = 100\nexamples_per_epoch = len(text)//(seq_length+1)\n\nchar_dataset = tf.data.Dataset.from_tensor_slices(text_as_int)\n\ndef split_input_target(chunk):\n    input_text = chunk[:-1]\n    target_text = chunk[1:]\n    return input_text, target_text\n\nsequences = char_dataset.batch(seq_length+1, drop_remainder=True)\ndataset = sequences.map(split_input_target)\n\n# Batching\nBATCH_SIZE = 64\nBUFFER_SIZE = 10000\ndataset = dataset.shuffle(BUFFER_SIZE).batch(BATCH_SIZE, drop_remainder=True)\n\n# --- 3. МОДЕЛЬ НАВЧАННЯ ---\nvocab_size = len(vocab)\nembedding_dim = 256\nrnn_units = 1024\n\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Embedding, GRU, Dense, Input\n\nmodel_nlp = Sequential([\n    Embedding(vocab_size, embedding_dim),\n    GRU(rnn_units, return_sequences=True, stateful=False, recurrent_initializer='glorot_uniform'),\n    Dense(vocab_size)\n])\n\ndef loss(labels, logits):\n    return tf.keras.losses.sparse_categorical_crossentropy(labels, logits, from_logits=True)\n\nmodel_nlp.compile(optimizer='adam', loss=loss)\n\n# --- 4. НАВЧАННЯ ---\nEPOCHS = 30\nprint(f\"Починаємо навчання на {EPOCHS} епох...\")\nhistory = model_nlp.fit(dataset, epochs=EPOCHS)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-12T17:07:33.095973Z","iopub.execute_input":"2025-12-12T17:07:33.096260Z","iopub.status.idle":"2025-12-12T17:10:30.612528Z","shell.execute_reply.started":"2025-12-12T17:07:33.096236Z","shell.execute_reply":"2025-12-12T17:10:30.611876Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# --- 5. ГЕНЕРАЦІЙНА МОДЕЛЬ ---\nmodel_gen = Sequential([\n    Input(batch_shape=(1, None)), \n    Embedding(vocab_size, embedding_dim),\n    GRU(rnn_units, return_sequences=True, stateful=True, recurrent_initializer='glorot_uniform'),\n    Dense(vocab_size)\n])\n\n# Копіюємо навчені ваги\nmodel_gen.set_weights(model_nlp.get_weights())\nprint(\"Модель готова до творчості.\")\n\n# --- 6. ФУНКЦІЯ ГЕНЕРАЦІЇ ---\ndef generate_text_safe(model, start_string):\n    # Скидаємо пам'ять GRU шару\n    for layer in model.layers:\n        if hasattr(layer, 'reset_states'):\n            layer.reset_states()\n\n    num_generate = 300 # Кількість літер\n    input_eval = [char2idx[s] for s in start_string]\n    input_eval = tf.expand_dims(input_eval, 0)\n\n    text_generated = []\n    temperature = 0.45\n\n    if len(start_string) > 1:\n        for i in range(len(start_string) - 1):\n            x = input_eval[:, i:i+1]\n            model(x)\n\n    next_input = input_eval[:, -1:]\n\n    for i in range(num_generate):\n        predictions = model(next_input)\n        predictions = tf.squeeze(predictions, 0)\n        predictions = tf.squeeze(predictions, 0)\n        predictions = predictions / temperature\n        \n        predicted_id = tf.random.categorical(tf.expand_dims(predictions, 0), num_samples=1)[-1,0].numpy()\n\n        next_input = tf.expand_dims([predicted_id], 0)\n        next_input = tf.expand_dims(next_input, 0)\n        \n        text_generated.append(idx2char[predicted_id])\n\n    return (start_string + ''.join(text_generated))\n\n# --- 7. РЕЗУЛЬТАТ ---\nprint(\"\\n--- ШТУЧНИЙ КОБЗАР ---\")\ntry:\n    generated_verse = generate_text_safe(model_gen, u\"Штучний інтелект\")\n    print(generated_verse)\nexcept Exception as e:\n    print(f\"Помилка: {e}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-12T17:10:30.613376Z","iopub.execute_input":"2025-12-12T17:10:30.613712Z","iopub.status.idle":"2025-12-12T17:10:34.382226Z","shell.execute_reply.started":"2025-12-12T17:10:30.613693Z","shell.execute_reply":"2025-12-12T17:10:34.381483Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Проект 5: Автоенкодери (Очищення зображень)","metadata":{}},{"cell_type":"code","source":"# --- ПРОЕКТ 5: Autoencoder Multi-GPU ---\nfrom tensorflow.keras.layers import Input, Conv2D, Conv2DTranspose, UpSampling2D\n\n# 1. Дані\n(x_train, _), (x_test, _) = tf.keras.datasets.mnist.load_data()\nx_train = np.expand_dims(x_train.astype('float32') / 255., -1)\nx_test = np.expand_dims(x_test.astype('float32') / 255., -1)\n\nnoise = 0.5\nx_train_noisy = np.clip(x_train + noise * np.random.normal(size=x_train.shape), 0., 1.)\nx_test_noisy = np.clip(x_test + noise * np.random.normal(size=x_test.shape), 0., 1.)\n\n# 2. Модель Multi-GPU\nwith strategy.scope():\n    input_img = Input(shape=(28, 28, 1))\n    \n    # Encoder\n    x = Conv2D(32, (3, 3), activation='relu', padding='same')(input_img)\n    x = MaxPool2D((2, 2), padding='same')(x)\n    x = Conv2D(32, (3, 3), activation='relu', padding='same')(x)\n    encoded = MaxPool2D((2, 2), padding='same')(x)\n\n    # Decoder\n    x = Conv2D(32, (3, 3), activation='relu', padding='same')(encoded)\n    x = UpSampling2D((2, 2))(x)\n    x = Conv2D(32, (3, 3), activation='relu', padding='same')(x)\n    x = UpSampling2D((2, 2))(x)\n    decoded = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(x)\n\n    autoencoder = tf.keras.models.Model(input_img, decoded)\n    autoencoder.compile(optimizer='adam', loss='binary_crossentropy')\n\n# 3. Навчання\nautoencoder.fit(x_train_noisy, x_train, \n                epochs=5, \n                batch_size=GLOBAL_BATCH_SIZE, # 128\n                validation_data=(x_test_noisy, x_test))\n\n# 4. Візуалізація підтвердження\ndecoded_imgs = autoencoder.predict(x_test_noisy[:10])\n\nn = 10\nplt.figure(figsize=(20, 6))\nplt.suptitle(\"Зверху: Зашумлене зображення | Знизу: Відновлене AI\", fontsize=16)\nfor i in range(n):\n    # Noisy\n    ax = plt.subplot(2, n, i + 1)\n    plt.imshow(x_test_noisy[i].reshape(28, 28), cmap='gray')\n    ax.get_xaxis().set_visible(False)\n    ax.get_yaxis().set_visible(False)\n\n    # Reconstructed\n    ax = plt.subplot(2, n, i + 1 + n)\n    plt.imshow(decoded_imgs[i].reshape(28, 28), cmap='gray')\n    ax.get_xaxis().set_visible(False)\n    ax.get_yaxis().set_visible(False)\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-12T17:10:34.382997Z","iopub.execute_input":"2025-12-12T17:10:34.383244Z","iopub.status.idle":"2025-12-12T17:11:13.267974Z","shell.execute_reply.started":"2025-12-12T17:10:34.383216Z","shell.execute_reply":"2025-12-12T17:11:13.267280Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\nimport tensorflow_hub as hub\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport os\n\n# 1. Завантаження моделі\nprint(\"Завантаження моделі Style Transfer...\")\nhub_model = hub.load('https://tfhub.dev/google/magenta/arbitrary-image-stylization-v1-256/2')\n\n# Функції обробки\ndef 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\n\ndef 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 tensor\n\n# 2. Вибір зображень\ntry:\n    content_dir = '/kaggle/working/train'\n    content_filename = os.listdir(content_dir)[0]\n    content_path = os.path.join(content_dir, content_filename)\n    print(f\"Використовуємо фото: {content_filename}\")\nexcept:\n    content_path = tf.keras.utils.get_file('labrador.jpg', 'https://storage.googleapis.com/download.tensorflow.org/example_images/YellowLabradorLooking_new.jpg')\n\ncontent_image = load_img(content_path)\n\n# СТИЛЬ (Style) - Ван Гог \"Зоряна ніч\"\nstyle_url = 'https://storage.googleapis.com/khanhlvg-public.appspot.com/arbitrary-style-transfer/style23.jpg'\npath_to_style = tf.keras.utils.get_file('starry_night.jpg', style_url)\nstyle_image = load_img(path_to_style)\n\n# 3. Стилізація\nprint(\"Застосування стилю...\")\nstylized_image = hub_model(tf.constant(content_image), tf.constant(style_image))[0]\n\n# 4. Результат\nplt.figure(figsize=(14, 6))\n\nplt.subplot(1, 3, 1)\nplt.title(\"Оригінал\")\nplt.imshow(tensor_to_image(content_image))\nplt.axis('off')\n\nplt.subplot(1, 3, 2)\nplt.title(\"Стиль (Ван Гог)\")\nplt.imshow(tensor_to_image(style_image))\nplt.axis('off')\n\nplt.subplot(1, 3, 3)\nplt.title(\"Результат AI\")\nplt.imshow(tensor_to_image(stylized_image))\nplt.axis('off')\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-12T17:11:13.268832Z","iopub.execute_input":"2025-12-12T17:11:13.269260Z","iopub.status.idle":"2025-12-12T17:11:21.909875Z","shell.execute_reply.started":"2025-12-12T17:11:13.269236Z","shell.execute_reply":"2025-12-12T17:11:21.909022Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom tensorflow.keras import layers\nimport time\n\n# --- 1. ПІДГОТОВКА ДАНИХ ---\n(train_images, train_labels), (_, _) = tf.keras.datasets.mnist.load_data()\n\ntrain_images = train_images.reshape(train_images.shape[0], 28, 28, 1).astype('float32')\ntrain_images = (train_images - 127.5) / 127.5 \n\nBUFFER_SIZE = 60000\nBATCH_SIZE = 128\n\n# Створюємо dataset\ntrain_dataset = tf.data.Dataset.from_tensor_slices(train_images).shuffle(BUFFER_SIZE).batch(BATCH_SIZE)\n\n# --- 2. ГЕНЕРАТОР (Художник) ---\ndef make_generator_model():\n    model = tf.keras.Sequential()\n    # Починаємо з \"зерна\" (seed)\n    model.add(layers.Dense(7*7*256, use_bias=False, input_shape=(100,)))\n    model.add(layers.BatchNormalization())\n    model.add(layers.LeakyReLU())\n\n    model.add(layers.Reshape((7, 7, 256)))\n    assert model.output_shape == (None, 7, 7, 256) \n\n    model.add(layers.Conv2DTranspose(128, (5, 5), strides=(1, 1), padding='same', use_bias=False))\n    model.add(layers.BatchNormalization())\n    model.add(layers.LeakyReLU())\n\n    model.add(layers.Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False))\n    model.add(layers.BatchNormalization())\n    model.add(layers.LeakyReLU())\n\n    model.add(layers.Conv2DTranspose(1, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh'))\n    assert model.output_shape == (None, 28, 28, 1)\n\n    return model\n\n# --- 3. ДИСКРИМІНАТОР (Критик) ---\ndef make_discriminator_model():\n    model = tf.keras.Sequential()\n    \n    # Згортка 1\n    model.add(layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same', input_shape=[28, 28, 1]))\n    model.add(layers.LeakyReLU())\n    model.add(layers.Dropout(0.3))\n\n    # Згортка 2\n    model.add(layers.Conv2D(128, (5, 5), strides=(2, 2), padding='same'))\n    model.add(layers.LeakyReLU())\n    model.add(layers.Dropout(0.3))\n\n    model.add(layers.Flatten())\n    model.add(layers.Dense(1)) # Видає число: позитивне = справжнє, негативне = фейк\n\n    return model\n\ngenerator = make_generator_model()\ndiscriminator = make_discriminator_model()\n\ncross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True)\n\ndef discriminator_loss(real_output, fake_output):\n    real_loss = cross_entropy(tf.ones_like(real_output) * 0.9, real_output)\n    fake_loss = cross_entropy(tf.zeros_like(fake_output), fake_output)\n    return real_loss + fake_loss\n\ndef generator_loss(fake_output):\n    return cross_entropy(tf.ones_like(fake_output), fake_output)\n\ngenerator_optimizer = tf.keras.optimizers.Adam(1e-4)\ndiscriminator_optimizer = tf.keras.optimizers.Adam(1e-4)\n\n# --- 5. ЦИКЛ НАВЧАННЯ ---\nEPOCHS = 30 \nnoise_dim = 100\nnum_examples_to_generate = 16\n\nseed = tf.random.normal([num_examples_to_generate, noise_dim])\n\n@tf.function\ndef train_step(images):\n    noise = tf.random.normal([BATCH_SIZE, noise_dim])\n\n    with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:\n      generated_images = generator(noise, training=True)\n\n      real_output = discriminator(images, training=True)\n      fake_output = discriminator(generated_images, training=True)\n\n      gen_loss = generator_loss(fake_output)\n      disc_loss = discriminator_loss(real_output, fake_output)\n\n    gradients_of_generator = gen_tape.gradient(gen_loss, generator.trainable_variables)\n    gradients_of_discriminator = disc_tape.gradient(disc_loss, discriminator.trainable_variables)\n\n    generator_optimizer.apply_gradients(zip(gradients_of_generator, generator.trainable_variables))\n    discriminator_optimizer.apply_gradients(zip(gradients_of_discriminator, discriminator.trainable_variables))\n\n# Функція для малювання\ndef generate_and_save_images(model, epoch, test_input):\n  predictions = model(test_input, training=False)\n\n  plt.figure(figsize=(4, 4))\n  for i in range(predictions.shape[0]):\n      plt.subplot(4, 4, i+1)\n      img = predictions[i, :, :, 0] * 127.5 + 127.5\n      plt.imshow(img.numpy().astype('uint8'), cmap='gray')\n      plt.axis('off')\n  \n  plt.suptitle(f\"Epoch: {epoch}\")\n  plt.show()\n\nprint(\"Починаємо навчання GAN...\")\nfor epoch in range(EPOCHS):\n  start = time.time()\n\n  for image_batch in train_dataset:\n    train_step(image_batch)\n\n  print(f'Time for epoch {epoch + 1} is {time.time()-start:.1f} sec')\n  generate_and_save_images(generator, epoch + 1, seed)\n\nprint(\"Навчання завершено.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-12T17:36:52.772702Z","iopub.execute_input":"2025-12-12T17:36:52.773041Z","iopub.status.idle":"2025-12-12T17:43:30.293845Z","shell.execute_reply.started":"2025-12-12T17:36:52.772997Z","shell.execute_reply":"2025-12-12T17:43:30.293045Z"}},"outputs":[],"execution_count":null}]}