Automl框架katib浅析
| 导语 AutoML是一种能将机器学习模型中特征工程、模型选择、超参选择等问题自动化解决的一种方案,使得机器学习模型无需人工干预即可被应用。而katib是一个基于kubernetes生态、简单且可扩展性强的AutoML的一种开源实现。腾讯内部的太极机器学习平台借鉴了katib的一些设计思想,使得AutoML能力集成到训练平台中。 本文将剖析katib框架,对其基本概念、框架和流程进行简要介绍。
一 、AutoML和katib介绍
AutoML
我们知道,机器学习的本质其实是针对某一种学习模型,搜索一组最优参数,使得预设的loss function最少。在这些模型参数之上,还有一组所谓超参数的东西,例如神经网络的层数、学习率、优化算法等,与普通参数不同的是,这些超参数都是在跑某组实验时事先固定好的,并不会在训练过程中调整。
为了避免每次训练都需要人工干预来调整超参数的情况,AutoML应运而生,AutoML将这些与特征、模型、优化、评价有关的重要步骤进行自动化地学习,使得机器学习模型无需人工干预即可被应用。
katib
对于现代机器学习,特别是深度学习而言,使用一组合适的算法训练一组实验需要大量的资源—无论是算力(cpu+gpu)还是存储。kubernetes作为当前资源容器化管理平台的王者,已成为业界机器学习平台的首选。
katib就是基于kubernetes生态的AutoML的一种开源实现,katib隶属于kubeflow社区,实现了一套云原生的超参数搜索与模型结构搜索系统,复用 Kubernetes 对 GPU 等资源的管理能力,同时保证系统的可扩展性。
二 、katib框架剖析
1. 三种crd
katib中有3种概念,分别是experiment、suggestion、trial,分别对应了三种crd,这三种crd相互配合,完成了AutoML对超参数的搜索。 experiment是AutoML的主体对象,用户首先需要构建一个experiment,experiment controller会根据experiment对象创建相应的suggestion对象,即搜索算法,之后根据suggestion对象的输出(即一组超参数),创建一系列的trial对象,即正在的训练实验。三种关系如下:
首先介绍这三种crd:
experiment
experiment表示一个AutoML的实验,当一个experiment完成之后,我们应该能得到这个AutoML搜索出来的最优超参数。一个典型的experiment的yaml如下:
apiVersion: "kubeflow.org/v1alpha2"
kind: Experiment metadata: namespace: kubeflow name: bayesianoptimization-experiment spec: parallelTrialCount: 3 maxTrialCount: 12 maxFailedTrialCount: 3 objective: type: maximize goal: 0.99 objectiveMetricName: Validation-accuracy additionalMetricNames: - accuracy algorithm: algorithmName: bayesianoptimization trialTemplate: goTemplate: rawTemplate: |- apiVersion: batch/v1 kind: Job metadata: name: {{.Trial}} namespace: {{.NameSpace}} spec: template: spec: containers: - name: {{.Trial}} image: katib/mxnet-mnist-example command: - "python" - "/mxnet/example/image-classification/train_mnist.py" - "--batch-size=64" {{- with .HyperParameters}} {{- range .}} - "{{.Name}}={{.Value}}" {{- end}} {{- end}} restartPolicy: Never parameters: - name: --lr parameterType: double feasibleSpace: min: "0.01" max: "0.03" - name: --num-layers parameterType: int feasibleSpace: min: "2" max: "5" - name: --optimizer parameterType: categorical feasibleSpace: list: - sgd - adam - ftrl
该yaml表示了一个experiment需要搜索3种超参数,分别是
- --lr学习率,搜索范围从0.01-0.03;
- --num-layers网络层数,范围是2-5;
- --optimizer优化算法,候选者是sgd,adam,ftrl。
采用的搜索算法是bayesianoptimization,搜索目标是Validation-accuracy,并且在Validation-accuracy大于0.99时停止搜索。
同时该experiment设定了最多跑12组实验,一次并行最多跑3组,如果超过3组实验失败了则停止。
suggestion
suggestion表示的是AutoML中的搜索算法,katib并没有实现某种特定的算法,而是给出了算法需要遵循的规范。搜索算法真正的实现是通过跑一个容器,并且该容器需要尊徐katib的一些通信规范实现的。一个典型的suggestion yaml如下:
apiVersion: kubeflow.org/v1beta1
kind: Suggestion
metadata:
labels:
controller-tools.k8s.io: "1.0"
name: bayesianoptimization-example
namespace: kubeflow
ownerReferences:
- apiVersion: kubeflow.org/v1beta1
blockOwnerDeletion: true
controller: true
kind: Experiment
name: bayesianoptimization-example
uid: c14270f4-d81f-4991-a049-00f0beb32770
spec:
algorithmName: bayesianoptimization
requests: 12
resumePolicy: LongRunning
status:
suggestionCount: 12
suggestions:
- name: bayesianoptimization-example-9xms9qr9
parameterAssignments:
- name: lr
value: "0.013988097299564232"
- name: num-layers
value: "4"
- name: optimizer
value: ftrl
- name: bayesianoptimization-example-9pk89ks2
parameterAssignments:
- name: lr
value: "0.01858578989212678"
- name: num-layers
value: "4"
- name: optimizer
value: ftrl
- name: bayesianoptimization-example-z7vftq6w
parameterAssignments:
- name: lr
value: "0.013979382191901278"
- name: num-layers
value: "5"
- name: optimizer
value: adam
这个yaml表示使用bayesianoptimization这个算法,从configmap中可以看出bayesianoptimization实际是一个docker镜像:
$ kubectl get configmaps -n kubeflow katib-config -o yaml
apiVersion: v1
data:
...
suggestion: |-
{
"hyperband": {
"image": "gcr.io/kubeflow-images-public/katib/v1beta1/suggestion-hyperband"
},
"bayesianoptimization": {
"image": "gcr.io/kubeflow-images-public/katib/v1beta1/suggestion-skopt"
}
}
...
当bayesianoptimization这个算法跑起来之后,suggestion controller会创建suggestion-skopt这个容器,会随着容器的运行产生新的超参数,并且写到status中,例如第一轮产生的超参数是--lr=0.013988097299564232,--num-layers=4,--optimizer=ftrl。这些超参数将会传递给trial跑一轮实验。
trial
trial表示的是在AutoML中的搜索算法给出一组超参后,真正使用这组超参跑一个真实的ML实验。一个典型的trial yaml中如下:
apiVersion: kubeflow.org/v1beta1
kind: Trial
metadata:
creationTimestamp: "2020-09-25T12:46:49Z"
finalizers:
- clean-metrics-in-db
generation: 1
labels:
controller-tools.k8s.io: "1.0"
experiment: bayesianoptimization-example
name: bayesianoptimization-example-4w96gvjb
namespace: kubeflow
ownerReferences:
- apiVersion: kubeflow.org/v1beta1
blockOwnerDeletion: true
controller: true
kind: Experiment
name: bayesianoptimization-example
uid: c14270f4-d81f-4991-a049-00f0beb32770
resourceVersion: "1242374"
uid: c1e395c9-27ea-4b3b-9e3b-933fb0130336
spec:
metricsCollector:
collector:
kind: StdOut
objective:
additionalMetricNames:
- Train-accuracy
goal: 0.99
metricStrategies:
- name: Validation-accuracy
value: max
- name: Train-accuracy
value: max
objectiveMetricName: Validation-accuracy
type: maximize
parameterAssignments:
- name: lr
value: "0.018575758156150434"
- name: num-layers
value: "2"
- name: optimizer
value: adam
runSpec:
apiVersion: batch/v1
kind: Job
metadata:
name: random-example-4w96gvjb
namespace: kubeflow
spec:
template:
spec:
containers:
- command:
- python3
- /opt/mxnet-mnist/mnist.py
- --batch-size=64
- --lr=0.018575758156150434
- --num-layers=2
- --optimizer=adam
image: docker.io/kubeflowkatib/mxnet-mnist
name: training-container
restartPolicy: Never
status:
completionTime: "2020-09-25T12:38:19Z"
observation:
metrics:
- latest: "0.939988"
max: "0.948447"
min: "0.927249"
name: Validation-accuracy
- latest: "0.947745"
max: "0.947745"
min: "0.910914"
name: Train-accuracy
startTime: "2020-09-25T12:37:18Z"
这个trial使用bayesianoptimization算法产生的超参数--lr=0.018575758156150434,--num-layers=2,--optimizer=adam来跑mxnet-mnist实验。实验结果是Train-accuracy=0.948447,Validation-accuracy=0.948447。experiment将拿这组实验结果来选取最优的超参数。
2. 主要组件
katib主要由以下几个组件组成:
-
katib controllers:katib的主逻辑部分,分为以下三个controller:
- experiment controller:根据experiment创建suggestion和trials,同时根据trials的状态,从suggestion中获取hyper parameters,创建新的trials。也就是说experiment是suggestion和trials的桥梁。
- suggestion controller:AutoML的算法控制器,接受trials和experiment,输出hyper parameters。
- trial controller:训练实验控制器,根据suggestion产生的hyper parameters,构建真正的训练程序,并实时更新训练状态。
- db-manager: 一个gRPC server,用于接受用户存储db数据和获取db数据的请求。
- pod webhook:拦截automl mpijob创建的pod,并且在pod中增加一个metrics sidecar container。这个metrics container会收集pod的训练日志,并上报给db-manager。
- experiment webhook:主要用于校验用户的experiment。
3. 框架图
katib的几个组件之间的关系如下所示:
4. 流程
下面简单介绍一下,一个用户从创建katib AutoML任务到获得结果之间,katib都做了哪些步骤,以mpijob为例:
1) 创建任务(experiment)
云原生用户提交experiment yaml给apiserver。apiserver创建experiment object。
2) 创建算法(suggestion)
- experiment controller观察到有新的experiment object产生,根据experiment创建一个suggestion object。
- suggestion controller观察到有新的suggestion创建,产生相应的suggestion pod,该pod拉取用户的算法镜像(要求该镜像实现一个grpc服务,并且监听指定端口、遵循平台协议)。
- 该pod接受experiment的请求并回复算法产生的hyper parameters,更新suggestion object。
3)创建训练实例(trial)
- experiment controller创建完算法后,由于刚开始没有任何trial,experiment controller会更新suggestion object的request,要求suggestion产生hyper paramters,并根据新的hyper paramters创建trials。trials controller会根据trials object创建mpijob
- 同时mpijob webhook会截取到该mpijob的创建请求,访问ts校验额度,创建相应实例。
4)训练实例的状态更新
- 创建状态->训练状态:mpijob训练实例产生后,会产生相应pod,并运行训练程序。pod webhook截取该pod的创建请求,增加metrics sidecar容器。metrics sidecar会读取用户的训练结果(要求用户训练程序将训练结构以指定格式写到写到指定文件),上报给db-manager存储。
- 训练状态->结束状态:mpijob训练完成后,trial会watch到,并从db-manger中获取训练结构、更新trial object状态。trial object状态变化会反映到experiment controller, 以促成下一轮hyper parameters的产生。即转到step 3的逻辑
5) 实验结束
- 当experiment观察到某一个trial的训练结果达到目标或者运行了指定数目的trial之后,实验结束并更新experiment状态。
三、如何开发自己的搜索算法
1.如果用户想要新开发一些automl调参算法,需要创建一个grpc服务,并监听指定端口(由环境变量KATIB_SUGGESTION_PORT指定)
2. grpc的请求格式为:
type GetSuggestionsRequest struct {
Experiment *Experiment `protobuf:"bytes,1,opt,name=experiment"
json:"experiment,omitempty"`
Trials []*Trial `protobuf:"bytes,2,rep,name=trials"
json:"trials,omitempty"`
RequestNumber int32
`protobuf:"varint,3,opt,name=request_number,json=requestNumber"
json:"request_number,omitempty"`
}
3. grpc的回复格式为:
type GetSuggestionsReply struct {
ParameterAssignments []*GetSuggestionsReply_ParameterAssignments
`protobuf:"bytes,1,rep,name=parameter_assignments,json=parameterAssignments"
json:"parameter_assignments,omitempty"`
Algorithm *AlgorithmSpec
`protobuf:"bytes,2,opt,name=algorithm" json:"algorithm,omitempty"`
}
四、总结
katib是基于kubernetes生态,在kubeflow社区下的一种AutoML开源框架。它有3个概念,分别是experiment,suggestion和trial。experiment创建suggestion,suggestion根据当前trial给出新的超参数,并且由experiment使用超参数创建新的trial,最终从众多trial中选择结果最好的一组trial,使用该组trial的超参数作为最终的超参。
如何有效地进行代码 Review?
浅析硬盘Media Error
- Vue.js系列之二Vue实例
- autoload自动加载机制使用
- EF 约定介绍
- 关于EF Code First模式不同建模方式对建表产生的影响
- C# 命名空间和程序集
- C# new关键字和对象类型转换(双括号、is操作符、as操作符)
- 防止小程序多次点击跳转解决方案
- 详述 SQL 中的 distinct 和 row_number() over() 的区别及用法
- Web API系列之三 基本功能实现
- 微信小程序的省市选择组件 citySelector分享
- 详述 Java 语言中的 String、StringBuffer 和 StringBuilder 的使用方法及区别
- Class与Style绑定
- 机器学习并不难
- android的RadioGroup讲解
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android加载Assets目录中Xml布局文件
- Android系统在shell中的df命令实现
- 面向对象版tab 栏切换案例
- 构造函数和原型
- 解决json中ensure_ascii=False的问题
- Django自定义列表 models字段显示方式
- 无人驾驶环境感知 | 01 车道线检测网络LanNet原理及实现
- 对象存储COS-数据处理能力升级!“组合拳”助力存储新时代!
- 基于python图像处理API的使用示例
- python 的topk算法实例
- android使用viewpager计算偏移量实现选项卡功能
- Android画板开发之撤销反撤销功能
- Android实现复制Assets文件到SD卡
- Android画板开发之添加背景和保存画板内容为图片
- 直播插件体系设计