Hit

120 практических задач

Tekst
Przeczytaj fragment
Oznacz jako przeczytane
Czcionka:Mniejsze АаWiększe Aa

5. Построение простой рекуррентной нейронной сети для анализа временных рядов

Задача: Прогнозирование цен на акции

Для построения простой рекуррентной нейронной сети (RNN) для анализа временных рядов и прогнозирования цен на акции можно использовать библиотеку TensorFlow и её высокоуровневый интерфейс Keras. В этом примере мы рассмотрим, как использовать LSTM (Long Short-Term Memory) слои, которые являются разновидностью RNN, чтобы построить модель для прогнозирования цен на акции.

Шаги:

1. Импорт библиотек и модулей.

2. Подготовка данных.

3. Построение модели RNN.

4. Компиляция и обучение модели.

5. Оценка и тестирование модели.

Пример кода:

```python

import numpy as np

import pandas as pd

import tensorflow as tf

from tensorflow.keras import layers, models

from sklearn.preprocessing import MinMaxScaler

from sklearn.model_selection import train_test_split

import matplotlib.pyplot as plt

# Шаг 1: Импорт библиотек

import numpy as np

import pandas as pd

import tensorflow as tf

from tensorflow.keras import layers, models

from sklearn.preprocessing import MinMaxScaler

from sklearn.model_selection import train_test_split

import matplotlib.pyplot as plt

# Шаг 2: Подготовка данных

# Загрузка данных. Предположим, что у нас есть CSV файл с историческими ценами на акции.

data = pd.read_csv('stock_prices.csv')

# Выбираем интересующие нас столбцы, например, 'Close'

prices = data['Close'].values.reshape(-1, 1)

# Нормализация данных

scaler = MinMaxScaler(feature_range=(0, 1))

scaled_prices = scaler.fit_transform(prices)

# Создание последовательностей для обучения модели

def create_sequences(data, sequence_length):

sequences = []

targets = []

for i in range(len(data) – sequence_length):

sequences.append(data[i:i + sequence_length])

targets.append(data[i + sequence_length])

return np.array(sequences), np.array(targets)

sequence_length = 60 # 60 дней

X, y = create_sequences(scaled_prices, sequence_length)

# Разделение данных на обучающую и тестовую выборки

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False)

# Шаг 3: Построение модели RNN

model = models.Sequential()

model.add(layers.LSTM(50, return_sequences=True, input_shape=(sequence_length, 1)))

model.add(layers.LSTM(50, return_sequences=False))

model.add(layers.Dense(25))

model.add(layers.Dense(1))

# Шаг 4: Компиляция и обучение модели

model.compile(optimizer='adam', loss='mean_squared_error')

history = model.fit(X_train, y_train, batch_size=32, epochs=10,

validation_data=(X_test, y_test))

# Шаг 5: Оценка модели

predictions = model.predict(X_test)

predictions = scaler.inverse_transform(predictions)

# Визуализация результатов

plt.figure(figsize=(10, 6))

plt.plot(data.index[:len(data) – len(y_test)], scaler.inverse_transform(scaled_prices[:len(scaled_prices) – len(y_test)]), color='blue', label='Исторические данные')

plt.plot(data.index[len(data) – len(y_test):], scaler.inverse_transform(scaled_prices[len(scaled_prices) – len(y_test):]), color='orange', label='Истинные значения')

plt.plot(data.index[len(data) – len(y_test):], predictions, color='red', label='Прогнозы')

plt.xlabel('Дата')

plt.ylabel('Цена акции')

plt.legend()

plt.show()

```

Пояснение:

1. Импорт библиотек: Импортируются необходимые библиотеки, включая TensorFlow, Keras, pandas и matplotlib.

2. Подготовка данных: Загружаются данные о ценах акций из CSV файла и нормализуются с помощью MinMaxScaler. Создаются последовательности для обучения модели.

