Нейронные сети для начинающих: готовые примеры кода для старта

Пройдите тест, узнайте какой профессии подходите
Сколько вам лет
0%
До 18
От 18 до 24
От 25 до 34
От 35 до 44
От 45 до 49
От 50 до 54
Больше 55

Для кого эта статья:

  • Новички в области искусственного интеллекта и машинного обучения
  • Практикующие разработчики, желающие улучшить свои навыки в нейронных сетях
  • Люди, интересующиеся созданием собственных проектов с использованием готовых примеров кода

    Вход в мир искусственного интеллекта часто напоминает попытку расшифровать инопланетные технологии — множество непонятных терминов, пугающие математические формулы и абстрактная теория. Однако за всей этой сложностью скрывается удивительно доступная практика. Готовые примеры кода нейронных сетей — это как карта сокровищ для начинающих исследователей ИИ, позволяющая пропустить месяцы изучения теории и сразу приступить к созданию работающих моделей. 🚀 Давайте рассмотрим конкретные примеры, которые вы можете запустить прямо сегодня.

Мечтаете создавать собственные нейронные сети, но не знаете, с чего начать? Обучение Python-разработке от Skypro — ваш быстрый старт в мире ИИ! Курс построен так, что даже новички без опыта программирования смогут освоить нейронные сети и машинное обучение. Вы пройдете путь от базового синтаксиса Python до создания собственных интеллектуальных систем с профессиональной поддержкой преподавателей-практиков.

Базовые нейронные сети на Python для новичков

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

Рассмотрим пример простейшей нейронной сети, реализующей логический оператор AND:

Python
Скопировать код
import numpy as np

# Создаем персептрон для логического оператора AND
class Perceptron:
def __init__(self, learning_rate=0.1, n_iterations=100):
self.learning_rate = learning_rate
self.n_iterations = n_iterations
self.weights = None
self.bias = None

def fit(self, X, y):
# Инициализируем веса и смещение случайными значениями
n_samples, n_features = X.shape
self.weights = np.zeros(n_features)
self.bias = 0

# Обучаем персептрон
for _ in range(self.n_iterations):
for idx, x_i in enumerate(X):
linear_output = np.dot(x_i, self.weights) + self.bias
y_predicted = 1 if linear_output >= 0 else 0

# Обновляем веса и смещение
update = self.learning_rate * (y[idx] – y_predicted)
self.weights += update * x_i
self.bias += update

def predict(self, X):
linear_output = np.dot(X, self.weights) + self.bias
return np.where(linear_output >= 0, 1, 0)

# Тестируем на логической операции AND
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([0, 0, 0, 1]) # AND логика

perceptron = Perceptron()
perceptron.fit(X, y)

# Проверяем результаты
predictions = perceptron.predict(X)
print("Входные данные:")
print(X)
print("Предсказания:")
print(predictions)
print("Ожидаемый результат:")
print(y)

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

Но давайте перейдем к более практичному примеру — построению модели для прогнозирования цен на недвижимость:

Python
Скопировать код
import numpy as np
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

# Загружаем данные о ценах на недвижимость
housing = fetch_california_housing()
X, y = housing.data, housing.target

# Разделяем на тренировочную и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Нормализуем данные
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

# Простая нейронная сеть для регрессии
class SimpleNeuralNetwork:
def __init__(self, input_size, hidden_size, output_size=1):
self.W1 = np.random.randn(input_size, hidden_size) * 0.01
self.b1 = np.zeros((1, hidden_size))
self.W2 = np.random.randn(hidden_size, output_size) * 0.01
self.b2 = np.zeros((1, output_size))

def forward(self, X):
# Прямой проход через сеть
self.z1 = np.dot(X, self.W1) + self.b1
self.a1 = np.maximum(0, self.z1) # ReLU
self.z2 = np.dot(self.a1, self.W2) + self.b2
return self.z2

def backward(self, X, y, y_pred, learning_rate=0.001):
# Обратное распространение ошибки
m = X.shape[0]

# Градиент для выходного слоя
dz2 = (y_pred – y.reshape(-1, 1)) / m
dW2 = np.dot(self.a1.T, dz2)
db2 = np.sum(dz2, axis=0, keepdims=True)

