1.Runner类
一个任务应用机器学习方法流程:
数据集构建
模型构建
损失函数定义
优化器
模型训练
模型评价
模型预测
所以根据以上,我们把机器学习模型基本要素封装成一个Runner类(加上模型保存、模型加载等功能。)
Runner类的成员函数定义如下:
- __init__函数:实例化Runner类时默认调用,需要传入模型、损失函数、优化器和评价指标等;
- train函数:完成模型训练,指定模型训练需要的训练集和验证集;
- evaluate函数:通过对训练好的模型进行评价,在验证集或测试集上查看模型训练效果;
- predict函数:选取一条数据对训练好的模型进行预测;
- save_model函数:模型在训练过程和训练结束后需要进行保存;
- load_model函数:调用加载之前保存的模型。
python
class Runner(object):
def __init__(self, model, optimizer, loss_fn, metric):
self.model = model # 模型
self.optimizer = optimizer # 优化器
self.loss_fn = loss_fn # 损失函数
self.metric = metric # 评估指标
# 模型训练
def train(self, train_dataset, dev_dataset=None, **kwargs):
pass
# 模型评价
def evaluate(self, data_set, **kwargs):
pass
# 模型预测
def predict(self, x, **kwargs):
pass
# 模型保存
def save_model(self, save_path):
pass
# 模型加载
def load_model(self, model_path):
pass
1.2Runner类流程
①初始化:传入模型、损失函数、优化器和评价指标
②训练:基于训练集调用train()
函数训练模型,基于验证集通过evaluate()
函数验证模型。通过save_model()
函数保存模型
③评价:基于测试集通过evaluate()
函数得到指标性能。
④预测:给定样本,通过predict()
函数得到该样本标签

2.案例:波士顿房价预测
波士顿房价预测基于线性回归模型和Runner类实现
2.1数据处理
2.1.1构建
开源库pandas导入。
python
import pandas as pd # 开源数据分析和操作工具
# 利用pandas加载波士顿房价的数据集
data=pd.read_csv("/home/aistudio/work/boston_house_prices.csv")
# 预览前5行数据
data.head()
2.1.2数据集划分
训练集 和 测试集。
python
import paddle
paddle.seed(10)
# 划分训练集和测试集
def train_test_split(X, y, train_percent=0.8):
n = len(X)
shuffled_indices = paddle.randperm(n) # 返回一个数值在0到n-1、随机排列的1-D Tensor
train_set_size = int(n*train_percent)
train_indices = shuffled_indices[:train_set_size]
test_indices = shuffled_indices[train_set_size:]
X = X.values
y = y.values
X_train=X[train_indices]
y_train = y[train_indices]
X_test = X[test_indices]
y_test = y[test_indices]
return X_train, X_test, y_train, y_test
X = data.drop(['MEDV'], axis=1)
y = data['MEDV']
X_train, X_test, y_train, y_test = train_test_split(X,y)# X_train每一行是个样本,shape[N,D]
2.1.3特征化工程
避免数据之间的可比性:对特征数据进行归一化处理,将数据缩放到[0, 1]区间
python
import paddle
X_train = paddle.to_tensor(X_train,dtype='float32')
X_test = paddle.to_tensor(X_test,dtype='float32')
y_train = paddle.to_tensor(y_train,dtype='float32')
y_test = paddle.to_tensor(y_test,dtype='float32')
X_min = paddle.min(X_train,axis=0)
X_max = paddle.max(X_train,axis=0)
X_train = (X_train-X_min)/(X_max-X_min)
X_test = (X_test-X_min)/(X_max-X_min)
# 训练集构造
train_dataset=(X_train,y_train)
# 测试集构造
test_dataset=(X_test,y_test)
2.2模型构建
python
rom nndl.op import Linear
# 模型实例化
input_size = 12
model=Linear(input_size)
2.3完善Runner类
测试集上使用MSE对模型性能进行评估。本案例利用飞桨框架提供的MSELoss API实现
python
import paddle
import os
from nndl.opitimizer import optimizer_lsm
class Runner(object):
def __init__(self, model, optimizer, loss_fn, metric):
# 优化器和损失函数为None,不再关注
# 模型
self.model=model
# 评估指标
self.metric = metric
# 优化器
self.optimizer = optimizer
def train(self,dataset,reg_lambda,model_dir):
X,y = dataset
self.optimizer(self.model,X,y,reg_lambda)
# 保存模型
self.save_model(model_dir)
def evaluate(self, dataset, **kwargs):
X,y = dataset
y_pred = self.model(X)
result = self.metric(y_pred, y)
return result
def predict(self, X, **kwargs):
return self.model(X)
def save_model(self, model_dir):
if not os.path.exists(model_dir):
os.makedirs(model_dir)
params_saved_path = os.path.join(model_dir,'params.pdtensor')
paddle.save(model.params,params_saved_path)
def load_model(self, model_dir):
params_saved_path = os.path.join(model_dir,'params.pdtensor')
self.model.params=paddle.load(params_saved_path)
optimizer = optimizer_lsm
# 实例化Runner
runner = Runner(model, optimizer=optimizer,loss_fn=None, metric=mse_loss)
2.4模型训练
组装完成Runner
之后,我们将开始进行模型训练、评估和测试
python
# 模型保存文件夹
saved_dir = '/home/aistudio/work/models'
# 启动训练
runner.train(train_dataset,reg_lambda=0,model_dir=saved_dir)
columns_list = data.columns.to_list()
weights = runner.model.params['w'].tolist()
b = runner.model.params['b'].item()
for i in range(len(weights)):
print(columns_list[i],"weight:",weights[i])
print("b:",b)
2.5模型测试
加载训练好的模型参数,在测试集上得到模型的MSE指标
python
# 加载模型权重
runner.load_model(saved_dir)
mse = runner.evaluate(test_dataset)
print('MSE:', mse.item())
2.6模型预测
load_model
函数加载保存好的模型,使用predict
进行模型预测
python
runner.load_model(saved_dir)
pred = runner.predict(X_test[:1])
print("真实房价:",y_test[:1].item())
print("预测的房价:",pred.item())
真实房价: 33.099998474121094 预测的房价: 33.04654312133789