Вопрос или проблема
Я получил задание и погрузился в изучение PyTorch, LSTM и CNN.
Используя известную библиотеку MNIST, я беру комбинации из 4 чисел, и для каждой комбинации она попадает в одну из 7 меток.
например:
1111 метка 1 (следует постоянной тенденции)
1234 метка 2 возрастающая тенденция
4321 метка 3 убывающая тенденция
…
7382 метка 7 убывающая тенденция – возрастающая тенденция – убывающая тенденция
Форма моего тензора после загрузки тензора становится (3,4,28,28), где 28 – это ширина и высота изображения MNIST. 3 – это размер пакета, а 4 – это каналы (4 изображения).
Я немного застрял с тем, как передать это в LSTM и CNN на базе PyTorch, так как все поиски в Google ведут к статьям, где передается просто одно изображение.
Я думал о переформатировании в один длинный массив (значений пикселей), где я помещаю все значения первого изображения построчно (28) одно за другим, затем добавляю таким же образом для второго, третьего и четвертого изображения. Таким образом, получится 4 * 28 * 28 = 3136.
Правильный ли мой подход к решению этой задачи или мне стоит пересмотреть его? Я довольно нов в этом и ищу руководство о том, как двигаться дальше. Я прочитал множество статей, просмотрел видео на YouTube и т.д., но все они, кажется, касаются только базовых вещей или альтернатив одной и той же темы.
CNN-LSTM используются в распознавании текста. Как структурирован текст? Символы располагаются горизонтально. Сделайте то же самое с вашими изображениями MNIST и для эталона создайте правильные метки (должны быть размера 4).
Ответ или решение
Для решения задачи классификации последовательности изображений с использованием LSTM и CNN-LSTM в библиотеке PyTorch, вам нужно учесть несколько ключевых моментов. Давайте разберем этот процесс шаг за шагом.
1. Структура данных
Ваши тензоры уже имеют форму (3, 4, 28, 28)
, где:
3
— это размер батча (количество последовательностей, которые вы обрабатываете одновременно),4
— количество изображений в последовательности,28, 28
— высота и ширина изображений из набора данных MNIST.
2. Форматирование данных
Вы правильно понимаете, что преобразование изображений в 1D вектор может быть полезным. Однако, учитывая, что вы работаете со временем (последовательностью изображений), рекомендуется оставлять информацию о пространственных признаках:
- Вместо того, чтобы делать преобразование в один длинный вектор с помощью
reshape
, вам лучше сохранить 4 канала входа (изображения) в каждой последовательности. Это позволит модели LSTM и CNN лучше понимать пространственную и временную структуру данных.
3. CNN-LSTM Модель
CNN-LSTM модель комбинирует свёрточные нейронные сети (CNN) для выделения пространственных признаков из изображений и LSTM для обработки временной информации:
Шаги:
-
Создание CNN слоя: Примените несколько свёрточных слоев к каждой картинке во временной последовательности. Например, вы можете использовать
nn.Conv2d
для обработки изображений. -
Плоское преобразование: После свёртки вы можете использовать
nn.MaxPool2d
для уменьшения размерности, а затем изменить размер наview
для подготовки данных к LSTM. -
LSTM слой: Примените
nn.LSTM
к полученному выходу из CNN, чтобы обрабатывать временные зависимости. -
Полносвязный слой: После LSTM добавьте финальный полносвязный слой для получения предсказания классов.
Пример реализации
Вот пример кода, описывающий общую структуру вашей модели:
import torch
import torch.nn as nn
class CNNLSTM(nn.Module):
def __init__(self, input_size, hidden_size, num_classes):
super(CNNLSTM, self).__init__()
self.cnn = nn.Sequential(
nn.Conv2d(in_channels=1, out_channels=32, kernel_size=3, stride=1, padding=1),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2),
nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1),
nn.ReLU(),
nn.MaxPool2d(2)
)
self.lstm = nn.LSTM(input_size, hidden_size, batch_first=True)
self.fc = nn.Linear(hidden_size, num_classes)
def forward(self, x):
batch_size, seq_length, channels, height, width = x.size()
# Применение CNN к каждому изображению во временной последовательности
c_in = x.view(batch_size * seq_length, channels, height, width)
cnn_out = self.cnn(c_in)
# Изменение размерности для LSTM
cnn_out = cnn_out.view(batch_size, seq_length, -1) # (batch_size, seq_length, features)
# LSTM
lstm_out, _ = self.lstm(cnn_out)
# Полносвязный слой для классификации
output = self.fc(lstm_out[:, -1, :]) # Выбираем последний временной шаг
return output
# Параметры модели
model = CNNLSTM(input_size=64*7*7, hidden_size=128, num_classes=7)
4. Обучение модели
Убедитесь, что ваш батч данных корректно загружается. Используйте DataLoader
, чтобы облегчить загрузку и разбивку данных. Определите функцию потерь и оптимизаторы, чтобы приступить к обучению модели.
Заключение
Сохраняя пространственную структуру ваших данных и комбинируя CNN и LSTM, вы сможете извлекать и классифицировать временные зависимости из последовательностей изображений. Удачи в вашем проекте, и не стесняйтесь экспериментировать с различными гиперпараметрами для улучшения результатов!