3. Построение модели RNN: Модель строится с использованием двух LSTM слоев. Первый слой LSTM возвращает последовательность, которая передается следующему слою. Второй слой LSTM возвращает конечный выход, который подается на полносвязные слои для получения прогноза.

4. Компиляция и обучение модели: Модель компилируется с использованием оптимизатора Adam и функции потерь mean_squared_error. Затем модель обучается на обучающей выборке.

5. Оценка и тестирование модели: Прогнозы модели сравниваются с реальными данными, и результаты визуализируются с помощью графика.

Этот подход может быть расширен и улучшен, например, путем настройки гиперпараметров модели или добавления дополнительных слоев для повышения точности прогнозов.

Построение модели RNN

Использование двух LSTM слоев

Для анализа временных рядов и прогнозирования цен на акции мы будем использовать два слоя LSTM. LSTM (Long Short-Term Memory) слои являются разновидностью рекуррентных нейронных сетей, специально разработанных для запоминания долгосрочных зависимостей в последовательных данных. В отличие от обычных RNN, которые могут страдать от проблем затухающих градиентов, LSTM могут эффективно обучаться на долгосрочных зависимостях.

Первый слой LSTM

Первый слой LSTM принимает последовательность данных на вход и возвращает последовательность, которая будет передана следующему слою. Возвращение последовательности (return_sequences=True) необходимо, чтобы каждый временной шаг предыдущего слоя был передан на вход следующего слоя LSTM. Это позволяет следующему слою LSTM дополнительно обрабатывать временные зависимости.

```python

model.add(layers.LSTM(50, return_sequences=True, input_shape=(sequence_length, 1)))

```

– 50 нейронов: Это количество нейронов в первом слое LSTM. Число нейронов определяет способность сети к обучению сложным паттернам.

–return_sequences=True: Указывает, что слой должен возвращать полную последовательность выходов для каждого временного шага, а не только последний выход.

– input_shape=(sequence_length, 1): Определяет форму входных данных, где `sequence_length` – это длина последовательности (например, 60 дней), а `1` – это количество признаков (в данном случае, только одно значение цены закрытия).

Второй слой LSTM

Второй слой LSTM принимает последовательность от первого слоя и возвращает конечный выход для всей последовательности. Здесь параметр `return_sequences` установлен в `False`, что означает, что слой будет возвращать только последний выходной элемент последовательности.

```python

model.add(layers.LSTM(50, return_sequences=False))

```

– 50 нейронов: Количество нейронов в втором слое LSTM, аналогично первому слою.

– return_sequences=False: Указывает, что слой должен возвращать только последний выход, который будет использоваться для прогнозирования.

Полносвязные слои

После обработки данных слоями LSTM, выходной вектор передается полносвязным слоям для окончательной классификации или регрессии. Полносвязные слои обеспечивают соединение каждого нейрона предыдущего слоя с каждым нейроном текущего слоя, что позволяет сети обучаться сложным нелинейным зависимостям.

```python

model.add(layers.Dense(25))

model.add(layers.Dense(1))

```

– Первый полносвязный слой:

– 25 нейронов: Полносвязный слой с 25 нейронами. Этот слой может использоваться для дополнительного обучения сложным паттернам в данных.

– Выходной слой:

– 1 нейрон: Выходной слой с одним нейроном, который будет выдавать прогнозируемую цену акции.

Эта архитектура сети, состоящая из двух слоев LSTM и двух полносвязных слоев, позволяет модели эффективно обрабатывать временные ряды и делать прогнозы на основе предыдущих данных. Первый слой LSTM возвращает полную последовательность, позволяя следующему слою LSTM дополнительно обучаться на временных зависимостях. Второй слой LSTM возвращает конечный выход, который затем передается через полносвязные слои для получения окончательного прогноза. Такая архитектура позволяет модели обучаться на длинных временных зависимостях и выдавать точные прогнозы цен на акции.

6. Создание LSTM сети для обработки текстовых данных