# Градиент для скрытого слоя
da1 = np.dot(dz2, self.W2.T)
dz1 = da1 * (self.z1 > 0) # Производная ReLU
dW1 = np.dot(X.T, dz1)
db1 = np.sum(dz1, axis=0, keepdims=True)

# Обновляем параметры
self.W1 -= learning_rate * dW1
self.b1 -= learning_rate * db1
self.W2 -= learning_rate * dW2
self.b2 -= learning_rate * db2

def train(self, X, y, epochs=1000, learning_rate=0.001):
for i in range(epochs):
y_pred = self.forward(X)
self.backward(X, y, y_pred, learning_rate)

if i % 100 == 0:
loss = np.mean(np.square(y_pred – y.reshape(-1, 1)))
print(f"Эпоха {i}, Потери: {loss:.4f}")

def predict(self, X):
return self.forward(X)

# Создаем и обучаем сеть
nn = SimpleNeuralNetwork(input_size=X_train.shape[1], hidden_size=64)
nn.train(X_train, y_train, epochs=500, learning_rate=0.01)

# Оцениваем результаты
predictions = nn.predict(X_test)
mse = np.mean(np.square(predictions – y_test.reshape(-1, 1)))
print(f"Среднеквадратическая ошибка на тестовых данных: {mse:.4f}")

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

Тип нейронной сети Применение Сложность реализации Время обучения
Персептрон Логические операции, линейная классификация Низкая Секунды
Полносвязная NN Регрессия, простая классификация Средняя Минуты
Сверточная NN Распознавание образов, изображения Высокая Часы
Рекуррентная NN Последовательные данные, текст Высокая Часы

Алексей Соколов, ведущий инженер по машинному обучению

Однажды мой студент, бухгалтер по профессии без опыта программирования, сомневался, что сможет создать нейронную сеть. Мы начали с простейшего персептрона для задачи бинарной классификации. Мария (так звали студентку) реализовала его на чистом Python, строчка за строчкой. "Это похоже на математический расчет в Excel, только немного сложнее," — призналась она после успешного запуска модели.

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

Пошаговый план для смены профессии

Простой классификатор изображений с TensorFlow и Keras

Классификация изображений — одно из самых впечатляющих применений нейронных сетей. С помощью TensorFlow и Keras можно создать модель для распознавания изображений буквально в несколько строк кода.

Начнем с классического примера — распознавания рукописных цифр из набора данных MNIST:

Python
Скопировать код
import tensorflow as tf
from tensorflow import keras
import matplotlib.pyplot as plt
import numpy as np

# Загружаем данные MNIST
(X_train, y_train), (X_test, y_test) = keras.datasets.mnist.load_data()

# Предобработка данных
X_train = X_train / 255.0
X_test = X_test / 255.0

# Создаем модель сверточной нейронной сети
model = keras.Sequential([
keras.layers.Reshape((28, 28, 1), input_shape=(28, 28)),
keras.layers.Conv2D(32, kernel_size=(3, 3), activation='relu'),
keras.layers.MaxPooling2D(pool_size=(2, 2)),
keras.layers.Conv2D(64, kernel_size=(3, 3), activation='relu'),
keras.layers.MaxPooling2D(pool_size=(2, 2)),
keras.layers.Flatten(),
keras.layers.Dense(128, activation='relu'),
keras.layers.Dropout(0.5),
keras.layers.Dense(10, activation='softmax')
])

# Компилируем модель
model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)

# Обучаем модель
history = model.fit(
X_train, y_train,
epochs=5,
validation_data=(X_test, y_test),
batch_size=128
)

# Оцениваем точность модели
test_loss, test_acc = model.evaluate(X_test, y_test)
print(f"Точность на тестовых данных: {test_acc:.4f}")

# Визуализируем несколько предсказаний
predictions = model.predict(X_test[:10])
predicted_labels = np.argmax(predictions, axis=1)

plt.figure(figsize=(12, 4))
for i in range(10):
plt.subplot(1, 10, i+1)
plt.imshow(X_test[i], cmap='gray')
plt.title(f"Pred: {predicted_labels[i]}\nTrue: {y_test[i]}")
plt.axis('off')
plt.tight_layout()
plt.show()

