本章我们将学习利用百度飞桨Paddle2.x实现经典波士顿房价预测模型。

禁止转载,侵权必究!Update2022.02.23

前言

波士顿房价问题是机器学习领域的”HelloWorld”(注:深度学习的”HelloWord”是手写数字识别问题)。波士顿房价问题:给定13个影响房价走势的参数以及收集的数据,请预测房价未来走势?

一、思路

分为6步:

  1. 读取训练&测试数据集
  2. 定义变量、函数、网络、主程序等等
  3. 配置PaddlePaddle框架
  4. 训练
  5. 保存训练好的模型
  6. 输出train_cost,可视化训练过程

二、数据集

#下载数据
wget https://archive.ics.uci.edu/ml/machine-learning-databases/housing/housing.data -O housing.data 

新建python文件view.py,可视化数据集合。

二、编写代码

1. import依赖包

import matplotlib //画图
import matplotlib.pyplot as plt //画图
import paddle //baidu框架
import paddle.fluid as fluid //baidu框架
import numpy as np //线性代数相关库:数组,矩阵等
import os // 保存本地文件相关

2. 读取数据

BUF_SIZE=500
BATCH_SIZE=20
#用于训练的数据提供器,每次从缓存中随机读取批次大小的数据
train_reader = paddle.batch(
    paddle.reader.shuffle(paddle.dataset.uci_housing.train(), 
                          buf_size=BUF_SIZE),                    
    batch_size=BATCH_SIZE)   
#用于测试的数据提供器,每次从缓存中随机读取批次大小的数据
test_reader = paddle.batch(
    paddle.reader.shuffle(paddle.dataset.uci_housing.test(),
                          buf_size=BUF_SIZE),
    batch_size=BATCH_SIZE)  

3. 各种定义

#定义张量变量x,表示13维的特征值
x = fluid.layers.data(name='x', shape=[13], dtype='float32')
#定义张量y,表示目标值
y = fluid.layers.data(name='y', shape=[1], dtype='float32')
#定义一个简单的线性网络,连接输入和输出的全连接层
#input:输入tensor;
#size:该层输出单元的数目
#act:激活函数
y_predict=fluid.layers.fc(input=x,size=1,act=None)

#Loss
#Mean Squared Error, MSE
#均方差损失函数: y-y_predict的平方
cost = fluid.layers.square_error_cost(input=y_predict, label=y) #求一个batch的损失值
avg_cost = fluid.layers.mean(cost)     

#OPT
optimizer = fluid.optimizer.SGDOptimizer(learning_rate=0.001)
opts = optimizer.minimize(avg_cost)

test_program = fluid.default_main_program().clone(for_test=True)

4. 配置PaddlePaddle

use_cuda = False                         #use_cuda为False,表示运算场所为CPU;use_cuda为True,表示运算场所为GPU           
place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()
exe = fluid.Executor(place)              #创建一个Executor实例exe
exe.run(fluid.default_startup_program()) #Executor的run()方法执行startup_program(),进行参数初始化

feeder = fluid.DataFeeder(place=place, feed_list=[x, y])#feed_list:向模型输入的变量表或变量表名

5. 循环训练&测试

for pass_id in range(EPOCH_NUM):                                  
    train_cost = 0
    for batch_id, data in enumerate(train_reader()):              
        train_cost = exe.run(program=fluid.default_main_program(),
                             feed=feeder.feed(data),              
                             fetch_list=[avg_cost])    
        if batch_id % 40 == 0:
            print("Pass:%d, Cost:%0.5f" % (pass_id, train_cost[0][0]))    
        iter=iter+BATCH_SIZE
        iters.append(iter)
        train_costs.append(train_cost[0][0])
   
    # 开始测试并输出最后一个batch的损失值
    test_cost = 0
    for batch_id, data in enumerate(test_reader()):               
        test_cost= exe.run(program=test_program,
                            feed=feeder.feed(data),               
                            fetch_list=[avg_cost])               
    print('Test:%d, Cost:%0.5f' % (pass_id, test_cost[0][0]))     

注意: 不需要在循环里面测试模型,这个例子只是为了简单化

6. 保存训练好的模型

if not os.path.exists(model_save_dir):
    os.makedirs(model_save_dir)
print ('save models to %s' % (model_save_dir))
fluid.io.save_inference_model(model_save_dir,   
                                  ['x'],            
                                  [y_predict],      
                                  exe) 

7. 画图

def draw_train_process(iters,train_costs):
    title="training cost"
    plt.title(title, fontsize=24)
    plt.xlabel("iter", fontsize=14)
    plt.ylabel("cost", fontsize=14)
    matplotlib.use('MacOSX')
    # print(plt.get_backend())
    plt.plot(iters, train_costs,color='red',label='training cost') 
    plt.grid()
    plt.show()

三、运行结果:

train_cost在迭代中逐渐收敛: