机器学习经典实例:使用pytorch 完成线性回归分析

机器学习经典实例:使用pytorch 完成线性回归分析


0.总结

Get to the points first. The article comes from LawsonAbs!
  • pytorch中相关函数的使用
  • 线性回归、梯度下降的理解与计算

1.要求

  • 使用随机生成的模拟数据去训练一个函数模型
  • 数据集是点对,呈现的是一次线性函数关系

2.主要思路

这个案例带有 “验证” 的味道,即我们事先定义好一个函数模型,并根据这个模型随机生成一些数据,然后给这些数据集加点儿噪声,最后得到的数据集就是通常所说的训练集。根据训练集训练一个一维函数模型,并使用随机生成的数据测试模型的效果如何,最后用matplotlib 展现拟合效果。

  • step1.事先定义一个函数,即我们的原始数据服从这个函数模型,然后在其中加点儿噪声就得到训练的数据集了;
  • step2.【因为这里是一维函数模型,所以我们就设一次线性函数为这个问题的模型】令函数模型为y=w*x+b。并随机初始化w,b的值;
  • step3.事先定义好学习率 lr = 0.001
  • step4.采用梯度下降的方法更新参数,这里没有调用Autograd中的方法,而是自己计算梯度并更新;
  • step5.每训练完一批数据之后,就开始进行一次模拟验证【对应if ii % 10 == 0:中的部分】

3.代码

from __future__ import print_function
import torch as t
import numpy as np
from matplotlib import pyplot as plt
from IPython import display

t.manual_seed(1000)  # 设置随机数种子,保证任何机器运行都相同
def get_fake_data(batch_size=8):
    # 从均匀分布[0,1) 中抽出8*1的数据,并放大20倍【这里的放大倍数是没有影响的】
    x = t.rand(batch_size, 1) * 20;
    # print(x) # 其类似一个8行1列的向量
    
    # 添加随机噪声
    # 这里的 1+t.randn(batch_size,1) 会在[8,1]这个tensor中每个位置都加1。举例如下:
    """
	tensor([[-0.9596],
        [ 0.3518],
        [-0.4039],
        [ 1.7584],
        [-0.4145],
        [ 0.8561],
        [-0.4429],
        [ 1.4079]])
tensor([[0.0404],
        [1.3518],
        [0.5961],
        [2.7584],
        [0.5855],
        [1.8561],
        [0.5571],
        [2.4079]])
	"""
    y = x * 2 + (1 + t.randn(batch_size, 1)) * 3  
    return x, y

x, y = get_fake_data()
# 只不过是将tensor 转换为numpy
#plt.scatter(x.squeeze().numpy(), y.squeeze().numpy())

# 随机初始化参数
w = t.rand(1, 1) # => w是个tensor
b = t.zeros(1, 1) # => b也是个tensor
lr = 0.001  # learning rate


'''01.这里的意思就是生成一个具有20000个数据对作为样本,然后用这20000个数据对去训练一个函数模型出来'''
for ii in range(20000):
    x, y = get_fake_data() # 模拟出假的数据
    # forward: 计算loss
    #print(x.size()) # torch.Size([8, 1])
    #print(w.size()) # torch.Size([1, 1])
    y_pred = x.mm(w) + b.expand_as(y)
    loss = 0.5 * (y_pred - y) ** 2  # 均方误差
    loss = loss.sum() # Returns the sum of all elements in the input tensor

    # backward: 手动计算梯度
    dloss = 1 # dloss是什么?
    dy_pred = dloss * (y_pred - y)
    # print(x.size()) # torch.Size([8, 1])
    # print(dy_pred.size()) # torch.Size([8, 1])

    '''    
    01.dw = x.t().mm(dy_pred) 里为什么有个x.t()操作? 是什么意思?
    02.mm函数计算的是两个tensor的乘积,但是如果要做矩阵乘积,显然是无法相乘的。
    所以就需要转换【转置】。
    这里的x.t()就是将x进行转置操作。
    03.结合learning rate 调整参数
    '''
    dw = x.t().mm(dy_pred)
    db = dy_pred.sum()
    w.sub_(lr * dw)
    b.sub_(lr * db)

    # 每训练100次就查看训练的效果到底怎么样了
    if ii % 10 == 0:
        # 清空输出 Clear the output of the current cell receiving output
        display.clear_output(wait=True)
        x = t.arange(0, 20).view(-1, 1)
        # print(x.dtype) # torch.int64 所以需要显式的调用.float()将其转换成float型
        # 其根本原因在于t.arange(0,20)是根据默认1为步长来分配的,导致会出现int64
        # print(w.dtype)

        '''
        01.这里再生成一批数据,就相当于测试集。让这个测试集去表示训练模型的具体效果如何
        02.plot是画出直线,scatter是画出离散的点。这样就可以直观地看出拟合的效果了
        03.为了图形更好看,所以设置了一下长度的限制。
        04.为了不直接跳出图形界面,暂缓了0.5s
        05.最后输出了w,b的两个参数值
        '''
        y = x.float().mm(w)+ b.expand_as(x)
        plt.plot(x.numpy(), y.numpy())  # predicted
        x2, y2 = get_fake_data(batch_size=20) # 这里生成的数据是20个
        plt.scatter(x2.numpy(), y2.numpy())  # true data
        plt.xlim(0, 20) # 设置x轴,y轴的最大值
        plt.ylim(0, 41)
        plt.show()
        print("w=",w.item(), "b=",b.item())