Этот код создает сверточную нейронную сеть (CNN), которая способна распознавать рукописные цифры с точностью более 98%. Важно отметить, что с помощью всего около 30 строк кода мы получили модель, сравнимую по эффективности с тем, что несколько десятилетий назад требовало месяцев исследований.

Теперь рассмотрим более сложный пример — классификацию цветных изображений с использованием предобученной модели:

Python
Скопировать код
import tensorflow as tf
from tensorflow import keras
import numpy as np
import matplotlib.pyplot as plt

# Загрузим набор данных CIFAR-10
(X_train, y_train), (X_test, y_test) = keras.datasets.cifar10.load_data()

# Названия классов
class_names = ['самолет', 'автомобиль', 'птица', 'кот', 'олень', 
'собака', 'лягушка', 'лошадь', 'корабль', 'грузовик']

# Нормализация данных
X_train = X_train.astype('float32') / 255.0
X_test = X_test.astype('float32') / 255.0

# Преобразуем метки в категории
y_train = keras.utils.to_categorical(y_train, 10)
y_test = keras.utils.to_categorical(y_test, 10)

# Создадим модель с использованием предобученной сети
base_model = keras.applications.MobileNetV2(
input_shape=(160, 160, 3),
include_top=False,
weights='imagenet'
)

# Заморозим веса предобученной модели
base_model.trainable = False

# Создаем полную модель
model = keras.Sequential([
keras.layers.experimental.preprocessing.Resizing(160, 160),
base_model,
keras.layers.GlobalAveragePooling2D(),
keras.layers.Dense(128, activation='relu'),
keras.layers.Dropout(0.5),
keras.layers.Dense(10, activation='softmax')
])

# Компилируем модель
model.compile(
optimizer=keras.optimizers.Adam(learning_rate=0.0001),
loss='categorical_crossentropy',
metrics=['accuracy']
)

# Обучаем модель (используем меньше эпох для примера)
history = model.fit(
X_train, y_train,
batch_size=32,
epochs=3,
validation_data=(X_test, y_test)
)

# Оцениваем точность модели
test_loss, test_acc = model.evaluate(X_test, y_test)
print(f"Точность на тестовых данных: {test_acc:.4f}")

Здесь мы использовали технику переноса обучения (transfer learning), применяя предобученную на миллионах изображений модель MobileNetV2 для классификации изображений из набора CIFAR-10. Такой подход позволяет получить высокую точность даже при небольшом количестве собственных данных и ограниченных вычислительных ресурсах.

Несколько рекомендаций для улучшения моделей классификации изображений:

  • Аугментация данных — добавление случайных искажений к изображениям для расширения обучающего набора
  • Регуляризация — использование слоев Dropout и L2-регуляризации для предотвращения переобучения
  • Применение BatchNormalization — стабилизирует и ускоряет обучение
  • Использование предобученных моделей — значительно сокращает время обучения и улучшает точность
  • Мониторинг метрик — отслеживание не только точности, но и других показателей, таких как precision, recall и F1-score

Обработка текста: создание чат-бота на PyTorch

Обработка естественного языка (NLP) — еще одна область, где нейронные сети произвели революцию. PyTorch предоставляет гибкие инструменты для разработки моделей обработки текста, включая чат-ботов.

Рассмотрим пример создания простого чат-бота с использованием рекуррентной нейронной сети (RNN):

Python
Скопировать код
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
import random
import json
import nltk
from nltk.stem.lancaster import LancasterStemmer

# Загружаем необходимые ресурсы NLTK
nltk.download('punkt')
stemmer = LancasterStemmer()

# Загрузим данные для обучения
with open('intents.json') as file:
data = json.load(file)

# Пример содержимого intents.json:
"""
{
"intents": [
{
"tag": "greeting",
"patterns": ["Привет", "Здравствуйте", "Добрый день", "Как дела"],
"responses": ["Привет! Чем могу помочь?", "Здравствуйте!", "Рад вас видеть!"]
},
{
"tag": "goodbye",
"patterns": ["Пока", "До свидания", "Увидимся"],
"responses": ["До свидания!", "Хорошего дня!", "Буду рад помочь снова!"]
},
{
"tag": "thanks",
"patterns": ["Спасибо", "Благодарю", "Это помогло"],
"responses": ["Всегда пожалуйста!", "Рад был помочь!", "Обращайтесь!"]
}
]
}
"""

# Подготовка данных
words = []
tags = []
patterns_and_tags = []

# Извлекаем слова и теги
for intent in data['intents']:
tag = intent['tag']
tags.append(tag)

for pattern in intent['patterns']:
# Токенизация предложения
w = nltk.word_tokenize(pattern.lower())
words.extend(w)
patterns_and_tags.append((w, tag))

# Стемминг и удаление дубликатов
words = [stemmer.stem(w.lower()) for w in words if w not in "?!.,"]
words = sorted(list(set(words)))
tags = sorted(list(set(tags)))

# Создание обучающих данных
training = []
output = []

# Создаем "мешок слов" (bag of words)
output_empty = [0] * len(tags)

for doc in patterns_and_tags:
bag = []
pattern_words = doc[0]
pattern_words = [stemmer.stem(word.lower()) for word in pattern_words]

for w in words:
bag.append(1) if w in pattern_words else bag.append(0)

output_row = list(output_empty)
output_row[tags.index(doc[1])] = 1

training.append(bag)
output.append(output_row)

# Преобразуем в тензоры PyTorch
X_train = torch.FloatTensor(training)
y_train = torch.FloatTensor(output)

# Определяем модель
class ChatbotModel(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(ChatbotModel, self).__init__()
self.layer1 = nn.Linear(input_size, hidden_size)
self.layer2 = nn.Linear(hidden_size, hidden_size)
self.layer3 = nn.Linear(hidden_size, output_size)
self.relu = nn.ReLU()
self.softmax = nn.Softmax(dim=1)

def forward(self, x):
x = self.layer1(x)
x = self.relu(x)
x = self.layer2(x)
x = self.relu(x)
x = self.layer3(x)
return self.softmax(x)

# Параметры модели
input_size = len(X_train[0])
hidden_size = 8
output_size = len(tags)

# Создание модели и определение функции потерь и оптимизатора
model = ChatbotModel(input_size, hidden_size, output_size)
criterion = nn.BCELoss() # Binary Cross Entropy
optimizer = optim.Adam(model.parameters(), lr=0.001)

# Обучение модели
epochs = 1000
for epoch in range(epochs):
optimizer.zero_grad()
outputs = model(X_train)
loss = criterion(outputs, y_train)
loss.backward()
optimizer.step()

if (epoch + 1) % 100 == 0:
print(f"Эпоха {epoch+1}/{epochs}, Потери: {loss.item():.4f}")

# Функция для прогнозирования ответа
def bag_of_words(sentence, words):
# Токенизация и стемминг предложения
sentence_words = nltk.word_tokenize(sentence.lower())
sentence_words = [stemmer.stem(word.lower()) for word in sentence_words]

# Создание мешка слов
bag = [0] * len(words)
for sw in sentence_words:
for i, word in enumerate(words):
if word == sw:
bag[i] = 1

return torch.FloatTensor([bag])

def predict_response(message):
# Получаем "мешок слов" для входного сообщения
bow = bag_of_words(message, words)

# Получаем предсказание от модели
with torch.no_grad():
output = model(bow)

# Находим тег с наибольшей вероятностью
_, predicted = torch.max(output, dim=1)
tag = tags[predicted.item()]

# Выбираем случайный ответ из соответствующего тега
for intent in data['intents']:
if intent['tag'] == tag:
responses = intent['responses']
return random.choice(responses)

return "Извините, я не понимаю."

# Пример использования
while True:
message = input("Вы: ")
if message.lower() == "выход":
break

response = predict_response(message)
print(f"Бот: {response}")

Этот код создает простую модель чат-бота, которая может распознавать намерения пользователя и выдавать соответствующие ответы. Обратите внимание, что для работы этого примера необходим файл intents.json с шаблонами вопросов и ответов.

Михаил Давыдов, технический директор образовательной платформы

В 2021 году я консультировал компанию, которая хотела внедрить чат-бот поддержки для своих клиентов. Они получали тысячи однотипных вопросов, на которые приходилось отвечать живым операторам. Компания рассматривала предложения от разработчиков стоимостью от 500 000 рублей с длительными сроками разработки.

Я предложил альтернативу — создать прототип на PyTorch за неделю. Мы взяли исторические диалоги из системы поддержки, структурировали их по тематикам и создали датасет для обучения, похожий на представленный выше. Результат превзошел ожидания: бот корректно распознавал около 70% запросов с первого дня работы.

За месяц мы довели точность до 85%, что позволило сократить нагрузку на операторов на 40%. Самое удивительное, что клиенты даже не замечали, что общаются с ботом, а не с человеком. Этот случай наглядно показал, как относительно простые решения на основе нейронных сетей могут давать значимый бизнес-эффект без огромных инвестиций.

Для создания более продвинутого чат-бота можно использовать архитектуру Transformer, которая является основой современных языковых моделей:

Python
Скопировать код
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader
import math
import numpy as np

# Определение класса для создания набора данных
class ChatDataset(Dataset):
def __init__(self, X, y):
self.n_samples = len(X)
self.x_data = X
self.y_data = y

def __getitem__(self, index):
return self.x_data[index], self.y_data[index]

def __len__(self):
return self.n_samples

# Реализация механизма внимания (Attention)
class AttentionLayer(nn.Module):
def __init__(self, d_model, n_heads):
super(AttentionLayer, self).__init__()
self.d_model = d_model
self.n_heads = n_heads
self.head_dim = d_model // n_heads

self.query = nn.Linear(d_model, d_model)
self.key = nn.Linear(d_model, d_model)
self.value = nn.Linear(d_model, d_model)
self.out = nn.Linear(d_model, d_model)

def forward(self, query, key, value, mask=None):
batch_size = query.shape[0]

# Линейные преобразования
Q = self.query(query).view(batch_size, -1, self.n_heads, self.head_dim).transpose(1, 2)
K = self.key(key).view(batch_size, -1, self.n_heads, self.head_dim).transpose(1, 2)
V = self.value(value).view(batch_size, -1, self.n_heads, self.head_dim).transpose(1, 2)

# Вычисление внимания
scores = torch.matmul(Q, K.transpose(-2, -1)) / math.sqrt(self.head_dim)

if mask is not None:
scores = scores.masked_fill(mask == 0, -1e9)

attention = torch.softmax(scores, dim=-1)
out = torch.matmul(attention, V)

# Конкатенация и финальное преобразование
out = out.transpose(1, 2).contiguous().view(batch_size, -1, self.d_model)
out = self.out(out)

return out

# Определение трансформерного блока
class TransformerBlock(nn.Module):
def __init__(self, d_model, n_heads, dropout=0.1):
super(TransformerBlock, self).__init__()
self.attention = AttentionLayer(d_model, n_heads)
self.norm1 = nn.LayerNorm(d_model)
self.norm2 = nn.LayerNorm(d_model)

self.feed_forward = nn.Sequential(
nn.Linear(d_model, d_model * 4),
nn.ReLU(),
nn.Linear(d_model * 4, d_model)
)

self.dropout = nn.Dropout(dropout)

def forward(self, x, mask=None):
# Применение самовнимания
attention_out = self.attention(x, x, x, mask)
x = self.norm1(x + self.dropout(attention_out))

# Применение полносвязного слоя
ff_out = self.feed_forward(x)
x = self.norm2(x + self.dropout(ff_out))

return x

# Полная модель трансформера для чат-бота
class TransformerChatbot(nn.Module):
def __init__(self, input_size, output_size, d_model=64, n_heads=4, n_layers=2, dropout=0.1):
super(TransformerChatbot, self).__init__()

self.embedding = nn.Linear(input_size, d_model)
self.transformer_blocks = nn.ModuleList(
[TransformerBlock(d_model, n_heads, dropout) for _ in range(n_layers)]
)

self.fc_out = nn.Linear(d_model, output_size)
self.dropout = nn.Dropout(dropout)

def forward(self, x):
# Преобразуем входные данные в эмбеддинги
x = self.embedding(x)
x = x.unsqueeze(1) # Добавляем размерность последовательности

# Применяем трансформерные блоки
for transformer in self.transformer_blocks:
x = transformer(x)

# Извлекаем результат и классифицируем
x = x.squeeze(1) # Убираем размерность последовательности
x = self.fc_out(x)

return torch.softmax(x, dim=1)

Этот фрагмент кода демонстрирует реализацию модели на основе архитектуры Transformer для более сложных задач обработки языка. Хотя полная реализация чат-бота требует дополнительных компонентов, этот код предоставляет основу для создания современной модели обработки естественного языка.

Тип модели Преимущества Недостатки Типичные применения
Простая нейронная сеть Легко реализовать, быстрое обучение Ограниченная способность понимать контекст Классификация запросов по шаблонам
RNN/LSTM Понимает последовательности, запоминает контекст Медленное обучение, проблема исчезающего градиента Обработка текста среднего размера, генерация ответов
Transformer Отлично работает с контекстом, параллельные вычисления Требует много данных, вычислительно интенсивен Современные чат-боты, перевод, генерация текста
Pre-trained LLMs Огромная база знаний, понимание естественного языка Очень ресурсоемкие, сложны в доработке Передовые диалоговые системы, ответы на сложные вопросы

Генеративные сети: код для синтеза изображений

Генеративно-состязательные сети (GAN) произвели революцию в области синтеза контента, позволяя создавать реалистичные изображения, которые не существуют в реальности. Рассмотрим пример реализации базовой GAN для создания изображений рукописных цифр:

Python
Скопировать код
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
import matplotlib.pyplot as plt
import numpy as np

# Настраиваем параметры
batch_size = 64
latent_dim = 100
image_shape = (1, 28, 28)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# Загрузка данных MNIST
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize([0\.5], [0\.5])
])

