TensorFlow 2.0 学习过程中,对一些细节掌握不牢固,写一下博文来挖掘自己的不足
因为是纯手打,方便记忆,可能存在一些字节错误,敬请谅解
一、 wide and deep 1. 引入资源库
import matplotlib as mpl # python 绘图库
import matplotlib.pyplot as plt # python 2D 绘图库
import numpy as np # 数学库,矩阵数组等
import sklearn
import pandas as pd # 大数据处理模块
import os # 处理文件和目录
import sys # 解释器使用或维护一些变量的访问,以及与解释器强交互的函数
import time # 格式化日期与时间
import tensorflow as tf
from tensorflow import keras
#显示重要库的对应版本
print(tf.__version__)
print(sys.version_info)
for module in mpl,np,pd,sklearn,tf,keras:
print(module.__name__,module.__version__)
2. 引入数据集
from sklearn.datasets import fetch_california_housing
# 引入加州房价预测数据
housing = fetch_california_housing()
# 显示数据的说明,数据的矩阵形状,标签的形状
print(housing.DESCR)
print(housing.data.shape)
print(housing.target.shape)
3. 分割数据集
# 引入机器学习数据集分割库
from sklearn.model_selection import train_test_split
# 引入预测房价的 data,target,并切分数据为 训练集(训练集中又该分为训练集和验证集) 与 测试集,
# x 为训练集,y 为测试集,这里将数据切割为 4 个部分,训练集的特征,验证集的特征,训练集的标签,验证集的标签
# 没有填写训练集与验证的分割比例的话,默认为 0.75
" train_test_split:
housing.data: 被划分样本的特征集
housing.target: 被划分样本的标签
random_state=7: 随机数设定为 7 ,那重复运行时,运行的是同一份数据,改为其他数字,将会导致数据不一致
"
x_train_all,x_test,y_train_all,y_test = train_test_split(
housing.data,housing.target,random_state=7)
# 将大训练集分割为小训练集与验证集
x_train,x_valid,y_train,y_valid =train_test_split(
x_train_all,y_train_all,random_state=11)
# 显示训练集,验证集,测试集的形状
print(x_train.shape,y_train.shape)
print(x_valid.shape,y_valid.shape)
print(x_test.shape,y_test.shape)
4. 归一化
# 引入标准化库 :计算训练集的平均值和标准差,以便测试数据集使用相同的变换
from sklearn.preproccessing import StandardScaler
# 引入标准化函数
scaler = StandarScaler()
# 训练集,验证集,测试集标准化
x_train_scaled = scaler.fit_transform(x_train)
x_valid_scaled = scaler.transform(x_valid)
x_test_scaled = scaler.transform(x_test)
5. 模型建立
经过上面的步骤,我们已经成功导入数据,并对数据完成分割和标准化,下面是建立模型
并且因为 wide and deep 模型是分为左右两个部分,不能使用 Sequential 来建立模型,我们就需要
使用函数式 API 或者 子类 API 来建立模型
在这里我们先演示一下两种模型建立方式:
5.1 函数 API 实现 wide and deep 模型
# 函数式 API 功能 API
#输入层,取训练集的第一行以后
# 设定输入格式 这里设定输入矩阵为 行为 None ,列为 8 ,意思是有八分特征值的任意数量的数据
input = keras.layers.Input(shape=x_train.shape[1:])
# 第一层隐藏层,上一层为 input 层,有 30 个节点
hidden1 = keras.layers.Dense(30,activation='relu')(input)
# 第二层隐藏层
hidden2 = keras.layers.Dense(30,activation='relu')(hidden1)
#神经网络不同层级之间就跟复合函数类似: f(x)=h(g(x))
# hidden2 为 deep model 的输出,input 为 wide model 的输入
# wide 模型是将输入直接线性输入给结果,deep 模型则是对输入进行处理后再输出
# 这里就将 wide and deep 模型的两个输出合并再输出
concat =keras.layers.concatenate([input,hidden2])
output =keras.layers.Dense(1)(concat)
#固化模型
model = keras.models.Model(inputs=[input],
outputs = [output])
5.2 子类 API 实现 wide and deep 模型
class WideDeepModel(keras.models.Model):
def __init__(self):
super(WideDeepModel,self).__init__()
"""定义模型的层次"""
self.hidden1_layer = keras.layers.Dense(30,activation='relu')
self.hidden2_layer = keras.layers.Dense(30,activation='relu')
self.output_layer = keras.layers.Dense(1)
# 因为没有反向传播部分,就只需要定义正向计算部分
def call(self,input):
"""完成模型的正向计算"""
hidden1 = self.hidden1_layer(input)
hidden2 = self.hidden2_layer(hidden1)
concat = keras.layers.concatenate([input,hidden2])
output = self.output_layer(concat)
return output
# 第一种子类 API 使用方法,定义一个模型的对象
# model = WideDeepModel()
# 再调用模型的 build 函数定义输入 ,8 对于 feature 数量
# model.build(input_shape+(None,8))
model = keras.models.Sequential([
WideDeepModel(),
])
model.build(input_shape=(None,8))
5.3 wide and deep 多输入
# 实现多输入 这里使用函数式的方法
# 我们假设我们将前 5 个 feature 输入 wide 模型,后 6 个 feature 输入 deep 模型,一共 8 个 feature ,也就是说, wide and deep 有交集部分
input_wide = keras.layers.Input(shape=[5])
input_deep = keras.layers.Input(shape=[6])
hidden1 = keras.layers.Dense(30,activation='relu')(input_deep)
hidden2 = keras.layers.Dense(30,activation='relu')(hidden1)
concat = keras.layers.concatenate([input_wide,hidden2])
model = keras.models.Model(inputs = [input_wide,input_deep],
outputs = [output])
6. 配置模型学习流程
# 先用 summary 看一下模型结构,概况
model.summary()
# 配置模型
# loss: 损失函数,这里设定为 mean_squared_error(均方误差)*sparse_categorical_crossentropy 交叉熵
# optimizer: 优化器,这里设定为 sgd(随机梯度下降)
# metrics :指标,可选 metrics=["accuracy"]
model.compile(loss="mean_squared_error",optimizer="sgd")
# 定义回调函数:在训练模型时,中间需要进行的一些操作
# keras.callbacks.EarlyStopping :提前结束训练,loss 不再下降时
# ModelCheckpoint : 每个一段时间显示一下各个参数的中间状态
# EarlyStopping 的参数介绍:
# patience : 进过 5 步没有进步,模型训练将被停止
# min_delta : 变化小于该值,则认为没有进步
callbacks = [keras.callbacks.EarlyStopping(
patience= 5,min_delta=1e-2)]
7. 开启训练
构建好图以后,我们就可以开启训练了
这里调用 model.fit 函数来进行训练
# 调用训练函数 fit ,
# 输入归一化后的训练集,以及训练集的标签
# 输入验证集,设定好后,每隔一段时间,就会对验证集做一次验证
# 设定遍历训练集的次数,100 次
# 获取 callbacks 函数
history = model.fit(x_train_scaled,y_train,
validation_data = (x_valid_scaled,y_valid),
epochs = 100,
callbacks = callbacks)
8. 训练过程的图表展示
以上我们的模型构建和训练已经完成了,但我们还想了解一下训练过程中参数的变化
# 设定图表展示函数,将模型训练的接受对象 history 输入到该函数中
def plot_learning_curves(history):
# 将 history 获取到的训练过程的参数变化的字典变为矩阵形状,并设定图的尺寸大小为 8 和 5
pd.DataFrame(history.history).plot(figsize=(8,5))
# 显示网格
plt.grid(True)
# 设置坐标范围 ,设定 y 为 0~1 之间
plt.gca().set_ylim(0,1)
# 显示这张图
plt.show()
plot_learning_curves(history)
9. 评估模型
最后我们可以使用测试集评估一下模型
# 输入测试集的特征与标签
model.evaluate(x_test_scaled,y_test)
参考资料、
Google老师亲授 TensorFlow2.0
作者:XMing666