Задача: Анализ настроений в текстах

Для анализа настроений в текстах с использованием LSTM сети можно использовать библиотеку TensorFlow и её высокоуровневый интерфейс Keras. В этом примере мы рассмотрим, как создать и обучить модель LSTM для анализа настроений на основе текстовых данных.

Шаги:

1. Импорт библиотек и модулей.

2. Подготовка данных.

3. Построение модели LSTM.

4. Компиляция и обучение модели.

5. Оценка и тестирование модели.

Пример кода:

```python

import numpy as np

import pandas as pd

import tensorflow as tf

from tensorflow.keras import layers, models

from tensorflow.keras.preprocessing.text import Tokenizer

from tensorflow.keras.preprocessing.sequence import pad_sequences

from sklearn.model_selection import train_test_split

import matplotlib.pyplot as plt

# Шаг 1: Импорт библиотек

import tensorflow as tf

from tensorflow.keras import layers, models

from tensorflow.keras.preprocessing.text import Tokenizer

from tensorflow.keras.preprocessing.sequence import pad_sequences

from sklearn.model_selection import train_test_split

# Шаг 2: Подготовка данных

# Загрузка данных. Предположим, что у нас есть CSV файл с текстами и метками настроений (0 – негативное, 1 – позитивное).

data = pd.read_csv('sentiment_data.csv')

# Пример структуры данных:

# text sentiment

# 0 This movie was great! 1

# 1 I did not like this movie. 0

# …

# Тексты и метки

texts = data['text'].values

 

labels = data['sentiment'].values

# Токенизация текстов

tokenizer = Tokenizer(num_words=10000) # Используем только 10,000 наиболее частотных слов

tokenizer.fit_on_texts(texts)

sequences = tokenizer.texts_to_sequences(texts)

# Ограничение длины последовательностей (padding)

maxlen = 100 # Максимальная длина последовательности

X = pad_sequences(sequences, maxlen=maxlen)

# Разделение данных на обучающую и тестовую выборки

X_train, X_test, y_train, y_test = train_test_split(X, labels, test_size=0.2, random_state=42)

# Шаг 3: Построение модели LSTM

model = models.Sequential()

model.add(layers.Embedding(input_dim=10000, output_dim=128, input_length=maxlen))

model.add(layers.LSTM(128, return_sequences=True))

model.add(layers.LSTM(128, return_sequences=False))

model.add(layers.Dense(1, activation='sigmoid'))

# Шаг 4: Компиляция и обучение модели

model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

history = model.fit(X_train, y_train, epochs=10, batch_size=32,

validation_data=(X_test, y_test))

# Шаг 5: Оценка модели

loss, accuracy = model.evaluate(X_test, y_test, verbose=2)

print(f'\nТочность на тестовых данных: {accuracy}')

# Визуализация процесса обучения

plt.plot(history.history['accuracy'], label='Точность на обучающем наборе')

plt.plot(history.history['val_accuracy'], label='Точность на валидационном наборе')

plt.xlabel('Эпоха')

plt.ylabel('Точность')

plt.legend(loc='lower right')

plt.show()

```

Пояснение:

1. Импорт библиотек: Импортируются необходимые библиотеки TensorFlow, Keras, pandas, matplotlib и другие.

2. Подготовка данных: Загрузка данных из CSV файла, содержащего тексты и метки настроений. Тексты токенизируются с использованием `Tokenizer`, и последовательности приводятся к одинаковой длине с помощью `pad_sequences`.

3. Построение модели LSTM: Модель строится с использованием слоя `Embedding` для преобразования токенов в плотные векторы, двух слоев LSTM для обработки последовательностей и одного полносвязного слоя для выдачи прогноза.

– Слой Embedding:

```python

model.add(layers.Embedding(input_dim=10000, output_dim=128, input_length=maxlen))

```

Этот слой преобразует входные токены в плотные векторы размерности 128.

– Первый слой LSTM:

