解决TypeError: Cannot iterate over a Tensor with unknown first dimension错误
问题原因分析
- GCN层输入格式不匹配:你用自定义的Keras
Input层直接喂给StellarGraph的GCN层,但StellarGraph的GCN层依赖FullBatchNodeGenerator生成的包含图结构(邻接矩阵)的批量输入,单独的节点特征张量缺少图拓扑信息,且维度不符合GCN要求,导致其无法处理未知第一维度的张量,触发迭代错误。 - 概念混淆:
node2vec是图嵌入预训练方法,并非可直接堆叠的Keras层,不能直接接在GCN输出后使用。- 你错误地将随机游走生成的
walks作为训练输入,GCN节点分类任务的输入应该是节点索引,而非随机游走序列。
- 损失函数选择错误:你的任务是4分类(多分类),却使用了二分类的
binary_crossentropy损失函数。
解决方案及修正代码
以下是修正后的完整代码,关键修改点已标注:
import numpy as np from sklearn.metrics.pairwise import cosine_similarity from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.model_selection import train_test_split from stellargraph import StellarGraph from tensorflow.keras import layers, Model, optimizers from stellargraph.mapper import FullBatchNodeGenerator from stellargraph.layer import GCN # --------------- 数据准备部分(保留原逻辑)--------------- pro_tweets = pprocess[0:10000] labels = df_encoded[['label_mild', 'label_moderate', 'label_non-depressed', 'label_severe']].values vectorizer = TfidfVectorizer() vectors = vectorizer.fit_transform(pro_tweets).toarray() # 转换为numpy数组,适配StellarGraph print(vectors.shape) similarity_matrix = cosine_similarity(vectors) adj_matrix = np.zeros(similarity_matrix.shape) adj_matrix[similarity_matrix > 0] = similarity_matrix[similarity_matrix > 0] # 创建StellarGraph对象,传入节点特征和邻接矩阵 graph = StellarGraph(node_features=vectors, adjacency=adj_matrix) # --------------- GCN模型构建(核心修改)--------------- # 1. 初始化FullBatchNodeGenerator,自动处理图结构 generator = FullBatchNodeGenerator(graph, method="gcn") # 2. 拆分节点索引与对应标签 nodes = list(range(graph.number_of_nodes())) train_nodes, test_nodes, train_labels, test_labels = train_test_split(nodes, labels, test_size=0.2, random_state=42) # 3. 生成模型所需的数据流(包含图结构+节点特征) train_gen = generator.flow(train_nodes, train_labels) test_gen = generator.flow(test_nodes, test_labels) # 4. 构建GCN层,获取输入输出张量 gcn = GCN(layer_sizes=[32, 16], activations=["relu", "relu"], generator=generator, dropout=0.2) x_inp, x_out = gcn.in_out_tensors() # 5. 构建多分类输出头 dense_layer = layers.Dense(16, activation="relu")(x_out) output_layer = layers.Dense(4, activation="softmax")(dense_layer) # 6. 创建并编译模型 model = Model(inputs=x_inp, outputs=output_layer) model.compile(optimizer=optimizers.Adam(learning_rate=0.01), loss="categorical_crossentropy", metrics=["acc"]) # --------------- 模型训练与评估--------------- history = model.fit(train_gen, validation_data=test_gen, epochs=50, verbose=1) # 测试集评估 test_metrics = model.evaluate(test_gen) print(f"Test Accuracy: {test_metrics[1]:.4f}") # 训练集评估 train_metrics = model.evaluate(train_gen) print(f"Train Accuracy: {train_metrics[1]:.4f}")
关键修改说明
- 将稀疏矩阵
vectors转换为numpy数组:StellarGraph的node_features更适配numpy数组,避免维度兼容问题。 - 移除自定义
Input层,改用FullBatchNodeGenerator:generator自动整合图的邻接矩阵和节点特征,生成GCN所需的批量输入格式。 - 修正训练输入:使用节点索引作为模型输入,通过
flow方法绑定对应标签。 - 替换损失函数:用
categorical_crossentropy适配4分类任务。 - 移除错误的
node2vec层使用:若需结合node2vec嵌入,可先预训练得到节点嵌入,再将其作为node_features传入StellarGraph,而非直接堆叠为Keras层。
内容的提问来源于stack exchange,提问作者kini.kg
相关产品推荐
相关产品推荐