mnist_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
dataloader = DataLoader(mnist_dataset, batch_size=batch_size, shuffle=True)

# Определяем генератор
class Generator(nn.Module):
def __init__(self):
super(Generator, self).__init__()

self.model = nn.Sequential(
nn.Linear(latent_dim, 128),
nn.LeakyReLU(0.2, inplace=True),
nn.Linear(128, 256),
nn.BatchNorm1d(256),
nn.LeakyReLU(0.2, inplace=True),
nn.Linear(256, 512),
nn.BatchNorm1d(512),
nn.LeakyReLU(0.2, inplace=True),
nn.Linear(512, 1024),
nn.BatchNorm1d(1024),
nn.LeakyReLU(0.2, inplace=True),
nn.Linear(1024, int(np.prod(image_shape))),
nn.Tanh()
)

def forward(self, z):
img = self.model(z)
img = img.view(img.size(0), *image_shape)
return img

# Определяем дискриминатор
class Discriminator(nn.Module):
def __init__(self):
super(Discriminator, self).__init__()

self.model = nn.Sequential(
nn.Linear(int(np.prod(image_shape)), 512),
nn.LeakyReLU(0.2, inplace=True),
nn.Linear(512, 256),
nn.LeakyReLU(0.2, inplace=True),
nn.Linear(256, 1),
nn.Sigmoid()
)

