Pytorch 学习 - 4.pytorch 张量数学-线性回归

先掌握pytorch,学好pytorch,  才能学好人工智能

Linear regression 

线性回归是一种用于建模两个或多个变量之间关系的统计方法。在这种模型中,一个或多个自变量(也称为预测变量或特征)与一个因变量(也称为响应变量或目标)之间的关系被假定为线性的,即这些变量的关系可以用一条直线(在二维空间中)或一个超平面(在多维空间中)来近似表示。

基本概念

  • 自变量(X):用于预测因变量的变量。
  • 因变量(Y):需要被预测的变量。
  • 线性关系:自变量和因变量之间的关系可以表示为一条直线(Y = aX + b),其中a是斜率,b是截距。
  • 回归系数(或权重):在线性方程中,每个自变量前的系数,表示该自变量对因变量的影响程度。
  • 截距:线性方程中当所有自变量都为0时的因变量值。

线性回归的步骤

  1. 数据收集:收集包含自变量和因变量的数据集。
  2. 数据预处理:处理缺失值、异常值,进行特征缩放等。
  3. 模型构建:建立线性回归模型,即确定线性方程的形式。
  4. 参数估计:使用最小二乘法或其他优化方法估计回归系数和截距。
  5. 模型评估:通过计算残差、决定系数(R²)、均方误差(MSE)等指标评估模型的拟合效果。
  6. 预测:使用训练好的模型对新的数据进行预测。

原始模型

import torch 
import matplotlib.pyplot as plt

# 设置CPU生成随机数的种子,方便下次复现实验结果。
torch.manual_seed(9)

# 准备训练数据
x = torch.rand(30,1)*10 
y = 3*x + 2 + torch.rand(30,1)
# print('output','\n', 'x :', x,x.shape)
# print('\n', 'y :', y,y.shape)
# 初始参数
# w = torch.rand(size=(30,1),requires_grad=True)
# b = torch.zeros(size=(30,1),requires_grad=True)
w = torch.randn(1,requires_grad=True) 
#.grad属性:在PyTorch中,每个tensor都有一个.grad属性,用于存储该tensor的梯度。对于leaf tensor,如果在计算图中它们参与了梯度计算,那么.grad属性会在反向传播后被填充。
b = torch.ones(1,requires_grad=True)
print('\n', 'w :', w,w.shape)
print('\n', 'b :', b,b.shape)
# 设置学习率为0.1
lr = 0.1
#
for i in range(1000):
    # 前向传播
    # torch.mul作element-wise的矩阵点乘,维数不限,可以矩阵乘标量
    # 当a, b维度不一致时,会自动填充到相同维度相点乘。
    wx = torch.mul(w, x)
    # 支持广播相加
    y_pred = torch.add(wx, b)
    
    # 计算MSE Loss
    # 反向传播, ✖2分之一是为了方便求导
    loss = (torch.sqrt(y - y_pred)*0.5).mean()
    print('loss:',loss)
    
    # 反向传播, 计算当前梯度
    loss.backward()
    # print('w.grad',w.grad)
    # print('b.grad',b.grad)
    
    # 更新参数
    # w = w- LR*w.grad
    # b = b- LR*w.grad
    # w = torch.sub(w,lr*w.grad)
    # b = torch.sub(b,lr*b.grad)

    
    # 函数形式:torch.sub(input, other, *, alpha=1, out=None)
    # 参数解读:
    #  input: 输入的被减数,格式为tensor格式
    #  other:输入的减数
    #  alpha:与上面other参数搭配使用,用来与other相乘,当使用torch.sub()函数时不指定alpha的值时,alpha默认为1
    #  out: 指定torch.sub()输出值被赋给的变量,可不指定。
    
    # 然而
    # torch.sub_()功能与torch.sub()相同,区别在与torch.sub_()是torch.sub()的in-place操作版本。
    
    b.data.sub_(lr * b.grad)
    w.data.sub_(lr * w.grad)
    
     # 绘图
    if i % 20 == 0 or loss.data.numpy() < 1:
        plt.cla()   # 防止社区版可视化时模型重叠2020-12-15
        plt.scatter(x.data.numpy(), y.data.numpy())
        plt.plot(x.data.numpy(), y_pred.data.numpy(), 'r-', lw=5)
        plt.text(2, 20, 'Loss=%.4f' % loss.data.numpy(), fontdict={'size': 20, 'color':  'red'})
        plt.xlim(1.5, 10)
        plt.ylim(8, 28)
        plt.title("Iteration: {}\nw: {} b: {}".format(i, w.data.numpy(), b.data.numpy()))
        plt.pause(0.5)

        if loss.data.numpy() < 1:
            break
    plt.show()

 

