在人工智能学习中,我们经常会碰到一些线性回归的问题,本文通过一个具体例子,使用飞奖高层API来呈现线性回归的实现过程。这里使用高层API主要为了减化代码,方便更清楚的了解如何做线性回归类似的项目。
这里我们自己模拟生成2000行数据,假定生成数据的方式是:y=3*x+100,为了演示从文件中获取数据,这里使用excel来生成数据,并保存为csv文件。也可以直接用numpy直接生成数据。
x |
y |
562 |
1786 |
705 |
2215 |
199 |
697 |
638 |
2014 |
754 |
2362 |
831 |
2593 |
85 |
355 |
215 |
745 |
559 |
1777 |
900 |
2800 |
728 |
2284 |
982 |
3046 |
417 |
1351 |
783 |
2449 |
206 |
718 |
271 |
913 |
202 |
706 |
239 |
817 |
622 |
1966 |
这里我们知道,通过已知公式,给出x很容易得到y的值,但是如果我们不知道公式,只是给出这2000行的x和y的数据,就很难反向推算出公式是什么。这里我们假定x和y存在的是线性关系,那我们就可以通过线性回归的算法来拟合从x到y的关系。
一、数据集预处理
#读取数据import pandas as pdimport numpy as np df=pd.read_csv('data/xy.csv')df.head()
#运行结果 x y0 1 931 2 982 3 1033 4 1084 5 113
#转换数据成numpy数组,并查看数据形状data=df.to_numpy()print(data.shape)
运行结果:(2000, 4)
#归一化处理max_value=np.max(data,axis=0)min_value=np.min(data,axis=0)avg_value=np.mean(data,axis=0)print(max_value,min_value,avg_value)print(max_value.shape,min_value.shape,avg_value.shape)data=(data-avg_value)/(max_value-min_value)print(data.shape)print(data[0][:-1],data[0][-1])
#运行结果:[ 998 3094] [ 2 106] [ 507.0685 1621.2055](2,) (2,) (2,)(2000, 2)[0.05515211] 0.05515210843373493
#数据分割tratio=0.7vratio=0.2train_data=data[:int(tratio*data.shape[0])]val_data=data[int(tratio*data.shape[0]):int((tratio+vratio)*data.shape[0])]test_data=data[int((tratio+vratio)*data.shape[0]):]print(train_data.shape,val_data.shape,test_data.shape)
运行结果:(1400, 4) (399, 4) (201, 4)
二、自定数据集
#自定义数据集import paddleclass xyDataset(paddle.io.Dataset): def __init__(self,data): self.data=data def __getitem__(self,idx): return self.data[idx][:-1].astype(np.float32),self.data[idx][-1].astype(np.float32) def __len__(self): return len(self.data) train_dataset=xyDataset(train_data)val_dataset=xyDataset(val_data)test_dataset=xyDataset(test_data)train_loader=paddle.io.DataLoader(train_dataset,batch_size=16,shuffle=True)val_loader=paddle.io.DataLoader(val_dataset,batch_size=16,shuffle=False)for i,(x,y) in enumerate(train_loader()): print(i,x,y) break
#运行结果:Tensor(shape=[16, 1], dtype=float32, place=CPUPlace, stop_gradient=True, [[-0.03420532], [-0.13661496], [ 0.26499146], [ 0.47683886], [ 0.14551355], [ 0.24993123], [-0.14665513], [-0.13360292], [ 0.18567419], [ 0.26499146], [ 0.37844527], [-0.14163505], [ 0.07623645], [-0.12356275], [ 0.17764206], [ 0.03808384]]) Tensor(shape=[16], dtype=float32, place=CPUPlace, stop_gradient=True, [-0.03420532, -0.13661496, 0.26499146, 0.47683886, 0.14551355, 0.24993123, -0.14665513, -0.13360292, 0.18567419, 0.26499146, 0.37844527, -0.14163505, 0.07623645, -0.12356275, 0.17764206, 0.03808384])
三、定义回归网络模型
#定义回归模型class xyModel(paddle.nn.Layer): def __init__(self): super(xyModel,self).__init__() self.fc=paddle.nn.Linear(1,1) def forward(self,x): y=self.fc(x) return y
#模型准备和查看model=paddle.Model(xyModel())model.summary((3,))model.prepare( paddle.optimizer.Adam(parameters=model.parameters()), paddle.nn.MSELoss() #线性回归模型最常用的损失函数–均方误差(MSE) )
#运行结果--------------------------------------------------------------------------- Layer (type) Input Shape Output Shape Param # =========================================================================== Linear-4 [[1]] [1] 2 ===========================================================================Total params: 2Trainable params: 2Non-trainable params: 0---------------------------------------------------------------------------Input size (MB): 0.00Forward/backward pass size (MB): 0.00Params size (MB): 0.00Estimated Total Size (MB): 0.00
四、模型训练
#训练模型model.fit(train_loader,val_loader,batch_size=32,epochs=500,verbose=1)
#最后部分的训练数据:step 70/88 - loss: 0.1078 - 14ms/stepstep 80/88 - loss: 0.0762 - 15ms/stepstep 88/88 - loss: 0.0465 - 15ms/step
五、模型评估
#模型评估result=model.evaluate(val_loader,batch_size=16,verbose=1)
#运行结果Eval begin...step 25/25 [==============================] - loss: 0.0480 - ETA: 0s - 12ms/st - loss: 0.0561 - ETA: 0s - 12ms/st - loss: 0.0831 - 12ms/step Eval samples: 399
六、模型保存
#保存模型model.save('models/xy_model')
在models目录下生成2个文件:1,模型参数文件:xy_model.pdparams。2,优化器参数文件:xy_model.pdopt
七、模型预测
这里主要使用高层API来进行预测。
#模型预测test_dataset=xyDataset(test_data)idx=np.random.randint(0,test_data.shape[0])print(idx)y=test_dataset[idx][-1]x=test_dataset[idx][:-1]pred = model.predict(x)pred=np.array(pred)#print(pred,y)#反归一化处理,取得真实值。pred=pred*(max_value[-1]-min_value[-1])+avg_value[-1]y=y*(max_value[-1]-min_value[-1])+avg_value[-1]print("预测值:",pred.item(),"实际值:",y)
运行结果:随机取2条测试数据
104Predict begin...step 1/1 [==============================] - 17ms/stepPredict samples: 1预测值: 1696.0706787109375 实际值: 2022.9999925427437
96Predict begin...step 1/1 [==============================] - 4ms/stepPredict samples: 1预测值: 1726.4815673828125 实际值: 2919.9999980859757
从预测值和实际值来看,并不是非常理想,只能说基本拟合。
评论留言