def forward(self, img):
img_flat = img.view(img.size(0), -1)
validity = self.model(img_flat)
return validity

# Инициализация моделей
generator = Generator().to(device)
discriminator = Discriminator().to(device)

# Оптимизаторы
optimizer_G = optim.Adam(generator.parameters(), lr=0.0002, betas=(0.5, 0.999))
optimizer_D = optim.Adam(discriminator.parameters(), lr=0.0002, betas=(0.5, 0.999))

# Функция потерь
adversarial_loss = nn.BCELoss()

# Обучение GAN
num_epochs = 100
sample_interval = 10

for epoch in range(num_epochs):
for i, (real_imgs, _) in enumerate(dataloader):
# Метки: реальные = 1, поддельные = 0
real_labels = torch.ones(real_imgs.size(0), 1).to(device)
fake_labels = torch.zeros(real_imgs.size(0), 1).to(device)

# Конфигурируем входные данные
real_imgs = real_imgs.to(device)

# -----------------
# Обучение генератора
# -----------------
optimizer_G.zero_grad()

# Генерируем случайный шум
z = torch.randn(real_imgs.size(0), latent_dim).to(device)

# Генерируем поддельные изображения
gen_imgs = generator(z)

# Вычисляем потери
g_loss = adversarial_loss(discriminator(gen_imgs), real_labels)

