@龙良曲TensorFlow第六章 汽车油耗预测

#%%
from __future__ import absolute_import, division, print_function, unicode_literals#加入绝对引入

import pathlib
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'


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, losses


#设置显示的最大列、宽等参数,消掉打印不完全中间的省略号
pd.set_option('display.max_columns', 1000)
pd.set_option('display.width', 1000)
pd.set_option('display.max_colwidth', 1000)
print("tensorflow version:",tf.__version__)


#==================
#===数据处理========
#==================


# 在线下载汽车效能数据集
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)# #sep: 指定分割符; skipinitialspace忽略分隔符后的空格
                        #names:用于结果的列名列表。na_values:一组用于替换NAN的值,用?替代NAN
                        #comment:标识多余的行不被解析 如果'\t'出现在行首,这一行将被忽略
dataset = raw_dataset.copy()
# 查看部分数据
print(dataset.tail())#后5行
print(dataset.head())#前5行
print(dataset)
#%%


# %%

# 统计空白数据,并清除
dataset.isna().sum()#isna()检测数组缺失值 sum()统计数量
dataset = dataset.dropna()#删除所有包含NAN的行
dataset.isna().sum()
print(dataset)
# %%

# 处理类别型数据,其中origin列代表了类别1,2,3,分布代表产地:美国、欧洲、日本
# 其弹出这一列
origin = dataset.pop('Origin')
# 根据origin列来写入新列
dataset['USA'] = (origin == 1) * 1.0
dataset['Europe'] = (origin == 2) * 1.0
dataset['Japan'] = (origin == 3) * 1.0
print(dataset.tail())#打印后5行

# 切分为训练集和测试集,8:2
train_dataset = dataset.sample(frac=0.8, random_state=0)#frac取样比例, random_state如果值为int, 则为随机数生成器或numpy RandomState对象设置种子
test_dataset = dataset.drop(train_dataset.index)#取train_dataset的数据下标,并drop,形成test_dataset


# %% 统计数据
sns.pairplot(train_dataset[["Cylinders", "Displacement", "Weight", "MPG"]],
             diag_kind="kde")#快速查看训练集中几对列的联合分布
# %%
# 查看训练集的输入X的统计数据
train_stats = train_dataset.describe()
train_stats.pop("MPG")#仅保留输入x,保留mpg
train_stats = train_stats.transpose()#转置
print(train_stats)

# 移动MPG油耗效能这一列为真实标签Y
#将MPG这一列作为标签
train_labels = train_dataset.pop('MPG')
test_labels = test_dataset.pop('MPG')


# 标准化数据 减去每个字段的均值并除以标准差
def norm(x):
    return (x - train_stats['mean']) / train_stats['std']


normed_train_data = norm(train_dataset)#标准化训练集
normed_test_data = norm(test_dataset)#标准化测试集
# %%

print(normed_train_data.shape, train_labels.shape)
print(normed_test_data.shape, test_labels.shape)


# %%

class Network(keras.Model):
    # 回归网络
    def __init__(self):
        super(Network, self).__init__()
        # 创建3个全连接层
        self.fc1 = layers.Dense(128, activation='relu')
        self.fc2 = layers.Dense(64, activation='relu')
        self.fc3 = layers.Dense(1)

    def call(self, inputs, training=None, mask=None):
        # 依次通过3个全连接层
        x = self.fc1(inputs)
        x = self.fc2(x)
        x = self.fc3(x)

        return x


# 创建网络类实例
model = Network()
# 通过 build 函数完成内部张量的创建,其中 4 为任意设置的 batch 数量, 9 为输入特征长度
model.build(input_shape=(4, 9))
model.summary()  # 打印网络信息
optimizer = tf.keras.optimizers.RMSprop(0.001)  # 创建优化器,指定学习率
# 构建datasets对象
train_db = tf.data.Dataset.from_tensor_slices((normed_train_data.values, train_labels.values))
train_db = train_db.shuffle(100).batch(32)  # 打乱,批处理

# # 未训练时测试
# example_batch = normed_train_data[:10]
# example_result = model.predict(example_batch)
# example_result

# mae:平均绝对误差
train_mse_losses=[]
test_mse_losses=[]
train_mae_losses = []
test_mae_losses = []
for epoch in range(200):  # 200个epoch
    for step, (x, y) in enumerate(train_db):  # 遍历一次数据集
        # 梯度记录器,训练时需要使用它
        with tf.GradientTape() as tape:
            out = model(x)  # 通过网络获得输出
            mse_loss = tf.reduce_mean(losses.MSE(y, out))  # 计算mse均值
            mae_loss = tf.reduce_mean(losses.MAE(y, out))  # 计算mae均值

        if step % 10 == 0:  # 间隔打印训练误差
            print(f'epoch:{epoch}, step:{step}, loss:{float(mse_loss)},mae_loss:{mae_loss}')
        # 计算梯度并更新
        grads = tape.gradient(mse_loss, model.trainable_variables)
        optimizer.apply_gradients(zip(grads, model.trainable_variables))

    train_mae_losses.append(float(mae_loss))
    train_mse_losses.append(float(mse_loss))
    out = model(tf.constant(normed_test_data.values))
    test_mae_losses.append(tf.reduce_mean(losses.MAE(test_labels, out)))
    test_mse_losses.append(tf.reduce_mean(losses.MSE(test_labels, out)))

plt.figure(2)
plt.xlabel('Epoch')
plt.ylabel('MAE')
plt.plot(train_mae_losses, label='Train')

plt.plot(test_mae_losses, label='Test')
plt.legend()

# plt.ylim([0,10])
plt.legend()
plt.savefig('auto.svg')



plt.figure(3)
plt.xlabel('Epoch')
plt.ylabel('MSE')
plt.plot(train_mse_losses, label='Train')

plt.plot(test_mse_losses, label='Test')
plt.legend()
plt.show()
# %%

运行结果:

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值