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

PyTorch报错RuntimeError:预期Double却发现Float求解决

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

问题代码

def encoder_block(inp, max_pool, in_channels):
    conv = torch.nn.Conv2d(in_channels=in_channels, out_channels=64, kernel_size=3, padding='same')(inp.double())
    relu = torch.nn.ReLU()(conv)
    conv = torch.nn.Conv2d(in_channels=64, out_channels=64, kernel_size=3, padding='same')(relu)
    relu = torch.nn.ReLU()(conv)
    if max_pool:
        return torch.nn.MaxPool2d(2,2)(relu)
    return relu

test_load = nib.load(fpath).get_fdata()
test_numpy = test_load[:,:,0].reshape(1,1,256,256).astype(np.double)
tens = torch.DoubleTensor(test_numpy)
out = encoder_block(tens, True, 1)

这段代码读取本地NIfTI文件转为numpy数组后,对2D图像执行卷积操作做基础测试,但运行时第一个Conv2d处报错RuntimeError: expected scalar type Double but found Float。

问题原因

PyTorch中,torch.nn.Conv2d实例化时默认使用Float32类型的权重和偏置参数,但你把输入转成了Double64类型。框架要求输入张量的 dtype 必须和模型层参数的 dtype 完全一致,否则就会出现类型不匹配错误。另外,每次调用encoder_block都重新实例化卷积层,不仅浪费资源,也会导致参数类型始终和输入不匹配。

修复方案

有两种常用的修复方式,选其一即可:

方式一:将输入转为Float32(推荐,符合PyTorch默认训练习惯)

直接把输入张量转为Float类型,不需要修改层的参数类型:

def encoder_block(inp, max_pool, in_channels):
    # 提前实例化层,避免重复初始化
    conv1 = torch.nn.Conv2d(in_channels=in_channels, out_channels=64, kernel_size=3, padding='same')
    conv2 = torch.nn.Conv2d(in_channels=64, out_channels=64, kernel_size=3, padding='same')
    max_pool_layer = torch.nn.MaxPool2d(2,2)
    
    conv = conv1(inp)
    relu = torch.nn.ReLU()(conv)
    conv = conv2(relu)
    relu = torch.nn.ReLU()(conv)
    if max_pool:
        return max_pool_layer(relu)
    return relu

test_load = nib.load(fpath).get_fdata()
# 转为float32类型
test_numpy = test_load[:,:,0].reshape(1,1,256,256).astype(np.float32)
tens = torch.FloatTensor(test_numpy)
out = encoder_block(tens, True, 1)

方式二:将卷积层参数转为Double64类型

如果必须使用Double类型输入,需要把所有卷积层的参数也转为Double:

def encoder_block(inp, max_pool, in_channels):
    conv1 = torch.nn.Conv2d(in_channels=in_channels, out_channels=64, kernel_size=3, padding='same').double()
    conv2 = torch.nn.Conv2d(in_channels=64, out_channels=64, kernel_size=3, padding='same').double()
    max_pool_layer = torch.nn.MaxPool2d(2,2)
    
    conv = conv1(inp)
    relu = torch.nn.ReLU()(conv)
    conv = conv2(relu)
    relu = torch.nn.ReLU()(conv)
    if max_pool:
        return max_pool_layer(relu)
    return relu

test_load = nib.load(fpath).get_fdata()
test_numpy = test_load[:,:,0].reshape(1,1,256,256).astype(np.double)
tens = torch.DoubleTensor(test_numpy)
out = encoder_block(tens, True, 1)

额外优化建议

更规范的做法是把编码器块定义为PyTorch的nn.Module子类,统一管理层的参数和类型,也方便后续扩展:

class EncoderBlock(torch.nn.Module):
    def __init__(self, in_channels, max_pool=True):
        super().__init__()
        self.max_pool = max_pool
        self.conv_layers = torch.nn.Sequential(
            torch.nn.Conv2d(in_channels, 64, kernel_size=3, padding='same'),
            torch.nn.ReLU(),
            torch.nn.Conv2d(64, 64, kernel_size=3, padding='same'),
            torch.nn.ReLU()
        )
        if self.max_pool:
            self.pool = torch.nn.MaxPool2d(2,2)
    
    def forward(self, x):
        x = self.conv_layers(x)
        if self.max_pool:
            x = self.pool(x)
        return x

# 使用示例
test_load = nib.load(fpath).get_fdata()
test_numpy = test_load[:,:,0].reshape(1,1,256,256).astype(np.float32)
tens = torch.FloatTensor(test_numpy)
encoder = EncoderBlock(in_channels=1, max_pool=True)
out = encoder(tens)

内容的提问来源于stack exchange,提问作者Ryan Marr

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 07:17:44