Python基于Tensorflow2.X实现汽车油耗预测
作者:嘟粥yyds 发布时间:2021-05-05 05:25:22
一、开发环境
集成开发工具:jupyter notebook 6.5.2
集成开发环境:Python 3.10.6
第三方库:tensorflow-gpu、numpy、matplotlib.pyplot、pandas
二 、代码实现
2.1 准备操作
2.1.1 导入所需模块
tensorflow若非GPU版本也可
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers, datasets, losses
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
2.1.2 matplotlib无法正常显示中文的解决方案(若无此情况可跳过)
博主由于已在matplotlib的配置文件中做了一系列修改,故可以正常显示中文,若出现无法正常显示中文的情况有以下两种解决方案:
1、在导入模块后加上下列两行代码(每次需要正常显示中文时都需要加):
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
2、在matplotlib的源文件中做了一系列修改(一劳永逸)
运行下列代码
import matplotlib
print(matplotlib.matplotlib_fname())
会输出配置文件路径,如:(进入python配置目录因人而异,只需从\LocalCache之后开始关注)
C:\Users\31600\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\matplotlib\mpl-data\matplotlibrc
打开此文件,找到#font.family:和#font.sans-serif:开头的这两行,将两行的注释#去掉,并在font.sans-serif:后添加自己想加入的中文字体名,如:(博主选用的打开方式为visual studio2017,不同的打开方式显示可能略有不同另博主打开演示前已完成去注释操作)
最后保存文件,重新运行python环境即可,不必在代码中做出任何修改。
2.2 加载数据集
# 在线下载汽车效能数据集
dataset_path = keras.utils.get_file("auto-mpg.data",
"http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data")
# 字段有效能(公里数每加仑) 气缸数 排量 马力 重量 加速度 型号年份 产地
column_names = ['MPG','Cylinders','Displacement','Horsepower','Weight',
'Acceleration', 'Model Year', 'Origin']
raw_dataset = pd.read_csv(dataset_path, names=column_names,
na_values = "?", comment='\t',
sep=" ", skipinitialspace=True)
各字段含义
dataset = raw_dataset.copy()
# 查看部分数据
dataset.head(8)
2.3 数据处理
2.3.1 数据清洗
原始数据可能含有空字段(缺失值)的数据项
isna()会返回为包含无效值的表单,再追加一个sum()实现计算无效值的和;其次,对无效数据进行处理;dropna()清除无效数据后返回一个新数据表单;
begin = dataset.isna().sum() # 统计空白数据
dataset = dataset.dropna() # 删除空白数据项
end = dataset.isna().sum() # 再次统计空白数据
print(f'========统计前:========\n{begin}\n========统计后:========\n{end}')
# 输出结果:
========统计前:========
MPG 0
Cylinders 0
Displacement 0
Horsepower 6
Weight 0
Acceleration 0
Model Year 0
Origin 0
dtype: int64
========统计后:========
MPG 0
Cylinders 0
Displacement 0
Horsepower 0
Weight 0
Acceleration 0
Model Year 0
Origin 0
dtype: int64
2.3.2 数据转换
由于Origin字段为类型数据,我们将其移除,并转换为新的3个字段:USA、Europe和Japan。(原数据里分别对应1、2、3)
将需要的产源地分类序号从表中提取出来,使用pop(‘Origin’)提取Origin列的数据,将Origin进行one-hot转换——即Origin不同的值仅对应一个数据有效;
# 先弹出(删除并返回)Origin这一列
origin = dataset.pop('Origin')
# 根据origin列的数据来写入新的3个列
dataset['USA'] = (origin == 1) * 1.0
dataset['Europe'] = (origin == 2) * 1.0
dataset['Japan'] = (origin == 3) * 1.0
dataset.tail()
转换后的数据为:
2.3.3 数据集划分
利用sample()函数将数据集拆分为0.8的数据集和0.2的测试集,并且移除已经取出的数据下标包含的数据并返回作为测试集
# 切分为训练集和测试集
train_dataset = dataset.sample(frac=0.8, random_state=0)
test_dataset = dataset.drop(train_dataset.index)
describe()用于观察一系列数据的范围,统计训练集的各个字段数值的均值和标准差,大小、波动趋势等。从获得的数据中获得训练数据的标签,即移除的MPG列数据
# 查看训练集的输入x的统计数据
train_stats = train_dataset.describe()
train_stats = train_stats.transpose() # 转置
train_stats
2.3.4 真实值设定
将MPG字段移除为标签数据
# 移动MPG油耗效能这一列为真实标签Y
train_labels = train_dataset.pop('MPG')
test_labels = test_dataset.pop('MPG')
2.3.5 标准化数据
统计训练集的各个字段数值的均值和标准差,并完成数据的标准化
# 标准化数据
def norm(x):
# 减去每个字段的均值并除以标准差
return (x - train_stats['mean']) / train_stats['std']
normed_train_data = norm(train_dataset) # 标准化训练集
normed_test_data = norm(test_dataset) # 标准化测试集
print(f'训练集大小:{normed_train_data.shape} {train_labels.shape}')
print(f"测试集大小:{normed_test_data.shape} {test_labels.shape}")
normed_train_data # 查看数据处理后的训练集
# 利用切分的训练集构建数据集对象
train_db = tf.data.Dataset.from_tensor_slices((normed_train_data.values, train_labels.values)) # 构建Dataset对象
# 为防止数据标准化后出现梯度弥散,切分训练集,分为几个batch,加速计算
train_db = train_db.shuffle(100).batch(32) # 随机打散,批量化
# 输出结果:
训练集大小:(314, 9) (314,)
测试集大小:(78, 9) (78,)
2.3.6 查看各字段对MPG的影响
# 创建同y轴的上下三联图,需要plt.subplots()
fig, axes = plt.subplots(nrows=1,ncols=3,sharey=True,figsize=(20,6))
fig.suptitle('各个字段对MPG的影响', fontsize=16)
#subplot1
axes[0].scatter(train_dataset['Cylinders'].to_numpy(), train_labels.to_numpy(), color='b',s=20)
axes[0].set_xlabel('Cylinders', fontsize=13)
axes[0].set_ylabel('MPG', fontsize=14)
#subplot2
axes[1].scatter(train_dataset['Displacement'].to_numpy(), train_labels.to_numpy(), color='b',s=20)
axes[1].set_xlabel('Displacement', fontsize=13)
#subplot3
axes[2].scatter(train_dataset['Weight'].to_numpy(), train_labels.to_numpy(), color='b',s=20)
axes[2].set_xlabel('Weight', fontsize=13)
#展示图片
plt.show()
2.4 创建网络
因为该数据集比较小,我们只创建一个3层的全连接网络来完成MPG值的预测任务。 我们将网络实现为一个自定义网络类,只需要在初始化函数中创建各个子网络层,并在前向计算函数 call 中实现自定义网络类的计算逻辑即可。自定义网络类继承自 keras.Model 基类,这也是自定义网络类的标准写法,以方便地利用 keras.Model 基类提供 的 trainable_variables、save_weights 等各种便捷功能。
class Network(keras.Model):
# 回归网络模型
def __init__(self):
super(Network, self).__init__()
# 创建3个全连接层
self.fc1 = layers.Dense(64, activation='relu', name='Layer1')
self.fc2 = layers.Dense(64, activation='relu', name='Layer2')
self.fc3 = layers.Dense(1, name='OutputLayer')
def call(self, inputs, training=None, mask=None):
# 依次通过3个全连接层
x = self.fc1(inputs)
x = self.fc2(x)
x = self.fc3(x)
return x
2.5 训练与测试
在训练网络时,一般的流程是通过前向计算获得网络的输出值, 再通过损失函数计算网络误差,然后通过自动求导工具计算梯度并更新,同时间隔性地测试网络的性能。
所以,在完成网络模型的搭建后,需要指定网络使用的优化器对象、 损失函数类型, 评价指标等设定,这一步称为装配。这里只指定网络使用的优化器对象,损失函数在梯度求导时在指定
# 创建网络类实例
model = Network()
# 通过build函数完成内部张量的创建(其中4为任意设置的batch量,9为输入特征长度)
model.build(input_shape=(4, 9))
# 打印网络信息
model.summary()
# 创建优化器,指定学习率为0.001
optimizers = tf.keras.optimizers.RMSprop(0.001)
# 接下来实现网络训练部分。通过 Epoch 和 Step 组成的双层循环训练网络,共训练 200 个 Epoch
Epoch = np.arange(0, 200)
train_MAE = np.zeros(200)
test_MAE = np.zeros(200)
for epoch in range(200):
for step, (x, y) in enumerate(train_db): # 遍历依次训练集
# 梯度记录器
with tf.GradientTape() as tape:
out = model(x) # 通过网络获得输出
loss = tf.reduce_mean(losses.MSE(y, out))
mae_loss = tf.reduce_mean(losses.MAE(y, out)) # 计算 MAE
# 计算梯度并更新
grads = tape.gradient(loss, model.trainable_variables)
Optimizers.apply_gradients(zip(grads, model.trainable_variables))
train_MAE[epoch] = float(mae_loss)
out = model(tf.constant(normed_test_data.values))
test_MAE[epoch] = tf.reduce_mean(losses.MAE(test_labels, out))
2.6 误差结果可视化
对于回归问题,除了 MSE 均方差可以用来模型的测试性能,还可以用平均绝对误差(Mean Absolute Error,简称 MAE)来衡量模型的性能,程序运算时记录每个 Epoch 结束时的训练和测试 MAE 数据,并绘制变化曲线
plt.xlabel('Epoch')
plt.ylabel('MAE')
plt.plot(Epoch, train_MAE, label="Train")
plt.plot(Epoch, test_MAE, label="Test")
plt.title('汽车油耗实战')
plt.legend(['Train', 'Test']) # 设置折线名称
plt.show()
三 、结果分析
可以观察到,在训练到约第 25 个 Epoch 时, MAE 的下降变得较缓慢,其中训练集的 MAE
还在继续不断波动,但是测试集 MAE 几乎保持不变,因此可以在约第 25 个 epoch 时提前结束训练,并利用此时的网络参数来预测新的输入样本即可。
来源:https://blog.csdn.net/zzp20031120/article/details/128800513


