【问题标题】:InvalidArgumentError: Specified a list with shape [1,1] from a tensor with shape [32,1] in tensorflow v2.4 but working well in tensorflow v1.14InvalidArgumentError:从 tensorflow v2.4 中形状为 [32,1] 的张量中指定形状为 [1,1] 的列表,但在 tensorflow v1.14 中运行良好
【发布时间】:2021-08-01 02:41:09
【问题描述】:

我正在尝试进行时间序列预测,训练进展顺利,但传递相同的数据集来预测函数时出现以下错误。

InvalidArgumentError:从形状为 [32,1] 的张量中指定了一个形状为 [1,1] 的列表 [[节点顺序/lstm/TensorArrayUnstack/TensorListFromTensor]] [Op:__inference_predict_function_55827] 函数调用栈: predict_function

我使用的是 Statefull Lstm,并且相同的代码和模型在 tensorflow v1.14 中运行良好,但在 tensorflow v2.4 中运行良好。

我的 X_train.shape,y_train.shape 是 ((6191, 10, 1), (6191, 1)), X_test.shape=(6191, 10, 1) 和 batch_size=1

model = Sequential()
model.add(LSTM(10,batch_input_shape=(batch_size, int(i_shape[0]), int(i_shape[1])), 
               activation=activation,stateful=True,
               kernel_regularizer=L1L2(0.01,0.001)))

Model: "sequential_6"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
lstm_11 (LSTM)               (1, 10)                   480       
_________________________________________________________________
dense_4 (Dense)              (1, 1)                    11        
=================================================================
Total params: 491
Trainable params: 491
Non-trainable params: 0
_________________________________________________________________
None

如果需要任何其他信息,请告诉我。

【问题讨论】:

    标签: tensorflow time-series lstm forecasting


    【解决方案1】:

    我遇到了同样的错误。就我而言,我在 LSTM 周围使用了双向包装器。

    我通过一次预测一个时间步来解决问题。

    1. 创建一个将数据拆分为 X 和 Y 的函数。(我想你已经有了)
    import numpy as np
    
    def split_sequence(sequence, n_steps):
        X, y = list(), list()
        for i in range(len(sequence)):
            # find the end of this pattern
            end_ix = i + n_steps
            # check if we are beyond the sequence
            if end_ix > len(sequence)-1:
                break
            # gather input and output parts of the pattern
            seq_x, seq_y = sequence[i:end_ix], sequence[end_ix]
            X.append(seq_x)
            y.append(seq_y)
        return np.array(X), np.array(y)
    
    1. 创建一个循环遍历 X 并进行预测的函数。
    def get_predictions(model, np_input, look_back):
        X = list()
        for i in range(len(np_input)):
            #print(np_input[i])
            
            n_features = 1
            testX = np_input[i].reshape((1, look_back, n_features))
            
            #this returns one prediction that has 2 dimensions so we need to flatten
            testPredict = model.predict(testX)
            X.append(testPredict.flatten())
            
        return np.array(X)
    

    测试split_sequence

    import numpy as np
    from keras.models import load_model
    
    raw_seq = np.array([0, 0, 0, 0, 0, 0,
                     0, 0, 0, 0, 0, 0,
                     0, 0, 0, 0, 0, 0,
                     0, 0, 0, 0, 0, 0, 1])
    
    n_steps = 24
    X, y = split_sequence(raw_seq, n_steps)
    
    for i in range(len(X)):
        print(X[i], y[i])
    
    n_features = 1
    testX = X.reshape((X.shape[0], X.shape[1], n_features))
    
    model = load_model("<your_model_file>")
    
    testPredict = model.predict(testX)
    print("===Prediction===")
    print(testPredict)
    

    在这个例子中,我有 24 个时间步(当然,模型是用 24 个时间步创建的),并预测第 25 个元素。因此,样本输入 (raw_seq) 共有 25 个元素。

    您会注意到,如果您将一个元素添加到 raw_seq,则会再次出现错误。这意味着 model.predict 一次只能做一个预测。

    测试 split_sequenceget_predictions

    raw_seq = np.array([0, 0, 0, 0, 0, 0,
                     0, 0, 0, 0, 0, 0,
                     0, 0, 0, 0, 0, 0,
                     0, 0, 0, 0, 0, 1, 1,
                       
                     0, 1, 0, 0, 0, 0,
                     0, 0, 0, 0, 0, 0,
                     0, 0, 0, 0, 0, 0,
                     0, 0, 0, 0, 0, 1, 2
                       
                       ])
    
    look_back = 24
    X, y = split_sequence(raw_seq, look_back)
    
    preds = get_predictions(model, X, look_back)
    print(preds)
    

    运行代码将给出 26 个预测 preds.shape = (26, 1)

    正如预期的那样,对整个数据集的预测需要很长时间。

    【讨论】:

    • 感谢您的回答。这是否适用于在模型中定义批量大小的有状态 lstm?因为您在 model.predict() 中的批大小为 1,但在训练模型期间定义的 batch_input_shape 可能不同。
    • 我正在做与您提到的类似的事情,我的用例是比较在整个数据集上训练与在线训练时的模型预测。所以问题只发生在使用整个数据集的过程中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-05
    • 1970-01-01
    • 2018-10-09
    • 1970-01-01
    • 2018-08-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多