这段代码是在一个训练循环中使用的,通常用于机器学习或深度学习中,特别是在训练一个模型时可视化损失函数和模型的预测情况。下面是对这段代码的逐行解释:

  1. if i % 20 == 0 or loss.data.numpy() < 1::这行代码检查两个条件是否满足其中之一。第一个条件是当前的迭代次数i是否是20的倍数(i % 20 == 0),这通常用于每隔一定数量的迭代更新一次可视化,以避免可视化过于频繁。第二个条件是当前的损失值loss是否小于1,这通常表示模型已经达到了一个较好的性能水平,可以提前结束训练。

  2. plt.cla():这行代码清除当前的轴内容,确保在每次更新可视化时不会重叠。

  3. plt.scatter(x.data.numpy(), y.data.numpy()):使用散点图绘制真实的数据点,其中xy分别是输入特征和目标输出的真实值。

  4. plt.plot(x.data.numpy(), y_pred.data.numpy(), 'r-', lw=5):绘制模型的预测线,其中y_pred是模型对x的预测输出。这里使用红色('r-')和线宽(lw=5)来突出显示预测线。

  5. plt.text(2, 20, 'Loss=%.4f' % loss.data.numpy(), fontdict={'size': 20, 'color': 'red'}):在图上添加文本,显示当前的损失值。文本的位置是(2, 20),字体大小为20,颜色为红色。

  6. plt.xlim(1.5, 10) 和 plt.ylim(8, 28):分别设置x轴和y轴的显示范围。

  7. plt.title("Iteration: {}\nw: {} b: {}".format(i, w.data.numpy(), b.data.numpy())):设置图表的标题,显示当前的迭代次数i,以及模型的参数(假设模型是一个简单的线性模型,参数为权重w和偏置b)。

  8. plt.pause(0.5):暂停0.5秒,以便用户可以看到更新的图表。这在实时可视化时非常有用。

  9. if loss.data.numpy() < 1::再次检查损失值是否小于1,如果是,则跳出循环。

  10. plt.show():在所有迭代完成后,显示最终的图表。

总的来说,这段代码的目的是在训练过程中实时可视化模型的性能和预测结果,特别是当模型性能达到一定标准(损失值小于1)或每隔一定数量的迭代时。

    • xy是输入特征和目标输出,它们也应该是torch.Tensor类型。
  1. 参数更新
    • 您正在使用.data.sub_()进行in-place更新,这是不推荐的做法,因为它绕过了PyTorch的梯度计算图。更好的做法是使用优化器(如torch.optim.SGD)来更新参数。
  2. 梯度清零
    • 在每次迭代开始时,您需要清零梯度,否则梯度会累积。
  3. 学习率(lr
    • 学习率需要事先定义。
  4. 可视化
    • 可视化代码看起来是正确的,但请确保plt(matplotlib.pyplot)已经导入。
  5. 代码结构
    • 代码应该放在一个函数或类中,以便更好地组织和管理。

下面是一个改进后的代码示例:

import torch  
import matplotlib.pyplot as plt  
  
# 假设x和y是已经准备好的数据   
x = torch.rand(size=(50,1),requires_grad=False)*10
y = 2*x + torch.rand(size=(50,1),requires_grad=False) 
# 这里需要您自己定义x和y  
  
# 定义模型参数  
w = torch.tensor(10., requires_grad=True)  # 假设只有一个特征,因此w是一个标量  
b = torch.tensor(0., requires_grad=True)  
print('w',w)
print('b',b)
  
# 学习率  
lr = 0.05  
  
# 训练循环  
for i in range(1000):  
    # 前向传播  
    wx = torch.mul(w, x)  # 这里假设x是一个标量或一维张量,与w兼容  
    y_pred = torch.add(wx, b)  
    # print('ypred',y_pred)
    # print('A',torch.sqrt (y - y_pred) )  
    # print('B',(y - y_pred)**2)
    # 计算MSE Loss  
    loss = (0.5 *  (y - y_pred)**2 ).mean()  
    print('loss',loss)


    # 反向传播  
    loss.backward()  
      
    # 更新参数  
    with torch.no_grad():  # 在更新参数时不需要计算梯度  
        w -= lr * w.grad  
        b -= lr * b.grad  
    # 梯度清零  
    w.grad.zero_()  
    b.grad.zero_()    
    # 绘图  
    if i % 20 == 0 or loss.item() < 1:  
        plt.cla()  
        plt.scatter(x.numpy(), y.numpy())  
        plt.plot(x.numpy(), y_pred.detach().numpy(), 'r-', lw=5)  # 使用detach()避免在绘图时计算梯度  
        plt.text(2, 20, 'Loss=%.4f' % loss.item(), fontdict={'size': 20, 'color': 'red'})  
        plt.xlim(0, 10)  
        plt.ylim(-5, 30)  
        plt.title(f"Iteration: {i}\nw: {w.item()} b: {b.item()}")  
        plt.pause(0.5)  
          
        if loss.item() < 1:  
            break  
  
plt.show()

tensor中

.grad属性:在PyTorch中,每个tensor都有一个.grad属性,用于存储该tensor的梯度。对于leaf tensor,如果在计算图中它们参与了梯度计算,那么.grad属性会在反向传播后被填充。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值