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

PyTorch训练神经网络报错RuntimeError:期望Long类型却得到Float

问题描述

尝试训练一个以整数为输入的基础神经网络,无法直接传入整数因此将其转换为tensor,但运行训练代码时出现错误:RuntimeError: expected scalar type Long but found Float。

用户代码如下:

模型定义

class Net(nn.Module):
  def __init__(self,dim_input,hidden_dim,dim_output):
    super(Net, self).__init__()
    self.inp = dim_input
    self.oup = dim_output
    self.l1 = nn.Linear(dim_input,hidden_dim);
    self.l2 = nn.Linear(hidden_dim,dim_output);
    #self.l3 = nn.Linear(hidden_dim,dim_output);
  def forward(self,x):
    # x = self.converter(x)
    #x = torch.tensor(x)
    x = F.sigmoid(self.l1(x))
    x = self.l2(x)
    return x
  def converter(self,x):
    n = x;
    n = bin(n).replace("0b", "")
    a = []
    for i in n:
      a.append(int(i))
    a.reverse()
    while(len(a) < self.inp):
      a.append(0)
    a.reverse()
    a = torch.tensor(a)
    a = a.to(dtype=torch.int64)
    return a

数据集准备

def prepare():
  global primes,batch_size,net
  inp = []
  oup = []
  for i in range(batch_size):
    a = random.choice(primes)
    b = random.choice(primes)
    inp.append(net.converter(a*b))
    oup.append(net.converter(min(a,b)))
  print(inp[0])
  return inp,oup;

训练代码

loss_fn = nn.BCELoss()  # binary cross entropy
optimizer = optim.Adam(net.parameters(), lr=0.001)

for i in range(n_epochs):
  inp,oup = prepare()
  for j in range(0,batch_size):
    y_pred = net(inp[j]);
    y_out = net(oup[j]);
    loss = loss_fn(y_pred,y_out)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
  print(f'Finished epoch {i}, latest loss {loss}')

错误原因分析

  1. 数据类型不匹配:

    • converter方法返回torch.int64(Long类型)张量,但PyTorch线性层nn.Linear的参数默认是Float32类型,Long张量无法直接参与线性运算,触发类型冲突。
    • BCELoss要求预测值和目标值都为Float类型,当前数据类型不满足要求。
  2. 目标值处理逻辑错误:
    训练代码中y_out = net(oup[j])是错误操作,目标值应直接使用oup[j](转换后的真实标签),而非将标签再次传入模型生成输出。


修正方案

1. 修正模型类

调整converter返回Float类型张量,确保forward输入类型统一,同时为最后一层添加sigmoid(适配BCELoss要求):

class Net(nn.Module):
    def __init__(self, dim_input, hidden_dim, dim_output):
        super(Net, self).__init__()
        self.inp = dim_input
        self.oup = dim_output
        self.l1 = nn.Linear(dim_input, hidden_dim)
        self.l2 = nn.Linear(hidden_dim, dim_output)

    def forward(self, x):
        # 确保输入为Float32类型
        x = x.to(dtype=torch.float32)
        x = F.sigmoid(self.l1(x))
        # BCELoss要求输出在0-1区间,最后一层添加sigmoid
        x = F.sigmoid(self.l2(x))
        return x

    def converter(self, x):
        n = bin(x).replace("0b", "")
        a = [int(i) for i in n]
        a.reverse()
        while len(a) < self.inp:
            a.append(0)
        a.reverse()
        # 直接返回Float32类型张量
        return torch.tensor(a, dtype=torch.float32)

2. 修正训练代码

直接使用真实标签作为目标值,同时确保类型匹配:

loss_fn = nn.BCELoss()
optimizer = optim.Adam(net.parameters(), lr=0.001)

for i in range(n_epochs):
    inp, oup = prepare()
    total_loss = 0.0
    for j in range(batch_size):
        x = inp[j]
        y_true = oup[j]
        
        y_pred = net(x)
        # 确保目标值为Float类型
        loss = loss_fn(y_pred, y_true.to(dtype=torch.float32))
        
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        total_loss += loss.item()
    # 打印 epoch 平均损失更合理
    print(f'Finished epoch {i}, average loss {total_loss / batch_size}')

3. 可选:优化数据集准备(批量张量提升效率)

将返回的列表转换为批量张量,支持后续批量训练:

def prepare():
    global primes, batch_size, net
    inp = []
    oup = []
    for i in range(batch_size):
        a = random.choice(primes)
        b = random.choice(primes)
        inp.append(net.converter(a*b))
        oup.append(net.converter(min(a,b)))
    # 转换为批量张量
    return torch.stack(inp), torch.stack(oup)

对应批量训练代码:

for i in range(n_epochs):
    x_batch, y_batch = prepare()
    
    y_pred = net(x_batch)
    loss = loss_fn(y_pred, y_batch)
    
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    
    print(f'Finished epoch {i}, loss {loss.item()}')

关键注意点

  • 神经网络输入和参数统一使用Float32类型,避免类型冲突。
  • 使用BCELoss时,模型最后一层必须加sigmoid激活,且预测值、目标值都需为Float类型。
  • 训练时目标值是真实标签,无需再传入模型处理。

内容的提问来源于stack exchange,提问作者Kaushal Tiwari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 20:34:59