外链论坛

 找回密码
 立即注册
搜索
查看: 35|回复: 4

运用贝叶斯优化调节深度神经网络

[复制链接]

3052

主题

2万

回帖

9910万

积分

论坛元老

Rank: 8Rank: 8

积分
99108887
发表于 2024-8-31 06:06:44 | 显示全部楼层 |阅读模式

在前一篇文案中,咱们介绍了一个运用Tensorflow和深度学习办法进行图像归类的案例科研

尽管案例科研很少,但它展示了设备学习项目的每一个周期:清理、预处理、模型构建、训练和评定。但咱们跳过了调优。

在本文中,咱们将深入科研超参数优化。一样咱们运用Tensorflow中包括的Fashion MNIST[1]数据集。

提醒一下,数据集包括60000个 训练集中的灰度图像和10,000 测试集中的图像。每一个照片表率属于10个类别(“T恤/上衣”、“裤子”、“套头衫”等)之一的时尚项目。因此呢咱们有一个多类归类问题。

设置

我将简要介绍准备数据集的过程相关更加多信息,请查看上一篇文案第1部分:简而言之,过程如下:

加载数据。

分为训练、验证和测试集。

规范化0–255到0–1范围内的像素值。

one-hot目的变量。

#load data

(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

# split into train, validation and test setstrain_x, val_x, train_y, val_y = train_test_split(train_images, train_labels, stratify=train_labels, random_state=48, test_size=0.05

)

(test_x, test_y)=(test_images, test_labels)

# normalize pixels to range 0-1train_x = train_x / 255.0val_x = val_x / 255.0test_x = test_x /255.0#one-hot encode target variable

train_y = to_categorical(train_y)

val_y = to_categorical(val_y)

test_y = to_categorical(test_y)

概括来讲,所有训练、验证和测试集的形状如下:

print(train_x.shape)  #(57000, 28, 28)print(train_y.shape)  #(57000, 10)print(val_x.shape)    #(3000, 28, 28)print(val_y.shape)    #(3000, 10)print(test_x.shape)#(10000, 28, 28)print(test_y.shape)   #(10000, 10)

超参数调节

此刻咱们运用Keras Tuner库[2]:它将帮忙咱们容易调节神经网络的超参数。要安装它,请执行以下操作:

pip install keras-tuner

重视:Keras Tuner需要Python 3.6+和TensorFlow 2.0+

快速提醒一下,超参数调节设备学习项目的基本部分。超参数有两种类型:

结构超参数:定义模型整体架构的超参数(例如,隐匿单元的数量、层数)

优化器超参数:影响训练速度和质量的参数(例如,优化器的学习速度和类型、批次体积、epoch数)

为何调优很棘手?

为何需要超参数调优库?咱们不可尝试所有可能的组合,瞧瞧验证集上什么是最好的吗?

不幸的是,

深层神经网络需要海量时间来训练,乃至需要几天。

倘若你在云上训练大型模型(例如亚马逊Sagemaker),记住每次实验都要花钱。

因此呢,一种限制超参数搜索空间的剪枝策略是必要的。

贝叶斯优化

幸运的是,Keras调节供给了贝叶斯优化调节器。贝叶斯优化调节搜索每一个可能的组合,而是遵循一个迭代过程,随机选取前几个。而后,基于这些超参数的性能,贝叶斯调节选取下一个可能的最佳。

因此呢每一个超参数的选取都取决于先前的尝试。按照历史选取下一组超参数并评定性能的迭代次数将连续,直到调节器找到最佳组合或用尽最大次数的尝试。咱们能够用参数“max_trials”来配置它。

除了贝叶斯优化调节器之外,Keras调节器还供给了两个调节器:RandomSearch和Hyperband。咱们将在本文末尾讨论它们。

回到咱们的例子

接下来,咱们将对网络应用超参数调节。在上一篇文案中,咱们尝试了两种网络架构,标准多层感知器(MLP)和卷积神经网络(CNN)。

多层感知器(MLP)

