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

GCNN训练报错RuntimeError: expected scalar type Double but found Float求助

解决GCNN中RuntimeError: expected scalar type Double but found Float问题

我在开发GCNN时,输入数据原本是float64类型的numpy数组,转换为PyTorch张量后,运行代码始终报错RuntimeError: expected scalar type Double but found Float,尝试将所有张量转为double类型仍无法解决。


问题代码与输出

数据处理代码

e_index1 = torch.tensor(edge_index)
x1 = torch.tensor(x)
y1 = torch.tensor(y)

print(x.dtype)
print(y.dtype)
print(edge_index.dtype)

from torch_geometric.data import Data
data = Data(x=x1, edge_index=e_index1, y=y1)

数据类型输出

float64
float64
int64

GCNN模型代码

import torch
import torch.nn.functional as F
from torch_geometric.nn import GCNConv


class GCN(torch.nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = GCNConv(data.num_node_features, 16)
        self.conv2 = GCNConv(16, data.num_node_features)

    def forward(self, data):
        x, edge_index = data.x, data.edge_index

        x = self.conv1(x, edge_index)
        x = F.relu(x)
        x = F.dropout(x, training=self.training)
        x = self.conv2(x, edge_index)

        return F.log_softmax(x, dim=1)

训练代码

device = torch.device('cpu')
model = GCN().to(device)
data = data.to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)

model.train()
for epoch in range(10):
    optimizer.zero_grad()
    out = model(data)
    loss = F.nll_loss(out[data.train_mask], data.y[data.train_mask])
    loss.backward()
    optimizer.step()

报错日志

---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-148-e816c251670b> in <module>
      7 for epoch in range(10):
      8     optimizer.zero_grad()
----> 9     out = model(data)
     10     loss = F.nll_loss(out[data.train_mask], data.y[data.train_mask])
     11     loss.backward()

5 frames
/usr/local/lib/python3.8/dist-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
   1188         if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1189                 or _global_forward_hooks or _global_forward_pre_hooks):
-> 1190             return forward_call(*input, **kwargs)
   1191         # Do not call functions when jit is used
   1192         full_backward_hooks, non_full_backward_hooks = [], []

<ipython-input-147-c1bfee724570> in forward(self, data)
     13         x, edge_index = data.x.type(torch.DoubleTensor), data.edge_index
     14 
---> 15         x = self.conv1(x, edge_index)
     16         x = F.relu(x)
     17         x = F.dropout(x, training=self.training)

/usr/local/lib/python3.8/dist-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
   1188         if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1189                 or _global_forward_hooks or _global_forward_pre_hooks):
-> 1190             return forward_call(*input, **kwargs)
   1191         # Do not call functions when jit is used
   1192         full_backward_hooks, non_full_backward_hooks = [], []

/usr/local/lib/python3.8/dist-packages/torch_geometric/nn/conv/gcn_conv.py in forward(self, x, edge_index, edge_weight)
    193                     edge_index = cache
    194 
-> 195         x = self.lin(x)
    196 
    197         # propagate_type: (x: Tensor, edge_weight: OptTensor)

/usr/local/lib/python3.8/dist-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
   1188         if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1189                 or _global_forward_hooks or _global_forward_pre_hooks):
-> 1190             return forward_call(*input, **kwargs)
   1191         # Do not call functions when jit is used
   1192         full_backward_hooks, non_full_backward_hooks = [], []

/usr/local/lib/python3.8/dist-packages/torch_geometric/nn/dense/linear.py in forward(self, x)
    134             x (Tensor): The features.
    135         """
-> 136         return F.linear(x, self.weight, self.bias)
    137 
    138     @torch.no_grad()

RuntimeError: expected scalar type Double but found Float

问题根源

报错核心是模型参数与输入张量的数据类型不匹配:

  • 输入数据data.x为float64(double)类型,但GCNConv层初始化的权重参数默认是float32类型。当double类型的输入传入float32类型的线性层时,就会触发类型不匹配错误。

两种解决方法

方法1:将模型转换为double类型

在实例化模型后,调用double()方法将所有模型参数转为float64,与输入数据类型保持一致:

device = torch.device('cpu')
model = GCN().to(device).double()  # 新增.double()转换模型参数类型
data = data.to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)

# 后续训练代码不变
model.train()
for epoch in range(10):
    optimizer.zero_grad()
    out = model(data)
    loss = F.nll_loss(out[data.train_mask], data.y[data.train_mask])
    loss.backward()
    optimizer.step()

方法2:将输入数据转换为float32类型

如果不需要高精度计算,可以直接将输入张量转为float32,匹配模型默认参数类型:
修改数据处理代码:

e_index1 = torch.tensor(edge_index)
x1 = torch.tensor(x, dtype=torch.float32)  # 指定dtype为float32
y1 = torch.tensor(y)

print(x1.dtype)  # 输出应为float32

from torch_geometric.data import Data
data = Data(x=x1, edge_index=e_index1, y=y1)

后续训练代码无需修改,模型保持默认float32类型即可。

额外注意

如果之前仅在forward方法中转换输入张量类型(比如x = data.x.type(torch.DoubleTensor)),但未同步转换模型参数,仍然会报错。必须保证模型参数和输入张量的dtype完全一致。


内容的提问来源于stack exchange,提问作者Md Tahmid Hasan Fuad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 10:50:16