Pytorch 如何自动优化/调整 模型超参

文章目录

  • Pytorch 如何自动优化/调整 模型超参
      • 背景
    • 优化模型参数
      • 贝叶斯优化
    • 深度学习框架下的参数优化
    • 平台安装
    • 使用参考
    • 参考

背景

对于优化模型性能表现而言,主要可归纳为两种方式:

  • 采用NAS的方式搜索,获得某个任务上最优的模型结构以及模型参数设置
  • 优化模型参数

诚然,对于第一种方式来说,NAS对算力的消耗是巨大的,因而需要具备巨量计算资源才能够进行,因此具有较高的门槛;而第二种方式来说,消耗的资源要小很多,因而对于本钱小的用户来说,采用第二种是比较合理的方式;尤其是在诸如kaggle等比赛上,很多团队并不具备类似于google那样的算力,因而采用第二种方法提高模型表现是最重要的手段。

优化模型参数

首先需要搞清楚,这里所指的优化模型参数是指在深度学习时代优化模型的超参。什么是超参了?超参是指,必须由人工设定的模型参数,比如学习率,比如mini-batch 的batch size,比如衰减率等等。参数优化特指的是这一类超参。


通常而言,在传统机器学习时代,针对一些结构较为简单的模型,比如随机数森林;其超参数量有限,并且超参的取值范围一般来说比较小,且并非连续数字;比如随机森林的depth参数只能是取整数;因而在这种情况下主要采用的是 网格搜索的方法即grid search 的方法进行合适超参的选取,即超参的优化。
很明显的是,采用grid search的方法不但浪费大量计算资源,并且效率无法保障。经过前人的验证,在传统机器学习时代形成了三种主要的调参方法:

  • grid search
  • random search(随机调参)
  • bayesian optimize (贝叶斯调参/贝叶斯优化)

其中普遍来说,后两者的效果要更好;尤其是bayesian optimzie 性能更好,更加优异;在当时广泛用在诸如kaggle等比赛上(我曾经见过有kaggle的比赛团队使用贝叶斯调参将模型accuracy从76% 调到95%)。

贝叶斯优化

贝叶斯优化的主体思想是基于贝叶斯原理,即根据现有发生的事情(一组超参下模型表现情况)来推断如果采用另一组超参模型会是什么样的表现;简而言之就是基于少量的现有超参组合来估计整个超参组合空间,从中挑选出最为合适的超参组合;这个过程常常采用基于高斯回归来做估计;具体的原理可以参考[1]链接。如果需要尝试下贝叶斯优化的效果,在使用传统算法时可以参考链接,这里有使用案例,可以配合sklearn 进行测试。我这里提供一段代码以供测试

# coding:utf-8from sklearn.datasets import make_classification
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score
import numpy as np
from bayes_opt import BayesianOptimizationx,y = make_classification(n_samples=1000,n_features=10,n_classes=2)
rf = RandomForestClassifier()
#rf.fit(x,y)
print(np.mean(cross_val_score(rf,x,y,cv=20,scoring='roc_auc')))def rf_cv(n_estimators,min_samples_split,max_features,max_depth):'''这里面输入的参量全是超参'''val = cross_val_score(RandomForestClassifier(n_estimators=int(n_estimators),min_samples_split=int(min_samples_split),max_features=min(max_features,0.999),max_depth=int(max_depth),random_state=2),x,y,scoring='roc_auc',cv=20).mean()return valrf_bo = BayesianOptimization(rf_cv,{'n_estimators': (10, 250),'min_samples_split': (2, 25),'max_features': (0.1, 0.999),'max_depth': (5, 15)},)rf_bo.maximize()

深度学习框架下的参数优化

那么现在问题来了,在深度学习框架下,一个模型往往比之前复杂的多,且计算资源消耗得多;即便是使用贝叶斯方法,理论上需要运行的次数更少,但是也难以承担这样的开销。
针对这样的问题,普遍的做法是针对特定的框架开发专门的平台来进行优化。

目前主流的优化方式有两种:1. google vizier 2.pytorch ax and Botorch [4]
其中前者是原先google内部进行调参所开发的工具,并于2017年发表相应论文[2]链接; 目前该方法仅仅公开了调用接口,优化过程需要在google的云平台上进行;当然google vizier实际上是一款强大的auto ML的框架,具有很多优良特性,但是针对普通开发者并不友好。
后者是facebook 推出的基于pytorch的贝叶斯调参工具以及适应性试验平台,适用性较为优良。一般来说针对普通需求的团队或者组织,出于快速开发的需要,还是建议使用pytorch ax botorch 为好。

平台安装

这里的平台安装部署非常简单,保持了pytorch 一贯的易于维护风格,直接使用pip 安装就可以了;安装过程可以参考
ax
botorch
不过需要注意的是,上面两个平台需要基于torch 1.5 版本

使用参考

使用AX 和 Botorch 优化我们自定义的模型是第一步,这里给出一段代码以供参考

class VAE(nn.Module):def __init__(self):super().__init__()self.fc1 = nn.Linear(784, 400)self.fc21 = nn.Linear(400, 20)self.fc22 = nn.Linear(400, 20)self.fc3 = nn.Linear(20, 400)self.fc4 = nn.Linear(400, 784)def encode(self, x):h1 = F.relu(self.fc1(x))return self.fc21(h1), self.fc22(h1)def reparameterize(self, mu, logvar):std = torch.exp(0.5*logvar)eps = torch.randn_like(std)return mu + eps*stddef decode(self, z):h3 = F.relu(self.fc3(z))return torch.sigmoid(self.fc4(h3))def forward(self, x):mu, logvar = self.encode(x.view(-1, 784))z = self.reparameterize(mu, logvar)return self.decode(z), mu, logvarvae_model = VAE().to(device)
vae_state_dict = torch.load(os.path.join(PRETRAINED_LOCATION, "mnist_vae.pt"), map_location=device)
vae_model.load_state_dict(vae_state_dict);

从上面可以看得出,这就是一个普通的pytorch 模型结构定义的方式,接下来就是构建贝叶斯优化要优化的目标函数,这当然是一个黑盒过程。这个函数其实也就是用于描述模型表现的一个函数

def score(y):"""Returns a 'score' for each digit from 0 to 9. It is modeled as a squared exponentialcentered at the digit '3'."""return torch.exp(-2 * (y - 3)**2)# Given the scoring function, we can now write our overall objective, which as discussed above, starts with an image and outputs a score. Let's say the objective computes the expected score given the probabilities from the classifier.# In[6]:def score_image_recognition(x):"""The input x is an image and an expected score based on the CNN classifier andthe scoring function is returned."""with torch.no_grad():probs = torch.exp(cnn_model(x))  # b x 10scores = score(torch.arange(10, device=device, dtype=dtype)).expand(probs.shape)return (probs * scores).sum(dim=1)# Finally, we define a helper function `decode` that takes as input the parameters `mu` and `logvar` of the variational distribution and performs reparameterization and the decoding. We use batched Bayesian optimization to search over the parameters `mu` and `logvar`# In[7]:def decode(train_x):with torch.no_grad():decoded = vae_model.decode(train_x)return decoded.view(train_x.shape[0], 1, 28, 28)

然后就是使用Botorch 和Ax进行模型贝叶斯优化的过程,这个过程分为4个主体步骤,下面代码中一一介绍

# 1.  定义每一次的模型初始化
from botorch.models import SingleTaskGP
from gpytorch.mlls.exact_marginal_log_likelihood import ExactMarginalLogLikelihoodbounds = torch.tensor([[-6.0] * 20, [6.0] * 20], device=device, dtype=dtype)def initialize_model(n=5):# generate training data  train_x = (bounds[1] - bounds[0]) * torch.rand(n, 20, device=device, dtype=dtype) + bounds[0]train_obj = score_image_recognition(decode(train_x))best_observed_value = train_obj.max().item()# define models for objective and constraintmodel = SingleTaskGP(train_X=train_x, train_Y=train_obj)model = model.to(train_x)mll = ExactMarginalLogLikelihood(model.likelihood, model)mll = mll.to(train_x)return train_x, train_obj, mll, model, best_observed_valuefrom botorch.optim import joint_optimizeBATCH_SIZE = 3# 2. 定义要优化的参量
def optimize_acqf_and_get_observation(acq_func):"""Optimizes the acquisition function, and returns a new candidate and a noisy observation"""# optimize 这里定义的调的超参是batch sizecandidates = joint_optimize(acq_function=acq_func,bounds=bounds,q=BATCH_SIZE,num_restarts=10,raw_samples=200,)# observe new values new_x = candidates.detach()new_obj = score_image_recognition(decode(new_x))return new_x, new_obj# 3. 定义优化过程
from botorch import fit_gpytorch_model
from botorch.acquisition.monte_carlo import qExpectedImprovement
from botorch.sampling.samplers import SobolQMCNormalSamplerseed=1
torch.manual_seed(seed)N_BATCH = 50
MC_SAMPLES = 2000
best_observed = []# call helper function to initialize model
train_x, train_obj, mll, model, best_value = initialize_model(n=5)
best_observed.append(best_value)# 4. 开始进行 优化
import warnings
warnings.filterwarnings("ignore")print(f"\nRunning BO ", end='')
from matplotlib import pyplot as plt# run N_BATCH rounds of BayesOpt after the initial random batch
for iteration in range(N_BATCH):    # fit the modelfit_gpytorch_model(mll)# define the qNEI acquisition module using a QMC samplerqmc_sampler = SobolQMCNormalSampler(num_samples=MC_SAMPLES, seed=seed)qEI = qExpectedImprovement(model=model, sampler=qmc_sampler, best_f=best_value)# optimize and get new observationnew_x, new_obj = optimize_acqf_and_get_observation(qEI)# update training pointstrain_x = torch.cat((train_x, new_x))train_obj = torch.cat((train_obj, new_obj))# update progressbest_value = score_image_recognition(decode(train_x)).max().item()best_observed.append(best_value)# reinitialize the model so it is ready for fitting on next iterationmodel.set_train_data(train_x, train_obj, strict=False)print(".", end='')

基本来说,采用Botorch Ax进行优化 就是上面的4个步骤,主要是要把优化的参数在candidates里面列好。
上述的步骤是针对一般性的优化函数,比距高斯回归优化函数的步骤,Botorch 还支持自定义的RBF优化函数;关于这一块的内容可以具体参考Botorch的相关文档。目前有一些研究结果[3]表明一些特定的RBF函数有较好的优化效果。

参考

  1. https://www.cnblogs.com/marsggbo/p/9866764.html
  2. Google Vizier: A Service for Black-Box Optimization
  3. Efficient Hyperparameter Optimization of Deep Learning Algorithms Using Deterministic RBF Surrogates
  4. botorch:programmable bayesian opt in pytorch

