Keras(6)Kerasモデルパッケージは、ハイパーパラメータ検索を使用してsklearnモデルに変換されます

この記事では以下を紹介します。

  • ハイパーパラメータ検索の概要
  • ハイパーパラメータ検索を手動で実装する
  • sklearnパッケージkerasモデル
  • sklearnはハイパーパラメータ検索を実装します
  • 実装の質問応答

1.ハイパーパラメータ検索

1.ハイパーパラメータとは
  • ニューラルネットワークには、トレーニング中に一定である多くのパラメータがあります
    • ネットワーク構造パラメータ:層の数、各層の幅、各層の活性化関数など。
    • トレーニングパラメータ:batch_size、学習率、学習率減衰アルゴリズムなど。
2.検索戦略
  • グリッド検索
  • ランダム検索
  • 遺伝的アルゴリズム検索
  • ヒューリスティック検索
1)グリッド検索
  • n次元グリッドを定義する
  • 各グリッドは、ハイパーパラメータのセットに対応します
  • トライアルパラメータのセット
    ここに画像の説明を挿入
2)ランダム検索
  • パラメータの生成方法はランダムです
  • 探索するためのより多くのスペース
    ここに画像の説明を挿入
3)遺伝的アルゴリズム検索
  • 自然界のシミュレーション
  • A.候補パラメーターセットを初期化する->トレーニング->生存確率としてモデルインデックスを取得する
  • B. [選択]-> [クロス]-> [ミューテーション]-> [次世代コレクションの生成]
  • C.Aに戻る
4)ヒューリスティック検索
  • リサーチホットスポット-AutoML
  • リカレントニューラルネットワークを使用してパラメーターを生成する
  • フィードバックに強化学習を使用し、モデルを使用してパラメーターをトレーニングおよび生成します

次に、ハイパーパラメータ検索を手動で実装します

この方法は実験専用であり、お勧めしません

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import sklearn
import pandas as pd
import os
import sys
import time
import tensorflow as tf
from tensorflow import keras

# 1,打印使用的python库的版本信息
print(tf.__version__)
print(sys.version_info)
for module in mpl, np, pd, sklearn, tf, keras:
    print(module.__name__, module.__version__)

# 2,下载并使用sklearn中的“fetch_california_housing”数据集
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

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.preprocessing import StandardScaler

scaler = StandardScaler()
x_train_scaled = scaler.fit_transform(x_train)
x_valid_scaled = scaler.transform(x_valid)
x_test_scaled = scaler.transform(x_test)

# 5,构建wide_deep回归模型、模型层级图、编译模型(添加损失函数、优化器)、添加回调函数
# learning_rate: [1e-4, 3e-4, 1e-3, 3e-3, 1e-2, 3e-2]
# W = W + grad * learning_rate

learning_rates = [1e-4, 3e-4, 1e-3, 3e-3, 1e-2, 3e-2]
histories = []
for lr in learning_rates:
    model = keras.models.Sequential([
        keras.layers.Dense(30, activation='relu',
                           input_shape=x_train.shape[1:]),
        keras.layers.Dense(1),
    ])
    optimizer = keras.optimizers.SGD(lr)
    model.compile(loss="mean_squared_error", optimizer=optimizer)
    callbacks = [keras.callbacks.EarlyStopping(
        patience=5, min_delta=1e-2)]
    # 训练构建的模型
    history = model.fit(x_train_scaled, y_train,
                        validation_data = (x_valid_scaled, y_valid),
                        epochs = 100,
                        callbacks = callbacks)
    histories.append(history)
    
# 6,得到训练曲线图
def plot_learning_curves(history):
    pd.DataFrame(history.history).plot(figsize=(8, 5))
    plt.grid(True)
    plt.gca().set_ylim(0, 1)
    plt.show()
for lr, history in zip(learning_rates, histories):
    print("Learning rate: ", lr)
    plot_learning_curves(history)

3つ目は、sklearnがkerasモデルをカプセル化することです。

1. keras組み込みインターフェースを使用して、kerasモデルをsklearnモデルに変換します

ここに画像の説明を挿入

def build_model(hidden_layers = 1,layer_size = 30,learning_rate = 3e-3):
    model = keras.models.Sequential()
    model.add(keras.layers.Dense(layer_size, activation='relu',input_shape=x_train.shape[1:]))
    for _ in range(hidden_layers - 1):
        model.add(keras.layers.Dense(layer_size,activation = 'relu'))
    model.add(keras.layers.Dense(1))
    optimizer = keras.optimizers.SGD(learning_rate)
    model.compile(loss = 'mse', optimizer = optimizer)
    return model

sklearn_model = keras.wrappers.scikit_learn.KerasRegressor(build_fn = build_model)
callbacks = [keras.callbacks.EarlyStopping(patience=5, min_delta=1e-2)]
2.コードを要約します
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import sklearn
import pandas as pd
import os
import sys
import time
import tensorflow as tf
from tensorflow import keras

