房价预测模型(使用paddlepaddle)
引入的头文件
import paddle
import numpy as np
import os
import paddle.nn as nn
import paddle.nn.functional as F
读取housing的数据集
#数据读取
paddle.dataset.uci_housing.train()
train_data = paddle.dataset.uci_housing.UCI_TRAIN_DATA
paddle.dataset.uci_housing.test()
test_data = paddle.dataset.uci_housing.UCI_TEST_DATA
print(train_data.shape)
print(test_data.shape)
结果为:
(404, 14) (102, 14)
说明:训练数据集有404个,每种数据有14个特征值
测试数据集有102个,每种数据有14个特征值
创建datasets类
# create datasets类
# 三个必须的函数:1.构造函数(初始化工作)2.__getitem__函数(根据index确保数据能被找到并返回这一行数据)3.返回数据集长度
# 不可或缺,定义错误会导致dataloader使用时出错;
class MyDataset(paddle.io.Dataset):
"""
继承paddle.io.Dataset类
"""
def __init__(self, data):
"""
实现构造函数(初始化这个class)
"""
super(MyDataset, self).__init__()
self.data = data
def __getitem__(self, index):
"""
步骤三:实现__getitem__方法,指定index-->返回数据
"""
data = self.data[index]
x_data = data[:-1]
label = data[-1]
return x_data, label
def __len__(self):
"""
步骤四:实现__len__方法,返回数据集长度
"""
return self.data.shape[0]
shape数组一共有两个元素,返回其中第1个元素(数据集的数目)
Datasets定义数据集,核心在于__getitem__,其返回值就是dataloader每次随机可以获得的一个样本
神经网络搭建
## create model structure
# 两个必须的函数:1.构造函数(初始化网络结构)2.forwad函数(定义前向传播过程)
class Mymodel(paddle.nn.Layer):
def __init__(self):
super(Mymodel, self).__init__()
self.linear1 = nn.Linear(13, 1)
def forward(self, inputs):
y = self.linear1(inputs)
return y
创建dataloader类
custom_dataset_train = MyDataset(train_data)
train_loader = paddle.io.DataLoader(custom_dataset_train, batch_size=100, shuffle=True,drop_last=True)
custom_dataset_test = MyDataset(test_data)
test_loader = paddle.io.DataLoader(custom_dataset_test, batch_size=len(test_data), shuffle=False)
lr_model = Mymodel()
optim = paddle.optimizer.Adam(parameters=lr_model.parameters(), learning_rate=0.1)
# 设置损失函数
loss_fn = paddle.nn.MSELoss()
print(len(custom_dataset_train))
print(len(custom_dataset_test))
custom_dataset_train:train_data数据集的长度
dataset:定义的dataset类返回的结果。
batchsize:每个bacth要加载的样本数,默认为1。
shuffle:在每个epoch中对整个数据集data进行shuffle重排,默认为False。
drop_last:当你的整个数据长度不能够整除你的batchsize,选择是否要丢弃最后一个不完整的batch,默认为False。
使用Adam优化器,nn.MSELoss损失函数:
print打印出的结果为404 102
具体的训练过程:
max_epoch = 200
for epoch in range(max_epoch):
lr_model.train()
train_loss = []
for batch_id, data in enumerate(train_loader()):
# pay attention to this dtype
x_data = paddle.to_tensor(data[0].numpy().astype('float32'))
y_data = paddle.to_tensor(data[1],dtype="float32")
optim.clear_grad()
y_hat = lr_model(x_data)
loss = loss_fn(y_hat,y_data)
loss.backward()
optim.step()
train_loss.append(loss.item())
import pdb
# pdb.set_trace()
lr_model.eval()
for batch_id, data in enumerate(test_loader()):
x_data = paddle.to_tensor(data[0].numpy().astype('float32'))
y_data = paddle.to_tensor(data[1],dtype="float32")
y_hat = lr_model(x_data)
loss_test = loss_fn(y_hat,y_data)
train_loss = np.mean(train_loss)
print("epoch:"+str(epoch)+"\t train loss:" + str(round(train_loss,4)) + "\t test loss:" + str(round(loss_test.item(),4)))
enumerate()用于可迭代/可遍历的数据对象组合为一个索引序列。
y_hat:通过x_data预测出来的预测值,通过loss_fn(y_hat,y_data)计算出loss值
clear_grad()的作用是梯度置零,也就是把loss关于weight的导数变成0。如果没有这句话,backward()的时候就会累加梯度。
step()的作用梯度更新,就是说每计算一个batch的数据会更新一次梯度。
backward()的作用是反向传播求解梯度。如果不执行那么梯度也不会发生更新。