首页 > 解决方案 > LSTM-CNN 对图像序列进行分类

问题描述

在学习 PyTorch、LSTM 和 cnn 的兔子洞中,我得到了一个任务并坚持下去。提供众所周知的 MNIST 库,我采用 4 个数字的组合,每个组合它属于 7 个标签之一。

eg: 1111 label 1 (跟随恒定趋势)
1234 label 2 上升趋势
4321 label 3下降趋势
...
7382 label 7下降趋势 - 上升趋势 - 下降趋势

加载张量后张量的形状变为 (3,4,28,28),其中 28 来自 MNIST 图像的宽度和高度。3 是批量大小,4 是通道(4 个图像)。

我有点不知道如何将它传递给 PyTorch 支持的 LSTM 和 CNN,因为基本上所有谷歌搜索都会导致只传递一张图像的文章。

我正在考虑将其重塑为 1 个长数组(像素值),在其中我将第一个图像的所有值逐行(28)一个接一个地放置,然后以相同的方法附加到第二个、第三个和第四个图像. 所以这将使 4 * 28 * 28 = 3136。

我对如何解决这个问题的思考方式是正确的,还是应该重新思考?我对这一切都很陌生,正在寻找一些关于如何前进的指导。我一直在阅读大量文章、YT 视频……但似乎都触及了同一主题的基本内容或替代方案。

我写了一些代码,但运行它会出错。

import numpy as np
import torch
import torch.nn as nn
from torch import optim, softmax
from sklearn.model_selection import train_test_split

#dataset = sequences of 4 MNIST images each
#datalabels =7

#Data
x_train, x_test, y_train, y_test = train_test_split(dataset.data, dataset.data_label, test_size=0.15,
                                                    random_state=42)
#model
class Mylstm(nn.Module):
    def __init__(self, input_size, hidden_size, n_layers, n_classes):
        super(Mylstm, self).__init__()
        self.input_size = input_size
        self.n_layers = n_layers
        self.hidden_size = hidden_size
        self.lstm = nn.LSTM(input_size, hidden_size, n_layers, batch_first=True)
        # readout layer
        self.fc = nn.Linear(hidden_size, n_classes)

    def forward(self, x):
        # Initialize hidden state with zeros
        h0 = torch.zeros(self.n_layers, x.size(0), self.hidden_size).requires_grad_()
        # initialize the cell state:
        c0 = torch.zeros(self.n_layers, x.size(0), self.hidden_size).requires_grad_()
        out, (h_n, h_c) = self.lstm(x, (h0.detach(), c0.detach()))
        x = h_n[-1, :, 1]  
        x = self.fc(x)
        x = softmax(x, dim=1)
        return x

#Hyperparameters
input_size = 28
hidden_size = 256
sequence_length = 28
n_layers = 2
n_classes = 7
learning_rate = 0.001
model = Mylstm(input_size, hidden_size, n_layers, n_classes)
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)


#training
bs = 0
num_epochs = 5
batch_size=3

if np.mod(x_train.shape[0], batch_size) == 0.0:
    iter = int(x_train.shape[0] / batch_size)
else:
    iter = int(x_train.shape[0] / batch_size) + 1
bs = 0
for i in range(iter):
    sequences = x_test[bs:bs + batch_size, :]
    labels = y_test[bs:bs + batch_size]
    test_images = dataset.load_images(sequences)
    bs += batch_size

for epoch in range(num_epochs):
    for i in range(iter):
        sequences = x_train[bs:bs + batch_size, :]
        labels = y_train[bs:bs + batch_size]
        input_images = dataset.load_images(sequences)
        bs += batch_size
        images=(torch.from_numpy(input_images)).view(batch_size,4,-1)
        labels=torch.from_numpy(labels)
        optimizer.zero_grad()
        output = model(images)
        # calculate Loss
        loss = criterion(output, labels)
        loss.backward()
        optimizer.step()

我目前得到的错误是:

RuntimeError: input.size(-1) 必须等于 input_size。预计28,得到784

标签: pythonpytorchconv-neural-networklstm

解决方案


将输入大小从 28 更改为 784。(784=28*28)。

输入大小参数是序列的一个元素中的特征数,因此是mnist图像的特征数,因此是图像的宽度*高度的像素数。


推荐阅读