```python

model.add(layers.LSTM(128, return_sequences=True))

```

Первый слой LSTM возвращает полную последовательность выходов, которая передается следующему слою LSTM.

– Второй слой LSTM:

```python

model.add(layers.LSTM(128, return_sequences=False))

```

Второй слой LSTM возвращает только последний выходной элемент.

– Выходной слой:

```python

model.add(layers.Dense(1, activation='sigmoid'))

```

Выходной слой с сигмоидной активацией для бинарной классификации настроений (позитивное или негативное).

4. Компиляция и обучение модели: Модель компилируется с использованием оптимизатора Adam и функции потерь binary_crossentropy. Затем модель обучается на обучающей выборке.

5. Оценка и тестирование модели: Оценивается точность модели на тестовой выборке и визуализируется процесс обучения с помощью графика.

Этот пример демонстрирует, как создать и обучить модель LSTM для анализа настроений в текстах. Модель включает слои embedding для преобразования текстовых данных в числовые векторы, два слоя LSTM для извлечения временных зависимостей и полносвязный слой для классификации. Эта архитектура позволяет эффективно анализировать тексты и предсказывать настроения на основе данных.

7. Создание простой GAN для генерации изображений

Задача: Генерация рукописных цифр (набор MNIST)

Для создания простой генеративно-состязательной сети (GAN) для генерации рукописных цифр из набора данных MNIST можно использовать TensorFlow и Keras. В этом примере мы рассмотрим, как создать и обучить GAN для генерации изображений цифр.

Шаги:

1. Импорт библиотек и модулей.

2. Подготовка данных.

3. Построение генератора.

4. Построение дискриминатора.

5. Построение GAN.

6. Обучение GAN.

7. Генерация изображений.

Пример кода:

```python

import tensorflow as tf

from tensorflow.keras import layers, models

import numpy as np

import matplotlib.pyplot as plt

# Шаг 1: Импорт библиотек

import tensorflow as tf

from tensorflow.keras import layers, models

import numpy as np

import matplotlib.pyplot as plt

# Шаг 2: Подготовка данных

# Загрузка набора данных MNIST

(train_images, _), (_, _) = tf.keras.datasets.mnist.load_data()

train_images = train_images.reshape(train_images.shape[0], 28, 28, 1).astype('float32')

train_images = (train_images – 127.5) / 127.5 # Нормализация изображений в диапазоне [-1, 1]

BUFFER_SIZE = 60000

BATCH_SIZE = 256

# Создание выборок

train_dataset = tf.data.Dataset.from_tensor_slices(train_images).shuffle(BUFFER_SIZE).batch(BATCH_SIZE)

# Шаг 3: Построение генератора

def build_generator():

model = models.Sequential()

model.add(layers.Dense(7 * 7 * 256, use_bias=False, input_shape=(100,)))

model.add(layers.BatchNormalization())

model.add(layers.LeakyReLU())

model.add(layers.Reshape((7, 7, 256)))

assert model.output_shape == (None, 7, 7, 256) # Убедитесь, что выходная форма такая

model.add(layers.Conv2DTranspose(128, (5, 5), strides=(1, 1), padding='same', use_bias=False))

model.add(layers.BatchNormalization())

model.add(layers.LeakyReLU())

model.add(layers.Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False))

model.add(layers.BatchNormalization())

model.add(layers.LeakyReLU())

model.add(layers.Conv2DTranspose(1, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh'))

assert model.output_shape == (None, 28, 28, 1)

return model

# Шаг 4: Построение дискриминатора

def build_discriminator():

model = models.Sequential()

model.add(layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same', input_shape=[28, 28, 1]))

model.add(layers.LeakyReLU())

model.add(layers.Dropout(0.3))

model.add(layers.Conv2D(128, (5, 5), strides=(2, 2), padding='same'))

model.add(layers.LeakyReLU())

model.add(layers.Dropout(0.3))

model.add(layers.Flatten())

model.add(layers.Dense(1, activation='sigmoid'))

return model

# Построение генератора и дискриминатора

generator = build_generator()

discriminator = build_discriminator()

# Определение функции потерь и оптимизаторов

cross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True)

def discriminator_loss(real_output, fake_output):

real_loss = cross_entropy(tf.ones_like(real_output), real_output)

fake_loss = cross_entropy(tf.zeros_like(fake_output), fake_output)

total_loss = real_loss + fake_loss

return total_loss

def generator_loss(fake_output):

return cross_entropy(tf.ones_like(fake_output), fake_output)

generator_optimizer = tf.keras.optimizers.Adam(1e-4)

discriminator_optimizer = tf.keras.optimizers.Adam(1e-4)

# Шаг 5: Построение GAN

@tf.function

def train_step(images):

noise = tf.random.normal([BATCH_SIZE, 100])

with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:

generated_images = generator(noise, training=True)

real_output = discriminator(images, training=True)

fake_output = discriminator(generated_images, training=True)

gen_loss = generator_loss(fake_output)

disc_loss = discriminator_loss(real_output, fake_output)

gradients_of_generator = gen_tape.gradient(gen_loss, generator.trainable_variables)

gradients_of_discriminator = disc_tape.gradient(disc_loss, discriminator.trainable_variables)

generator_optimizer.apply_gradients(zip(gradients_of_generator, generator.trainable_variables))

discriminator_optimizer.apply_gradients(zip(gradients_of_discriminator, discriminator.trainable_variables))

def train(dataset, epochs):

for epoch in range(epochs):

for image_batch in dataset:

train_step(image_batch)

print(f'Эпоха {epoch + 1} завершена')

# Шаг 6: Обучение GAN

EPOCHS = 50

train(train_dataset, EPOCHS)

# Шаг 7: Генерация изображений

def generate_and_save_images(model, epoch, test_input):

predictions = model(test_input, training=False)

fig = plt.figure(figsize=(4, 4))

for i in range(predictions.shape[0]):

plt.subplot(4, 4, i+1)

plt.imshow(predictions[i, :, :, 0] * 127.5 + 127.5, cmap='gray')

plt.axis('off')

plt.savefig(f'image_at_epoch_{epoch:04d}.png')

plt.show()

# Генерация изображений после обучения

noise = tf.random.normal([16, 100])

generate_and_save_images(generator, EPOCHS, noise)

```

Пояснение:

1. Импорт библиотек: Импортируются необходимые библиотеки TensorFlow, Keras, numpy и matplotlib.

2. Подготовка данных: Загружаются данные MNIST и нормализуются в диапазоне [-1, 1]. Данные затем разделяются на батчи для обучения.

3. Построение генератора: Генератор создает изображения из случайного шума. Он включает плотные слои, batch normalization и Conv2DTranspose слои для генерации изображений размером 28x28 пикселей.

4. Построение дискриминатора: Дискриминатор оценивает, являются ли изображения реальными или сгенерированными. Он состоит из свёрточных слоев, слоев LeakyReLU и dropout для классификации изображений.

5. Построение GAN: Генератор и дискриминатор объединяются в модель GAN. Определяются функции потерь и оптимизаторы для обеих моделей.

6. Обучение GAN: GAN обучается в течение заданного числа эпох. На каждом шаге обучения генератор пытается создать реалистичные изображения, а дискриминатор учится отличать реальные изображения от сгенерированных.

7. Генерация изображений:  После обучения GAN, создаются и сохраняются изображения, сгенерированные генератором.

Этот пример демонстрирует, как создать простую GAN для генерации рукописных цифр из набора данных MNIST. Модель может быть улучшена за счет добавления дополнительных слоев, настройки гиперпараметров и использования более сложных архитектур.

8. Построение сложной GAN для генерации реалистичных изображений

Задача: Генерация изображений лиц

