Stellargraph搭建GCN多标签分类时出现形状不兼容报错
问题描述
基于Stellargraph库实现GCN模型完成图节点分类任务,已完成StellarGraph图对象构建,任务类型为多标签分类:共需预测19列标签,每列标签编码为0或1。
数据集基础信息:
- 总边数:271045条
- 总节点数:16354个
- 训练节点数:12265个
单列标签的单分类场景下模型可正常运行,传入19列多标签训练时抛出形状不匹配错误,报错数值233035恰好等于训练节点数12265与标签类别数19的乘积。
原有实现代码
数据集拆分与生成器初始化
from sklearn.model_selection import train_test_split from stellargraph.mapper import FullBatchNodeGenerator train_subjects, test_subjects = train_test_split(nodelist, test_size = .25) generator = FullBatchNodeGenerator(graph, method="gcn")
GCN层初始化
from stellargraph.layer import GCN train_gen = generator.flow(train_subjects['ID'], train_subjects.drop(['ID'], axis = 1)) gcn = GCN(layer_sizes=[16, 16], activations=["relu", "relu"], generator=generator, dropout=0.5)
输出层定义
from tensorflow.keras import layers, optimizers, losses, metrics, Model x_inp, x_out = gcn.in_out_tensors() predictions = layers.Dense(units = 1, activation="sigmoid")(x_out)
模型编译
from tensorflow.keras.metrics import Precision as Precision model = Model(inputs=x_inp, outputs=predictions) model.compile( optimizer=optimizers.Adam(learning_rate = 0.01), loss=losses.categorical_crossentropy, metrics= [Precision()]) val_gen = generator.flow(test_subjects['ID'], test_subjects.drop(['ID'], axis = 1))
模型训练
from tensorflow.keras.callbacks import EarlyStopping es_callback = EarlyStopping(monitor="val_precision", patience=200, restore_best_weights=True) history = model.fit( train_gen, epochs=200, validation_data=val_gen, verbose=2, shuffle=False, callbacks=[es_callback])
报错信息
InvalidArgumentError: Incompatible shapes: [1,12265] vs. [1,233035] [[node LogicalAnd_1 (defined at tmp/ipykernel_52/2745570431.py:7) ]] [Op:__inference_train_function_1405]
错误原因
形状不匹配由两处核心配置错误导致:
- 输出层维度设置错误:任务需要为每个节点输出19个独立标签的预测概率,原代码将输出层
Dense的units参数设为1,仅能输出1维结果,与19维的真实标签形状冲突。 - 损失函数选型错误:
categorical_crossentropy适用于标签互斥的单标签多分类任务(标签为one-hot编码);当前多标签分类任务中每个标签独立取0/1值,不满足该损失函数的输入要求。
修复方案
修改两处对应代码即可:
- 调整输出层维度为标签总数19,保留sigmoid激活函数(为每个标签独立输出0-1之间的概率值):
# 原错误配置:predictions = layers.Dense(units = 1, activation="sigmoid")(x_out) predictions = layers.Dense(units=19, activation="sigmoid")(x_out)
- 替换损失函数为适用于多标签分类的二分类交叉熵:
model.compile( optimizer=optimizers.Adam(learning_rate = 0.01), loss=losses.binary_crossentropy, # 替换原categorical_crossentropy metrics= [Precision()])
修改完成后重新运行即可解决形状不匹配问题,正常开展模型训练。
内容的提问来源于stack exchange,提问作者Muhammad Ezzat
相关产品推荐
相关产品推荐

