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
相关产品推荐
相关产品推荐

