Tensorflow回归入门实践-预测70年代末到80年代初汽车燃油效率的模型(详解,提供数据集)

本文主要是介绍Tensorflow回归入门实践-预测70年代末到80年代初汽车燃油效率的模型(详解,提供数据集),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章较长,可以跳转查看需要的部分

  • 回归的目的
  • 数据集(提供网盘下载)
    • 网盘下载(如果无法直接下载数据集)
  • 基本实现结构的分析(数据部分)
    • 首先引入需要的模块or包
    • 获取数据集(本地数据集读取)
    • 设置数据标签
      • 补充data文件类型:
    • 使用panda读取数据集
    • 对数据进行处理(一)
    • 对数据进行处理(二)
    • 对数据进行处理(三)
    • 数据归一化
  • 模型分析
    • 模型构建
    • 模型检测
    • 数据拟合
  • 训练结果数据展示(建议使用jupyter notebook)
    • 模型日志的查看
    • 模型训练的日志信息-可视化
      • 创建绘图函数
      • 可视化展示(发现训练多了反而出问题了——过拟合)
  • 模型改进
  • 模型评估
  • 使用完整的测试数据预测(最后阶段可视化)
    • 预测MPG的数据可视化
    • 误差分布可视化
  • 总结

                         QQ:3020889729                                                                                 小蔡

这是一个学习例程的学习分享,希望对tensorflow的学习和理解有所帮助,当然还有API-keras本身的认识提升。
(本博客提供数据集下载(备份),是因为原官方数据集在下载时,出现链接超时的失败问题。)
(建议使用jupyter notebook)
(文章较长,还望根据需要合适的阅读——有效利用学习时间。)

回归的目的

与其说什么是回归来促进理解,我觉得了解回归的目的是什么会更有效。
回归是为了,预测出如价格或概率以及某种这样连续值/信息的输出。
比如,我给一段连续时间的食品销售量,然后在相同的条件下去预估接下来一段时间或下一次可能的结果。(这和我们上学时,接触的数学回归问题,得到一个回归方程展示其在具体问题中的实际意义是一样的。)
与分类相比,它的目的是为了预测下一段时间/空间最可能出现的结果,不同于分类需要具体的图像或者感知才进行预测是什么。

数据集(提供网盘下载)

本次使用的数据集是Auto MPG数据集——我们将利用它来构建一个用于预测70年代末到80年代初汽车燃油效率的模型。

该数据集包含信息:气缸数,排量,马力以及重量

网盘下载(如果无法直接下载数据集)

数据集下载:https://pan.baidu.com/s/13fCzCHk3Myhdv0X70QL0Fw
提取码:bnoz

基本实现结构的分析(数据部分)

首先引入需要的模块or包

  • import pathlib # 引入文件路径操作的模块
  • import pandas as pd # 引入panda科学数据处理包
  • import seaborn as sns # 引入seaborn——绘图包,在pycharm中使用,需要调用pyplot的show()
  • import matplotlib.pyplot as plt # 标准绘图包
  • import tensorflow as tf # 引入tensorflow包
  • from tensorflow import keras # 引用tf包下的keras——这就是我们将用使用的高级API
  • from tensorflow.keras import layers # 引出layers模块,这是网络层相关的模块

关于下载包/模块,需要说明几点(这里默认下载好了tensorflow):

  1. pathlib无需下载——内置
  2. seaborn需要下载,最好用pip,conda可能会有问题
  3. keras可能在一开始下载tensorflow后没有,那你需要单独下载keras——如果是2.0.0及以上的tensroflow只需要安装比较新的keras即可(也就是直接pip)。

代码:

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

获取数据集(本地数据集读取)

无论是否是去Auto MPG下载的数据集,都还是调用以下方法加载数据集本地路径:

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

如果是通过网盘下载的数据集,我们都需要将数据集放在C盘的user文件夹下的.keras文件夹里的datasets下:即:C->user(也就是用户根目录)->.keras->datasets
如果没有文件就user目录下,创建对应的文件,然后存放数据集。

代码:

dataset_path = keras.utils.get_file("auto-mpg.data", "http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data")
dataset_path  # 可查看数据——jupyter notebook可直接显示,pycharm需要print

