浅谈深度学习中超参数调整策略

 

欢迎访问Oldpan博客,分享人工智能有趣消息,持续酝酿深度学习质量文。

前言

深度学习中,设计模型以及保证模型的正确性是首要需要考虑的。当模型设置完成时,理论上模型不存在问题,实现效果也通过计算可以复现出来。一切准备就绪后,那么接下来需要操作的就是——调参了。

正文

为什么很多人都称深度学习为炼丹?为什么丹药那么难炼?为什么为什么,因为炼丹的调料放多少不知道啊?得一个一个去尝试啊。

很多时候,模型搭建好了,但是随之而来的就是参数选择问题。参数选择我们一般大概分为两种方式,手动选择和自动选择。

  • 手动选择就是我们利用对模型的理解和对结果的分析进行调参,手动选择参数,这样准确率稍高一些,但是时间长了我们会受不了,有时候真的会怀疑人生。
  • 自动选择就是设计一个自动调参工具,让程序自己跑就行了,当然这个对机子的要求高一些,相同情况下用GPU调参速度是用CPU的几十倍。

接下来主要说一下自动选择的几个方式,程序利用pytorch代码说明。

手动选择

手动选择就是自个儿看,自己根据对模型的理解和对结果的分析进行,最好是可视化卷积层进行分析,这样可以观察并慢慢寻找到一些迭代时隐藏的规律。

关于如何可视化可以看一下,知乎上相关问题的回答

自动选择

自动选择说白了就是让代码一直跑,然后用你提供的不同超参数一遍一遍尝试然后得到比较满意的结果。

Photo by SigOpt

如上图,假设我们有2个超参数(n_estimatorsmax_depth),每个超参数的取值的不同组合所得到的score结果也不同。取值越合适score越高,当然上面的图只是展示了二维的超参数,如果是3个或3个以上的超参数,我们可以想象一个超平面,最合适的参数组合得到的分数在最高点。

网格搜索

网格搜索是我们最常用的超参数调参策略。我们把每个可能的超参数组合都写下来,进行尝试:

style_weights = [0.1, 0.5, 1, 1.5, 2.5, 5, 10, 15, 20, 50, 100, 150, 200, 500, 1000,
                 5000, 10000, 50000, 100000, 500000, 1000000]
content_weights = [1, 5, 10, 100]

比如上面的代码,我们有两个超参数,分别是style_weightcontent_weight,我们列出这些参数可能的值,然后进行训练:

for i in range(len(content_weights)):
    for j in range(len(style_weights)):
        output = run_painterly_transfer(cnn, cnn_normalization_mean, cnn_normalization_std, style_img=style_image,
                                        content_img=content_image, mask_img=mask_image, tmask_img=tmask_image,
                                        style_weight=int(style_weights[j]), content_weight=int(content_weights[i]))

代码很简单,通过循环将你觉得可能的参数都尝试了一遍,我们可以在程序执行的过程中把你觉得需要的中间结果和最终结果都保存到一个文件夹中,当训练完成后去查看分析即可。

整个过程就像下面的动图:

Photo by SigOpt

一个一个找,尝试就行了,可能某一天你睡觉起来,就会发现惊喜。

随机搜索

随机搜索就是利用分布函数来模拟随机数,然后利用随机数生成的参数来进行训练:

# 我们利用numpy中的随机数生成器来生成随机数
style_weights_rd = list(np.random.randint(0, 1000, size=20))
content_weights_rd = list(np.random.randint(0, 10, size=5))

同上面的参数一样,只不过换成了在特定范围的随机值,当然这个范围是我们自己定的。

然后将下面list换成随机list即可:

for i in range(len(content_weights_rd)):
    for j in range(len(style_weights_rd)):
        output = run_painterly_transfer(cnn, cnn_normalization_mean, cnn_normalization_std, style_img=style_image,
                                        content_img=content_image, mask_img=mask_image, tmask_img=tmask_image,
                                        style_weight=int(style_weights_rd[j]), content_weight=int(content_weights_rd[i]))

整个过程动图分析如下:

Photo by SigOpt

在《Random Search for Hyper-Parameter Optimization》这篇论文中提高了为什么我们经常使用随机搜索而不是用网格,其实上面的图很形象了,那就是实际中适合的参数往往在一个完整分布中的一小块部分,我们使用网络搜索并不能保证直接搜索到合适的超参数中,而随机搜索则大大提高了找到合适参数的可能性。

