TensorFlow2.0 (1) wide and deep 模型多輸入代碼詳解

前言、

                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])
# deep model 有兩個隱藏層
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. 配置模型學習流程

                 6.1 非多輸入的模型配置

# 先用 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)]

                 6.2 多輸入的訓練集配置

                                在多輸入的情況下,訓練集不但需要拆分,還有重複訓練部分,所以我們需要根據多輸入的情況,對數據做

                                拆分處理,所以需要多加上這一部分的代碼

# wide 模型的輸入,前 5 個特徵的數據集 ,deep 模型輸入後 6 個
x_train_scaled_wide = x_train_scaled[:,:5]
x_train_scaled_deep = x_train_scled[:,2:]
# 驗證集和測試集同上
x_valid_scaled_wide = x_valid_scaled[:,:5]
x_valid_scaled_deep = x_valid_scaled[:,2:]
x_test_scaled_wide = x_test_scaled[:,:5]
x_test_scaled_deep = x_test_scaled[:.2:]

           7. 開啓訓練

                 7.1 非多輸入的訓練

                       構建好圖以後,我們就可以開啓訓練了

                       這裏調用 model.fit 函數來進行訓練

# 調用訓練函數 fit ,
# 輸入歸一化後的訓練集,以及訓練集的標籤
# 輸入驗證集,設定好後,每隔一段時間,就會對驗證集做一次驗證
# 設定遍歷訓練集的次數,100 次
# 獲取 callbacks 函數
history = model.fit(x_train_scaled,y_train,
                    validation_data = (x_valid_scaled,y_valid),
                    epochs = 100,
                    callbacks = callbacks)

                  7.2 多輸入的模型訓練

               

history = model.fit([x_train_scaled_wide,x_train_scaled_deep],
                    y_train,
                    validation_data=(
                                    [x_valid_scaled_wide,x_valid_scaled_deep],
                                    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 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章