Pytorch实现线性回归

对于样本集D=\left \{ (x_{1},y_{1}),(x_{2},y_{2})\cdots (x_{n},y_{n}) \right \}由n个数据对组成,线性回归的任务就是训练出一个函数f(x)使得f(x_{i})=\omega x_{i}+by_{i}的误差尽可能小,即保证f(x)所拟合的直线能很好地反映出数据集D的特征,而这其中的关键在于f(x)\omega和b的取值。

利用pytorch实现线性回归可分为4步

第一步 准备数据

x = np.arange(20)
y = np.array([5 * x[i] + random.randint(1,20) for i in range(len(x))])
x_train = torch.from_numpy(x).float() # 将数据x转换为Tensor
y_train = torch.from_numpy(y).float() # 将数据y转换为Tensor

 此时对于对于每一个(x_{i},y__{i})都对应了一个一元函数f(x_{i}),此时可利用plt包中的scatter()函数画出散点图,如图1.1所示。

Pytorch实现线性回归_第1张图片

 图1.1 数据散点图

 第二步 构建模型

由散点图可知需要借助pytorch训练出一个一元线性模型,才能最大限度地逼近这些点,使误差最小。而搭建线性模型需要引入pytorch中的nn.Modle,新建一个类继承nn.Modle。线性模型构建好之后,进行实例化,输入x_train便可得到预测值\hat{y}_train。

class LinearRegression(torch.nn.Module):
    def __init__(self): # 初始化
        super(LinearRegression,self).__init__()
        self.linear = torch.nn.Linear(1,1) # 输入维度是1,输出维度是1
    def forward(self,x): # 前馈函数 返回预测值
        return self.linear(x)

第三步 构建损失函数和优化器

 其中损失函数是用来计算\hat{y}与y之间的差值的平方,差值越大则说明所拟合的直线与样本点之间的误差越大,其损失的计算公式如下。

Loss=\sum_{i=0}^{n}(\hat{y_{i}}-y_{i})^{2}

 优化器是在计算出损失值Loss的基础上分别对\omega和b求偏导,然后在反馈传播中对\omega和b进行更新,其更新公式如下,其中a是学习率。在求偏导时又可分为梯度下降,随机梯度下降。两者的区分在于梯度下降是计算所有样本的损失,而随机梯度下降是取样本中的一个样本点作为该epoch的损失,并更新\omega和b。

\omega =\omega -a\frac{\varphi Loss}{\varphi \omega }

b=b-a\frac{\varphi Loss}{\varphi b}

modle = LinearRegression()  # 构建模型对象
criterion = torch.nn.MSELoss() # 构建损失函数对象
optimizer = torch.optim.SGD(modle.parameters(),0.001) #构建优化器函数对象,学习率0.001

第四步 进行训练

对样本集中的所有数据进行一轮训练称之为epoch,每一轮epoch后需计算损失更新\omega和b。

nums_epochs = 10   # 将轮数设置为10,即训练将进行10轮
for i in range(nums_epochs): 
    input_data = x_train.unsqueeze(1)    # 在x_train的第二个维度上增加一个维度,其目的是为计算损失data_loss时输出为标量
    output_target = y_train.unsqueeze(1) # 在y_train的第二个维度上增加一个维度,其目的是为计算损失data_loss时输出为标量 
    output_predict = modle(input_data)   # 存放预测值
    data_loss = criterion(output_predict,output_target) # 存放损失值
    optimizer.zero_grad()                # 进行梯度清零操作
    data_loss.backward()                 # 进行反馈传播
    optimizer.step()                     # 进行更新
    print("Epoch:[{}/{}],data_loss:[{:.4f}]".format(i+1,nums_epochs,data_loss.item()))
    if ((i+1) % 2 == 0):                 # 每进行2轮输出一次训练函数图像
        pridict_view = modle(input_data)
        plt.plot(x_train.data.numpy(),pridict_view.squeeze(1).data.numpy(),"r") # f(x)的图像
        loss_view = criterion(pridict_view,output_target)  
        plt.title("Loss:{:.4f}".format(loss_view.item()))  # 损失
        plt.xlabel("X")
        plt.ylabel("Y")
        plt.scatter(x_train,y_train)  # 数据散点图
        plt.show()

 经过10轮训练可得到如下结果,通过以下几幅图可知在线性模型的训练下损失Loss的值不断减小,函数f(x)的图像与样本点越来越贴近,误差越来越小。

Pytorch实现线性回归_第2张图片

                    图 4.1

Pytorch实现线性回归_第3张图片

 图 4.2

Pytorch实现线性回归_第4张图片

图 4.3 

Pytorch实现线性回归_第5张图片

 图 4.4

Pytorch实现线性回归_第6张图片

 图 4.5 

你可能感兴趣的:(人工智能,python,线性回归,人工智能,机器学习)