Pytorch 如何 优化/调整 模型参数相关推荐

  1. 3Dmax调整模型参数的精度教程

    3Dmax调整模型参数的精度教程 3Dmax调整模型参数的精度有哪些步骤?今天教大家在3Dmax里调整模型参数精度的方法,那么本篇文章讲解需要注意的是:这里的数量就是小数点后的位数,比如设置0,就是整 ...

  2. angularjs中state的参数4_一文梳理pytorch保存和重载模型参数攻略

    训练过程中保存模型参数,就不怕断电了--沃资基·索德 在训练完成之前,我们需要每隔一段时间保存模型当前参数值,一方面可以防止断电重跑,另一方面可以观察不同迭代次数模型的表现:在训练完成以后,我们需要保 ...

  3. 果蝇优化算法优化Z-SCORE模型参数

    Z-SCORE模型 (企业风险预测) 定义 Z = 1.2* X1 + 1.4 X2 + 3.3 *X3 + 0.6 X4 + 1.0* X5 其中 Z 为 Z-SCORE,而 X1 至 X5 为 X ...

  4. PyTorch计算损失函数对模型参数的Hessian矩阵

    前言 在实现Per-FedAvg的代码时,遇到如下问题: 可以发现,我们需要求损失函数对模型参数的Hessian矩阵. 模型定义 我们定义一个比较简单的模型: class ANN(nn.Module) ...

  5. 【转载】Pytorch在加载模型参数时指定设备

    转载 https://sparkydogx.github.io/2018/09/26/pytorch-state-dict-gpu-to-cpu/ >>> torch.load('t ...

  6. numpy将所有数据变为0和1_PyTorch 学习笔记(二):张量、变量、数据集的读取、模组、优化、模型的保存和加载...

    一. 张量 PyTorch里面最基本的操作对象就是Tensor,Tensor是张量的英文,表示的是一个多维的矩阵,比如零维就是一个点,一维就是向量,二维就是一般的矩阵,多维就相当于一个多维的数组,这和 ...

  7. 超参数优化 贝叶斯优化框架_mlmachine-使用贝叶斯优化进行超参数调整

    超参数优化 贝叶斯优化框架 机器 (mlmachine) TL; DR (TL;DR) mlmachine is a Python library that organizes and acceler ...

  8. 谷歌大脑新优化器VeLO火了!让AI自己调整超参数,自适应不同任务,83个任务训练加速比经典Adam更快!...

    点击下方卡片,关注"CVer"公众号 AI/CV重磅干货,第一时间送达 点击进入-> CV 微信技术交流群 萧箫 发自 凹非寺 转载自:量子位(QbitAI) 还在苦恼怎么给 ...

  9. pytorch 状态字典:state_dict 模型和参数保存

    pytorch 中的 state_dict 是一个简单的python的字典对象,将每一层与它的对应参数建立映射关系.(如model的每一层的weights及偏置等等) (注意,只有那些参数可以训练的l ...

最新文章

  1. VMware VSphere 虚拟化云计算学习配置笔记(一)
  2. 一种PacBio测序数据组装得到的基因组序列的纠错方法技术 (专利技术)
  3. Codeforces 216D Spider#39;s Web 树状数组+模拟
  4. 软件测试 学习之路 基本介绍
  5. [Python] - 批处理git conflict文件
  6. NET-TreeView控件说明
  7. java抓取动态生成的网页
  8. Codeforces Round #493 (Div. 2):D. Roman Digits
  9. java迷题_Java——类谜题
  10. c语言编译器好玩的代码,读懂这4个函数,528行代码,你也可以实现一个C语言编译器...
  11. android多个点的圆形进度条,Android 自定义圆形进度条总结
  12. python网址解码_python用于url解码和中文解析的小脚本(python url decoder)
  13. 布局中颜色搭配怎么看最舒服之白色的最佳10种颜色搭配
  14. 调用微信接口上传图片总结
  15. android课程设计健身,健身软件课程设计.doc
  16. Spring统一日志处理(AOP)
  17. iOS 常用第三方库及插件
  18. 一种控制方法并发的注解方法,@Ylock
  19. 分布式存储开发:Curve中的内存管理
  20. vue 打印(模板套打)

热门文章

  1. PhaserTape:把智能手机变成测距仪
  2. AHCI,SATA,NVME
  3. MySQL数据库入门(十)多表复杂查询练习及讲解-下
  4. 验证码爬取并识别-云大urp教务系统大作战(1)
  5. 超凡颖想之一【换位思考】
  6. 肩周炎的自我运动疗法
  7. Java--IDEA之Tomcat重启之后无法活化
  8. 阿里测试岗,面试官狂问自动化,把我问到哑口无言……
  9. php intval获取手机号,微信小程序获取微信绑定授权手机号getPhoneNumber
  10. @Scripts “does not exist”