Неделя 8: Рекуррентные нейронные сети (RNN) и обработка временных рядов
1. Теоретическая часть
1.1. Основы RNN
Рекуррентные нейронные сети — архитектура для обработки последовательностей (текст, временные ряды, речь).
Ключевые особенности
Скрытое состояние (hidden state): Сохраняет информацию о предыдущих элементах последовательности
Рекуррентная формула:
ℎ𝑡=𝜎(𝑊𝑥ℎ𝑥𝑡+𝑊ℎℎℎ𝑡−1+𝑏ℎ)ht=σ(Wxhxt+Whhht−1+bh)𝑦𝑡=𝑊ℎ𝑦ℎ𝑡+𝑏𝑦yt=Whyht+by
Проблемы базовых RNN
Исчезающие градиенты: Сложность обучения на длинных последовательностях
Взрывающиеся градиенты
1.2. Усовершенствованные архитектуры
Архитектура
Решаемая проблема
LSTM (Long Short-Term Memory)
Контроль потока информации (входные, выходные и забывающие gates)
GRU (Gated Recurrent Unit)
Упрощенная версия LSTM с двумя gates
1.3. Применение RNN
Классификация текста
Генерация последовательностей
Прогнозирование временных рядов
2.1. Реализация LSTM на PyTorch
python
Copy
import torch.nn as nn
class LSTMClassifier(nn.Module):
def __init__(self, input_size, hidden_size, num_layers, num_classes):
super(LSTMClassifier, self).__init__()
self.hidden_size = hidden_size
self.num_layers = num_layers
self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
self.fc = nn.Linear(hidden_size, num_classes)
def forward(self, x):
h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size)
c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size)
out, _ = self.lstm(x, (h0, c0))
out = self.fc(out[:, -1, :])
return out
2.2. Обучение на IMDB Reviews
python
Copy
from torchtext.data import Field, BucketIterator
from torchtext.datasets import IMDB
# Подготовка данных
TEXT = Field(tokenize='spacy', lower=True)
LABEL = Field(dtype=torch.float)
train_data, test_data = IMDB.splits(TEXT, LABEL)
# Построение словаря
TEXT.build_vocab(train_data, max_size=25000)
LABEL.build_vocab(train_data)
# Создание итераторов
train_iterator, test_iterator = BucketIterator.splits(
(train_data, test_data),
batch_size=64,
device=device
)
# Обучение
model = LSTMClassifier(input_size=100, hidden_size=256, num_layers=2, num_classes=1)
optimizer = torch.optim.Adam(model.parameters())
criterion = nn.BCEWithLogitsLoss()
for epoch in range(5):
for batch in train_iterator:
predictions = model(batch.text).squeeze(1)
loss = criterion(predictions, batch.label)
optimizer.zero_grad()
loss.backward()
optimizer.step()
2.3. Визуализация внимания
python
Copy
# Пример реализации механизма внимания
class Attention(nn.Module):
def __init__(self, hidden_size):
super(Attention, self).__init__()
self.attention = nn.Linear(hidden_size, 1)
def forward(self, lstm_output):
attention_weights = torch.softmax(self.attention(lstm_output), dim=1)
context_vector = torch.sum(attention_weights * lstm_output, dim=1)
return context_vector
3. Домашнее задание
Задача 1: Прогнозирование временных рядов
1. Загрузите данные акций (например, AAPL) через yfinance.
2. Реализуйте многошаговое прогнозирование с помощью LSTM.
Решение:
python
Copy
import yfinance as yf
# Загрузка данных
data = yf.download('AAPL', start='2020-01-01', end='2023-01-01')
prices = data['Close'].values
# Нормализация и создание последовательностей
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
scaled_prices = scaler.fit_transform(prices.reshape(-1, 1))
def create_sequences(data, seq_length):
X, y = [], []
for i in range(len(data)-seq_length-1):
X.append(data[i:i+seq_length])
y.append(data[i+seq_length])
return np.array(X), np.array(y)
X, y = create_sequences(scaled_prices, 10)
Задача 2: Сравнение RNN, LSTM и GRU
1. Реализуйте три модели (RNN, LSTM, GRU) для классификации текста.
2. Сравните их точность и время обучения.
Решение:
python
Copy
class RNNModel(nn.Module):
def __init__(self, input_size, hidden_size, num_layers, num_classes):
super(RNNModel, self).__init__()
self.rnn = nn.RNN(input_size, hidden_size, num_layers, batch_first=True)
self.fc = nn.Linear(hidden_size, num_classes)
class GRUModel(nn.Module):
def __init__(self, input_size, hidden_size, num_layers, num_classes):
super(GRUModel, self).__init__()
self.gru = nn.GRU(input_size, hidden_size, num_layers, batch_first=True)
self.fc = nn.Linear(hidden_size, num_classes)
Задача 3: Генерация текста
1. Обучите char-level LSTM на произведениях Шекспира.
2. Реализуйте функцию генерации текста.
Решение:
python
Copy
# Загрузка данных
with open('shakespeare.txt', 'r') as f:
text = f.read()
# Создание словаря символов
chars = sorted(list(set(text)))
char_to_idx = {ch:i for i, ch in enumerate(chars)}
# Подготовка последовательностей
seq_length = 100
sequences = []
for i in range(0, len(text)-seq_length):
sequences.append(text[i:i+seq_length+1])
# Обучение модели генерации
class CharLSTM(nn.Module):
def __init__(self, vocab_size, hidden_size):
super(CharLSTM, self).__init__()
self.lstm = nn.LSTM(vocab_size, hidden_size, batch_first=True)
self.fc = nn.Linear(hidden_size, vocab_size)
Итоги недели
✅ Изучили архитектуры RNN, LSTM и GRU.
✅ Реализовали классификацию текста и прогнозирование временных рядов.
✅ Сравнили различные рекуррентные модели.
✅ Научились работать с механизмами внимания.
Следующая тема: Трансформеры и механизм внимания. 🤖