您当前的位置: 首页 >  算法

wendy_ya

暂无认证

  • 2浏览

    0关注

    342博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

PyTorch实战案例(二)——利用PyTorch实现线性回归算法(进阶)

wendy_ya 发布时间:2021-11-11 21:44:25 ,浏览量:2

目录
    • 一、案例描述
    • 二、代码详解
      • 2.1 根据直线方程构造数据集
      • 2.2 构建数据迭代器
      • 2.3 定义模型
      • 2.4 模型评价指标函数
      • 2.5 编译和训练
      • 2.6 输出结果可视化
      • 2.7 模型评估
    • 三、完整代码

一、案例描述

上一篇文章【PyTorch实战案例(一)——利用PyTorch实现线性回归算法(基础)】,介绍了PyTorch实现线性回归的基础算法,使用预定义好的层构建了一个单层神经网络,本文将介绍利用PyTorch实现线性回归的进阶算法,通过构建LinearRegression类实现线性回归。

案例为:利用PyTorch设计神经网络拟合直线y=Wx+b,其中W=[2,-3.4]T , b=4.2。 该案例有两个特征,分别是W的两个维度,有一个标签,为输出y。

二、代码详解 2.1 根据直线方程构造数据集

定义构造数据集函数:

#根据带有噪声的线性模型构造一个人造数据集
def synthetic_data(w,b,num_examples):
    '''生成y=wx+b+e(噪声)'''
    x=torch.normal(0,1,(num_examples,len(w)))  # 形状:num_examples*len(w)
    y=torch.matmul(x,w)+b                      # 形状:num_examples
    y+=torch.normal(0,0.01,y.shape)
    return x,y.reshape(-1,1) #将y转成列向量

接着,将w和b的真实值传入构造数据集,构造400个数据集样本:

# y=Wx+b     W=[2,-3.4]T     b=4.2
true_w=torch.tensor([2,-3.4])
true_b=4.2
n=400    #样本数量
features,labels=synthetic_data(true_w,true_b,n)  #生成数据features和labels

我们也可以利用matplotlib库对features和labels进行可视化操作:

# 将features和labels进行可视化
plt.figure(figsize = (12,5))
ax1 = plt.subplot(121)
ax1.scatter(features[:,0],labels, c = "b",label = "features[:,0]")
ax1.legend()
plt.xlabel("x1")
plt.ylabel("y",rotation = 0)

ax2 = plt.subplot(122)
ax2.scatter(features[:,1],labels, c = "g",label = "features[:,1]")
ax2.legend()
plt.xlabel("x2")
plt.ylabel("y",rotation = 0)

运行结果: 在这里插入图片描述

2.2 构建数据迭代器

构建数据迭代器代码如下:

ds = data.TensorDataset(features,labels)    #构建数据迭代器
ds_train,ds_valid = data.random_split(ds,[int(400*0.7),400-int(400*0.7)])
dl_train = data.DataLoader(ds_train,batch_size = 10,shuffle=True,num_workers=2)
dl_valid = data.DataLoader(ds_valid,batch_size = 10,num_workers=2)

random_split函数将数据集随机拆分为给定长度的非重叠新数据集,这里将训练集和测试集按比例7:3拆分,然后利用DataLoader函数对其进行加载。

2.3 定义模型

这里利用了torchkeras库,定义模型代码如下:

# 定义模型
from torchkeras import Model
class LinearRegression(Model):
    def __init__(self):
        super(LinearRegression, self).__init__()
        self.fc = nn.Linear(2,1)    #线性层
    
    def forward(self,x):
        return self.fc(x)

model = LinearRegression()

torchkeras 是在pytorch上实现的仿keras的高层次Model接口。有了它,就可以像Keras那样,对pytorch构建的模型进行summary,compile,fit,evaluate , predict五连击。

可以利用compile()查看模型结构:

#输出模型结构
model.summary(input_shape = (2,))

模型结构如下:

Layer (type)Output ShapeParam#Linear-1[-1, 1]3

Total params: 3 Trainable params: 3 Non-trainable params: 0

2.4 模型评价指标函数

平均绝对误差(Mean Absolute Error,MAE): M A E = 1 n ∑ i = 1 n ∣ y ^ i − y i ∣ MAE=\frac{1}{n}\sum_{i=1}^n{|\hat{y}_i-y_i|} MAE=n1​i=1∑n​∣y^​i​−yi​∣

其范围为[0,+∞),当预测值与真实值完全吻合时等于0,即完美模型;误差越大,该值越大。

定义MAE函数:

#MAE——平均绝对误差
def mean_absolute_error(y_pred,y_true):
    return torch.mean(torch.abs(y_pred-y_true))

