超参数优化方案|部署·总结

主要内容记录对于机器学习超参数调整原理,部署相关记录

常用的超参数框架有很多:

  1. Hyperopt
  2. Scikit Optimize
  3. Optuna
  4. NNI

这里主要使用NNI进行部署(简单便捷,支持一键多卡、log输出)

超参数优化

1.优化框架Microsoft NNI

官方GitHub:GitHub - microsoft/nni: An open source AutoML toolkit for automate machine learning lifecycle, including feature engineering, neural architecture search, model compression and hyper-parameter tuning.

操作文档:NNI Documentation — Neural Network Intelligence

========注意:本文档记录于NNI2.0时期,现在已更新至3.0,可能会有所不同=======

1.1 使用教程

1.使用argparser包引入相关超参数

2.将相关参数按照新格式引入原模型

3.期间评价参数使用nni.report_intermediate_result(val_loss)

time_dif = get_time_dif(start_time)
val_loss = evaluate(model, config, val_loader) # 这是你的模型评价参数

'''
nni修改之处,中间评估参数【加入下列代码,让nni获取你的模型评价值】
'''
nni.report_intermediate_result(val_loss)

4.总体评价参数使用nni.report_final_result(val_loss)

nni.report_final_result(val_loss)
# 当你的模型所有的epoch跑完,输出训练后选择的最佳模型评价指标

5.参数引入与更新nni.get_next_parameter()

这里使用tune_params输入到模型中进行迭代计算

if __name__ == '__main__':
    try:
        tuner_params = nni.get_next_parameter()
        print(tuner_params)
        params = vars(get_param())  # namespace->dict
        params.update(tuner_params)
        main(params)
    except Exception as exception:
        print(exception)

6.运行nni

一种方式是通过py文件进行运行:下面是代码示例

from nni.experiment import Experiment

search_space = {
    "num_layers": {"_type": "choice", "_value": [1, 2, 3, 4, 5]},
    "hidden_size": {"_type": "choice", "_value": [64, 128, 256, 512, 1024]},
    "lr": {"_type": "choice", "_value": [0.0001, 0.001, 0.01, 0.1]},
    "dropout_rate": {"_type": "uniform", "_value": [0, 1]}
}

experiment = Experiment('local')
experiment.config.experiment_name = 'test_experiment'
experiment.config.trial_command = 'python 0411_NNI_Data.py'
experiment.config.trial_code_directory = '.'
experiment.config.search_space = search_space
experiment.config.tuner.name = 'TPE'
experiment.config.tuner.class_args['optimize_mode'] = 'maximize'
experiment.config.max_trial_number = 10
experiment.config.trial_concurrency = 1
experiment.run(8088)

# input('Press enter to quit')
# experiment.stop()

seach_space即超参数的取值范围:可以定义类型“choice”、“uniform”等离散或者连续的变量,包含数值、字符等变量。

另一种是通过config.yml文件命令行直接运行,同时可以将search_space文件单独列为.json文件

运行命令:nnictl create --config your_file_name/config.yml --port 8088

# This is the minimal config file for an NNI experiment.
# Use "nnictl create --config config.yml" to launch this experiment.
# Afterwards, you can check "config_detailed.yml" for more explanation.
# 运行:nnictl create --config your_file_name/config.yml --port 8088

experimentName: LSTM
searchSpaceFile: search_space.json
trialCommand: python 0411_NNI_Data.py
trialCodeDirectory: .
trialGpuNumber: 1
trialConcurrency: 1
maxExperimentDuration: 2h
maxTrialNumber: 10
tuner:
  name: TPE
  classArgs:
    optimize_mode: maximize
trainingService:
  platform: local
  useActiveGpu: True

1.2 nni常用指令

# 运行
nnictl create --config your_file_name/config.yml --port 8088
nnictl create [-h] --config CONFIG [--port PORT] [--debug]
              [--url_prefix URL_PREFIX] [--foreground]
# 查看
nnictl view --port 8088 a0fevbwc
# 这里的a0fevbwc就是你的nni实例的id

nnictl view [-h] [--port PORT] [--experiment_dir EXPERIMENT_DIR] id
# 复原
nnictl resume [-h] [--port PORT] [--debug] [--foreground]
              [--experiment_dir EXPERIMENT_DIR]
              id