Для создания сложной генеративно-состязательной сети (GAN) для генерации реалистичных изображений лиц можно использовать библиотеку TensorFlow и Keras. Мы будем использовать улучшенную архитектуру GAN, известную как DCGAN (Deep Convolutional GAN), которая доказала свою эффективность в создании реалистичных изображений. Набор данных CelebA, содержащий фотографии лиц знаменитостей, является хорошим выбором для этой задачи.

Шаги:

1. Импорт библиотек и модулей.

2. Подготовка данных.

3. Построение генератора.

4. Построение дискриминатора.

5. Построение и компиляция GAN.

6. Обучение GAN.

7. Генерация изображений.

Пример кода:

```python

import tensorflow as tf

from tensorflow.keras import layers, models

import numpy as np

import os

import matplotlib.pyplot as plt

from tensorflow.keras.preprocessing.image import ImageDataGenerator

# Шаг 1: Импорт библиотек

import tensorflow as tf

from tensorflow.keras import layers, models

import numpy as np

import matplotlib.pyplot as plt

import os

# Шаг 2: Подготовка данных

# Загрузка набора данных CelebA

# Этот пример предполагает, что данные находятся в папке 'img_align_celeba/img_align_celeba'

# Скачивание и подготовка данных не входит в код

DATA_DIR = 'img_align_celeba/img_align_celeba'

IMG_HEIGHT = 64

IMG_WIDTH = 64

BATCH_SIZE = 128

BUFFER_SIZE = 60000

def load_image(image_path):

image = tf.io.read_file(image_path)

image = tf.image.decode_jpeg(image, channels=3)

image = tf.image.resize(image, [IMG_HEIGHT, IMG_WIDTH])

image = (image – 127.5) / 127.5 # Нормализация изображений в диапазоне [-1, 1]

return image

def load_dataset(data_dir):

image_paths = [os.path.join(data_dir, img) for img in os.listdir(data_dir)]

 

image_dataset = tf.data.Dataset.from_tensor_slices(image_paths)

image_dataset = image_dataset.map(load_image, num_parallel_calls=tf.data.experimental.AUTOTUNE)

image_dataset = image_dataset.shuffle(BUFFER_SIZE).batch(BATCH_SIZE).prefetch(tf.data.experimental.AUTOTUNE)

return image_dataset

train_dataset = load_dataset(DATA_DIR)

# Шаг 3: Построение генератора

def build_generator():

model = models.Sequential()

model.add(layers.Dense(8 * 8 * 256, use_bias=False, input_shape=(100,)))

model.add(layers.BatchNormalization())

model.add(layers.LeakyReLU())

model.add(layers.Reshape((8, 8, 256)))

assert model.output_shape == (None, 8, 8, 256) # Убедитесь, что выходная форма такая

model.add(layers.Conv2DTranspose(128, (5, 5), strides=(2, 2), padding='same', use_bias=False))

model.add(layers.BatchNormalization())

model.add(layers.LeakyReLU())

assert model.output_shape == (None, 16, 16, 128)

model.add(layers.Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False))

model.add(layers.BatchNormalization())

model.add(layers.LeakyReLU())

assert model.output_shape == (None, 32, 32, 64)

model.add(layers.Conv2DTranspose(3, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh'))

assert model.output_shape == (None, 64, 64, 3)

return model

# Шаг 4: Построение дискриминатора

def build_discriminator():

model = models.Sequential()

model.add(layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same', input_shape=[64, 64, 3]))

model.add(layers.LeakyReLU())

model.add(layers.Dropout(0.3))

model.add(layers.Conv2D(128, (5, 5), strides=(2, 2), padding='same'))

model.add(layers.LeakyReLU())

model.add(layers.Dropout(0.3))

model.add(layers.Conv2D(256, (5, 5), strides=(2, 2), padding='same'))

model.add(layers.LeakyReLU())

model.add(layers.Dropout(0.3))

model.add(layers.Flatten())

model.add(layers.Dense(1, activation='sigmoid'))

return model

# Построение генератора и дискриминатора

generator = build_generator()

discriminator = build_discriminator()

# Определение функции потерь и оптимизаторов

cross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True)

def discriminator_loss(real_output, fake_output):

real_loss = cross_entropy(tf.ones_like(real_output), real_output)

fake_loss = cross_entropy(tf.zeros_like(fake_output), fake_output)

total_loss = real_loss + fake_loss

return total_loss

def generator_loss(fake_output):

return cross_entropy(tf.ones_like(fake_output), fake_output)

generator_optimizer = tf.keras.optimizers.Adam(1e-4)

discriminator_optimizer = tf.keras.optimizers.Adam(1e-4)

# Шаг 5: Построение и компиляция GAN

@tf.function

def train_step(images):

noise = tf.random.normal([BATCH_SIZE, 100])

with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:

generated_images = generator(noise, training=True)

real_output = discriminator(images, training=True)

fake_output = discriminator(generated_images, training=True)

gen_loss = generator_loss(fake_output)

disc_loss = discriminator_loss(real_output, fake_output)

gradients_of_generator = gen_tape.gradient(gen_loss, generator.trainable_variables)

gradients_of_discriminator = disc_tape.gradient(disc_loss, discriminator.trainable_variables)

generator_optimizer.apply_gradients(zip(gradients_of_generator, generator.trainable_variables))

discriminator_optimizer.apply_gradients(zip(gradients_of_discriminator, discriminator.trainable_variables))

def train(dataset, epochs):

for epoch in range(epochs):

for image_batch in dataset:

train_step(image_batch)

print(f'Эпоха {epoch + 1} завершена')

# Генерация изображений в конце каждой эпохи

if (epoch + 1) % 10 == 0:

noise = tf.random.normal([16, 100])

generate_and_save_images(generator, epoch + 1, noise)

# Шаг 6: Обучение GAN

EPOCHS = 100

train(train_dataset, EPOCHS)

# Шаг 7: Генерация изображений

def generate_and_save_images(model, epoch, test_input):

predictions = model(test_input, training=False)

fig = plt.figure(figsize=(4, 4))

for i in range(predictions.shape[0]):

plt.subplot(4, 4, i+1)

plt.imshow((predictions[i] * 127.5 + 127.5).numpy().astype(np.uint8))

plt.axis('off')

plt.savefig(f'image_at_epoch_{epoch:04d}.png')

plt.show()

# Генерация изображений после обучения

noise = tf.random.normal([16, 100])

generate_and_save_images(generator, EPOCHS, noise)

```

