如何向TensorFlow Keras模型输入scipy.sparse._csr.csr_matrix稀疏矩阵
解决方案:将Scipy CSR稀疏矩阵输入Keras模型
核心问题
直接传入Scipy csr_matrix到Keras模型会触发转换错误,因为TensorFlow对Scipy稀疏矩阵的自动处理存在兼容性问题,手动转换为TensorFlow原生SparseTensor是解决关键。
步骤1:实现CSR到TensorFlow SparseTensor的转换
先将Scipy稀疏矩阵转为COO格式(更适合构造TensorFlow稀疏张量),再生成对应的SparseTensor:
import tensorflow as tf import numpy as np def csr_to_tf_sparse(csr_mat): # 转为COO格式获取行列索引和数值 coo_mat = csr_mat.tocoo() # 构造TensorFlow SparseTensor需要的索引、值和密集形状 indices = tf.transpose(tf.convert_to_tensor([coo_mat.row, coo_mat.col], dtype=tf.int64)) values = tf.convert_to_tensor(coo_mat.data, dtype=tf.float32) # 转float32节省内存 dense_shape = tf.convert_to_tensor(coo_mat.shape, dtype=tf.int64) return tf.sparse.SparseTensor(indices=indices, values=values, dense_shape=dense_shape)
步骤2:转换训练/测试数据
用上面的函数处理预处理后的稀疏矩阵:
X_train_tf_sparse = csr_to_tf_sparse(X_train_transformed) X_test_tf_sparse = csr_to_tf_sparse(X_test_transformed)
步骤3:构建兼容稀疏输入的模型并训练
无论是函数式模型还是Sequential模型,只要输入层设置sparse=True,即可接收SparseTensor输入:
函数式模型(推荐)
from tensorflow.keras.layers import Input, Dense, Dropout from tensorflow.keras.models import Model input_layer = Input(shape=(X_train_transformed.shape[1],), sparse=True) dense1 = Dense(64, activation='relu')(input_layer) dropout1 = Dropout(0.2)(dense1) dense2 = Dense(64, activation='relu')(dropout1) dropout2 = Dropout(0.2)(dense2) output_layer = Dense(1)(dropout2) model = Model(input_layer, output_layer) model.compile(optimizer='adam', loss='mean_squared_error')
Sequential模型
model = tf.keras.models.Sequential([ tf.keras.layers.Dense(64, activation='relu', input_shape=(X_train_transformed.shape[1],), sparse=True), tf.keras.layers.Dropout(0.2), tf.keras.layers.Dense(64, activation='relu'), tf.keras.layers.Dropout(0.2), tf.keras.layers.Dense(1) ]) model.compile(optimizer='adam', loss='mean_squared_error')
步骤4:启动训练
直接传入转换后的SparseTensor即可:
history = model.fit( X_train_tf_sparse, y_train, epochs=20, batch_size=32, validation_data=(X_test_tf_sparse, y_test) )
额外优化建议
- 降低数据精度:在
TfidfVectorizer初始化时指定dtype=np.float32,生成的稀疏矩阵直接使用单精度浮点,可减少一半内存占用:title_transformer = TfidfVectorizer(dtype=np.float32) - 使用tf.data.Dataset包装(可选):如果需要更灵活的数据管道,可将稀疏张量包装为Dataset,Keras同样支持:
train_ds = tf.data.Dataset.from_tensor_slices((X_train_tf_sparse, y_train)).batch(32) test_ds = tf.data.Dataset.from_tensor_slices((X_test_tf_sparse, y_test)).batch(32) history = model.fit(train_ds, epochs=20, validation_data=test_ds)
内容的提问来源于stack exchange,提问作者Cyamc
相关产品推荐
相关产品推荐