平均绝对百分比误差(Mean Absolute Percentage Error,MAPE): M A P E = 100 % n ∑ i = 1 n ∣ y ^ i − y i y i ∣ MAPE=\frac{100\%}{n}\sum_{i=1}^n{\left| \frac{\hat{y}_i-y_i}{y_i} \right|} MAPE=n100%​i=1∑n​∣∣∣∣​yi​y^​i​−yi​​∣∣∣∣​

其范围为[0,+∞),MAPE为0%表示完美模型,MAPE大于100%则表示劣质模型。

可以看到,MAPE跟MAE很像,就是多了个分母。

【注意】:当真实值有数据等于0时,存在分母0除问题,该公式不可用,所以一般同时在分子和分母上加一个较小的数值防止出现error。

定义MAPE评价指标:

#MAPE——平均绝对百分比误差
def mean_absolute_percent_error(y_pred,y_true):
    absolute_percent_error = (torch.abs(y_pred-y_true)+1e-7)/(torch.abs(y_true)+1e-7)
    return torch.mean(absolute_percent_error)
2.5 编译和训练

compile()用于配置训练模型(编译),fit()用于训练模型 代码如下:

model.compile(loss_func = nn.MSELoss(),
              optimizer= torch.optim.Adam(model.parameters(),lr = 0.01),
             metrics_dict={"mae":mean_absolute_error,"mape":mean_absolute_percent_error})
dfhistory = model.fit(200,dl_train = dl_train, dl_val = dl_valid,log_step_freq = 20)

损失函数利用MSELoss(),优化器采用Adam优化器,学习率为0.01,metrics_dict参数指定在训练和测试期间的模型评估标准,这里指定MAE和MAPE作为评估标准。最后利用fit()函数训练模型,训练200次,fit函数返回History对象,History类对象包含两个属性,分别为epoch和history,epoch为训练轮数,history为字典类型,默认包含val_loss,val_acc,loss,acc四个key值,由于这里在compile()函数中加入mae和mape,因此这里的history字典中包含6个key值。如下所示: 在这里插入图片描述 训练完成后,可以查看w和b的值:

#查看w和b的值
w = model.state_dict()["fc.weight"]
b=model.state_dict()["fc.bias"]
w,b
2.6 输出结果可视化

利用最终训练出来的w和b可以进行最终输出结果可视化:

#结果可视化
plt.figure(figsize = (12,5))
ax1 = plt.subplot(121)
ax1.scatter(features[:,0],labels, c = "b",label = "features[:,0]")
ax1.plot(features[:,0],w[0,0]*features[:,0]+b[0],"-r",linewidth = 5.0,label = "model")
ax1.legend()
plt.xlabel("x1")
plt.ylabel("y",rotation = 0)


ax2 = plt.subplot(122)
ax2.scatter(features[:,1],labels, c = "g",label = "features[:,1]")
ax2.plot(features[:,1],w[0,1]*features[:,1]+b[0],"-r",linewidth = 5.0,label = "model")
ax2.legend()
plt.xlabel("x2")
plt.ylabel("y",rotation = 0)

运行结果: 在这里插入图片描述

2.7 模型评估

定义模型评估可视化函数:

def plot_metric(dfhistory, metric):
    train_metrics = dfhistory[metric]
    val_metrics = dfhistory['val_'+metric]
    epochs = range(1, len(train_metrics) + 1)
    plt.plot(epochs, train_metrics, 'bo--')
    plt.plot(epochs, val_metrics, 'ro-')
    plt.title('Training and validation '+ metric)
    plt.xlabel("Epochs")
    plt.ylabel(metric)
    plt.legend(["train_"+metric, 'val_'+metric])
    plt.show()

查看训练集和验证集的损失:

plot_metric(dfhistory,"loss")

在这里插入图片描述 查看训练集和验证集的MAPE:

plot_metric(dfhistory,"mape")

在这里插入图片描述 在测试模式下评估模型性能:

# 评估
model.evaluate(dl_valid)

运行结果: {‘val_loss’: 0.0001073539030282215, ‘val_mae’: 0.008271524915471673, ‘val_mape’: 0.0075647564566073315}

使用模型进行预测:

# 使用模型进行预测
dl = data.DataLoader(data.TensorDataset(features))
model.predict(dl)[0:10]

运行结果: tensor([[ 3.1832], [-1.5471], [12.1956], [ 6.6161], [ 1.7743], [ 3.5524], [ 6.3739], [ 3.3306], [ 7.2390], [ 2.9116]])

三、完整代码

完整代码可以参考:https://download.csdn.net/download/didi_ya/40510830

ok,以上便是本文的全部内容了,看完了之后记得一定要亲自独立动手实践一下呀~

关注
打赏
1659256378
查看更多评论
立即登录/注册

微信扫码登录

0.0406s