You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

单变量LSTM时间序列建模报错:输入应为张量而非Sequential对象

问题描述

搭建单变量LSTM时间序列预测模型时,反复触发如下错误:

TypeError: Inputs to a layer should be tensors. Got '<keras.src.engine.sequential.Sequential object at 0x7fe7fdec8820>' (of type <class 'keras.src.engine.sequential.Sequential'>) as input for layer 'lstm_4'

已尝试用数组、矩阵格式化训练数据,确认输入格式正确,但错误依然存在。相关代码及使用的数据如下:

复现代码

library(keras)
library(tensorflow)

# Split the data into training and test sets
train_data <- data[1:4, ]
test_data <- data[2:nrow(data), ]

# Normalize the data
normalize <- function(x) {
  (x - mean(x)) / sd(x)
}
train_data$value <- normalize(train_data$value)
test_data$value <- normalize(test_data$value)

# Prepare the training data
lag <- 3  # Number of lag observations

train_y <- train_data$value[(lag + 1):nrow(train_data)]

# Create an empty matrix for train_x with appropriate dimensions
train_x <- matrix(0, nrow = nrow(train_data) - lag, ncol = lag)

# Assign values to train_x
for (i in 1:(nrow(train_data) - lag)) {
  train_x[i, ] <- as.numeric(train_data[i:(i + lag - 1), 1])
}


# Reshape train_x to 3D tensor
train_x <- array(train_x, dim = c(dim(train_x)[1], dim(train_x)[2], 1))

# Define the LSTM model
model <- keras_model_sequential()
model %>%
  layer_lstm(units = 50, input_shape = c(dim(train_x)[2], 1)) %>%
  layer_dense(units = 1)

使用的数据

data = read.table(
  text =  'year value
          1990  30614250
          1991  30761180
          1992  30678770
          1993  30819730
          1994  31105680
          1995  31890420',
  header = TRUE)

问题分析与修复

核心错误:训练数据取错列

代码中准备train_x时,错误提取了year列(第1列),而非需要预测的value列。这不仅导致输入数据语义错误,还结合Keras张量处理逻辑触发了类型错误。

修复循环赋值的代码行:

# 原错误代码
train_x[i, ] <- as.numeric(train_data[i:(i + lag - 1), 1])

# 修改为(提取value列,即第2列)
train_x[i, ] <- as.numeric(train_data[i:(i + lag - 1), 2])

其他关键优化

  1. 训练样本量不足
    当前训练集仅4条数据,lag设为3后train_x仅1行样本,无法有效训练LSTM。建议扩大训练集规模,例如将train_data改为data[1:5, ],可得到2行有效训练样本。

  2. 标准化逻辑修正
    测试集的标准化必须使用训练集的均值和标准差,避免数据泄露:

# 用训练集统计量做标准化
train_mean <- mean(train_data$value)
train_sd <- sd(train_data$value)

normalize <- function(x, mean, sd) {
  (x - mean) / sd
}

train_data$value <- normalize(train_data$value, train_mean, train_sd)
test_data$value <- normalize(test_data$value, train_mean, train_sd)
  1. 补充模型编译与训练步骤
    原代码仅定义了模型结构,需补充编译和训练逻辑才能运行:
model %>% compile(
  loss = 'mse',
  optimizer = optimizer_adam(learning_rate = 0.001)
)

history <- model %>% fit(
  x = train_x,
  y = train_y,
  epochs = 100,
  batch_size = 1,
  verbose = 1
)

修复后的完整代码

library(keras)
library(tensorflow)

# 加载数据
data = read.table(
  text =  'year value
          1990  30614250
          1991  30761180
          1992  30678770
          1993  30819730
          1994  31105680
          1995  31890420',
  header = TRUE)

# 划分训练集和测试集(扩大训练集规模)
train_data <- data[1:5, ]
test_data <- data[2:nrow(data), ]

# 标准化数据(用训练集统计量)
train_mean <- mean(train_data$value)
train_sd <- sd(train_data$value)

normalize <- function(x, mean, sd) {
  (x - mean) / sd
}

train_data$value <- normalize(train_data$value, train_mean, train_sd)
test_data$value <- normalize(test_data$value, train_mean, train_sd)

# 准备训练数据
lag <- 3
train_y <- train_data$value[(lag + 1):nrow(train_data)]

train_x <- matrix(0, nrow = nrow(train_data) - lag, ncol = lag)
for (i in 1:(nrow(train_data) - lag)) {
  # 提取value列(第2列)
  train_x[i, ] <- as.numeric(train_data[i:(i + lag - 1), 2])
}

# 转换为LSTM需要的3D张量 [样本数, 时间步长, 特征数]
train_x <- array(train_x, dim = c(nrow(train_x), lag, 1))

# 定义并编译模型
model <- keras_model_sequential()
model %>%
  layer_lstm(units = 50, input_shape = c(lag, 1)) %>%
  layer_dense(units = 1) %>%
  compile(
    loss = 'mse',
    optimizer = optimizer_adam(learning_rate = 0.001)
  )

# 训练模型
history <- model %>% fit(
  x = train_x,
  y = train_y,
  epochs = 100,
  batch_size = 1,
  verbose = 1
)

内容的提问来源于stack exchange,提问作者Nick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 00:58:15