tjdnbj 2024-02-03 12:35 采纳率: 41.2%
浏览 9

深度学习多项式函数拟合基础问题询问

以下是我的代码,为什么运行之后会出现a Tensor with 100 elements cannot be converted to Scalar的错误呢?该如何修改呢?

import torch
import numpy as np
import sys
import torchvision
import torchvision.transforms as transforms
sys.path.append("C:/Users/zyx20/Desktop/深度学习编程/pythonProject")
import d2lzh_pytorch as d2l
#在训练数据集和测试数据集中,给定样本特征 ,我们使⽤如下的三阶多项式函数来⽣成该样本的标签:y=1.2x-3.4x²+5.6xsancifang+噪声项
#其中噪声项 服从均值为0、标准差为0.01的正态分布。训练数据集和测试数据集的样本数都设为100。
n_train,n_test,true_w,true_b=100,100,[1.2,-3.4,5.6],5
features=torch.randn((n_train + n_test,1))
poly_features=torch.cat((features,torch.pow(features,2),torch.pow(features,3)),1)
labels=(true_w[0]*poly_features[:,0]+true_w[1]*poly_features[:,1]+true_w[2]*poly_features[:,2]+true_b)
labels+=torch.tensor(np.random.normal(0,0.01,size=labels.size()),dtype=torch.float)


#定义作图函数semilogy
def semilogy(x_vals,y_vals,x_label,y_label,x2_vals=None,y2_vals=None,legend=None,figsize=(3.5,2.5)):
    d2l.set_figsize(figsize)
    d2l.plt.xlabel(x_label)
    d2l.plt.ylabel(y_label)
    d2l.plt.semilogy(x_vals,y_vals)
    if x2_vals and y2_vals:
        d2l.plt.semilogy(x2_vals,y2_vals,linestyle=':')
        d2l.plt.legend(legend)
#定义损失函数,并把模型定义部分放在fit_and_plot函数中
num_epochs,loss=100,torch.nn.MSELoss()
def fit_and_plot(train_features,test_features,train_labels,test_labels):
    net=torch.nn.Linear(train_features.shape[-1],1)
    batch_size=min(10,train_labels.shape[0])
    dataset=torch.utils.data.TensorDataset(train_features,train_labels)
    train_iter=torch.utils.data.DataLoader(dataset,batch_size,shuffle=True)
    optimizer=torch.optim.SGD(net.parameters(),lr=0.01)
    train_ls,test_ls=[],[]
    for _ in range(num_epochs):
        for X,y in train_iter:
            l=loss(net(X),y.view(-1,1))
            optimizer.zero_grad()
            l.backward()
            optimizer.step()
        train_labels=train_labels.view(-1,1)
        test_labels=test_labels.view(-1,1)
        train_ls.append(loss(net(train_features),train_labels.item()))
        test_ls.append(loss(net(test_features),test_labels).item())
    print('final epoch:train loss',train_ls[-1],'test loss',test_ls[-1])
    semilogy(range(1,num_epochs+1),train_ls,'epochs','loss',range(1,num_epochs+1),test_ls,['train','test'])
    print('weight:',net.weight.data,'\nbias:',net.bias.data)
fit_and_plot(poly_features[:n_train,:],poly_features[n_train:,:],labels[:n_train],labels[n_train:])

  • 写回答

1条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-02-03 12:37
    关注

    引自免费微信小程序:皆我百晓生

    在您的代码中,问题出在计算训练损失时,您尝试将一个形状为 (batch_size, 1) 的输出张量与一个标量进行比较。在以下这行代码里:

    train_ls.append(loss(net(train_features), train_labels.item()))
    

    train_labels.item() 将整个训练标签数据集转换成了一个标量,但 net(train_features) 的输出是一个批量的预测值,它的形状取决于每个批次中的样本数(在每次迭代中可能不同)。要修正这个问题,您应该保持 train_labels 为向量形式,并确保它们与网络输出维度匹配。

    修改后的这部分代码应该是这样的:

    def fit_and_plot(train_features, test_features, train_labels, test_labels):
        ...
        for _ in range(num_epochs):
            for X, y in train_iter:
                l = loss(net(X), y)
                optimizer.zero_grad()
                l.backward()
                optimizer.step()
            # 不再需要.view(-1,1),因为y在DataLoader中已经被正确处理了形状
            train_ls.append(loss(net(train_features), train_labels).item())
            test_ls.append(loss(net(test_features), test_labels).item())
        ...
    

    删除了 .view(-1,1) 这一行,因为在 train_iter 中,y 的形状已经由 DataLoader 处理得与网络输出相匹配。同时,在计算训练损失和测试损失时,直接使用整个 train_labelstest_labels 而不是调用 .item() 方法。这样,您就可以正确地计算并记录每个时期的训练损失和测试损失了。

    评论

报告相同问题?

问题事件

  • 创建了问题 2月3日

悬赏问题

  • ¥15 vscode编译ros找不到头文件,cmake.list文件出问题,如何解决?(语言-c++|操作系统-linux)
  • ¥15 通过AT指令控制esp8266发送信息
  • ¥15 有哪些AI工具提供可以通过代码上传EXCEL文件的API接口,并反馈分析结果
  • ¥15 二维装箱算法、矩形排列算法(相关搜索:二维装箱)
  • ¥20 nrf2401上电之后执行特定任务概率性一直处于最大重发状态
  • ¥15 二分图中俩集合中节点数与连边概率的关系
  • ¥20 wordpress如何限制ip访问频率
  • ¥15 自研小游戏,需要后台服务器存储用户数据关卡配置等数据
  • ¥15 请求解答odoo17外发加工某工序的实操方法
  • ¥20 IDEA ssm项目 跳转页面报错500