The Web UI urls are: http://223.255.255.1:8080   http://127.0.0.1:8080
-----------------------------------------------------------------------
​
You can use these commands to get more information about the experiment
-----------------------------------------------------------------------
         commands                       description
​
1. nnictl experiment show        show the information of experiments
2. nnictl trial ls               list all of trial jobs
3. nnictl top                    monitor the status of running experiments
4. nnictl log stderr             show stderr log content
5. nnictl log stdout             show stdout log content
6. nnictl stop                   stop an experiment
7. nnictl trial kill             kill a trial job by id
8. nnictl --help                 get help information about nnictl
-----------------------------------------------------------------------
​

1.3 使用过程中碰到的问题以及解决方案

1.防止结束后退出

如果您使用的是普通 Python 而不是 Jupyter Notebook, 您可以在代码末尾加上一行 input() 或者 signal.pause() 来避免 Python 解释器自动退出, 这样您就能继续使用网页控制台。

实验完全停止之后,您可以使用 nni.experiment.Experiment.view() 重新启动网页控制台。

2. 错误:experimentconfig: type of experiment_name (none) is not typing.union[str, nonetype]

以及AttributeError: 'dict' object has no attribute 'name'

NNI v2.x users may need to manually downgrade typeguard by pip install "typeguard<3" This will be fixed in upcoming v3.0 release【现在已经更新至3.0】

参考链接:incompatible with new typeguard version · Issue #5452 · microsoft/nni · GitHub

3. 问题:有时候用GPU跑?logging参数设置

有时候运行时间过长,某个trial会陷入dead状态,进程不动,在无人值守状态下极易造成时间资源浪费,目前原因不知。

4. 使用技巧--记得设置每个trail的限制时长

设置之后可以规避问题三。

5. 脚本提取超参数数据,中间过程数据等--科研作图用

nni输出的log里包含所有的中间参数信息,包括超参数调整的过程中每个trail的超参数、结果、中间进程的结果等。但论文、报告撰写过程一般需要各位按照要求画图,nni的log目录结构是按照一个nni项目大id目录下多个trial的小id进行分布,故这里使用爬虫过滤一下log内容。

这里给出提取超参数的爬虫代码示例:

import re
import csv

def extract_parameters(file_path):
    parameters = []
    with open(file_path, 'r', encoding='utf-8') as file:
        data = file.read()
        # 这里pattern为你所需要内容的正则表达式
        pattern = r'"parameters":\s\{"num_layers":\s\d+,\s"hidden_size":\s\d+,\s"window_size":\s\d+,\s"batch_size":\s\d+,\s"lr":\s\d+\.\d+,\s"input_size":\s\d+,\s"dropout_rate":\s\d+\.\d+\},'
        matches = re.findall(pattern, data, re.DOTALL)
        # 解析为Python数据结构
        csv_data = []
        dr=0.
        for match in matches:
            match = match.strip(',')  # 去除末尾的逗号
            match = match.replace('"parameters": ', '')  # 去除"parameters":
            eval_data = eval(match)  # 将字符串解析为Python字典
            if (dr != eval_data["dropout_rate"]):
                dr = eval_data["dropout_rate"]
                csv_data.append(eval_data)  # 提取字典中的values作为CSV的一行

        # 写入CSV文件
        column_names = list(csv_data[0].keys())
        csv_file_path = "D:\\Data\\NNIlog\\nni_parameters.csv"
        with open(csv_file_path, mode='w', newline='') as file:
            writer = csv.DictWriter(file, fieldnames=column_names)
            # 写入CSV文件头部
            writer.writeheader()
            # 写入数据行
            writer.writerows(csv_data)
        print(f"CSV文件已保存至:{csv_file_path}")
        
file_path = 'D:\\Data\\NNIlog\\nnimanager.txt' # 你的目录
parameters_list = extract_parameters(file_path)
print(parameters_list)

1.4 需要回顾的问题

1.NNI版本大更新

2.更新后的数据收集需要重写爬虫代码

2.超参数优化原理

2.1 总体超参数优化一览

这里主要参考论文:

《algorithms-for-hyper-parameter-optimization》

《On hyperparameter optimization of machine learning algorithms——Theory and practice》

下图为常用的超参数优化算法的优缺点。

下图为机器学习模型适用的超参数优化算法总结

2.2 树状结构Parzen估计器(TPE)详解

[待施工]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值