深度学习——使用国产深度学习框架“飞桨(PaddlePaddle)”重写房价预测模型

一、安装飞桨

  1. 官方教程:https://www.paddlepaddle.org.cn/install/quick
    博主本人使用的是Windows+pip+Python3+CPU版本
    安装过程十分简单,在此不再赘述。

二、使用飞桨重写模型

说明:普通方法实现房价预测模型,在本人的上一篇文章中有详细说明,戳链接即可查看
https://blog.csdn.net/narutodzx/article/details/106319806

  1. 首先需要导入相关库

    # 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
    
    
  2. 数据处理
    注:
    此次数据处理新增了:记录数据的归一化参数,在预测时对数据做归一化。其余部分与上一篇文章相同,详细说明可戳上方链接查看。

    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
    
  3. 模型设计
    注:
    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
    
  4. 训练配置
    注:
    模型实例有两种状态:训练状态 .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())
    
    
  5. 训练过程
    步骤:
    数据准备:将一个批次的数据转变成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')
    
  6. 测试模型

    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))
    
    

    输出结果:
    深度学习——使用国产深度学习框架“飞桨(PaddlePaddle)”重写房价预测模型_第1张图片

  7. 总结
    飞桨很大程度的上降低了深度学习的学习成本,深度学习框架对入门者很友好,编写少量的代码即可实现需要的功能。

参考:

【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

你可能感兴趣的:(深度学习)