调参工具的工作原理是:将深度学习的训练、实验过程以kubeflow任务的形式发布,多次实验迭代会有多个任务发布;
目前Katib能支持一些主流算法框架,如tensorflow、mxnet、pytorch、xgboost等。
目前Katib调参功能细化为:超参数调节和神经网络结构搜索,开发者可以在kubeflow ui中实现配置和发布调参任务。
Hyperparameter Tuning
如下图所示,开发人员在ui中设置调参配置有两种方式:对k8s比较熟练的人员可以选择yaml文件配置;
不熟练的人员可以选择在配置选项框中配置,需要注意的是包含工程镜像信息和脚本执行方式的trialTemplate文件需要自己指定。
定义寻参配置,主要包含4个部分:
- parameters: 需要调节的超参和参数的范围
- objective: 收敛目标,如测试集准确率、训练集准确率
- algorithm: 寻参使用的算法,搜索算法介绍详见 https://www.bookstack.cn/read/kubeflow-1.0-en/038175346054c1a3.md#search-algorithms
- trialTemplate: 每一次调参实验的模板,确保调参代码以命令行的方式传入参数运行,如此才能进行调参迭代实验;目前支持k8s-job、kubeflow-tfjob、kubeflow-pytorchjob三种任务方式训练模型
此外可以手动添加额外配置,对任务做限制:
- parallelTrialCount: 并行实验个数
- maxTrialCount: 最大实验次数
- maxFailedTrialCount: 最多失败实验次数
- metricsCollectorSpec: 回收存储每次迭代实验结果的方式,使用方法详见 https://www.bookstack.cn/read/kubeflow-1.0-en/038175346054c1a3.md#metrics-collector
Neural Architecture Search
使用强化学习算法,其他部分同调超参功能。
目前神经网络结构搜索功能仍在初级试用阶段,暂不做复杂功能支持。
Katib调参工程结构
下面以一个随机寻参例子做调参工程结构的介绍:
准备调参工程的镜像
开始调参实验前,需要将将训练模型代码打包成镜像;此外,需要将主脚本需要支持命令行的方式传入参数(如不支持则需要改造代码)
如本次实验中的主代码部分:
train_mnist.py
"""
image: kubeflowkatib/mxnet-mnist-example:v0.0.2
locate in image: /mxnet/example/image-classification/
"""
"""
Train mnist, see more explanation at http://mxnet.io/tutorials/python/mnist.html
"""
if __name__ == '__main__':
# parse args
parser = argparse.ArgumentParser(description="train mnist",
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('--num-classes', type=int, default=10,
help='the number of classes')
parser.add_argument('--num-examples', type=int, default=60000,
help='the number of training examples')
parser.add_argument('--add_stn', action="store_true", default=False,
help='Add Spatial Transformer Network Layer (lenet only)')
fit.add_fit_args(parser)
parser.set_defaults(
# network
network='mlp',
# train
gpus=None,
batch_size=64,
disp_batches=100,
num_epochs=20,
lr=.05,
lr_step_epochs='10'
)
args = parser.parse_args()
制作工程镜像需要的基础镜像得依据具体的需求:如python版本、是否使用gpu等
如果代码执行需要联网,制作镜像时需要将代理配置到系统环境变量中。
配置调参实验
定义寻参配置可以参考Hyperparameter Tuning小节
在这里我使用yaml文件的方式定义任务,详见yaml文件:
random-example-update.yaml
apiVersion: "kubeflow.org/v1alpha3"
kind: Experiment
metadata:
namespace: wbliu
labels:
controller-tools.k8s.io: "1.0"
name: random-example
spec:
objective:
type: maximize
goal: 0.99
objectiveMetricName: Validation-accuracy
additionalMetricNames:
- Train-accuracy
algorithm:
algorithmName: random
parallelTrialCount: 3
maxTrialCount: 12
maxFailedTrialCount: 3
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
trialTemplate:
goTemplate:
rawTemplate: |-
apiVersion: batch/v1
kind: Job
metadata:
name: {{.Trial}}
namespace: {{.NameSpace}}
spec:
template:
spec:
containers:
- name: {{.Trial}}
image: kubeflowkatib/mxnet-mnist-example:v0.0.2
command:
- "python"
- "/mxnet/example/image-classification/train_mnist.py"
- "--batch-size=64"
{{- with .HyperParameters}}
{{- range .}}
- "{{.Name}}={{.Value}}"
{{- end}}
{{- end}}
restartPolicy: Never
spec定义了调参目标、范围、方法
trialTemplate定义了调参任务的方法和执行模板
实验结果展示
调参任务执行完毕后,在ui中能查看调参迭代过程: