RNN - 运行时错误:输入必须有 3 维,得到 2

问题描述

我收到以下错误

运行时错误:输入必须有 3 个维度,得到 2 个

我有一个单一的特征列,我试图将它输入到 GRU 神经网络中。

下面是我的数据加载器和神经网络。当我检索一批数据时,我还包含了数据加载器的输出

我做错了什么???

def batch_data(feature1,sequence_length,batch_size):
“”"
Batch the neural network data using DataLoader
:param feature1: the single feature column
:param sequence_length: The sequence length of each batch
:param batch_size: The size of each batch; the number of sequences in a batch
:return: DataLoader with batched data
“”"
    # total number of batches we can make
    n_batches = len(feature1)//batch_size

    # Keep only enough characters to make full batches
    feature1= feature1[:n_batches * batch_size]

    y_len = len(feature1) - sequence_length

    x,y = [],[]
    for idx in range(0,y_len):
        idx_end = sequence_length + idx
        x_batch = feature1[idx:idx_end]
        x.append(x_batch)
        # only making predictions after the last item in the batch
        batch_y = feature1[idx_end]    
        y.append(batch_y)    

    # create tensor datasets
    data = TensorDataset(torch.from_numpy(np.asarray(x)),torch.from_numpy(np.asarray(y)))

    data_loader = DataLoader(data,shuffle=False,batch_size=batch_size)

    # return a DataLoader
    return data_loader



# test DataLoader on subset of actual data

test_text = data_subset_b
t_loader = batch_data(test_text,sequence_length=5,batch_size=10)
 
data_iter = iter(t_loader)
sample_x,sample_y = data_iter.next()
 
print(sample_x.shape)
print(sample_x)
print()
print(sample_y.shape)
print(sample_y)

当我传入数据时,会生成以下批处理...

torch.Size([10,5])
tensor([[ 0.0045,0.0040,-0.0008,0.0005,-0.0012],[ 0.0040,-0.0012,0.0000],[-0.0008,0.0000,-0.0015],[ 0.0005,-0.0015,0.0008],[-0.0012,0.0008,[ 0.0000,[-0.0015,-0.0008],[ 0.0008,-0.0039],-0.0039,-0.0026],-0.0026,-0.0082]],dtype=torch.float64)

torch.Size([10])
tensor([ 0.0000,-0.0082,0.0078],dtype=torch.float64)

这是我的神经网络架构:

class GRU(nn.Module):
def __init__(self,input_dim,output_dim,n_hidden,n_layers,dropout=0.25,lr=0.001):
    super().__init__()
    
    # set class variables
    self.output_dim = output_dim
    self.n_layers = n_layers
    self.n_hidden = n_hidden
    
    # define model layers
    
    # define gru layer
    self.gru = nn.GRU(input_dim,dropout=dropout,batch_first=True)
    
    # define a dropout layer
    self.dropout = nn.Dropout(dropout)
    
    # define the final,fully-connected output layer
    self.fc = nn.Linear(n_hidden,output_dim)   


def forward(self,nn_input,hidden):
    ''' Forward pass through the network. 
        These inputs are x,and the hidden/cell state `hidden`. '''
    
    # batch_size equals the input's first dimension
    batch_size = nn_input.size(0)
    
    # Get the outputs and the new hidden state from the lstm
    r_output,hidden = self.gru(nn_input,hidden)
    
    # pass through a dropout layer
    out = self.dropout(r_output)
    
    # Stack up LSTM outputs using view
    # you may need to use contiguous to reshape the output
    out = out.contiguous().view(-1,self.n_hidden)
    
    # put nn_input through the fully-connected layer
    out = self.fc(out)

    # reshape into (batch_size,seq_length,output_size)
    out = out.view(batch_size,-1,self.output_dim)
    
    # get last batch
    out = out[:,-1]
    
    # return the final output and the hidden state
    return out,hidden


def init_hidden(self,batch_size):
    ''' Initializes hidden state '''
    # Create two new tensors with sizes n_layers x batch_size x n_hidden,# initialized to zero,for hidden state and cell state of LSTM
    weight = next(self.parameters()).data
    
    if (train_on_gpu):
        hidden = (weight.new(self.n_layers,batch_size,self.n_hidden).zero_().cuda(),weight.new(self.n_layers,self.n_hidden).zero_().cuda())
    else:
        hidden = (weight.new(self.n_layers,self.n_hidden).zero_(),self.n_hidden).zero_())
    
    return hidden

解决方法

正如你得到的错误所暗示的那样,GRU 期望的输入张量形状是三维的,形状为 (batch_size,seq_len,input_size)1

但是您正在输入一个形状为 (10,5) 的张量。你说你的输入有一个特征值,所以你应该为 input_size 添加一个尺寸为 1 的维度。这可以这样做

sample_x.unsqueeze(-1)
,

实际上错误本身会告诉您问题所在。 RNN 类是 GRU 的超类,期望输入形状为:

 (#batch,#number_of_timesteps,#number_of_features)

因此,对于您的情况,您有 1 个特征,5 个时间步长。在您的数据加载器中,您需要将 X 扩展为 (#batch,5,1)。