LSTM-CNN 对图像序列进行分类

时间:2021-04-21 11:59:14

标签: python pytorch conv-neural-network lstm

我得到了一项作业,并在深入学习 PyTorch、LSTM 和 cnn 的过程中坚持了下来。 提供众所周知的 MNIST 库,我采用 4 个数字的组合,每个组合都属于 7 个标签之一。

例如: 1111标签1(顺应潮流)
1234标签2增加趋势
4321标签3下降趋势
...
7382标签7下降趋势-上升趋势-下降趋势

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

我对如何将其传递到 PyTorch 支持的 LSTM 和 CNN 有点困惑,因为基本上所有 Google 搜索都会导致文章只传递一张图像。

我正在考虑将它重塑为 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()

我目前遇到的错误是:

<块引用>

运行时错误:input.size(-1) 必须等于 input_size。预计 28,得到 784

1 个答案:

答案 0 :(得分:1)

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

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