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

Keras中RNN(LSTM/GRU)处理稀疏张量报错排查

问题

我正在用Python3构建医疗文本分类神经网络,计划采用LSTM层搭配Dense层实现。因数据集采用单词级独热编码后内存浪费严重,需使用稀疏张量表示数据。但构建模型时出现TypeError报错,提示无法将SparseTensor转换为Tensor。我尝试改用SimpleRNN、GRU层,或在LSTM前添加Dense层,均出现相同报错;使用密集张量的小规模模型可正常运行。

模型代码

import tensorflow as tf

in_shape=(8, 4581, 2126) 
out_size=200

data= tf.sparse.SparseTensor(indices=[[0,0,0]],values=[1],dense_shape = in_shape)

X_i = tf.keras.Input(shape= tf.shape(data)[1:], sparse=True) #shape=(None,)

X = tf.keras.layers.LSTM(in_shape[-1])(X_i)

X = tf.keras.layers.Dense(out_size)(X_i)
    
X = tf.keras.layers.Activation('sigmoid')(X)

model = tf.keras.Model(X_i, X)

参数说明

  • 4581:测试文本的最大长度
  • 2126:经过裁剪后的词汇表大小
  • 8:使用密集张量且无内存问题时的样本数

报错信息

起始部分

TypeError                                 Traceback (most recent call last)
~/Henv/lib/python3.6/site-packages/tensorflow/python/framework/tensor_util.py in make_tensor_proto(values, dtype, shape, verify_shape, allow_broadcast)

548     try:

--> 549       str_values = [compat.as_bytes(x) for x in proto_values]

550     except TypeError:

~/Henv/lib/python3.6/site-packages/tensorflow/python/framework/tensor_util.py in <listcomp>(.0)

548     try:

--> 549       str_values = [compat.as_bytes(x) for x in proto_values]

550     except TypeError:

结尾部分

TypeError: Failed to convert object of type <class 'tensorflow.python.framework.sparse_tensor.SparseTensor'> to Tensor. Contents: SparseTensor(indices=Tensor("inputs:0", shape=(None, 3), dtype=int64), values=Tensor("inputs_1:0", shape=(None,), dtype=float32), dense_shape=Tensor("inputs_2:0", shape=(3,), dtype=int64)). Consider casting elements to a supported type.

注:实际报错发生在LSTM层,但未在报错信息中显示。


解决方案

核心问题

TensorFlow的循环层(LSTM/GRU/SimpleRNN)以及普通Dense层不直接支持稀疏张量输入,它们只能处理密集张量,这是报错的根本原因。你尝试的几种改法都绕不开这个限制。另外原代码存在逻辑错误:LSTM层的输出被直接丢弃,后续Dense层错误地连接到输入张量X_i,完全没用到序列特征。

最优解决步骤

1. 替换独热编码为嵌入层(Embedding)

单词级独热编码本身内存效率极低,没必要用稀疏张量硬扛。tf.keras.layers.Embedding是NLP任务的标准方案,它能把整数形式的单词索引(比如每个单词对应0~2125的整数)转换成低维稠密向量,既省内存又能提升模型效果。

2. 调整模型结构

把稀疏独热输入换成整数索引输入,通过嵌入层转成稠密张量后,再接入LSTM和Dense层。修改后的示例代码:

import tensorflow as tf

max_seq_len = 4581
vocab_size = 2126
out_size = 200

# 输入为整数索引,形状:(None, max_seq_len)
X_i = tf.keras.Input(shape=(max_seq_len,))
# 嵌入层将索引转为稠密向量,输出形状(None, max_seq_len, 128)
X = tf.keras.layers.Embedding(input_dim=vocab_size, output_dim=128)(X_i)
# LSTM层处理序列特征
X = tf.keras.layers.LSTM(128)(X)
# 分类输出层(合并激活函数)
X = tf.keras.layers.Dense(out_size, activation='sigmoid')(X)

model = tf.keras.Model(X_i, X)
model.summary()

特殊场景替代方案(不推荐)

若因特殊需求必须保留稀疏独热输入,可在循环层前手动将稀疏张量转为稠密张量,但这会失去内存优势:

import tensorflow as tf

max_seq_len = 4581
vocab_size = 2126
out_size = 200

X_i = tf.keras.Input(shape=(max_seq_len, vocab_size), sparse=True)
# 手动转换为稠密张量
X_dense = tf.keras.layers.Lambda(lambda x: tf.sparse.to_dense(x))(X_i)
X = tf.keras.layers.LSTM(vocab_size)(X_dense)
X = tf.keras.layers.Dense(out_size, activation='sigmoid')(X)

model = tf.keras.Model(X_i, X)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 10:07:07