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

PyTorch回归模型训练报错:mat1与mat2 dtype不一致求助

问题描述

我正尝试构建一个神经网络,基于美国县居民的教育水平预测该县的人均收入。已确认输入特征X和标签y的dtype均为torch.int64,但训练时仍报错。

数据集示例

county_FIPS state          county  per_capita_personal_income_2019  
0        51013    VA   Arlington, VA                            97629   

   per_capita_personal_income_2020  per_capita_personal_income_2021  
0                           100687                           107603    

   associate_degree_numbers_2016_2020  bachelor_degree_numbers_2016_2020  
0                               19573                             132394   

网络代码

import torch
import pandas as pd
df = pd.read_csv("./input/US counties - education vs per capita personal income - results-20221227-213216.csv")
X = torch.tensor(df[["bachelor_degree_numbers_2016_2020", "associate_degree_numbers_2016_2020"]].values)
y = torch.tensor(df["per_capita_personal_income_2020"].values)

X.dtype
torch.int64

y.dtype
torch.int64

import torch.nn as nn
class BaseNet(nn.Module):
    def __init__(self, in_dim, hidden_dim, out_dim):
        super(BaseNet, self).__init__()
        self.classifier = nn.Sequential(
        nn.Linear(in_dim, hidden_dim, bias=True), 
        nn.ReLU(), 
        nn.Linear(feature_dim, out_dim, bias=True))
        
    def forward(self, x): 
        return self.classifier(x)

from torch import optim
import matplotlib.pyplot as plt
in_dim, hidden_dim, out_dim = 2, 20, 1
lr = 1e-3
epochs = 40
loss_fn = nn.CrossEntropyLoss()
classifier = BaseNet(in_dim, hidden_dim, out_dim)
optimizer = optim.SGD(classifier.parameters(), lr=lr)

def train(classifier, optimizer, epochs, loss_fn):
    classifier.train()
    losses = []
    for epoch in range(epochs):
        out = classifier(X)
        loss = loss_fn(out, y)
        loss.backward()
        optimizer.step()
        optimizer.zero_grad()
        losses.append(loss/len(X))
        print("Epoch {} train loss: {}".format(epoch+1, loss/len(X)))
    
    plt.plot([i for i in range(1, epochs + 1)])
    plt.xlabel("Epoch")
    plt.ylabel("Training Loss")
    plt.show()

train(classifier, optimizer, epochs, loss_fn)

报错信息

---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
Input In [77], in <cell line: 39>()
     36     plt.ylabel("Training Loss")
     37     plt.show()
---> 39 train(classifier, optimizer, epochs, loss_fn)

Input In [77], in train(classifier, optimizer, epochs, loss_fn)
     24 losses = []
     25 for epoch in range(epochs):
---> 26     out = classifier(X)
     27     loss = loss_fn(out, y)
     28     loss.backward()

File ~/opt/anaconda3/lib/python3.9/site-packages/torch/nn/modules/module.py:1194, in Module._call_impl(self, *input, **kwargs)
   1190 # If we don't have any hooks, we want to skip the rest of the logic in
   1191 # this function, and just call forward.
   1192 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1193         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1194     return forward_call(*input, **kwargs)
   1195 # Do not call functions when jit is used
   1196 full_backward_hooks, non_full_backward_hooks = [], []

Input In [77], in BaseNet.forward(self, x)
     10 def forward(self, x): 
---> 11     return self.classifier(x)

File ~/opt/anaconda3/lib/python3.9/site-packages/torch/nn/modules/module.py:1194, in Module._call_impl(self, *input, **kwargs)
   1190 # If we don't have any hooks, we want to skip the rest of the logic in
   1191 # this function, and just call forward.
   1192 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1193         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1194     return forward_call(*input, **kwargs)
   1195 # Do not call functions when jit is used
   1196 full_backward_hooks, non_full_backward_hooks = [], []

File ~/opt/anaconda3/lib/python3.9/site-packages/torch/nn/modules/container.py:204, in Sequential.forward(self, input)
    202 def forward(self, input):
    203     for module in self:
---> 204         input = module(input)
    205     return input