Пояснение:

1. Импорт библиотек: Импортируются необходимые библиотеки TensorFlow, Keras, numpy и matplotlib.

2. Подготовка данных: Загружаются и подготавливаются данные CelebA. Изображения нормализуются в диапазоне [-1, 1].

3. Построение генератора: Генератор создает изображения из случайного шума. Он включает плотные слои, batch normalization и Conv2DTranspose слои для генерации изображений размером 64x64 пикселей.

4. Построение дискриминатора: Дискриминатор оценивает, являются ли изображения реальными или сгенерированными. Он состоит из свёрточных слоев, слоев LeakyReLU и dropout для классификации изображений.

5. Построение и компиляция GAN: Генератор и дискриминатор объединяются в модель GAN. Определяются функции потерь и оптимизаторы для обеих моделей. Процедура `train_step` выполняет одну итерацию обучения GAN.

6. Обучение GAN: GAN обучается в течение заданного числа эпох. На каждом шаге обучения генератор пытается создать реалистичные изображения, а дискриминатор учится отличать реальные изображения от сгенерированных.

7. Генерация изображений: После обучения GAN, создаются и сохраняются изображения, сгенерированные генератором.

Этот пример демонстрирует, как создать сложную GAN для генерации реалистичных изображений лиц. Модель может быть улучшена за счет добавления дополнительных