# 1,打印使用的python库的版本信息
print(tf.__version__)
print(sys.version_info)
for module in mpl, np, pd, sklearn, tf, keras:
    print(module.__name__, module.__version__)
    
# 2,下载并使用sklearn中的“fetch_california_housing”数据集
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

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.preprocessing import StandardScaler

scaler = StandardScaler()
x_train_scaled = scaler.fit_transform(x_train)
x_valid_scaled = scaler.transform(x_valid)
x_test_scaled = scaler.transform(x_test)

# 5,构建模型、模型层级图、编译模型(添加损失函数、优化器)、添加回调函数
# RandomizedSearchCV
# -1-. 转化为sklearn的model
# -2-. 定义参数集合
# -3-. 搜索参数

def build_model(hidden_layers = 1,layer_size = 30,learning_rate = 3e-3):
    model = keras.models.Sequential()
    model.add(keras.layers.Dense(layer_size, activation='relu',input_shape=x_train.shape[1:]))
    for _ in range(hidden_layers - 1):
        model.add(keras.layers.Dense(layer_size,activation = 'relu'))
    model.add(keras.layers.Dense(1))
    optimizer = keras.optimizers.SGD(learning_rate)
    model.compile(loss = 'mse', optimizer = optimizer)
    return model

sklearn_model = keras.wrappers.scikit_learn.KerasRegressor(build_fn = build_model)
callbacks = [keras.callbacks.EarlyStopping(patience=5, min_delta=1e-2)]

# 6,训练构建的模型
history = sklearn_model.fit(x_train_scaled, y_train,
                            epochs = 10,
                            validation_data = (x_valid_scaled, y_valid),
                            callbacks = callbacks)

# 7,得到训练曲线图
def plot_learning_curves(history):
    pd.DataFrame(history.history).plot(figsize=(8, 5))
    plt.grid(True)
    plt.gca().set_ylim(0, 1)
    plt.show()
plot_learning_curves(history)

第四に、sklearnはハイパーパラメータ検索を実装します

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import sklearn
import pandas as pd
import os
import sys
import time
import tensorflow as tf
from tensorflow import keras

# 1,打印使用的python库的版本信息
print(tf.__version__)
print(sys.version_info)
for module in mpl, np, pd, sklearn, tf, keras:
    print(module.__name__, module.__version__)
    
# 2,下载并使用sklearn中的“fetch_california_housing”数据集
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

x_train_all, x_test, y_train_all, y_test = train_test_split(housing.data, housing.target, random_state = 7,test_size=0.3)
x_train, x_valid, y_train, y_valid = train_test_split(x_train_all, y_train_all, random_state = 11,test_size=0.3)
print(x_train.shape, y_train.shape)
print(x_valid.shape, y_valid.shape)
print(x_test.shape, y_test.shape)

# 4,在将数据带入到模型之前,先进行预处理-训练、验证、测试数据标准化
from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
x_train_scaled = scaler.fit_transform(x_train)
x_valid_scaled = scaler.transform(x_valid)
x_test_scaled = scaler.transform(x_test)

# 5,构建模型、模型层级图、编译模型(添加损失函数、优化器)、添加回调函数
# RandomizedSearchCV
# 1. 转化为sklearn的model
# 2. 定义参数集合
# 3. 搜索参数

def build_model(hidden_layers = 1,layer_size = 30,learning_rate = 3e-2):
    model = keras.models.Sequential()
    model.add(keras.layers.Dense(layer_size, activation='relu',input_shape=x_train.shape[1:]))
    for _ in range(hidden_layers - 1):
        model.add(keras.layers.Dense(layer_size,activation = 'relu'))
    model.add(keras.layers.Dense(1))
    optimizer = keras.optimizers.SGD(learning_rate)
    model.compile(loss = 'mse', optimizer = optimizer)
    return model

sklearn_model = keras.wrappers.scikit_learn.KerasRegressor(build_fn = build_model)

callbacks = [keras.callbacks.EarlyStopping(patience=5, min_delta=1e-2)]

# 6,训练构建的模型
# history = sklearn_model.fit(x_train_scaled, y_train,
#                             epochs = 10,
#                             validation_data = (x_valid_scaled, y_valid),
#                             callbacks = callbacks)

# # 7,得到训练曲线图
# def plot_learning_curves(history):
#     pd.DataFrame(history.history).plot(figsize=(8, 5))
#     plt.grid(True)
#     plt.gca().set_ylim(0, 1)
#     plt.show()
# plot_learning_curves(history)

# 8,使用sk-learn实现网格搜索,交叉验证
from scipy.stats import reciprocal
reciprocal.rvs(1e-4,1e-2,size=10)

from scipy.stats import reciprocal
# f(x) = 1/(x*log(b/a)) a <= x <= b