上面这段代码在pycharm中的执行结果就是:

  • 屏幕上会弹出若干幅图形,这些图形由两部分构成:
    (1)训练得到的函数模型
    (2)真实数据(其实就是我们模拟生成的数据)的一个个参数点坐标
  • 底部会打印出参数w,b的值。

运行结果和一部分的参数展示:
在这里插入图片描述

4.难点分析
  • tensor【其实就是矩阵】间的相互运算
  • pytorch函数的学习
    这里我都在文章中的代码中进行了详细的注释。
  • 梯度下降的理解与计算
4.1 看看到底是怎么运算?

我觉得新手最容易怀疑的问题就是:y=w*x+b,这个乘与加的过程到底是什么样的?这里我就把数据拿出来,专门做个解释。

  • 函数模型
    y = x*w + b

  • 数据

x = tensor([[ 8.8605],
        [13.1534],
        [ 8.5220],
        [ 6.9218],
        [13.6363],
        [16.2603],
        [ 4.5726],
        [12.9265]])
w = tensor([[0.3915]])

我们手动相乘一下,就得到了如下的结果:

x*w = tensor([[3.46888575],
[5.1495561],
[]...
])

实际计算机运算得到的x*w值如下:

tensor([[3.4685],
        [5.1490],
        [3.3360],
        [2.7096],
        [5.3380],
        [6.3652],
        [1.7900],
        [5.0602]])

然后再加上b的值【这里是0矩阵】,最后就成了y_pred的值【即y的预测值】。可以发现二者是相同的。【计算机应该不会算错的】

而此时生成的y的值为:

y = tensor([[24.2896],
        [23.1069],
        [21.5958],
        [12.2041],
        [35.8736],
        [36.4838],
        [14.5665],
        [28.4940]])

可以看到他们的之间的loss太大了,现在的问题就是调整这个w,b去减少loss。这是后话,不说了。

4.2 具体函数的使用
  • expand_as()
    把一个tensor变成和函数括号内一样形状的tensor,用法与 expand()类似
    具体实例:
>>> import torch as t
>>> x=t.rand(3,4)
>>> print(x.size())
torch.Size([3, 4])
>>> print(x)
tensor([[0.7740, 0.1354, 0.3477, 0.7286],
        [0.3327, 0.4944, 0.3491, 0.1855],
        [0.3790, 0.8667, 0.6716, 0.2647]])
>>> b=t.zeros(1,1)
>>> print(b)
tensor([[0.]])
>>> print(b.size())
torch.Size([1, 1])
>>> b=b.expand_as(a)
>>> print(b.size())
torch.Size([2, 3])
>>> print(b)
tensor([[0., 0., 0.],
        [0., 0., 0.]])
  • 平方运算【**2
    这里我们在loss函数中用到了平方运算。是将(y_pred-y)**2,这里的y是一个tensor,相当于一个8行一列的数组,其平方运算就是直接将tensor的每位直接对应相乘,然后得到的结果。示例如下:
import torch as t
x=t.rand(8,1) * 10
print("x=",x)
y=x**2
print("y=(x**2)=",y)

在这里插入图片描述当二维或者更加高维的tensor去验证也可以发现的确就是这样运算方法。