首要,让咱们记住咱们的基线MLP模型是什么:

model_mlp = Sequential()

model_mlp.add(Flatten(input_shape=(2828

)))

model_mlp.add(Dense(350, activation=relu

))

model_mlp.add(Dense(10, activation=softmax

))

print(model_mlp.summary())

model_mlp.compile(optimizer="adam",loss=categorical_crossentropy

)

调节过程需要两种重点办法

hp.Int:设置值为整数的超参数范围-例如,“Dense”层中的隐匿单位数:

model.add(Dense(units = hp.Int(dense-bot, min_value=50, max_value=350, step=50

))

hp.Choice:为超参数供给一组值-例如,Adam或SGD是最佳优化器?

hp_optimizer=hp.Choice(Optimizer, values=[AdamSGD

])

因此呢,在原始MLP示例中运用贝叶斯优化调节器,咱们测试以下超参数:

隐匿层数:1–3

第1体积:50–350

第二和第三层体积:50–350

Dropout率:0、0.1、0.2

优化器:SGD(nesterov=True, momentum=0.9)或Adam

学习率:0.1、0.01、0.001

model = Sequential()

model.add(Dense(units = hp.Int(dense-bot, min_value=50, max_value=350, step=50), input_shape=(784,), activation=relu

))

for i in range(hp.Int(num_dense_layers12

)):

  model.add(Dense(units=hp.Int(dense_+ str(i), min_value=50, max_value=100, step=25), activation=relu

))

  model.add(Dropout(hp.Choice(dropout_+ str(i), values=[0.00.10.2

])))

model.add(Dense(10,activation="softmax"

))

hp_optimizer=hp.Choice(Optimizer, values=[AdamSGD

])

if hp_optimizer == Adam

:

    hp_learning_rate = hp.Choice(learning_rate, values=[1e-11e-21e-3

])

elif hp_optimizer == SGD

:

    hp_learning_rate = hp.Choice(learning_rate, values=[1e-11e-21e-3

])

    nesterov=True    momentum=0.9

重视第5行的for循环:咱们让模型决定网络的深度!

最后,咱们起步调节器。重视前面说到的max_trials参数。

model.compile(optimizer = hp_optimizer, loss=categorical_crossentropy, metrics=[accuracy

])

tuner_mlp = kt.tuners.BayesianOptimization(

    model,

    seed=random_seed,

    objective=val_loss

,

    max_trials=30

,

    directory=.

,

    project_name=tuning-mlp

)

tuner_mlp.search(train_x, train_y, epochs=50, batch_size=32

, validation_data=(dev_x, dev_y), callbacks=callback)

这将打印:

该过程耗尽了迭代次数,花费了约1小时完成。咱们能够运用以下命令打印模型的最优超参数:

best_mlp_hyperparameters = tuner_mlp.get_best_hyperparameters(1)[0

]

print("Best Hyper-parameters"

)

best_mlp_hyperparameters.values

这般咱们此刻能够运用最优超参数重新训练咱们的模型:

model_mlp = Sequential()

model_mlp.add(Dense(best_mlp_hyperparameters[dense-bot], input_shape=(784,), activation=relu

))

for i in range(best_mlp_hyperparameters[num_dense_layers

]):

model_mlp.add(Dense(units=best_mlp_hyperparameters[dense_ +str(i)], activation=relu

))

  model_mlp.add(Dropout(rate=best_mlp_hyperparameters[dropout_

 +str(i)]))

model_mlp.add(Dense(10,activation="softmax"

))

model_mlp.compile(optimizer=best_mlp_hyperparameters[Optimizer], loss=categorical_crossentropy,metrics=[accuracy

])

history_mlp= model_mlp.fit(train_x, train_y, epochs=100, batch_size=32

, validation_data=(dev_x, dev_y), callbacks=callback)

咱们能够用更少的仔细信息重新训练咱们的模型:

model_mlp=tuner_mlp.hypermodel.build(best_mlp_hyperparameters)

history_mlp=model_mlp.fit(train_x, train_y, epochs=100, batch_size=32

validation_data=(dev_x, dev_y), callbacks=callback)

咱们此刻要做的便是检测测试精度:

mlp_test_loss, mlp_test_acc = model_mlp.evaluate(test_x,  test_y, verbose=2

)

print(\nTest accuracy:

, mlp_test_acc)

# Test accuracy: 0.8823

与基线的模型测试精度相比:

基线MLP模型:86.6%

最佳MLP模型:88.2%

事实上,咱们观察到测试准确度相差约3%!

卷积神经网络(CNN)

一样咱们将遵循相同的程序。运用CNN,咱们能够测试更加多的参数。

首要,这是咱们的基线模型:

model_cnn = Sequential()

model_cnn.add(Conv2D(32, (33), activation=relu, input_shape=(28281

)))

model_cnn.add(MaxPooling2D((22

)))

model_cnn.add(Flatten())

model_cnn.add(Dense(100, activation=relu

))

model_cnn.add(Dense(10, activation=softmax

))

model_cnn.compile(optimizer="adam", loss=categorical_crossentropy, metrics=[accuracy

])

基线模型仅包括一组滤波和池层。针对咱们的调优,咱们将测试以下内容:

卷积、MaxPooling和Dropout层的“块”数

每一个块中Conv层的滤波器尺寸:32、64

Conv层上的有效或相同填充

最后附加层的隐匿体积:25–150,乘以25

优化器:SGD(nesterov=真,动量=0.9)或Adam

学习率:0.01,0.001

model = Sequential()

model = Sequential()

model.add(Input(shape=(28281

)))

for i in range(hp.Int(num_blocks12

)):

hp_padding=hp.Choice(padding_+ str(i), values=[validsame

])

    hp_filters=hp.Choice(filters_+ str(i), values=[3264

])

    model.add(Conv2D(hp_filters, (33), padding=hp_padding, activation=relu, kernel_initializer=he_uniform, input_shape=(28281

)))

    model.add(MaxPooling2D((22

)))

    model.add(Dropout(hp.Choice(dropout_+ str(i), values=[0.00.10.2

])))

model.add(Flatten())

hp_units = hp.Int(units, min_value=25, max_value=150, step=25

)

model.add(Dense(hp_units, activation=relu, kernel_initializer=he_uniform

))

model.add(Dense(10,activation="softmax"

))

hp_learning_rate = hp.Choice(learning_rate, values=[1e-21e-3

])

hp_optimizer=hp.Choice(Optimizer, values=[AdamSGD

])

if hp_optimizer == Adam

:

    hp_learning_rate = hp.Choice(learning_rate, values=[1e-21e-3

])

elifhp_optimizer ==SGD

:

    hp_learning_rate = hp.Choice(learning_rate, values=[1e-21e-3

])

    nesterov=True    momentum=0.9

像以前同样咱们让网络决定其深度。

此刻咱们准备好调用贝叶斯调节器了。最大迭代次数设置为100:

model.compile( optimizer=hp_optimizer,loss=categorical_crossentropy, metrics=[accuracy

])

tuner_cnn = kt.tuners.BayesianOptimization(

    model,

    objective=val_loss

,

max_trials=100

,

    directory=.

,

    project_name=tuning-cnn

)

这将打印:

最好的超参数是:

最后,咱们运用最佳超参数训练咱们的CNN模型:

model_cnn = Sequential()

model_cnn.add(Input(shape=(28281

)))

foriin range(best_cnn_hyperparameters[num_blocks

]):

  hp_padding=best_cnn_hyperparameters[padding_

+ str(i)]

  hp_filters=best_cnn_hyperparameters[filters_

+ str(i)]

  model_cnn.add(Conv2D(hp_filters, (33), padding=hp_padding, activation=relu, kernel_initializer=he_uniform, input_shape=(28281

)))

model_cnn.add(MaxPooling2D((22

)))

  model_cnn.add(Dropout(best_cnn_hyperparameters[dropout_

+ str(i)]))

model_cnn.add(Flatten())

model_cnn.add(Dense(best_cnn_hyperparameters[units], activation=relu, kernel_initializer=he_uniform

))

model_cnn.add(Dense(10,activation="softmax"

))

model_cnn.compile(optimizer=best_cnn_hyperparameters[Optimizer

], 

                                                 loss=categorical_crossentropy

                                                 metrics=[accuracy

])

print(model_cnn.summary())

history_cnn= model_cnn.fit(train_x, train_y, epochs=50, batch_size=32

, validation_data=(dev_x, dev_y), callbacks=callback)

检测测试集的准确性:

cnn_test_loss, cnn_test_acc = model_cnn.evaluate(test_x,  test_y, verbose=2

)

print(\nTest accuracy:

, cnn_test_acc)

# Test accuracy: 0.92

与基线的CNN模型测试精度相比(来自咱们上一篇文案):

基线CNN模型:90.8%

最佳CNN模型:92%

一样咱们看到了优化模型的性能加强

除了准确性之外,咱们能够确认调节器的工作做得很好,原由如下:

调节器在每种状况下都选取了一个非零的Dropout值,尽管咱们调节供给了零Dropout。这是意料之中的,由于Dropout是一种减少过拟合的机制。

有趣的是,最好的CNN架构是标准管道,其中每层中的滤波器数量逐步增多。这是意料之中的,由于随着后续层中的计算向前推进,模式变得更加繁杂因此呢,有更加多的模式组合需要更加多的滤波器才可捕捉

结束

毫无疑问,Keras Tuner是运用Tensorflow优化深度神经网络的通用工具。

显著选取是贝叶斯优化调节器。然则,还有两个选项能够运用

随机搜索:这种类型的调节经过随机选取几个超参数来避免探索超参数的全部搜索空间。然则,它不可保证此调节器会找到最佳调节器。

Hyperband:这个调节选取有些超参数的随机组合,并运用它们来训练模型,只用于几个epoch。而后调节运用这些超参数来训练模型,直到所有的epoch都用完,并从中选取最好的。

感谢阅读!

参考引用

Fashion MNIST dataset by Zalando, https://www.kaggle.com/datasets/zalando-research/fashionmnist, MIT Licence (MIT) Copyright © [2017]

Keras Tuner, https://keras.io/keras_tuner/

✄-----------------------------------------------

看到这儿,说明你爱好这篇文案,请点击「在看」或顺手「转发」「点赞」。

欢迎微X搜索「panchuangxx」,添加博主磐小小仙微X,每日伴侣圈更新一篇高质量推文(无宣传),为您供给更加多精彩内容。

▼   扫描二维码添加博主  ▼▼  

回复

使用道具 举报

2880

主题

2万

回帖

9997万

积分

论坛元老

Rank: 8Rank: 8

积分
99979669
发表于 2024-10-10 12:38:33 | 显示全部楼层
太棒了、厉害、为你打call、点赞、非常精彩等。
回复

使用道具 举报

3080

主题

2万

回帖

9996万

积分

论坛元老

Rank: 8Rank: 8

积分
99968837
发表于 2024-10-14 22:56:34 | 显示全部楼层
感谢你的精彩评论,带给我新的思考角度。
回复

使用道具 举报

3027

主题

2万

回帖

9909万

积分

论坛元老

Rank: 8Rank: 8

积分
99099001
发表于 2024-10-16 00:51:18 | 显示全部楼层
你的话语如春风拂面,让我感到无比温暖。
回复

使用道具 举报

3027

主题

2万

回帖

9909万

积分

论坛元老

Rank: 8Rank: 8

积分
99099001
发表于 2024-10-27 14:38:37 | 显示全部楼层
在遇到你之前,我对人世间是否有真正的圣人是怀疑的。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

站点统计|Archiver|手机版|小黑屋|外链论坛 ( 非经营性网站 )|网站地图

GMT+8, 2024-11-5 14:57 , Processed in 0.073278 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2023, Tencent Cloud.