一、安装飞桨
- 官方教程:https://www.paddlepaddle.org.cn/install/quick
博主本人使用的是Windows+pip+Python3+CPU版本
安装过程十分简单,在此不再赘述。
二、使用飞桨重写模型
说明:普通方法实现房价预测模型,在本人的上一篇文章中有详细说明,戳链接即可查看
https://blog.csdn.net/narutodzx/article/details/106319806
-
首先需要导入相关库
# paddle/fluid:飞桨的主库,目前大部分的实用函数均在paddle.fluid包内。 # dygraph:动态图的类库。 import paddle.fluid as fluid import paddle.fluid.dygraph as dygraph from paddle.fluid.dygraph import Linear import numpy as np
-
数据处理
注:
此次数据处理新增了:记录数据的归一化参数,在预测时对数据做归一化。其余部分与上一篇文章相同,详细说明可戳上方链接查看。def load_data(): firstdata = np.fromfile('housing.data', sep=' ') # 添加属性 feature_names = ['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT', 'MEDV'] # 列的长度 feature_num = len(feature_names) # 构造506*14的二维数组 data = firstdata.reshape([firstdata.shape[0] // feature_num, feature_num]) # 训练集设置为总数据的80% ratio = 0.8 offset = int(data.shape[0] * ratio) training_data = data[:offset] # 训练集每列的最大值、最小值、平均值 maximums, minimums, avgs = training_data.max(axis=0), training_data.min(axis=0), training_data.sum(axis=0) / \ training_data.shape[0] # 记录数据的归一化参数,在预测时对数据做归一化 global max_values global min_values global avg_values max_values = maximums min_values = minimums avg_values = avgs # 对所有数据进行归一化处理 for i in range(feature_num): data[:, i] = (data[:, i] - avgs[i]) / (maximums[i] - minimums[i]) # 覆盖上面的训练集 training_data = data[:offset] # 剩下的20%为测试集 test_data = data[offset:] return training_data, test_data
-
模型设计
注:
FC:神经网络的全连接层函数,即包含所有输入权重相加和激活函数的基本神经元结构。在房价预测任务中,使用只有一层的神经网络(全连接层)来实现线性回归模型。class Regressor(fluid.dygraph.Layer): def __init__(self): super(Regressor, self).__init__() # 定义一层全连接层 # 输入维度为13,输出维度为1,不适用激活函数 self.fc = Linear(input_dim=13, output_dim=1, act=None) # 网络的前向计算函数,返回预测结果 def forward(self, inputs): x = self.fc(inputs) return x
-
训练配置
注:
模型实例有两种状态:训练状态 .train() 和预测状态 .eval() 。
训练时要执行正向计算和反向传播梯度两个过程,而预测时只需要执行正向计算。# 定义飞桨动态图的工作环境 with fluid.dygraph.guard(): model = Regressor() # 开启模型训练 model.train() training_data, test_data = load_data() # 定义优化算法,SGD为随机梯度下降法 # 学习率为0.01 opt = fluid.optimizer.SGD(learning_rate=0.01, parameter_list=model.parameters())
-
训练过程
步骤:
数据准备:将一个批次的数据转变成np.array和内置格式。
前向计算:将一个批次的样本数据灌入网络中,计算输出结果。
计算损失函数:以前向计算结果和真实房价作为输入,通过损失函数square_error_cost计算出损失函数值(Loss)。
反向传播:执行梯度反向传播backward函数,即从后到前逐层计算每一层的梯度,并根据设置的优化算法更新参数opt.minimize。
保存模型:将模型当前的参数数据model.state_dict()保存到文件中(通过参数指定保存的文件名 LR_model),以备预测或校验的程序调用。with dygraph.guard(fluid.CPUPlace()): EPOCH_NUM = 10 BATCH_SIZE = 10 # 外层循环 for epoch_id in range(EPOCH_NUM): # 打乱训练数据顺序 np.random.shuffle(training_data) # 拆分数据,每个mini_batches包含10条数据 mini_batches = [training_data[k:k + BATCH_SIZE] for k in range(0, len(training_data), BATCH_SIZE)] # 内层循环 for iter_id, mini_batch in enumerate(mini_batches): x = np.array(mini_batch[:, :-1]).astype('float32') y = np.array(mini_batch[:, -1:]).astype('float32') # 将numpy数据转化为飞桨动态图variable形式 house_features = dygraph.to_variable(x) prices = dygraph.to_variable(y) # 前向计算 predicts = model(house_features) # 计算损失 loss = fluid.layers.square_error_cost(predicts, label=prices) avg_loss = fluid.layers.mean(loss) if iter_id % 20 == 0: print("epoch: {}, iter: {}, loss is: {}".format(epoch_id, iter_id, avg_loss.numpy())) # 反向传播 avg_loss.backward() # 最小化loss,更新参数 opt.minimize(avg_loss) # 清除数据 model.clear_gradients() # 保存模型 fluid.save_dygraph(model.state_dict(), 'LR_model')
-
测试模型
def load_one_example(data_dir): f = open(data_dir, 'r') datas = f.readlines() # 倒数第十条数据 tmp = datas[-10] # 修改数据格式 tmp = tmp.strip().split() # 修改数据类型 one_data = [float(v) for v in tmp] # 归一化处理 for i in range(len(one_data) - 1): one_data[i] = (one_data[i] - avg_values[i]) / (max_values[i] - min_values[i]) # 取one_data的前13个数据,修改矩阵为1行13列,再变化数组类型 # 【2】【3】 data = np.reshape(np.array(one_data[:-1]), [1, -1]).astype(np.float32) # 取one_data的最后一个数据 label = one_data[-1] return data, label with dygraph.guard(): # 载入保存的模型 model_dict, _ = fluid.load_dygraph('LR_model.pdparams') model.load_dict(model_dict) # 调整模型状态 model.eval() # 读取数据 test_data, label = load_one_example('housing.data') # 将数据转化为飞桨动态图variable形式 test_data = dygraph.to_variable(test_data) results = model(test_data) # 对结果进行反归一化处理 results = results * (max_values[-1] - min_values[-1]) + avg_values[-1] print("Inference result is {}, the corresponding label is {}".format(results.numpy(), label))
输出结果:
-
总结
飞桨很大程度的上降低了深度学习的学习成本,深度学习框架对入门者很友好,编写少量的代码即可实现需要的功能。
参考:
【1】https://www.paddlepaddle.org.cn/tutorials/projectdetail/392090
【2】https://blog.csdn.net/ms961516792/article/details/79467002/
【3】https://blog.csdn.net/doufuxixi/article/details/80357444