Tensorflow2.0学习(六) — 线性回归模型(燃油效率预测)

这一节开始主要讲述Tensorflow官方提供的样例代码,我会对其中一些代码部分进行修改并且详细解释大部分代码的意思,方便初学的朋友们学习。这节课我们要完成的是一个线性回归模型的搭建及Auto MPG数据集的预测,顺便附上官方代码的链接:https://tensorflow.google.cn/tutorials/keras/regression

这一节我们使用的数据集为Auto MPG数据集,我们需要根据该数据集提供的一些相关特征(如气缸数、排量和马力等)搭建一个线性回归模型去预测一种汽车的燃油效率。

一.Auto MPG数据集的加载

1.导入相关库。这里也许有些朋友们不知道第一行future导进一些库的意思,这行代码存在的原因主要是因为python2和python3版本的不同有时候会导致一些库无法兼容使用,如果想在一个python版本使用另一个版本不兼容的函数,就需要导入这行代码。然后seaborn库作用则是用于画图。

from __future__ import absolute_import, division, print_function, unicode_literals
import pathlib
import matplotlib.pyplot as plt
import pandas as pd 
import seaborn as sns #画图
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers

2.auto mpg数据集加载。

dataset_path = keras.utils.get_file("auto-mpg.data", "http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data")

3.为数据集每列数据添加列名。其中MPG为燃油效率,Displacement为排水量,Horsepower为马力,Weight为重量,Acceleration为加速度,Model Year为车型年份,origin代表车型的生产地。

column_names = ['MPG','Cylinders','Displacement','Horsepower','Weight','Acceleration', 'Model Year', 'Origin']

4.读入数据。打开原数据文件我们可以发现里面有一些数据是“?”,代表数据遗失。因此我们可以用na_values='?'将指定的这些数据标名为NAN(未知值),而comment=’\t‘的意思是忽略以"\t"(一个制表符)开头后的行内容,这部分内容不读入,sep=' '的意思是将数据中有空白的部分当作分隔符,用来分割不同列的数据,最后skipinitialspace=True的意思则是忽略分隔符后的空白。

raw_dataset = pd.read_csv(dataset_path, names=column_names,na_values = "?", comment='\t',sep=" ", skipinitialspace=True)

5.显示数据集部分数据集。tail()的意思是显示数据后5行的内容。

dataset = raw_dataset.copy()
dataset.tail()

二.Auto MPG数据集的预处理

1.显示为空值(NAN)的特征类别和数目。

dataset.isna().sum()

2.因为空值数据不多,因此我们直接用dropna()函数删除这些数据。

dataset = dataset.dropna()

3.将origin转换成独热码。pop为移除的意思,同时也可以用变量储存起来。

origin = dataset.pop('Origin') #移除origin特征同时保存成变量
dataset['USA'] = (origin == 1)*1.0 
dataset['Europe'] = (origin == 2)*1.0
dataset['Japan'] = (origin == 3)*1.0
dataset.tail() #显示后5行内容

4.分割训练集和测试集。采用sample函数进行训练集分割,其中frac参数为分割比例,random_state=0意思取得的数据不重复,如果等于1则是代表取得的数据可以重复。接着测试集就是训练集剩下的部分,我们用drop函数移除训练集的部分,剩下的部分自然就是测试集,并用变量保存起来。

train_dataset = dataset.sample(frac=0.8,random_state=0) #分割80%训练集,取不重复的数据
test_dataset = dataset.drop(train_dataset.index) #分割20测试集

5.用seaborn库画图,将指定变量的图画出,diag_kind='kde'为图的设定,若是单变量图(自己和自己比较)则是线性图,若是不同变量比较则为散点图。

sns.pairplot(train_dataset[["MPG", "Cylinders", "Displacement", "Weight"]], diag_kind="kde")

6.我们可以用describe函数来查看数据集更详细的查看一些数据集的参数,这样我们就不用自己调用函数计算了。

train_stats = train_dataset.describe() #查看数据统计的参数值
train_stats.pop("MPG") #删除燃油效率特征,因为是标签
train_stats = train_stats.transpose() #行列转置显示
train_stats

7.因为我们预测是燃油效率,因此需要将MPG(燃油效率)从数据集中取出作为标签。

train_labels = train_dataset.pop('MPG') #从数据集删除并保存成变量作为标签
test_labels = test_dataset.pop('MPG')

8.数据归一化,归一化的作用就不反复再提了,前几节有说到。

def norm(x):
    return (x - train_stats['mean']) / train_stats['std']