Photo by Bergstra, 2012

上图则表明重要参数和不重要的参数在不同方法下的搜索情况,我们给了两个超参数,网格搜索只能在我们设定的一小组范围内进行,而随机搜索中的每个超参数是独立的。也就是说网格搜索因为我们的设定,超参数之间是有些许联系的,并不是独一无二。研究表明随机搜索能够更快地减少验证集的误差。

下面的代码中,加入content_weight中的1和5对结果的影响不大,但是我们通过for循环组合,和style_weights中的所有值都进行了尝试了,显然浪费了时间。

style_weights = [0.1, 0.5, 1, 1.5, 2.5, 5, 10, 15, 20, 50, 100, 150, 200, 500, 1000,
                   5000, 10000, 50000, 100000, 500000, 1000000]
content_weights = [1, 5, 10, 100]

贝叶斯优化

这个优化方法,说白了就是让优化算法来对超参数进行优化,也就是说,这个优化算法的对象是超参数,然后结果是loss损失,通过求超参数对损失的梯度来实现对超参数的更新,呃,这个计算量真的很大很大,个人几乎不用这个方法,一般都是大企业才会用。通过学习来调节参数,这个结果真的是更加不可预知的。

Photo by SigOpt

上面这个图大概描述了这个过程,当然这只是“好的那一面”的过程。

后记

复现、调参并不容易,其实很多论文中实现的效果看起来不错,但是实际上如果自己去复现是很难的。而且也有很多论文其实自身并没有复现,只是理论上的实现就可以发表,神经网络在调参中不确定性因素太多,玄学深度学习名副其实。最后再强调一遍,如果超参数足够多,训练一两个月都是有可能的。

所以说,路道阻且长。

此文由腾讯云爬虫爬取,文章来源于Oldpan博客

欢迎关注Oldpan博客公众号,持续酝酿深度学习质量文:

### 使用网格搜索优化随机森林 (RF) 超参数 为了有效利用网格搜索来优化随机森林模型的超参数,可以遵循以下方法: #### 准备数据集并导入必要的库 首先,确保已准备好用于训练的数据集,并加载所需的Python库。 ```python import numpy as np from sklearn.model_selection import GridSearchCV, train_test_split from sklearn.ensemble import RandomForestRegressor from sklearn.datasets import make_regression ``` 创建或载入数据集之后,将其划分为训练集和测试集以便后续评估模型表现。 ```python X, y = make_regression(n_features=4, n_informative=2, random_state=0, shuffle=False) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) ``` #### 定义超参数范围 定义要探索的最大特征数`max_features`、最大深度`max_depth`、内部节点再划分所需最小样本数`min_samples_split`以及叶子节点最少样本数`min_samples_leaf`等重要超参数的不同取值组合[^3]。 ```python param_grid = { 'n_estimators': [100, 200], 'max_features': ['auto', 'sqrt'], 'max_depth' : [None, 10, 20], 'min_samples_split': [2, 5], 'min_samples_leaf': [1, 2] } ``` #### 初始化随机森林回归器对象并与GridSearchCV结合使用 通过初始化`RandomForestRegressor()`实例并将此实例传递给`GridSearchCV`函数来进行全面搜索。设置交叉验证次数和其他必要选项以提高效率和准确性。 ```python rf = RandomForestRegressor(random_state = 42) grid_search = GridSearchCV(estimator=rf, param_grid=param_grid, cv=5, scoring='neg_mean_squared_error', verbose=2, n_jobs=-1) ``` 执行上述配置好的网格搜索过程,在整个指定范围内寻找最优解。 ```python grid_result = grid_search.fit(X_train, y_train) ``` 获取最佳得分及其对应的参数集合。 ```python best_params = grid_result.best_params_ print(f"Best parameters found: {best_params}") ``` 最后应用这些最佳参数重新构建一个新的随机森林模型,并对其进行最终评价。 ```python optimized_rf = RandomForestRegressor(**best_params).fit(X_train, y_train) final_score = optimized_rf.score(X_test, y_test) print(f"The final R-squared score on the testing set is: {final_score:.3f}") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老潘的博客

请老潘吃块饼干!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值