效果:(我已经下载放在指定目录,所以没有下载步骤的显示)
在这里插入图片描述

设置数据标签

由于读取的数据是是一个data文件,本身就类似于表格,所以我们需要为其读取前,设置好对应的列名-标签。

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

数据标签含义:

  • MPG:每加仑燃料所行英里数
  • Cylinders:气缸数
  • Displacement:排量
  • Horsepower:马力
  • Weight:重量
  • Acceleration:加速能力
  • Model Year:车型年份——即生产(研发)年份
  • Origin:产源地

代码:

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

补充data文件类型:

DataFrame是Pandas中的一个表格型的数据结构,包含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔型等),DataFrame即有行索引也有列索引,可以被看做是由Series组成的字典。

使用panda读取数据集

需要说明以下主要参数:依次为路径,索引名,空(无效)值设置,指定注释行,分隔符,是否考虑为False的数据

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

参数含义对应展示:

  1. dataset_path——读取路径
  2. names——数据读取后的列索引名
  3. na_values——空(无效)值设置,这里设置为?
  4. comment——指定‘\t’对应的行为注释行,不读取
  5. sep——数据分隔符
  6. skipinitialspace——是否考虑为False的数据,即数据中存在False的bool值是被允许的

代码:

raw_dataset = pd.read_csv(dataset_path, names=column_names,na_values = "?", comment='\t',sep=" ", skipinitialspace=True)dataset = raw_dataset.copy()  # 复制读取的数据,避免修改元数据
dataset.tail()  # 显示表格数据——jupyter自显,pycharm需要print

效果:
在这里插入图片描述

对数据进行处理(一)

主要是删除无效值和数据分类操作

  1. 数据清洗——首先是无效数据查看:isna()会返回为包含无效值的表单,再追加一个sum()实现计算无效值的和;其次,对无效数据进行处理:dropna()清除无效数据后返回一个新数据表单。
  2. 将需要的产源地分类序号从表中提取出来,使用pop(‘Origin’)提取Origin列的数据
  3. 将Origin进行one-hot转换——即Origin不同的值仅对应一个数据有效:
  4. dataset['USA'] = (origin == 1)*1.0
  5. dataset['Europe'] = (origin == 2)*1.0
  6. dataset['Japan'] = (origin == 3)*1.0——如此,仅当对应的标号时,某一列中的数据才为1,满足one-hot定义:[0,0,1,0,0……1,0],只有有效数据为1,其余为零。

代码:

dataset.isna().sum()  # 显示无效数据分布情况

效果:
在这里插入图片描述

dataset = dataset.dropna()  # 移除无效数据

效果:
在这里插入图片描述

origin = dataset.pop('Origin')  # 获取分类序号——以供one-hot转换需要

效果:
在这里插入图片描述

dataset['USA'] = (origin == 1)*1.0  
# one-hot转换:只有当列数据中值为1时,才设为1,否则为0,也就相当于一整列数据按 (origin == 1)条件转换为1 or 0dataset['Europe'] = (origin == 2)*1.0
dataset['Japan'] = (origin == 3)*1.0
dataset.tail()  # 显示表格数据

效果:
在这里插入图片描述

对数据进行处理(二)

主要是拆分数据集和获取数据状况分析信息

  1. 采用sample(frac=0.8,random_state=0)——随机拆分80%的panda的DataFrame数据作为训练集
  2. 采用drop(train_dataset.index)——移除已经取出的数据下标包含的数据并返回。
  3. describe()用于观察一系列数据的范围,大小、波动趋势等等。(会存到train_stats)
  4. 补充说明,描述信息需要pop(‘MPG’)——因为这是我们需要单独处理的数据。

代码:

train_dataset = dataset.sample(frac=0.8,random_state=0)  # 拆分获得训练数据
test_dataset = dataset.drop(train_dataset.index)  # 拆分获得测试数据

效果:
在这里插入图片描述
在这里插入图片描述

train_stats = train_dataset.describe()  # 获取数据的一系列描述信息
train_stats.pop("MPG")  # 移除MPG的数据列
train_stats = train_stats.transpose()  # 行列转换——也就是相当于翻转
train_stats  # 显示描述信息——jupyter自显