param_distribution = {
    
    
    "hidden_layers":[ 3, 4],
    "layer_size": np.arange(3, 7),
    "learning_rate": reciprocal(1e-4, 1e-3),
    # "layer_size": [1,2,3,4,5,6,7,8,9,10],
    # "learning_rate": [1e-4, 5e-5, 1e-3, 5e-3, 1e-2],
}

from sklearn.model_selection import RandomizedSearchCV

random_search_cv = RandomizedSearchCV(sklearn_model,  # 调用的模型
                                      param_distribution,# 参数字典
                                      n_iter = 10,  # 输出多少参数集合
                                      cv = 4,   # 指定几折交叉验证
                                      n_jobs = 1)# 多少核的并行计算

random_search_cv.fit(x_train_scaled, y_train, epochs = 5,
                      validation_data = (x_valid_scaled, y_valid),
                      callbacks = callbacks)

# cross_validation: 训练集分成n份,n-1训练,最后一份验证.

# 9,打印最佳
print(random_search_cv.best_params_)    # 最佳参数
print(random_search_cv.best_score_)     # 最佳得分(为-loss)
print(random_search_cv.best_estimator_) # 最佳估计器返回的模型

model = random_search_cv.best_estimator_.model
# print(model.evaluate(x_test_scaled, y_test))
print(model.evaluate(x_test_scaled, y_test,verbose = 0))

記事も共有してください:https//zhuanlan.zhihu.com/p/65974369
注:

  • RandomizedSearchCVのパラメーター "n_iter"は、出力されるパラメーターセットの数を指定します
  • RandomizedSearchCVのパラメーター "cv"は、フォールドクロス検証の数、n-1個のテストセット、1個の検証セットを指定します。
  • グリッド/ランダム検索トレーニングでは、各トレーニングで、トレーニングセットは(トレーニングセットテストデータ*(cv番号-1 / cv番号))であり、検証セットは(トレーニングセットテストデータ*(1 / cv番号))です。
  • トレーニング後に最適なパラメーターセットが取得されたら、すべてのトレーニングデータと最適なパラメーターをモデルトレーニングに取り込み、x_valid_stdを使用して検証すると、プログラムトレーニングの総数もn_iter * cv + 1に等しくなります。
  • tf2.2では、印刷されたテストデータの各グループの値が小さすぎるため、tf2.1を使用すると通常の値に戻ります。

五、既存の問題の実現

1. RandomizedSearchCVメソッドのn_jobsパラメーターは、1以外の値を取ることはできません

通常のscikitモデルは、n_jobsが1より大きい値に設定されている場合は成功しますが、テンソルフローモデルの場合、n_jobsが1より大きい値に設定されていると、ジョブをシリアル化できないという問題が発生します。当面、この問題の解決策はありません。

2.検証データはcross_validationで分離されていますが、validation_dataを渡す必要がありますか?

Cross_validationは、パラメーターを見つけるために使用されます。パラメーターを見つけた後、最後にすべてのトレーニングセットでトレーニングされ、validation_dataで検証されます。

3. cross_validationのパラメーターの各セットの複数のトレーニングで、損失が最も少ないパラメーターまたは最後に使用されたパラメーターはありますか?

最後に、パラメータの各グループの最後のエポックのパラメータ検証が使用されます。

4. param_distributionでnp.arangeまたはreciprocalを使用すると、エラーが報告されます

新しいバージョンのtensorflowのKerasRegressorに問題がある可能性があります。新しいバージョンのパラメーターには、ディープコピーを実行するときに問題があり、複雑なnumpyオブジェクトをコピーするときにエラーが発生します。ディープコピーの操作はユーザーには表示されないため、結論はsklearnのバージョン0.21.3に戻るか、param_distributionで通常のリストを使用することです。

5. tensorflowはハイパーパラメータ検索を実行できますか?

現在、tensorflowにはそのようなライブラリの実装はなく、自分で実装する必要があります。AutoMLは、ハイパーパラメータ検索だけでなく、モデル構造検索など、他の多くの複雑なアルゴリズムでもあります。これらのアルゴリズムは1つずつ実装する必要があり、比較的完全なアルゴリズムライブラリはありません。

6. best_score_が負の理由は何ですか?

実装では、検索時にKerasRegressorのscore関数が呼び出され、この関数の実装は-lossを返し、mse(平均二乗誤差)は正の数であるため、scoreは負の数になります。負の数を使用する理由は、検索プロセスで、スコアが高いほど良い、mseが低いほど良いことを期待しているため、統一のために負の数が返されるためです。

7. RandomizedSearchCVがフィットプロセス中に渡されたx_valid_stdとy_validを検証しているときに、なぜ多くの「======」があるのですか?

バージョンが原因である可能性があります。1つのバージョン(2.0.0を覚えています)には等号がたくさんあります。verbose= 0を使用して、進行状況を出力しないように設定できます。2.1.0にアップデートしましたが、同様の問題は見つかりませんでした。

おすすめ

転載: blog.csdn.net/TFATS/article/details/110191447