PyTorch 2D张量转1D方法及模型训练损失不更新问题解决
1 张量形状转换解决方案
你的张量每行所有元素完全一致,要得到形状为[32]的张量,直接取每行任意一个位置的元素即可,推荐以下两种写法:
- 直接取每行第0个元素:
train_y = train_y[:, 0],执行后shape自动变为torch.Size([32]) - 若不确定是否每行所有元素相同,可先做校验再取众数:
train_y = train_y.mode(dim=1)[0],如果是分类标签记得转成long类型:train_y = train_y.long()
你之前用squeeze、view无效的原因:squeeze仅能删除大小为1的维度,你的第二个维度大小是20,所以没有效果;view只是对张量元素做顺序重塑,直接调用
view(-1)会得到长度为640的一维张量,不符合你的需求。
2 损失不更新解决方案
你猜测的标签形状错误是原因之一,还有一个核心问题是你的训练代码缺少了优化器更新模型参数的步骤,修正方案如下:
- 首先在训练循环外定义优化器:
import torch.optim as optim optimizer = optim.Adam(model.parameters(), lr=1e-3) # 学习率可根据你的任务调整
- 修正训练循环逻辑,在
loss.backward()后添加优化器更新参数的代码,同时把损失函数的定义移到循环外避免重复实例化:
loss_fn= nn.CrossEntropyLoss() # 移到循环外 for epoch_i in range(5): total_loss = 0 model.train() for step, batch in enumerate(train_data): train_x, train_y = tuple(t.to(device)for t in batch) # 先转换train_y的形状 train_y = train_y[:, 0].long() model.zero_grad() logits=model(train_x) loss= loss_fn(logits,train_y) total_loss += loss.item() # 用item()取数值避免显存泄漏 loss.backward() optimizer.step() # 这步是更新参数的核心,你之前漏了 # 每个epoch结束后打印损失 print(f"epoch {epoch_i} 总损失: {total_loss}")
- 额外检查点:确认你的logits形状是[32, 类别数],和CrossEntropyLoss的输入要求匹配。
内容的提问来源于stack exchange,提问作者amarykya_ishtmella
相关产品推荐
相关产品推荐