normed_train_data = norm(train_dataset) #对训练集进行归一化
normed_test_data = norm(test_dataset) #对测试集进行归一化

9.显示归一化后的数据。

print(normed_train_data)

三.模型建立

1.我们直接模型的层搭建和优化器部分包装成一个函数。这里注意的是层的最后一层不用激活函数,因为我们做的是线性回归预测是具体数值,不是分类概率,输入的特征dim为9,如上图所示有9个特征,优化器使用RMSprop,学习率选择为0.001,损失函数选择为mse(mean-square error   均方误差)。度量的参数为mae(绝对值误差)和mse(均方误差)的loss。

def build_model():
    model = keras.Sequential([
    layers.Dense(64, activation='relu',input_dim=9),
    layers.Dense(64, activation='relu'),
    layers.Dense(1)
  ])

    optimizer = tf.keras.optimizers.RMSprop(0.001) #优化器

    model.compile(loss='mse',                      #模型设置
                optimizer=optimizer,
                metrics=['mae', 'mse'])
    return model

model = build_model()

2.打印模型概要。

model.summary()

3.在未训练前,送入一些数据到模型中预测,看看结果。

example_batch = normed_train_data[:10] #取前10个数据
example_result = model.predict(example_batch) #预测
example_result

四.模型训练

1.训练模型。

history = model.fit(
  normed_train_data, train_labels,
  epochs=1000, validation_split = 0.2, verbose=2)

2.这里我们可以用pandas将训练的记录保存起来,帮助更方便地显示并且我们还可以在上面添加一些其它参数如训练次数等。

hist = pd.DataFrame(history.history)
hist['epoch'] = history.epoch #添加训练次数列
hist.tail() #显示后5行

3.定义训练过程显示函数,将训练过程可视化为图。这里我们不采用官方教程的代码,而是用我们之前几节所写的函数,更简介一些,具体参数意思可参照前几节内容。

def show_train_history(train_history,epoch,train,validation,y_limit):
    plt.plot(epoch,train_history.history[train]) 
    plt.plot(epoch,train_history.history[validation])
    plt.title('Train History')
    plt.xlabel('epoch')
    plt.ylabel(train)
    plt.ylim(y_limit) #限制显示的y的大小
    plt.legend(['train','validation'],loc='upper left')
show_train_history(history,hist['epoch'],'mae','val_mae',[0,5])
show_train_history(history,hist['epoch'],'mse','val_mse',[0,20])

4.从训练数据上看,结果到了后面越来越糟糕,那我是否有办法在训练结果变糟糕之前提取停止训练呢?这边有一个函数为EarlyStopping,意思为提早停止。其中monitor参数为我们要监督的参数,patience为可以忍受结果变坏的训练次数。这里代码的意思就是我们监督val_loss这个值,当它的结果连续变坏10次,我们则就停止训练。之后我们将这个值作为callback传入训练模型中,重新进行训练。

model=build_model()
early_stop = keras.callbacks.EarlyStopping(monitor='val_loss',patience=10) #提早停止训练
history = model.fit(normed_train_data,train_labels,epochs=1000,validation_split=0.2,verbose=2,callbacks=[early_stop]) #模型训练
plot_history(history)

我们可以观察到训练次数在77次就停止了。

五.模型测试和预测

1.模型测试集测试。

loss, mae, mse = model.evaluate(normed_test_data, test_labels, verbose=2) #测试
print("Testing set Mean Abs Error: {:5.2f} MPG".format(mae))

2.模型预测,并画图显示。这里离散图的意思为标签和预测值的偏离,如果我们的预测值和标签相等,则会像图中的直线一样,否则就会偏离这条直线,如其中离散点所示。

test_predictions = model.predict(normed_test_data).flatten() #转一维
plt.scatter(test_labels, test_predictions) #离散图
plt.xlabel('True Values [MPG]')
plt.ylabel('Predictions [MPG]')
plt.axis('equal')
plt.axis('square')
plt.xlim([0,plt.xlim()[1]])
plt.ylim([0,plt.ylim()[1]])
_ = plt.plot([-100, 100], [-100, 100]) #画直线

3.计算标签和预测值的loss差,并用直方图显示,其中bins代表直方图的频数。

error= test_predictions-test_labels
plt.hist(error,bins=25) #直方图显示
plt.xlabel("Prediction Error [MPG]")
_ = plt.ylabel("Count")

 

以上就是本节的内容,这一节我对官方的代码进行了比较详细的解释,相信大家看完之后应该可以更直观的理解源代码的意思了,谢谢你们的观看和支持!

 

 

  • 9
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值