猜你喜欢
- 如果是后台上传文件:setting配置:STATIC_URL = '/static/'STATICFILES_DIRS =
- 数据库是数据的集合,与数学的集合论有密不可分的关系。为提高查询速度,我们可以:对数据表添加索引,以加快搜索速度;通过编程技巧最大限度地利用索
- 1.DNS查询过程:以查询 www.baidu.com为例(1)电脑向本地域名服务器发送解析www.baidu.com的请求(2)本地域名服
- 导语哈喽哈喽!大家好!我是木木子,又到了每日游戏更新环节!8月30日,对暑假还意犹未尽的孩子们收到了一份“开学大礼”:通知要求,严格限制向未
- Fabric是一个用Python开发的部署工具,最大特点是不用登录远程服务器,在本地运行远程命令,几行Python脚本就可以轻松部署。文档入
- 本文主要是对leveldb进行一个简单的介绍及使用Python语言对其进行操作的代码示例,具体如下。leveldb 是google实现的一种
- 个人使用环境WIN10x64系统,Python3.8,PyCharm2020.01.03安装过程一、安装Python3.8(自己参考其他教程
- 关于多线程的大概讲解:在Python的标准库中给出了2个模块:_thread和threading,_thread是低级模块不支持守护线程,当
- 一、新手常犯的错误在论坛看到很多帖子代码中都有一个共同的基本错误,字段类型错误。程序和数据库是紧紧相连的,数据库字段文本型或时间型的都使用单
- 你是一位交互设计师吗?告诉我,你具体做些什么?我是做网站设计的?听起来不够专业。我是做网页设计的,听起来……你们是做界面的……恩,好吧,我勉
- 前言这是一个轮子。大家都知道 Ansible 是功能超级强大的自动化运维工具,十分的高大上。太高大上了以至于在低端运维有点水土不服,在于三点
- 话不多说,直接上代码运行截图 1.语音合成------->执行:结果:输入要转换的内容,程序直接帮你把转换好的mp3文件输出
- Python实现AES算法密码学课程老师留的作业,我觉得用python实现更简单,就用python写了一个加解密的程序。程序分成三个部分,一
- #-*- coding:utf-8 -*- from win32com.client import Dispatch if __name__
- 1、转化成时间格式seconds =35400m, s = divmod(seconds, 60)h, m = divmod(m, 60)p
- PHP Session 变量当运行一个应用程序时,你会打开它,做些更改,然后关闭它。这很像一次会话。计算机清楚你是谁。它知道你何时启动应用程
- 最近需要做集团的SRC系统。暂无安全研发,所以只能找我这个小菜兼职开发。系统使用Django框架,在整个过程中,有许多奇特的需求。在某项需求
- 本文实例讲述了Python基于pillow判断图片完整性的方法。分享给大家供大家参考,具体如下:1、安装第三方库。pip install p
- 比如有下面一段代码: for i in range(10): print ("%s" % (f_list[i].name
- 直方图,又称质量分布图,是一种统计报告图,由一系列高度不等的纵条或线段表示数据分布情况。用横轴表示数据类型,纵轴表示分布情况。直方图是数值数