单变量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])
其他关键优化
训练样本量不足
当前训练集仅4条数据,lag设为3后train_x仅1行样本,无法有效训练LSTM。建议扩大训练集规模,例如将train_data改为data[1:5, ],可得到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)
- 补充模型编译与训练步骤
原代码仅定义了模型结构,需补充编译和训练逻辑才能运行:
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
相关产品推荐
相关产品推荐