### 回答1: 下面是一个使用PyTorch完成线性回归的示例代码: ```python import torch import torch.nn as nn import numpy as np # 构造数据 x_train = np.array([[3.3], [4.4], [5.5], [6.71], [6.93], [4.168], [9.779], [6.182], [7.59], [2.167], [7.042], [10.791], [5.313], [7.997], [3.1]], dtype=np.float32) y_train = np.array([[1.7], [2.76], [2.09], [3.19], [1.694], [1.573], [3.366], [2.596], [2.53], [1.221], [2.827], [3.465], [1.65], [2.904], [1.3]], dtype=np.float32) # 转换为Tensor x_train = torch.from_numpy(x_train) y_train = torch.from_numpy(y_train) # 定义模型 class LinearRegression(nn.Module): def __init__(self): super(LinearRegression, self).__init__() self.linear = nn.Linear(1, 1) def forward(self, x): out = self.linear(x) return out model = LinearRegression() # 定义损失函数和优化器 criterion = nn.MSELoss() optimizer = torch.optim.SGD(model.parameters(), lr=0.01) # 训练模型 num_epochs = 1000 for epoch in range(num_epochs): # 前向传播 outputs = model(x_train) loss = criterion(outputs, y_train) # 反向传播和优化 optimizer.zero_grad() loss.backward() optimizer.step() if (epoch+1) % 100 == 0: print('Epoch [{}/{}], Loss: {:.4f}'.format(epoch+1, num_epochs, loss.item())) # 测试模型 model.eval() with torch.no_grad(): predicted = model(x_train).detach().numpy() print('Predicted:', predicted) ``` 在这个示例中,我们首先构造了一组简单的数据,包括输入数据x_train和对应的输出数据y_train。然后我们定义了一个LinearRegression的类,它继承自nn.Module,并在其中定义了一个线性层,它只有一个输入和一个输出。我们使用MSELoss作为损失函数,使用SGD优化器进行优化。在训练过程中,我们进行了1000次迭代,每100次输出一次损失值。最后,我们使用训练好的模型对输入数据进行预测,并输出预测结果。 ### 回答2: PyTorch是一个用于科学计算的开源机器学习库,它提供了一个Python接口。使用PyTorch可以轻松地实现线性回归模型。 首先,我们需要导入PyTorch库以及其他必要的库: ``` import torch import torch.nn as nn import torch.optim as optim ``` 然后,我们需要创建输入数据和目标值: ``` # 创建输入数据 x = torch.tensor([[1], [2], [3], [4], [5]], dtype=torch.float32) # 创建目标值数据 y = torch.tensor([[3], [6], [9], [12], [15]], dtype=torch.float32) ``` 接下来,我们需要定义一个线性回归模型。在PyTorch中,模型是通过创建一个继承`nn.Module`类的子类来定义的。我们可以在子类的构造函数中定义模型的结构。 ``` # 定义线性回归模型 class LinearRegressionModel(nn.Module): def __init__(self): super(LinearRegressionModel, self).__init__() self.linear = nn.Linear(1, 1) def forward(self, x): return self.linear(x) ``` 在定义模型后,我们需要实例化模型: ``` # 实例化模型 model = LinearRegressionModel() ``` 然后,我们需要定义损失函数和优化器。这里我们选择平方差损失函数(Mean Squared Error)作为我们的损失函数,并使用随机梯度下降(SGD)作为优化器。 ``` # 定义损失函数 criterion = nn.MSELoss() # 定义优化器 optimizer = optim.SGD(model.parameters(), lr=0.01) ``` 接下来,我们需要训练模型。在每个训练迭代中,我们将输入数据传入模型并计算预测值。然后,我们将预测值与目标值进行比较,并计算损失。接下来,我们使用优化器来更新模型的参数。 ``` # 训练模型 num_epochs = 1000 for epoch in range(num_epochs): # 向前传递 outputs = model(x) loss = criterion(outputs, y) # 反向传播和优化 optimizer.zero_grad() loss.backward() optimizer.step() # 打印训练信息 if (epoch+1) % 100 == 0: print('Epoch [{}/{}], Loss: {:.4f}'.format(epoch+1, num_epochs, loss.item())) ``` 最后,我们可以使用训练完成的模型进行预测: ``` # 使用训练完成的模型进行预测 predicted = model(x).detach() # 打印模型预测值 print('Predicted: {}'.format(predicted)) ``` 以上就是使用PyTorch完成线性回归的步骤。通过定义模型、损失函数和优化器,循环训练模型,可以得到一个准确的线性回归模型,并可用于预测未知数据的结果。 ### 回答3: PyTorch是一个非常流行的深度学习框架,可以用来完成线性回归任务。线性回归是一种基本的机器学习算法,用于建立一个线性关系模型来预测因变量和自变量之间的关系。以下是使用PyTorch完成线性回归的步骤: 1. 导入所需要的库:首先,我们需要导入PyTorch库和其他必要的库,例如numpy和matplotlib。 2. 准备数据:接下来,我们需要准备我们的训练数据,包括自变量和因变量。通常,这些数据可以从文件或数据库中读取。 3. 创建模型:在PyTorch中,我们可以使用torch.nn模块来创建我们的线性回归模型。我们需要定义模型的输入和输出维度,并创建一个线性层来建立模型。 4. 定义损失函数:为了训练我们的模型,我们需要定义一个损失函数来度量模型预测结果和真实结果之间的差异。在线性回归中,最常用的损失函数是均方误差(Mean Squared Error)。 5. 定义优化器:PyTorch提供了各种优化器,例如随机梯度下降(SGD)和Adam。我们可以选择一个适合我们问题的优化器,并为模型的参数设置学习率。 6. 训练模型:在这一步骤中,我们将使用我们准备好的训练数据来训练我们的模型。我们需要将自变量传递给模型,计算模型的预测值,然后将预测值和真实值传递给损失函数来计算损失。接下来,我们反向传播误差,更新模型的参数。 7. 评估模型:在完成模型的训练后,我们需要评估模型的性能。我们可以使用测试数据集来计算模型的准确性、精确度等指标。 8. 使用模型进行预测:最后,我们可以使用我们训练好的模型来对新的数据进行预测。 总之,PyTorch提供了一个强大的工具集,使得线性回归任务变得简单而灵活。通过以上步骤,我们可以更快地构建和训练我们的线性回归模型,并应用它们于实际问题中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

说文科技

看书人不妨赏个酒钱?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值