效果:
在这里插入图片描述

对数据进行处理(三)

主要是分离训练数据的标签——从获得的数据中。

  1. 同样采用pop(‘MPG’)——获取指定列的数据

代码:

train_labels = train_dataset.pop('MPG')   # 将移除的MPG列数据返回,赋值给train_labels 
test_labels = test_dataset.pop('MPG')
train_labels   # 显示数据
test_labels 

效果:
在这里插入图片描述
在这里插入图片描述

数据归一化

在这次的数据中,虽然说只是一些简单数据的分析,但是数据归一化,特征归一化还是很有必要的。这样有助于数据收敛,得到更好的训练结果。
采用的计算方式如下:x为需要归一化的数据,train_stats为当前表格的描述信息——通过以下运算就实现了归一化。(0 or 1)

(x - train_stats['mean']) / train_stats['std']

这样获得的归一化数据,应该是被保留下来用与后边的其它运算。

代码:
(采用函数,方便多次调用,避免公式重复导致可读性,降低人为失误)

def norm(x):return (x - train_stats['mean']) / train_stats['std']
normed_train_data = norm(train_dataset)  # 获取训练数据中的归一化数据
normed_test_data = norm(test_dataset)  # 获取测试归一化数据

效果:
在这里插入图片描述
在这里插入图片描述

模型分析

模型构建

本模型采用线性模型——包含两个紧密相连的隐藏层,以及返回单个、连续值得输出层。
为了代码结构,采用函数式编程:执行模型——网络层结构创建,以及模型编译。

