PyTorch实现Softmax回归时前向传播异常问题求助
问题:Softmax回归分类2D数据点出错排查
我尝试用Softmax回归将2D数据点分类为0或1,但代码运行存在问题,不确定哪里出错。我初始化了接收2个输入、输出2个类别的Softmax模型,训练时把包含x、y列的训练数据输入模型,以下是我的代码、数据输出和完整CSV文件:
原代码
import csv import torch import numpy data_path = "C:\\Users\\bchen\\Downloads\\2d-2class-dataset.csv" data_numpy = numpy.loadtxt(data_path, dtype=int, delimiter=',', skiprows=1) data_torch = torch.from_numpy(data_numpy) row_count = data_torch.size()[0] training_count = 16 training_xy = data_torch[:training_count, [0, 1]] training_labels = data_torch[:training_count, 2] test_xy = data_torch[:training_count + 1, [0, 1]] test_labels = data_torch[:training_count + 1, 2] class Softmax(torch.nn.Module): def __init__(self, n_inputs, n_outputs): super().__init__() self.linear = torch.nn.Linear(n_inputs, n_outputs) def forward(self, x): pred = self.linear(x) return pred model_softmax = Softmax(2, 2) optimizer = torch.optim.SGD(model_softmax.parameters(), lr=0.01) criterion = torch.nn.CrossEntropyLoss Loss = [] epochs = 100 for epoch in range(epochs): optimizer.zero_grad() model_softmax.train() xy_pred = model_softmax(training_xy) #ISSUE loss = criterion(xy_pred, training_labels) Loss.append(loss) loss.backward() optimizer.step() print(Loss) with torch.inference_mode: y_pred = model_softmax(test_xy) print(test_labels) print(y_pred)
training_xy输出
tensor([[ -85, 40], [ -18, 82], [-154, 150], [ 140, 162], [ 102, 64], [ 22, 28], [ 126, -108], [ 171, 52], [ 276, 43], [ 77, -63], [ 251, -196], [ 52, -201], [ 181, -30], [ 32, -22], [ -34, -129], [ -77, -60]], dtype=torch.int32)
完整CSV文件
# x,y,label -85,40,1 -18,82,1 -154,150,1 140,162,0 102,64,0 22,28,0 126,-108,0 171,52,0 276,43,0 77,-63,0 251,-196,0 52,-201,0 181,-30,0 32,-22,1 -34,-129,1 -77,-60,1 -127,-207,1 -244,-63,1 -189,60,1 -48,198,1 73,214,0 217,221,0 -72,-248,0
问题排查与修正
你的代码存在以下几个关键问题:
- 数据类型不匹配
training_xy是int32类型,而PyTorch线性层默认使用float32进行计算,类型不兼容会导致报错。需要将输入数据转换为浮点型:
training_xy = data_torch[:training_count, [0, 1]].float() test_xy = data_torch[training_count:, [0, 1]].float()
- 损失函数未实例化
criterion = torch.nn.CrossEntropyLoss只是引用了类,没有创建实例,应该加上括号:
criterion = torch.nn.CrossEntropyLoss()
- 测试集划分错误
原代码里测试集取了前17行,和训练集(前16行)大量重叠,应该取训练集之后的数据:
test_xy = data_torch[training_count:, [0, 1]] test_labels = data_torch[training_count:, 2]
- inference_mode使用错误
torch.inference_mode是上下文管理器,需要加括号调用:
with torch.inference_mode(): y_pred = model_softmax(test_xy)
- 损失值存储问题
直接存储张量会占用不必要的内存,应该存储数值:
Loss.append(loss.item())
修正后完整代码
import torch import numpy data_path = "C:\\Users\\bchen\\Downloads\\2d-2class-dataset.csv" # 加载数据并转换为PyTorch张量 data_numpy = numpy.loadtxt(data_path, dtype=int, delimiter=',', skiprows=1) data_torch = torch.from_numpy(data_numpy) row_count = data_torch.size()[0] training_count = 16 # 划分训练集和测试集,转换为浮点型 training_xy = data_torch[:training_count, [0, 1]].float() training_labels = data_torch[:training_count, 2] test_xy = data_torch[training_count:, [0, 1]].float() test_labels = data_torch[training_count:, 2] # 定义Softmax模型(CrossEntropyLoss已包含Softmax,无需额外实现) class Softmax(torch.nn.Module): def __init__(self, n_inputs, n_outputs): super().__init__() self.linear = torch.nn.Linear(n_inputs, n_outputs) def forward(self, x): return self.linear(x) model_softmax = Softmax(2, 2) optimizer = torch.optim.SGD(model_softmax.parameters(), lr=0.01) criterion = torch.nn.CrossEntropyLoss() # 实例化损失函数 Loss = [] epochs = 100 for epoch in range(epochs): model_softmax.train() optimizer.zero_grad() xy_pred = model_softmax(training_xy) loss = criterion(xy_pred, training_labels) Loss.append(loss.item()) # 存储损失数值 loss.backward() optimizer.step() print("训练损失变化:", Loss) # 测试模型 with torch.inference_mode(): y_pred = model_softmax(test_xy) # 转换为预测类别 pred_labels = torch.argmax(y_pred, dim=1) print("测试集真实标签:", test_labels) print("测试集预测类别:", pred_labels)
内容的提问来源于stack exchange,提问作者codingcultivator445
相关产品推荐
相关产品推荐

