重庆建设招标造价信息网站,虚拟主机免费云服务器,做论坛网站如何赚钱,网络设计网站多少钱1. AutoML 概述
AutoML是指对于一个超参数优化任务#xff08;比如规定计算资源内#xff0c;调整网络结构找到准确率最高的网络#xff09;#xff0c;尽量减少人为干预#xff0c;使用某种学习机制#xff0c;来调节这些超参数#xff0c;使得目标问题达到最优。
这…1. AutoML 概述
AutoML是指对于一个超参数优化任务比如规定计算资源内调整网络结构找到准确率最高的网络尽量减少人为干预使用某种学习机制来调节这些超参数使得目标问题达到最优。
这些学习机制包括最基本的
Grid SearchRandom Search
也有比较传统的
贝叶斯优化多臂老虎机multi-armed bandit
还有比较新颖的
进化算法强化学习
在AutoML中有一个分支专注于自动学习深度神经网络的网络架构叫做Neural architecture search (NAS)当下分类网络中效果最好的EfficientNets就是这个领域的产物。
2. Bayesian Optimization
2.1 Grid Search Random Search
神经网络训练是由许多超参数决定的例如网络深度卷积类型卷积核大小channel数量等等。为了找到一个好的超参数组合最直观的想法就是Grid Search其实也就是对离散化的参数取值进行穷举搜索
不同于传统AutoML相关的问题比如决策树相关的RandomForestGBDT等。对于NAS领域随着网络越来越复杂超参数也越来越多要想将每种可能的超参数组合都实验一遍(即Grid Search)明显不现实。
另一种比较朴素的想法是进行随机搜索但显然也不是一种高效的策略。
2.2 Bayesian Optimization
贝叶斯优化是一种近似逼近的方法用一个代理函数来拟合超参数与模型评价结果之间的关系在每次迭代中采集函数 根据当前代理函数的反馈选择最有潜力的超参数进行实验。实验得到了一组真实的超参数-模型评价结果的pair对将这个结果喂回给代理函数进行修正如此反复迭代期望其在过程中以更高的效率找到比较好的超参数组合。
上面介绍的是贝叶斯优化中最简单的一种形式Sequential model-based optimization (SMBO)这段描述中涉及了3个概念
代理函数
代理函数本质上就是一个概率模型对超参数与模型效果背后对应的黑箱映射关系进行建模。
常用的代理函数有高斯过程高斯混合模型还有基于树的模型比如回归随机森林
首先我们用f代表超参数与模型效果背后对应的真实映射关系
我们用代理函数记为模型M来建模f代表的映射关系。
也就是通过已知的采样数据集D拟合模型M来得到一个近似表达f的概率模型
FITMODEL(M,D) - p(y|x, D)
在后面的介绍中都假设f服从高斯过程也就是使用高斯过程作为代理函数
即f~GP(μ,K)。(GP:高斯过程μ:均值K:协方差kernel)。
所以预测也是服从正态分布的即有p(y|x,D)N(y|μ,σ^2)
采集函数
采集函数被用来根据当前的代理函数选出本次迭代要尝试的超参数。
采集函数的选择有许多种包括Probability of improvement、Expected improvement、Entropy search、 Upper confidence bound等。
这里给出Expected improvement的详细定义
假设f′minf,这个f′表示目前已知的f的最小值。
utility function定义如下代表超参数为x时的收益/提升:
u(x)max(0,f′−f(x))
Expected improvement的含义是收益/提升的期望
因此 EI(x) E[u(x)|x,D]
当带入我们的假设即f服从高斯过程时,EI的计算公式如下 于是遍寻所有的超参数取值x便可以通过采集函数获取本次迭代需要尝试的超参数。
exploitation-and-exploration 利用与探索
在学习贝叶斯优化的过程中我思考了两个问题
Grid Search Random Search 不是很高效的结论很容易接受究其根本原因是什么
为什么不直接选择能够使代理函数取最优值的超参数组合还要使用采集函数呢
我发现很多资料使用exploitation-and-exploration的概念对此进行了解释。
上面两个问题代表了搜索过程中的两种极端。
第一个问题即 Random Search 对应了exploration搜索过程只是一味的在探索位置区域并没有对已经获得的信息进行任何的利用。
第二个问题如果我们直接使用代理函数对应的概率模型进行搜索对应了exploitation即充分的对已知信息进行挖掘利用但是缺乏对位置超参数区域的探索。
因此我们需要在利用与探索之间进行一些权衡来达到更高的搜索效率和更好的搜索结果。
Expected improvement这个采集函数就能很好的体现这一点我们回到它的公式 当均值μ(x)较小时EI(x)取值会因为左式较大而增大 当协方差K(x,x)较大时EI(x)取值会因为右式较大而增大
μ(x)较小对应的是已经探索过的点中哪些比较好的超参数组合
K(x,x)较大对应的是那些为探索过的区域
因此Expected improvement 公式从原理上对exploitation-and-exploration进行了很好权衡当发现了一个点结果不错时会更倾向于在它附近进行深入挖掘但同时这个邻域内的点的方差不断变小采集函数又会去探索那些完全未知的区域。
观察下面两幅图可以更直观的感受一下。其中蓝色曲线是要拟合的函数红色点是已经探索过的采样点橙色曲线对应在这些采样点上学习出来的概率模型的均值浅蓝色阴影是置信区间。
3. Bayesian Optimization 练习
为了更好的学习贝叶斯优化的使用这里做了一个练习。
首先我选择的是scikit- optimization库的ask-and-tell方法实现我的贝叶斯优化器。
使用peaks函数加上一些随机噪声来作为待优化的目标函数。函数定义如下
def cost_function(x, y):z 3 * (1-x)**2 * np.exp(-(x**2) - (y1)**2) \- 10 * (x/5 - x**3 - y**5) * np.exp(-x**2 - y**2) \- 1/3 * np.exp(-(x1)**2 - y**2) np.random.randn()return z函数可视化如下 编写 Bayesian Optimization 寻优代码如下
# -*- coding: utf-8 -*-Created on Fri Oct 11 20:55:06 2019skopt(Scikit Optimize) 练习1使用ask-and-tell的流程来模拟进行超参数的优化author: zyb_asfrom mpl_toolkits.mplot3d import Axes3D
import imageio
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpldef cost_function(x, y):z 3 * (1-x)**2 * np.exp(-(x**2) - (y1)**2) \- 10 * (x/5 - x**3 - y**5) * np.exp(-x**2 - y**2) \- 1/3 * np.exp(-(x1)**2 - y**2) np.random.randn()return zdef transform_coordinate2index(coordinate, interval0.01):index int((coordinate 3)/interval)return index# 计算目标函数Z(用于画图)
interval 0.01
xnp.arange(-3, 3, interval)
ynp.arange(-3, 3, interval)
X, Y np.meshgrid(x, y)
Z np.zeros(X.shape)
for i in range(X.shape[0]):for j in range(X.shape[1]):xij X[i][j]yij Y[i][j]Z[i][j] cost_function(xij, yij)# 绘制目标函数
fig plt.figure()
ax Axes3D(fig)
plt.xlabel(x)
plt.ylabel(y)
ax.plot_surface(X, Y, Z, rstride1, cstride1, cmaprainbow)
ax.view_init(elev-50.,azim270)
plt.savefig(peaks.png)
plt.show()# 计算理论最优值用于判断优化效果
min_z np.min(Z)
min_idx np.where(Zmin_z)
x_min_idx int(min_idx[1])
y_min_idx int(min_idx[0])# define the skopt optimizer
import skopt
opt skopt.Optimizer([skopt.space.Real(-3.0, 3.0, namex),skopt.space.Real(-3.0, 3.0, namey),],n_initial_points5,base_estimatorGP,acq_funcEI,acq_optimizerauto,random_state0,)cmap mpl.cm.get_cmap(jet, 1000) # color mapimages []
total_epochs 100
point_x_list []
point_y_list []
best_cost 1e100
best_hyperparams None
for i in range(total_epochs):fig plt.figure()plt.imshow(Z, cmapcmap)# plot the hyperparams find beforeplt.scatter(point_x_list, point_y_list, s30, cslategray)# plot the theoretical best hyperparamsplt.scatter(x_min_idx, y_min_idx, s50, cwhite)# ask a new hyperparamscur_hyperparams opt.ask()# use the hyperparams to train the model# ...# evaluate the costcur_cost cost_function(cur_hyperparams[0], cur_hyperparams[1])print(i1, cur_cost, cur_hyperparams)find_new_best Falseif cur_cost best_cost:best_cost cur_costbest_hyperparams cur_hyperparamsprint(find new best hyperparams)find_new_best True# tell the optimizer the costopt.tell(cur_hyperparams, cur_cost)# 绘制本次超参的位置 new_x_list []new_y_list []new_x transform_coordinate2index(cur_hyperparams[0])new_y transform_coordinate2index(cur_hyperparams[1])new_x_list.append(new_x)new_y_list.append(new_y)point_x_list.append(new_x)point_y_list.append(new_y)if find_new_best:plt.scatter(new_x_list, new_y_list, s100, cblack) else:plt.scatter(new_x_list, new_y_list, s30, cblack)# 显示plt.savefig(temp.png)plt.close()#plt.show()# 记录一帧图像images.append(imageio.imread(temp.png))# 生成gif图
imageio.mimsave(GP_rand5.gif, images, duration0.5)使用高斯过程作为代理函数的优化过程可视化如下前5次随机共迭代100次进行了3次实验均能收敛到最优值附近 图中白点是全局最优值当前迭代的采样点显示为黑色如果当前采样点是历史最优值会进行放大显示。图片大小原因gif图没传上来只能放个静态图片在这里感兴趣可以运行下代码看下具体效果
使用随机森林作为代理函数前5次随机共迭代100次进行了3次实验只有一次收敛到最优值附近优化过程分别可视化如下
实验1成功 实验2失败 实验3失败 通过实验我发现在低维问题的优化中高斯过程要比基于树模型的代理函数好用。有材料提到像随机森林GBDT这样的树模型在高维空间中的表现要好很多这个我没有验证。
此外随机森林这类的模型有个突出优势就是能够处理离散输入这使得在很多情况下它是唯一选择。
因此我又修改了下代码尝试让RF在本实验上的效果大幅提升。
思路是使用RandomForestRandom结合的方式进行并行的搜索。每次搜索3个点一个点使用采集函数获得两个点进行随机然后将3个点的采样值都喂回给RF进行学习这样就很好的解决了RF不喜欢探索未知区域进而无法寻找到最优值的问题。
改进的代码如下
# -*- coding: utf-8 -*-Created on Mon Oct 14 15:51:56 2019skopt(Scikit Optimize) 练习3练习2的优化版本使用RandomForestRandom结合的方式进行并行的策略搜索
RF模型结合随机试图解决RF模型探索未知区域能力差的缺点author: zyb_as
from mpl_toolkits.mplot3d import Axes3D
import imageio
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpldef cost_function(x, y):z 3 * (1-x)**2 * np.exp(-(x**2) - (y1)**2) \- 10 * (x/5 - x**3 - y**5) * np.exp(-x**2 - y**2) \- 1/3 * np.exp(-(x1)**2 - y**2) np.random.randn()return zdef transform_coordinate2index(coordinate, interval0.01):index int((coordinate 3)/interval)return index# 计算目标函数Z(用于画图)
interval 0.01
xnp.arange(-3, 3, interval)
ynp.arange(-3, 3, interval)
X, Y np.meshgrid(x, y)
Z np.zeros(X.shape)
for i in range(X.shape[0]):for j in range(X.shape[1]):xij X[i][j]yij Y[i][j]Z[i][j] cost_function(xij, yij)# 计算理论最优值用于判断优化效果
min_z np.min(Z)
min_idx np.where(Zmin_z)
x_min_idx int(min_idx[1])
y_min_idx int(min_idx[0])# define the skopt optimizer
import skopt
opt skopt.Optimizer([skopt.space.Real(-3.0, 3.0, namex),skopt.space.Real(-3.0, 3.0, namey),],n_initial_points1,base_estimatorRF, # can choose GP, RF, ET, GBRTacq_funcEI,acq_optimizerauto,random_state0,)# use these api as a random augment polices loader
rand_opt skopt.Optimizer([skopt.space.Real(-3.0, 3.0, namex),skopt.space.Real(-3.0, 3.0, namey),],n_initial_points1e10,base_estimatorRF, # no matter to choose what valueacq_funcEI,acq_optimizerauto,random_state3, # better to be different with opts random_state)cmap mpl.cm.get_cmap(jet, 1000) # color mapimages []
total_epochs 30
point_x_list []
point_y_list []
best_cost 1e100
best_hyperparams None
parallel_level 3
for i in range(total_epochs):fig plt.figure()plt.imshow(Z, cmapcmap)# plot the hyperparams find beforeplt.scatter(point_x_list, point_y_list, s30, cslategray)# plot the theoretical best hyperparamsplt.scatter(x_min_idx, y_min_idx, s50, cwhite)# ask for a list of new hyperparamsrand_hyperparams_list rand_opt.ask(parallel_level - 1)new_hyperparams opt.ask()new_hyperparams_list rand_hyperparams_listnew_hyperparams_list.append(new_hyperparams)# parallel distribute taskscost_list []for parallel_index in range(parallel_level):cur_hyperparams new_hyperparams_list[parallel_index]# use the hyperparams to train the model# ...# evaluate the costcur_cost cost_function(cur_hyperparams[0], cur_hyperparams[1])print(epoch{}_parallel{}.format(i1, parallel_index1), cur_cost, cur_hyperparams)cost_list.append(cur_cost) if cur_cost best_cost:best_cost cur_costbest_hyperparams cur_hyperparamsprint(find new best hyperparams)# tell the optimizer the cost for parallel_index in range(parallel_level):opt.tell(new_hyperparams_list[parallel_index], cost_list[parallel_index])rand_opt.tell(new_hyperparams_list[parallel_index], cost_list[parallel_index])# 绘制本次并行探索的超参的位置new_x_list []new_y_list []for parallel_index in range(parallel_level):cur_hyperparams new_hyperparams_list[parallel_index]new_x transform_coordinate2index(cur_hyperparams[0])new_y transform_coordinate2index(cur_hyperparams[1])new_x_list.append(new_x)new_y_list.append(new_y)point_x_list.append(new_x)point_y_list.append(new_y)plt.scatter(new_x_list, new_y_list, s30, cblack) # 显示plt.savefig(temp.png)plt.close()#plt.show()# 记录一帧图像images.append(imageio.imread(temp.png))# 生成gif图
imageio.mimsave(parallel_randRF_rand5.gif, images, duration1)改进后的效果如下 可以看到改进的效果还是挺明显的对于exploitation-and-exploration有了很好的权衡。
借助 Bayesian Optimization 自动搜索数据增强方法的探索
借鉴Insight研究员的一个工作
AutoML数据增广
GitHub
我探索了使用 Bayesian Optimization 自动搜索数据增强方法的实验。
在上面工作的基础上我主要做了如下的修改
1 将代理任务的网络由一个5层CNN改为mobilenet。
这样做虽然明显提高了整个算法搜索过程的耗时但是单个评估实验的结论会更可靠基于mobilenet的规模也不至于使得搜索过程的耗时完全不可接受。
2 对架构进行修改使其支持并行训练
实际使用中经常面临可用的gpu资源比较零碎要想提高实验速度需要解决多卡多机器的问题。
因此我对程序框架进行了修改采用单服务端多客户端的模式。服务端负责学习贝叶斯优化器并根据学习结果分发任务给客户端客户端领任务对收到的数据增强组合进行评估然后把结果返回给服务端。并且简化了使用过程仅需要修改一个类似如下的配置文件 这个实验由于比较消耗资源有很多细节需要实验和调整暂时还没有得到很好的成果。再加上最近又出了PBAFast AutoAugmentRandAugment这三篇自动搜索数据增强方法的paper个人认为更有价值去研究毕竟时间有限本实验对应的这种思路后面可能就不再继续跟进了。
不过我感觉这个尝试还是很有意义的因为这份代码可以作为一个autoML的通用并行框架使用稍微改改就可以跑其它任务。
整个项目的代码整理到了我维护的AI工具箱中具体位置bayesian-autoaugment感兴趣的小伙伴可以看看
参考文献
写作本文阅读的资料及文中部分配图出自以下地址
AutoML数据增广
AutoML总结
贝叶斯优化(Bayesian Optimization)深入理解
机器学习贝叶斯超参数优化
贝叶斯优化(BayesianOptimization)
Bayesian Optimization Primer