File ~/opt/anaconda3/lib/python3.9/site-packages/torch/nn/modules/module.py:1194, in Module._call_impl(self, *input, **kwargs)
   1190 # If we don't have any hooks, we want to skip the rest of the logic in
   1191 # this function, and just call forward.
   1192 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1193         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1194     return forward_call(*input, **kwargs)
   1195 # Do not call functions when jit is used
   1196 full_backward_hooks, non_full_backward_hooks = [], []

File ~/opt/anaconda3/lib/python3.9/site-packages/torch/nn/modules/linear.py:114, in Linear.forward(self, input)
    113 def forward(self, input: Tensor) -> Tensor:
--> 114     return F.linear(input, self.weight, self.bias)

RuntimeError: mat1 and mat2 must have the same dtype

更新

尝试将X和y转换为float张量后,出现新错误:expected scalar type Long but found Float。


解决方案

1. 修复数据类型不匹配问题

PyTorch的Linear层参数默认是float32类型,输入X的int64类型和权重类型不一致,导致矩阵乘法报错。需将X转为float32:

X = torch.tensor(df[["bachelor_degree_numbers_2016_2020", "associate_degree_numbers_2016_2020"]].values, dtype=torch.float32)

2. 替换损失函数

当前任务是回归任务(预测连续的人均收入),但误用了分类任务的CrossEntropyLoss,该损失要求标签为Long类型,这也是转float后报错的原因。回归任务应使用MSELoss:

loss_fn = nn.MSELoss()

同时标签y也要转为float32,和模型输出 dtype 一致:

y = torch.tensor(df["per_capita_personal_income_2020"].values, dtype=torch.float32)

3. 修正网络定义的变量错误

网络__init__方法中第二个Linear层使用了未定义的feature_dim,需替换为hidden_dim:

self.classifier = nn.Sequential(
    nn.Linear(in_dim, hidden_dim, bias=True), 
    nn.ReLU(), 
    nn.Linear(hidden_dim, out_dim, bias=True)
)

4. 修复绘图代码

原绘图代码未传入损失值,无法显示损失曲线,需修改为:

plt.plot([i for i in range(1, epochs + 1)], losses)

完整修正后代码

import torch
import pandas as pd
df = pd.read_csv("./input/US counties - education vs per capita personal income - results-20221227-213216.csv")
# 转换X为float32
X = torch.tensor(df[["bachelor_degree_numbers_2016_2020", "associate_degree_numbers_2016_2020"]].values, dtype=torch.float32)
# 转换y为float32
y = torch.tensor(df["per_capita_personal_income_2020"].values, dtype=torch.float32)

import torch.nn as nn
class BaseNet(nn.Module):
    def __init__(self, in_dim, hidden_dim, out_dim):
        super(BaseNet, self).__init__()
        self.classifier = nn.Sequential(
        nn.Linear(in_dim, hidden_dim, bias=True), 
        nn.ReLU(), 
        nn.Linear(hidden_dim, out_dim, bias=True))
        
    def forward(self, x): 
        return self.classifier(x)

from torch import optim
import matplotlib.pyplot as plt
in_dim, hidden_dim, out_dim = 2, 20, 1
lr = 1e-3
epochs = 40
# 使用回归任务损失函数
loss_fn = nn.MSELoss()
classifier = BaseNet(in_dim, hidden_dim, out_dim)
optimizer = optim.SGD(classifier.parameters(), lr=lr)

def train(classifier, optimizer, epochs, loss_fn):
    classifier.train()
    losses = []
    for epoch in range(epochs):
        out = classifier(X)
        loss = loss_fn(out, y)
        loss.backward()
        optimizer.step()
        optimizer.zero_grad()
        losses.append(loss.item()/len(X))
        print("Epoch {} train loss: {}".format(epoch+1, loss.item()/len(X)))
    
    # 正确绘制损失曲线
    plt.plot([i for i in range(1, epochs + 1)], losses)
    plt.xlabel("Epoch")
    plt.ylabel("Training Loss")
    plt.show()

train(classifier, optimizer, epochs, loss_fn)

内容的提问来源于stack exchange,提问作者George Garman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 21:35:29