深度学习基础3: 使用 tensorflow2.0 和 sklearn...RandomizeSearchCV进行超参数搜索

目录

  • 介绍
  • 实现方法
  • 总结

介绍

  本片博客将记录自己如何利用tf2.0和skleran对建立的回归模型(用于加利福尼亚房价预测)进行超参数搜索,代码运行于jupyter notebook.

实现方法

  1. 首先导入依赖的库
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__)
  1. 利用tf.keras中的数据集接口下载数据集,并查看数据结构
from sklearn.datasets import fetch_california_housing
housing = fetch_california_housing()
print(housing.DESCR)
print(housing.data.shape)
print(housing.target.shape)
  1. 数据集拆分:将数据集分为训练集(train data),验证集(valid data),以及测试集(test data)
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或不填,每次都会不一样。
  随机数的产生取决于种子,随机数和种子之间的关系遵从以下两个规则:种子不同,产生不同的随机数;种子相同,即使实例不同也产生相同的随机数。

  1. 利用sklearn.preprocessing的函数对训练、验证、测试数据进行标准化,目的是使输入数据服从标准的正态分布x~(0,1)
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 σ对输入数据进行标准化。

  1. 利用keras.wrappers.scikit_learn.KerasRegressor函数将定义的模型转化为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_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)
  1. 定义参数集合和搜索参数
    reciprocal(a,b)函数:产生一个连续空间的分布,f(x) = 1/(x*log(b/a)) a<=x<=b
    这里我们可以查看一下reciprocal的函数功能:
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 用于训练,最后一份用于验证
  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

你可能感兴趣的:(深度学习DL_CV,深度学习DL_NLP)