封装Keras模型,使用skleran实现超参数随机随机搜索

ⅰ亾dé卋堺 提交于 2020-02-24 13:28:06

封装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)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!