# Обратное распространение и обновление параметров
g_loss.backward()
optimizer_G.step()

# -----------------
# Обучение дискриминатора
# -----------------
optimizer_D.zero_grad()

# Вычисляем потери для реальных и поддельных изображений
real_loss = adversarial_loss(discriminator(real_imgs), real_labels)
fake_loss = adversarial_loss(discriminator(gen_imgs.detach()), fake_labels)
d_loss = (real_loss + fake_loss) / 2

# Обратное распространение и обновление параметров
d_loss.backward()
optimizer_D.step()

# Выводим информацию о процессе обучения
if i % 100 == 0:
print(f"[Эпоха {epoch}/{num_epochs}] [Батч {i}/{len(dataloader)}] "
f"[D loss: {d_loss.item():.4f}] [G loss: {g_loss.item():.4f}]")

# Сохраняем сгенерированные изображения
if epoch % sample_interval == 0:
# Генерируем и сохраняем образцы
with torch.no_grad():
z = torch.randn(25, latent_dim).to(device)
gen_imgs = generator(z).cpu()

# Отображаем сгенерированные изображения
fig, axs = plt.subplots(5, 5, figsize=(10, 10))
for i in range(5):
for j in range(5):
axs[i, j].imshow(gen_imgs[i*5 + j].view(28, 28), cmap='gray')
axs[i, j].axis('off')
plt.savefig(f"gan_images/epoch_{epoch}.png")
plt.close()

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

Более сложный пример — реализация StyleGAN для генерации лиц:

Python
Скопировать код
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
import numpy as np

# Определение слоя адаптивной нормализации экземпляра (AdaIN)
class AdaIN(nn.Module):
def __init__(self, style_dim, channels):
super(AdaIN, self).__init__()
self.channels = channels
self.style_mapping = nn.Linear(style_dim, channels * 2)
self.style_mapping.bias.data[:channels] = 1
self.style_mapping.bias.data[channels:] = 0

def forward(self, x, style):
style = self.style_mapping(style).unsqueeze(2).unsqueeze(3)
gamma, beta = style.chunk(2, dim=1)

# Нормализация
normalized = F.instance_norm(x)

# Применение стиля
out = gamma * normalized + beta

return out

# Определение блока генератора
class GeneratorBlock(nn.Module):
def __init__(self, in_channels, out_channels, style_dim):
super(GeneratorBlock, self).__init__()

self.conv1 = nn.Conv2d(in_channels, out_channels, 3, padding=1)
self.adain1 = AdaIN(style_dim, out_channels)

self.conv2 = nn.Conv2d(out_channels, out_channels, 3, padding=1)
self.adain2 = AdaIN(style_dim, out_channels)

def forward(self, x, style):
out = self.conv1(x)
out = self.adain1(out, style)
out = F.leaky_relu(out, 0.2)

out = self.conv2(out)
out = self.adain2(out, style)
out = F.leaky_relu(out, 0.2)

return out

# Определение генератора StyleGAN
class StyleGANGenerator(nn.Module):
def __init__(self, style_dim=512, num_channels=3, img_size=64):
super(StyleGANGenerator, self).__init__()

self.style_dim = style_dim
self.init_size = img_size // 8 # Начальный размер фичмапы
self.init_channel = 512

# Маппинг-сеть
self.mapping = nn.Sequential(
nn.Linear(style_dim, style_dim),
nn.LeakyReLU(0.2),
nn.Linear(style_dim, style_dim),
nn.LeakyReLU(0.2),
nn.Linear(style_dim, style_dim),
nn.LeakyReLU(0.2),
nn.Linear(style_dim, style_dim),
nn.LeakyReLU(0.2)
)

# Начальная константа
self.const = nn.Parameter(torch.randn(1, self.init_channel, self.init_size, self.init_size))

# Блоки генератора
self.blocks = nn.ModuleList([
GeneratorBlock(self.init_channel, 512, style_dim),
GeneratorBlock(512, 256, style_dim),
GeneratorBlock(256, 128, style_dim),
GeneratorBlock(128, 64, style_dim)
])

# Upsampling
self.up = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=False)

# Финальный слой
self.to_rgb = nn.Conv2d(64, num_channels, 1)

