本片博客将记录自己如何利用tf2.0和skleran对建立的回归模型(用于加利福尼亚房价预测)进行超参数搜索,代码运行于jupyter notebook.
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import sklearn
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__)
from sklearn.datasets import fetch_california_housing
housing = fetch_california_housing()
print(housing.DESCR)
print(housing.data.shape)
print(housing.target.shape)
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_test.shape, y_test.shape)
print(x_valid.shape, y_valid.shape)
关于train_test_split函数:用于将矩阵随机划分为训练子集和测试子集,并返回划分好的训练集测试集样本和训练集测试集标签。
参数random_state:是随机数的种子。随机数种子:其实就是该组随机数的编号,在需要重复试验的时候,保证得到一组一样的随机数。比如你每次都填1,其他参数一样的情况下你得到的随机数组是一样的。但填0或不填,每次都会不一样。
随机数的产生取决于种子,随机数和种子之间的关系遵从以下两个规则:种子不同,产生不同的随机数;种子相同,即使实例不同也产生相同的随机数。
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
x_train_scaler = scaler.fit_transform(x_train)
x_valid_scaler = scaler.transform(x_valid)
x_test_scaler = scaler.transform(x_test)
StandardScaler 类是一个用来将数据进行归一化和标准化的类。
标准化做法: X = ( x − μ ) / σ X=(x-\mu) / \sigma X=(x−μ)/σ, μ \mu μ为数据 x x x的均值, σ \sigma σ为数据 x x x的标准差,此时 X X X~ N ( 0 , 1 ) N(0,1) N(0,1)
fit_transform方法是fit和transform的结合:fit_transform(x_train) 计算x_train的 μ \mu μ和 σ \sigma σ并保存 μ \mu μ和 σ \sigma σ,然后再将 x x x标准化。
transform是利用x_train的 μ \mu μ和 σ \sigma σ对输入数据进行标准化。
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_scaler.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
# step 1:转化模型:如果定义的是回归模型,就用KerasRegressor;分类模型用KerasClassifier
sklearn_model = keras.wrappers.scikit_learn.KerasRegressor(
build_fn = build_model)
callbacks = [keras.callbacks.EarlyStopping(patience = 5, min_delta = 1e-2)]
history = sklearn_model.fit(x_train_scaler, y_train,
validation_data = (x_valid_scaler, y_valid),
epochs = 10,
callbacks = callbacks)
from scipy.stats import reciprocal
reciprocal.rvs(1e-4, 1e-2, size=10)
# 1e-4: 自变量下限
# 1e-2: 自变量上线
# size: 显示的值的数目
param_distribution :该字典存储的参数就是上一步build_model函数的输入参数
# step 2: 定义参数集合:
from scipy.stats import reciprocal
# f(x) = 1/(x*log(b/a)) a<=x<=b
param_distribution = {
'hidden_layers': [1, 2, 3, 4],
'layer_size': np.arange(1, 100),
'learning_rate': reciprocal(1e-4, 1e-2),
}
# step 3: 搜索参数
from sklearn.model_selection import RandomizedSearchCV
random_search_cv = RandomizedSearchCV(sklearn_model,
param_distribution,
n_iter = 10,
cv =3,
n_jobs = 1)
random_search_cv.fit(x_train_scaler, y_train, epochs = 100,
validation_data = (x_valid_scaler, y_valid),
callbacks = callbacks)
# cross_validation: 训练集分成n份,n-1 用于训练,最后一份用于验证
print(random_search_cv.best_params_)
print(random_search_cv.best_score_)
print(random_search_cv.best_estimator_)
model = random_search_cv.best_estimator_.model
model.evaluate(x_test_scaler, y_test)
以上就是使用 tensorflow2.0 和 sklearn…RandomizeSearchCV进行超参数搜索的全过程,完整的代码课请参考我的github