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

PyTorch训练CNN报错:input type(double)与bias type(float)类型不匹配

问题修复方案

核心问题分析

报错PyTorch Runtime Error: input type (double) and bias type (float) should be the same主要由以下原因导致:

  • 输入数据类型为float64(numpy默认类型),但PyTorch模型参数默认是float32,类型不匹配
  • 输入张量维度不符合Conv2d要求(缺少通道维度)
  • 训练循环中模型变量名错误
  • 损失函数与输出/标签的格式不匹配

具体修复步骤

1. 统一数据与模型的数值类型

将输入数据转为float32,确保和模型参数类型一致:

# 修改训练数据生成部分
train_dat = torch.utils.data.TensorDataset(
    torch.tensor(test_data_x, dtype=torch.float32).to(device), 
    torch.tensor(test_data_y, dtype=torch.float32).to(device)
)

2. 修正输入张量维度

模型第一个Conv2d的in_channels=1,但输入是(batch, 19, 1000),需要增加通道维度(将19视为高度维度,通道设为1):

# 在训练循环的forward前修改输入维度
inputs = inputs.unsqueeze(1)  # 从(16,19,1000)变为(16,1,19,1000)

3. 修正训练循环中的模型变量名

定义的模型是test_model,调用时误写为model,修改为:

outputs = test_model(inputs)

4. 调整损失函数与输出层的匹配

  • CrossEntropyLoss要求输入是logits(不需要Softmax,损失函数内部已包含),移除最后一层的Softmax:
# 修改fc层的最后部分
self.fc = torch.nn.Sequential(
    torch.nn.Dropout1d(p = 0.5),
    torch.nn.Linear(in_features = channels * 64 * samples, out_features = 32),
    torch.nn.BatchNorm1d(32, eps = 0.001, momentum = 0.99),
    torch.nn.ReLU(),
    torch.nn.Dropout1d(p = 0.3),
    torch.nn.Linear(in_features = 32, out_features = outputs)
    # 移除Softmax()
)
  • CrossEntropyLoss的标签需要是类别索引(不是one-hot向量),如果是one-hot标签,要转为索引:
# 训练循环中修改标签处理
labels = torch.argmax(labels, dim=1).to(device)

5. 修正模型初始化中的计算错误

模型初始化中使用了floor但未导入,需要添加:

from math import floor

完整修正后的关键代码片段

模型定义(修正后)

import torch
from math import floor

class NNnet(torch.nn.Module):
    def __init__(self, channels = 19, samples = 1000.0, outputs = 4):
        super(NNnet, self).__init__()
        #Sequential 1
        self.seq1 = torch.nn.Sequential(
            torch.nn.Conv2d(in_channels = 1, out_channels = 32, kernel_size = (1,20), stride = 1),
            torch.nn.Conv2d(in_channels = 32, out_channels = 32, kernel_size = (3,1), stride = 1),
            torch.nn.BatchNorm2d(32, eps = 0.001, momentum = 0.99),
            torch.nn.ReLU(),
            torch.nn.MaxPool2d(kernel_size = [1,5], stride = [1,2])
        )
        #calculate output of sample at each opeartion
        samples = (samples - 20) + 1
        samples = (samples - 1) + 1
        channels = channels - 3 + 1
        samples = floor((samples - 5) / 2 + 1)

        #Sequential 2
        self.seq2 = torch.nn.Sequential(
            torch.nn.Conv2d(in_channels = 32, out_channels = 64, kernel_size = (1,20)),
            torch.nn.BatchNorm2d(64, eps = 0.001, momentum = 0.99),
            torch.nn.ReLU(),
            torch.nn.MaxPool2d(kernel_size = [1,7], stride = [1,2])
        )
        samples = (samples - 20) + 1
        samples = floor((samples- 7) / 2 + 1)

        #Sequential 3
        self.seq3 = torch.nn.Sequential(
            torch.nn.Conv2d(in_channels = 64, out_channels = 64, kernel_size = (1,10)),
            torch.nn.BatchNorm2d(64, eps = 0.001, momentum = 0.99),
            torch.nn.ReLU(),
            torch.nn.MaxPool2d(kernel_size = [1,5], stride = [1,2])
        ) 
        samples = (samples - 10) + 1
        samples = floor((samples - 5) / 2 + 1)

        #fully connect
        self.fc = torch.nn.Sequential(
            torch.nn.Dropout1d(p = 0.5),
            torch.nn.Linear(in_features = channels * 64 * samples, out_features = 32),
            torch.nn.BatchNorm1d(32, eps = 0.001, momentum = 0.99),
            torch.nn.ReLU(),
            torch.nn.Dropout1d(p = 0.3),
            torch.nn.Linear(in_features = 32, out_features = outputs)
        )

    def forward(self, x):
        x = self.seq1(x)
        x = self.seq2(x)
        x = self.seq3(x)
        x = torch.flatten(x, start_dim = 1, end_dim = -1)
        x = self.fc(x)
        return x

训练循环(修正后)

import torch
import numpy as np

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

#dummy data of 540 instances, 19 channel and 1000 sample
test_data_x = np.ones(shape = (540,19,1000))
#dummy label - 改为类别索引(示例用0),如果是one-hot后续要转
test_data_y = np.zeros(shape = (540,), dtype=np.int64)

train_dat    = torch.utils.data.TensorDataset(
    torch.tensor(test_data_x, dtype=torch.float32).to(device), 
    torch.tensor(test_data_y).to(device)
)
train_loader = torch.utils.data.DataLoader(train_dat, batch_size = 16, shuffle = True)

test_model = NNnet(channels = 19, samples = 1000, outputs = 4)
optimizer = torch.optim.Adam(test_model.parameters(), lr = 0.001, weight_decay = 0.0001)
criterion = torch.nn.CrossEntropyLoss()

test_model.to(device)
criterion.to(device)

#train loop-----------------------------------------------
for epoch in range(10):
    running_loss = 0.0
    for i, data in enumerate(train_loader,0):
        inputs, labels = data
        inputs, labels = inputs.to(device), labels.to(device)
        
        # 增加通道维度
        inputs = inputs.unsqueeze(1)
        
        optimizer.zero_grad()

        outputs = test_model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        running_loss += loss.item()
    print(f'Epoch {epoch+1}, Loss: {running_loss/len(train_loader):.4f}')

内容的提问来源于stack exchange,提问作者G.P

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 13:00:46