def forward(self, noise):
# Генерируем стиль из шума
style = self.mapping(noise)

# Начинаем с константы
out = self.const.repeat(noise.shape[0], 1, 1, 1)

# Применяем блоки генератора с upsample
for block in self.blocks:
out = self.up(out)
out = block(out, style)

# Преобразуем в RGB
out = self.to_rgb(out)

return torch.tanh(out)

# Определение дискриминатора
class StyleGANDiscriminator(nn.Module):
def __init__(self, num_channels=3, img_size=64):
super(StyleGANDiscriminator, self).__init__()

self.model = nn.Sequential(
nn.Conv2d(num_channels, 64, 4, stride=2, padding=1),
nn.LeakyReLU(0.2, inplace=True),

nn.Conv2d(64, 128, 4, stride=2, padding=1),
nn.BatchNorm2d(128),
nn.LeakyReLU(0.2, inplace=True),

nn.Conv2d(128, 256, 4, stride=2, padding=1),
nn.BatchNorm2d(256),
nn.LeakyReLU(0.2, inplace=True),

nn.Conv2d(256, 512, 4, stride=2, padding=1),
nn.BatchNorm2d(512),
nn.LeakyReLU(0.2, inplace=True),

nn.Conv2d(512, 1, 4, padding=0)
)

def forward(self, img):
validity = self.model(img)
return validity.view(img.size(0), -1)

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

Другие популярные разновидности генеративных моделей:

  • DCGAN (Deep Convolutional GAN) — использует свёрточные слои вместо полносвязных, что улучшает качество генерируемых изображений
  • CycleGAN — позволяет переносить стиль между изображениями без необходимости иметь парные образцы
  • Pix2Pix — модель для генерации изображений на основе контурных рисунков или схем
  • BigGAN — масштабная архитектура, способная генерировать изображения высокого разрешения
  • Diffusion Models — новейший класс генеративных моделей, показывающий великолепные результаты в генерации изображений

Готовые проекты нейросетей с GitHub для практики

GitHub — это настоящая сокровищница готовых проектов по нейронным сетям, которые можно изучать и использовать для практики. Вот список полезных репозиториев с работающим кодом:

  1. TensorFlow Models — официальный репозиторий с моделями от Google
  2. PyTorch Examples — коллекция примеров использования PyTorch для различных задач
  3. Keras Examples — простые для понимания примеры с использованием Keras
  4. Fast.ai Courses — учебные материалы и примеры кода от популярной образовательной платформы
  5. YOLO (You Only Look Once) — популярная система объектного распознавания в реальном времени
  6. StyleGAN2 — реализация продвинутой генеративной сети для создания фотореалистичных изображений
  7. GPT-2 — открытая реализация языковой модели для генерации текста
  8. DeepSpeech — система распознавания речи на основе глубокого обучения
  9. AlphaZero — реализации системы обучения с подкреплением для настольных игр
  10. DeOldify — проект для колоризации черно-белых изображений и видео

Для начинающих особенно полезны репозитории с пошаговыми руководствами:

Bash
Скопировать код
# Клонирование репозитория с примерами TensorFlow
git clone https://github.com/tensorflow/examples.git
cd examples/tensorflow_examples/models/pix2pix

# Установка зависимостей
pip install -r requirements.txt

# Запуск примера
python pix2pix.py

Если вы хотите практиковаться с продвинутыми моделями, не имея мощного оборудования, рассмотрите возможность использования Google Colab. Многие репозитории адаптированы для запуска в этой среде:

Bash
Скопировать код
# Пример использования Colab с клонированием репозитория
!git clone https://github.com/tensorflow/models.git
!cd models/research/object_detection && pip install -q .

# Импортирование и использование
from object_detection.utils import visualization_utils as vis_util
from object_detection.builders import model_builder

Для более структурированного подхода к практике рекомендую выполнить следующие проекты в порядке возрастания сложности:

  1. Классификация MNIST — создание модели для распознавания рукописных цифр
  2. Классификация CIFAR-10 — б

Читайте также

Проверь как ты усвоил материалы статьи
Пройди тест и узнай насколько ты лучше других читателей
Какая библиотека используется для создания и обучения нейронных сетей на языке Python?
1 / 5

Загрузка...