封装Keras模型,使用skleran实现超参数随机随机搜索
本文展示如何使用RandomizedSearchCV进行超参数随机搜索
RandomizedSearchCV
1.将tf.keras.models转化为sklearn的model
2.定义参数集合
3.搜索参数
相关的参数注释已经展示在代码中
1.引用函数库
import matplotlib as mpl
import matplotlib.pyplot as plt
%matplotlib inline
#为了能在notebook中显示图像
import numpy as np
import sklearn
import pandas as pd
import os
import sys
import time
import tensorflow as tf
from tensorflow import keras
2.加载数据
from sklearn.datasets import fetch_california_housing #从sklearn中引用加州的房价数据
housing = fetch_california_housing()
print(housing.DESCR)
print(housing.data.shape)
print(housing.target.shape)
(20640, 8)
(20640,)
3.处理数据
#引用train_test_split对数据集进行拆分
# test_size 控制切分比例,默认切分比例3:1
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 = 1)
#将训练集进行一次拆分为验证集和测试集
x_train, x_valid, y_train, y_valid = train_test_split(x_train_all, y_train_all, random_state=2)
print(x_train.shape, y_train.shape)
print(x_valid.shape, y_valid.shape)
print(x_test.shape, y_test.shape)
(11610, 8) (11610,)
(3870, 8) (3870,)
(5160, 8) (5160,)
4.数据归一化处理
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
#对数据进行归一化处理
#由于transform处理处理数据时二维数组,所以要将数据转化一下
#x_train: [none, 28, 28] -> [none, 784]
#对于使用fit_transform 和transform 请参考我的TensorFlow中的博客
x_train_scaled = scaler.fit_transform(x_train)
x_valid_scaled = scaler.transform(x_valid)
x_test_scaled = scaler.transform(x_test)
#注意在归一化数据后,之后使用的数据要使用新的归一化数据
#以下展示如何实现随机超参数搜索
#1.将tf.keras.models。sequential转化为sklearn的model
#封装模型
def bulid_model(hidden_layers =1, layer_size = 30, learning_rate = 3e-3):
#使用序贯模型Sequential tf.keras.models.sequential()
model = keras.models.Sequential()
#第一个layer不循环创建,因为要输入input_shape,之后的layer可以循环创建
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))
#定义优化函数,使用自定义的learning_rate
optimizer = keras.optimizers.Adam(learning_rate)
#编译compile
model.compile(loss = "mean_squared_error", #损失函数:使用均方根误差
optimizer = optimizer, #优化函数
)
return model
#转化模型 tf.keras.wrappers.scikit_learn.KerasRegressor
sklearn_model = keras.wrappers.scikit_learn.KerasRegressor(bulid_model)
#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)
}
#3.参数搜索 RandomizedSearchCV
from sklearn.model_selection import RandomizedSearchCV
#RandomizedSearchCV参数说明,
#clf1设置训练的学习器
#param_dist字典类型,放入参数搜索范围
#scoring = 'neg_log_loss',精度评价方式设定为"neg_log_loss"
#n_iter=300,训练300次,数值越大,获得的参数精度越大,但是搜索时间越长
#n_jobs = -1,使用所有的CPU进行训练,默认为1,使用1个CPU
#RandomizedSearchCV采用了cross-validation: 将训练集分成n分,n-1训练,最后一份验证。默认cv=3
random_search_cv = RandomizedSearchCV(sklearn_model,
param_distribution,
cv = 5,
n_iter = 10,
n_jobs = 1)
#使用回调函数
callbacks = [
keras.callbacks.EarlyStopping(patience=5, min_delta=1e-3),
]
#训练函数
random_search_cv.fit(x_train_scaled, y_train,
epochs = 100,
validation_data = (x_valid_scaled, y_valid),
callbacks = callbacks )
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_scaled, y_test)