目录
线性回归(Linear regression)是利用回归方程(函数)对一个或多个自变量(特征值)和因变量(目标值)之间关系进行建模的一种分析方式。
本实践基于百度飞浆平台(PaddlePaddle),使用深度学习框架paddle,paddle API 文档链接:
uci-housing数据集共506行,每行14列。前13列用来描述房屋的各种信息,最后一列为该类房屋价格中位数。PaddlePaddle提供了读取uci_housing训练集和测试集的接口,分别为paddle.dataset.uci_housing.train( ) 和 paddle.dataset.uci_housing.test( ) 。
- #设置默认的全局dtype(数据类型)为float64
- paddle.set_default_dtype("float64")
- # 训练数据集
- train_dataset = paddle.text.datasets.UCIHousing(mode='train')
- # 评估数据集
- eval_dataset = paddle.text.datasets.UCIHousing(mode='test')
- # 初始化数据读取器
- train_loader = paddle.io.DataLoader(train_dataset, batch_size=32, shuffle=True)
- eval_loader = paddle.io.DataLoader(eval_dataset, batch_size = 8, shuffle=False)
相关API:
- # 设置全局数据类型
- paddle.set_default_dtype("float64")
-
- # paddle.io.DataLoader API 可对数据集进行多进程的读取,并且可自动完成划分 batch 的工作。
- train_loader = paddle.io.DataLoader(train_custom_dataset, batch_size=64, shuffle=True,
- num_workers=1, drop_last=True)
- ·train_custom_dataset:训练数据集
- ·batch_size:每批次读取样本数,batch_size=64 表示每批次读取 64 个样本。
- ·shuffle:样本乱序,shuffle=True 表示在取数据时打乱样本顺序,以减少过拟合发生的可能。
- ·num_workers:同步/异步读取数据,通过 num_workers 来设置加载数据的子进程个数,
- num_workers的值设为大于0时,即开启多进程方式异步加载数据,可提升数据读取速度。
- ·drop_last:丢弃不完整的批次样本, drop_last=True 表示丢弃因数据集样本数不能被
- batch_size 整除而产生的最后一个不完整的 batch 样本。
本模型比较简单,只有一层隐藏层网络,对算力需求不高
- # 定义全连接网络
- class Regressor(paddle.nn.Layer):
- def __init__(self):
- super(Regressor, self).__init__()
- # 定义一层全连接层,输出维度是1,激活函数为None,即不使用激活函数
- self.linear = paddle.nn.Linear(13, 1, None)
-
- # 网络的前向计算函数
- def forward(self, inputs):
- x = self.linear(inputs)
- return x
相关API:
- class paddle.nn.Linear(in_features, out_features, weight_attr=None, bias_attr=None, name=None)
- ·in_features (int):线性变换层输入单元的数目。
- ·out_features (int):线性变换层输出单元的数目。
- ·weight_attr (ParamAttr,可选):指定权重参数的属性。默认值为 None,表示使用默认的权重参数属性。
- ·bias_attr (ParamAttr|bool,可选):指定偏置参数的属性。bias_attr为 bool 类型且设置为 False 时,
- 表示不会为该层添加偏置。bias_attr如果设置为 True 或者 None,则表示使用默认的偏置参数属性,将偏
- 置参数初始化为 0。
- ·name (str,可选):一般无需设置,默认值为 None。
- 注:该类定义了__call__方法,允许对象像函数一样调用
定义画图函数:
- Batch=0
- Batchs=[]
- all_train_accs=[]
- def draw_train_acc(Batchs, train_accs):
- title="training accs"
- plt.title(title, fontsize=24)
- plt.xlabel("batch", fontsize=14)
- plt.ylabel("acc", fontsize=14)
- plt.plot(Batchs, train_accs, color='green', label='training accs')
- plt.legend()
- plt.grid()
- plt.show()
-
- all_train_loss=[]
- def draw_train_loss(Batchs, train_loss):
- title="training loss"
- plt.title(title, fontsize=24)
- plt.xlabel("batch", fontsize=14)
- plt.ylabel("loss", fontsize=14)
- plt.plot(Batchs, train_loss, color='red', label='training loss')
- plt.legend()
- plt.grid()
- plt.show()
训练模型:
- model=Regressor() # 模型实例化
- model.train() # 训练模式
- mse_loss = paddle.nn.MSELoss() # 初始化误差计算对象
- opt=paddle.optimizer.SGD(learning_rate=0.0005, parameters=model.parameters()) # 初始化优化器
-
- epochs_num=200 #迭代次数
-
- # 一共进行200次迭代,训练200次,得到较为接近的xi值
- for pass_num in range(epochs_num):
- for batch_id,data in enumerate(train_loader()):
- image = data[0] # 特征值,即前13个数
- label = data[1] # 目标值,最后一个数——房价中位数
-
- predict=model(image) # 数据传入model,得到预测值
- loss=mse_loss(predict,label) # 计算预测值和目标值的均方差误差
-
- # 打印每次迭代训练的结果
- if batch_id!=0 and batch_id%10==0:
- Batch = Batch+10
- Batchs.append(Batch)
- all_train_loss.append(loss.numpy()[0])
- print("epoch:{},step:{},train_loss:{}".format(pass_num,batch_id,loss.numpy()[0]) )
-
- # 将误差反向传播
- loss.backward()
- # 优化器进行优化,即优化x1,x2,x3...的值
- opt.step()
- # opt.clear_grad()来重置梯度
- opt.clear_grad()
-
- paddle.save(model.state_dict(),'Regressor') # 保存模型
- draw_train_loss(Batchs,all_train_loss) # 画训练批次和损失的关系图
相关API:
- paddle.nn.MSELoss(reduction='mean')
- 作用:计算预测值和目标值的均方差误差
-
- class paddle.optimizer.SGD(learning_rate=0.001, parameters=None, weight_decay=None,
- grad_clip=None, name=None)
- 随机梯度下降算法的优化器,为网络添加反向计算过程,并根据反向计算所得的梯度,更新 parameters 中的
- Parameters,最小化网络损失值 loss。
- ·learningrate (float|LRScheduler,可选):学习率,用于参数更新的计算。可以是一个浮点型值或者一个
- LRScheduler 类,默认值为 0.001。
- ·parameters (list,可选):指定优化器需要优化的参数。在动态图模式下必须提供该参数;在静态图模式下默
- 认值为 None,这时所有的参数都将被优化。
- ·weight_decay (float|Tensor,可选):权重衰减系数,是一个 float 类型或者 shape 为[1],数据类型为
- float32 的 Tensor 类型。默认值为 0.01。
- ·grad_clip (GradientClipBase,可选) – 梯度裁剪的策略,支持三种裁剪策略:
- paddle.nn.ClipGradByGlobalNorm, paddle.nn.ClipGradByNorm, paddle.nn.ClipGradByValue。
- 默认值为 None,此时将不进行梯度裁剪。
- ·name (str,可选):一般无需设置,默认值为 None。
模型评估:
- #模型评估
- para_state_dict = paddle.load("Regressor")
- model = Regressor()
- model.set_state_dict(para_state_dict) #加载模型参数
- model.eval() #验证模式
-
- losses = []
- infer_results=[]
- groud_truths=[]
-
- for batch_id,data in enumerate(eval_loader()):#测试集
- image=data[0]
- label=data[1]
- groud_truths.extend(label.numpy())
- predict=model(image)
- infer_results.extend(predict.numpy())
- loss=mse_loss(predict,label)
- losses.append(loss.numpy()[0])
- avg_loss = np.mean(losses)
- print("当前模型在验证集上的损失值为:",avg_loss)
线性回归模型就是围绕公式 开展模型搭建,根据已有的数据进行大量训练得到初步的 值和误差 ,接着优化器优化 值使 不断减小,经过多轮循环得到更为合适的 ,从而用已知的公式预测想要得到的数据。