使用神经网络进行稀疏采样_使用KerasTuner和Hiplot进行神经网络超参数调整

本文不仅向您展示如何调整神经网络的超参数,还将通过FAIR的Hiplot直观地查看调整过程/训练过程。

使用神经网络进行稀疏采样_使用KerasTuner和Hiplot进行神经网络超参数调整_第1张图片

神经网络训练历史可视化

导入Python依赖

!pip install hiplotimport tensorflow as tfimport hiplot as hip

准备数据

我们将使用Fashion MNIST机器学习数据集

# download datamnist = tf.keras.datasets.fashion_mnist(x_train, y_train), (x_test, y_test) = mnist.load_data()# define the input shape and normalise datax_train=x_train.reshape(60000, 28, 28, 1)x_train=x_train / 255.0x_test = x_test.reshape(10000, 28, 28, 1)x_test=x_test/255.0

定义我们的神经网络模型

我们将构建一个简单的模型,其中包含几个卷积层,最大池化层,dropout和dropout层

model = tf.keras.models.Sequential([    tf.keras.layers.Conv2D(64, (3,3), activation=’relu’,     input_shape=(28, 28, 1)),    tf.keras.layers.MaxPooling2D(2, 2),    tf.keras.layers.Dropout(0.5),    tf.keras.layers.Conv2D(64, (3,3), activation=’relu’),    tf.keras.layers.MaxPooling2D(2,2),    tf.keras.layers.Dropout(0.5),    tf.keras.layers.Flatten(),    tf.keras.layers.Dense(128, activation=’relu’),    tf.keras.layers.Dense(10, activation=’softmax’)    ])

我们可以编译我们的模型并打印它的摘要

model.compile(optimizer=’adam’, loss=’sparse_categorical_crossentropy’, metrics=[‘accuracy’])# model.summary()

我们可以绘制刚刚定义的神经网络模型的结构:

使用神经网络进行稀疏采样_使用KerasTuner和Hiplot进行神经网络超参数调整_第2张图片

一旦编译完成,就可以对模型进行训练和评估。我们声明一个变量,它将用于提取历史训练数据

num_epochs = 20history = model.fit(training_images,                     training_labels,                     epochs=num_epochs,                     validation_split=0.2          )model.evaluate(x_test, y_test)

我们的模型配置非常简单,在测试集中显示了90.7%的准确率。

现在让我们进行一些可视化。当在Jupyter笔记本中运行时,Hiplot要求其输入数据采用python字典的形式,因此我们可以使用列表来解析历史数据并将其绘制出来。

import hiplot as hipdata = [{'epoch': idx,    'loss': history.history['loss'][idx],    'val_loss': history.history['val_loss'][idx],    'accuracy': history.history['accuracy'][idx],    'val_accuracy': history.history['val_accuracy'][idx]}     for idx in range(num_epochs)]hip.Experiment.from_iterable(data).display()
使用神经网络进行稀疏采样_使用KerasTuner和Hiplot进行神经网络超参数调整_第3张图片

使用FAIR的Hilpot可视化训练过程

我们可以在一个位置查看损失,指标值及其关系,从而看到我们的模型在每个epoch的表现如何。

超参数调整和可视化

!pip install keras-tunerfrom kerastuner import HyperModelfrom kerastuner.tuners import RandomSearch

首先,我们需要为每个需要调整的参数定义模型和搜索空间。您可以使用build_model函数或我们将要执行的HyperModel类来执行此操作:

class CNNHyperModel(HyperModel):    def __init__(self, input_shape, num_classes):        self.input_shape = input_shape        self.num_classes = num_classes    def build(self, hp):        model = tf.keras.Sequential()        model.add(            tf.keras.layers.Conv2D(                filters=hp.Choice(                    'num_filters_1',                    values=[32, 64, 128],                    default=64,                ),                kernel_size=3,                activation='relu',                input_shape=self.input_shape            )        )        model.add(tf.keras.layers.MaxPooling2D(pool_size=2))        model.add(            tf.keras.layers.Dropout(                rate=hp.Float(                    'dropout_1',                    min_value=0.0,                    max_value=0.5,                    default=0.25,                    step=0.05                )            )        )        model.add(            tf.keras.layers.Conv2D(                filters=hp.Choice(                    'num_filters_2',                    values=[32, 64, 128],                    default=64,                ),                activation='relu',                kernel_size=3            )        )        model.add(tf.keras.layers.MaxPooling2D(pool_size=2))        model.add(            tf.keras.layers.Dropout(                rate=hp.Float(                    'dropout_2',                    min_value=0.0,                    max_value=0.5,                    default=0.25,                    step=0.05                )            )        )        model.add(tf.keras.layers.Flatten())        model.add(            tf.keras.layers.Dense(                units=hp.Int(                    'units',                    min_value=32,                    max_value=512,                    step=32,                    default=128                ),                activation=hp.Choice(                    'dense_activation',                    values=['relu', 'tanh', 'sigmoid'],                    default='relu'                )            )        )        model.add(tf.keras.layers.Dense(self.num_classes, activation='softmax'))        model.compile(            optimizer=tf.keras.optimizers.Adam(                hp.Float(                    'learning_rate',                    min_value=1e-4,                    max_value=1e-2,                    sampling='LOG',                    default=1e-3                )            ),            loss='sparse_categorical_crossentropy',            metrics=['accuracy']        )        return modelhypermodel = CNNHyperModel(input_shape=(28, 28, 1), num_classes=10)

我们必须以这种方式描述每个层,指定要调优的参数、搜索空间和默认值。

为了搜索超参数值的不同组合,我们将使用RandomSearch类。其背后的思想是从搜索空间中随机迭代采样值,训练模型并测试它们的性能,以选择最佳组合。

这是超参数调优的几个参数:

max_epochs :训练模型的最大epochs数max_trials:最多测试的试验总数(模型配置)PROJECT_NAME:用于可视化的数据将被保存到的文件夹的名称

from kerastuner.tuners import RandomSearchtuner = RandomSearch(    hypermodel,    objective='val_accuracy',    seed=42,    max_trials=20,    directory='random_search',    project_name='fashion_mnist')

您可以调用tuner.search_space_summary()来查看您的tuner所拥有的搜索空间。

对于我们的优化器来说,在训练期间使用early stopping来减少搜索时间是完全有意义的(例如,通过回调)。

callback = tf.keras.callbacks.EarlyStopping(monitor=’val_loss’,     patience=3)tuner.search(training_images, training_labels, epochs=num_of_epochs,     validation_split=0.2, callbacks=[callback])tuner.results_summary()

让我们提取我们拥有的最佳模型,在测试集中评估它的结果,看看调优是否有不同:

best_model = tuner.get_best_models(num_models=1)[0]best_model.evaluate(x_test, y_test)

尽管调谐器的搜索参数很弱,但在测试集上它使我们模型的精度提高到91.4%。考虑到Keras Tuner具有更高级的搜索算法,建议您设置一些搜索参数“在资源预算范围内尽可能高的值”,因此这种改进并不是您能获得的最佳效果,因此我认为这将是一个不错的工具进入您的武器库。

可视化

RandomSearch是其他优化器在您的项目目录中创建的一个文件夹,它将保存带有搜索历史数据的JSON文件,我们将对这些数据进行可视化处理。我们所需要做的就是解析所有这些文件并生成一个带有数据的字典。

import osimport jsonvis_data = []rootdir = 'random_search/fashion_mnist'for subdirs, dirs, files in os.walk(rootdir):    for file in files:        if file.endswith("trial.json"):          with open(subdirs + '/' + file, 'r') as json_file:            data = json_file.read()          vis_data.append(json.loads(data))import hiplot as hipdata = [{'num_filters_1': vis_data[idx]['hyperparameters']['values']['num_filters_1'],         'num_filters_2': vis_data[idx]['hyperparameters']['values']['num_filters_2'],          'units': vis_data[idx]['hyperparameters']['values']['units'],          'dense_activation': vis_data[idx]['hyperparameters']['values']['dense_activation'],          'learning_rate': vis_data[idx]['hyperparameters']['values']['learning_rate'],          'loss': vis_data[idx]['metrics']['metrics']['loss']['observations'][0]['value'],           'val_loss': vis_data[idx]['metrics']['metrics']['val_loss']['observations'][0]['value'],          'accuracy': vis_data[idx]['metrics']['metrics']['accuracy']['observations'][0]['value'],         'val_accuracy': vis_data[idx]['metrics']['metrics']['val_accuracy']['observations'][0]['value']         } for idx in range(num_of_epochs)]hip.Experiment.from_iterable(data).display()

用Hiplot绘制的超参数调优历史

这些信息可以帮助您了解哪些参数最容易影响准确性

你可能感兴趣的:(使用神经网络进行稀疏采样)