# 第一层Dense的input_shape为输入层大小,前边的64为该全连接层的输出层(隐藏层)——只有最后的全连接层 layers.Dense(1)输出才是输出层,否则为隐藏层。
# activation为激活函数——这里是线性激活
def build_model():model = keras.Sequential([layers.Dense(64, activation='relu', input_shape=[len(train_dataset.keys())]),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()  # 创建一个模型
model.summary()  # 展示模型结构

效果:
在这里插入图片描述

模型检测

采用上边创建好的模型进行预测——查看效果。

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

效果:(看起来似乎它已经可以用来直接使用了,但其实这还不够,我们一定记得要进行拟合数据才算是一个完整的学习模型的构建完全。)
在这里插入图片描述

数据拟合

在这里添加一个输出点的函数——目的是显示训练的进程(提示:本次训练拟合周期(次数)为1000,你也可以进行更多的尝试)

# 通过为每个完成的时期打印一个点来显示训练进度
class PrintDot(keras.callbacks.Callback):def on_epoch_end(self, epoch, logs):if epoch % 100 == 0: print('')print('.', end='')
EPOCHS = 1000  # 拟合次数# 返回的history为一个对象,内包含loss信息等
history = model.fit(normed_train_data, train_labels,epochs=EPOCHS, validation_split = 0.2, verbose=0,callbacks=[PrintDot()])

拟合fit函数的参数依次为:

  1. 训练所需的归一化数据,训练数据对应的标签;
  2. 拟合次数
  3. validation_split用于在没有提供验正集的时候,按一定比例从训练集中取出一部分作为验证集
  4. 日志显示配置:verbose = 0 为不在标准输出流输出日志信息
    verbose = 1 为输出进度条记录
    verbose = 2 为每个epoch输出一行记录
    注意: 默认为 1
  5. callbacks——简单的说就是提供训练中的操作

效果:
在这里插入图片描述

训练结果数据展示(建议使用jupyter notebook)

模型日志的查看

hist = pd.DataFrame(history.history)  # 返回一个DataFrame对象,包含history的history数据
hist['epoch'] = history.epoch  # 末尾添加一列数据包含epoch信息
hist.tail()  # 展示表单数据

效果:
在这里插入图片描述
在这里插入图片描述

模型训练的日志信息-可视化

创建绘图函数

def plot_history(history):hist = pd.DataFrame(history.history)hist['epoch'] = history.epochplt.figure()  # 创建新窗口plt.xlabel('Epoch')  # x轴标签(名字)plt.ylabel('Mean Abs Error [MPG]')  # y轴标签(名字)plt.plot(hist['epoch'], hist['mae'],label='Train Error')  # 绘图,label为图例plt.plot(hist['epoch'], hist['val_mae'],label = 'Val Error')  # 绘图,label为图例plt.ylim([0,5])  # y轴长度限制plt.legend()  # 展示图例plt.figure()plt.xlabel('Epoch')plt.ylabel('Mean Square Error [$MPG^2$]')plt.plot(hist['epoch'], hist['mse'],label='Train Error')plt.plot(hist['epoch'], hist['val_mse'],label = 'Val Error')plt.ylim([0,20])plt.legend()plt.show()  # 必须要有show才能显示绘图

可视化展示(发现训练多了反而出问题了——过拟合)

有一个问题:也许你的图形不一样,这可能是数据训练和机器相关。
在这里插入图片描述

模型改进

以下模型改进——在jupyter notebook中可以直接进行,而使用pycharm的朋友需要在原来的位置进行替换(early_stop添加在原fit前)

model = build_model()  # 重新定义模型# patience 值用来检查改进 epochs 的数量
# 定义callbacks的操作设置,这里采用了每10次fit,进行一次判断是否停下,判断依据是当val_loss不改变甚至降低。
early_stop = keras.callbacks.EarlyStopping(monitor='val_loss', patience=10)  history = model.fit(normed_train_data, train_labels, epochs=EPOCHS,validation_split = 0.2, verbose=0, callbacks=[early_stop, PrintDot()])plot_history(history)

效果:看得出,模型有效准确值稳定在了一定范围后,训练就停止了。
在这里插入图片描述

模型评估

loss, mae, mse = model.evaluate(normed_test_data, test_labels, verbose=2)  # 返回第一个数据loss为损失值
print("Testing set Mean Abs Error: {:5.2f} MPG".format(mae))  # mae为我们构建网络归回预测的值——即预测的MPG

打印结果:说明MPG稳定在2.00左右
在这里插入图片描述

使用完整的测试数据预测(最后阶段可视化)

预测MPG的数据可视化

test_predictions = model.predict(normed_test_data).flatten()  
# 预测信息会被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])  # 画一条y = x的直线,方便分析

效果:(MPG数据基本集中于该直线)
在这里插入图片描述

误差分布可视化

error = test_predictions - test_labels  # test_labels 是原始的MPG值序列,所以相减得到误差。
plt.hist(error, bins = 25)  # 画矩形图——bins表示每次绘图的最大矩形数目
plt.xlabel("Prediction Error [MPG]")
_ = plt.ylabel("Count")

效果误差主要分布在-2~2之间,0最多。说明训练模型较为合适。
在这里插入图片描述

总结

  1. 常见的回归指标是平均绝对误差(MAE)。
  2. 均方误差(MSE)是用于回归问题的常见损失函数(分类问题中使用不同的损失函数)。
  3. 当数字输入数据特征的值存在不同范围时,每个特征应独立缩放到相同范围。(归一化,一般采用one-hot编码形式)
  4. 早期停止是一种防止过度拟合的有效技术。

这篇入门讲解到这里就全部结束了。也许我的文章写得不是很好,还有点长长的——希望对阅读到这里的你有所帮助。

如果对函数参数,或者函数方法有疑惑,需要解答的,可以评论,我尽量回答。如果有需要,我后边可以补写一篇关于这部分参数和函数的讲解。(因为这篇文章实在有点太长了。)

这篇关于Tensorflow回归入门实践-预测70年代末到80年代初汽车燃油效率的模型(详解,提供数据集)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/369959

相关文章

一份LLM资源清单围观技术大佬的日常;手把手教你在美国搭建「百万卡」AI数据中心;为啥大模型做不好简单的数学计算? | ShowMeAI日报

👀日报&周刊合集 | 🎡ShowMeAI官网 | 🧡 点赞关注评论拜托啦! 1. 为啥大模型做不好简单的数学计算?从大模型高考数学成绩不及格说起 司南评测体系 OpenCompass 选取 7 个大模型 (6 个开源模型+ GPT-4o),组织参与了 2024 年高考「新课标I卷」的语文、数学、英语考试,然后由经验丰富的判卷老师评判得分。 结果如上图所

C++必修:模版的入门到实践

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:C++学习 贝蒂的主页:Betty’s blog 1. 泛型编程 首先让我们来思考一个问题,如何实现一个交换函数? void swap(int& x, int& y){int tmp = x;x = y;y = tmp;} 相信大家很快就能写出上面这段代码,但是如果要求这个交换函数支持字符型

零基础STM32单片机编程入门(一)初识STM32单片机

文章目录 一.概要二.单片机型号命名规则三.STM32F103系统架构四.STM32F103C8T6单片机启动流程五.STM32F103C8T6单片机主要外设资源六.编程过程中芯片数据手册的作用1.单片机外设资源情况2.STM32单片机内部框图3.STM32单片机管脚图4.STM32单片机每个管脚可配功能5.单片机功耗数据6.FALSH编程时间,擦写次数7.I/O高低电平电压表格8.外设接口

十四、观察者模式与访问者模式详解

21.观察者模式 21.1.课程目标 1、 掌握观察者模式和访问者模式的应用场景。 2、 掌握观察者模式在具体业务场景中的应用。 3、 了解访问者模式的双分派。 4、 观察者模式和访问者模式的优、缺点。 21.2.内容定位 1、 有 Swing开发经验的人群更容易理解观察者模式。 2、 访问者模式被称为最复杂的设计模式。 21.3.观察者模式 观 察 者 模 式 ( Obser

大语言模型(LLMs)能够进行推理和规划吗?

大语言模型(LLMs),基本上是经过强化训练的 n-gram 模型,它们在网络规模的语言语料库(实际上,可以说是我们文明的知识库)上进行了训练,展现出了一种超乎预期的语言行为,引发了我们的广泛关注。从训练和操作的角度来看,LLMs 可以被认为是一种巨大的、非真实的记忆库,相当于为我们所有人提供了一个外部的系统 1(见图 1)。然而,它们表面上的多功能性让许多研究者好奇,这些模型是否也能在通常需要系

【操作系统】信号Signal超详解|捕捉函数

🔥博客主页: 我要成为C++领域大神🎥系列专栏:【C++核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞👍收藏⭐评论✍️ 本博客致力于知识分享,与更多的人进行学习交流 ​ 如何触发信号 信号是Linux下的经典技术,一般操作系统利用信号杀死违规进程,典型进程干预手段,信号除了杀死进程外也可以挂起进程 kill -l 查看系统支持的信号

ps基础入门

1.基础      1.1新建文件      1.2创建指定形状      1.4移动工具          1.41移动画布中的任意元素          1.42移动画布          1.43修改画布大小          1.44修改图像大小      1.5框选工具      1.6矩形工具      1.7图层          1.71图层颜色修改          1

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测 目录 时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测基本介绍程序设计参考资料 基本介绍 MATLAB实现LSTM时间序列未来多步预测-递归预测。LSTM是一种含有LSTM区块(blocks)或其他的一种类神经网络,文献或其他资料中LSTM区块可能被描述成智能网络单元,因为

C++入门01

1、.h和.cpp 源文件 (.cpp)源文件是C++程序的实际实现代码文件,其中包含了具体的函数和类的定义、实现以及其他相关的代码。主要特点如下:实现代码: 源文件中包含了函数、类的具体实现代码,用于实现程序的功能。编译单元: 源文件通常是一个编译单元,即单独编译的基本单位。每个源文件都会经过编译器的处理,生成对应的目标文件。包含头文件: 源文件可以通过#include指令引入头文件,以使

亮相WOT全球技术创新大会,揭秘火山引擎边缘容器技术在泛CDN场景的应用与实践

2024年6月21日-22日,51CTO“WOT全球技术创新大会2024”在北京举办。火山引擎边缘计算架构师李志明受邀参与,以“边缘容器技术在泛CDN场景的应用和实践”为主题,与多位行业资深专家,共同探讨泛CDN行业技术架构以及云原生与边缘计算的发展和展望。 火山引擎边缘计算架构师李志明表示:为更好地解决传统泛CDN类业务运行中的问题,火山引擎边缘容器团队参考行业做法,结合实践经验,打造火山