ray-tune 笔记 核心概念

1 ray-tune 整体流程

  • 在搜索空间(search space)中定义要调整的超参数
  • ——>将它们传递到指定要tune的目标的可训练对象中(trainable)
  • ——>选择一种搜索算法(search algorithm)来有效地优化您的参数(是mean-accuracy还是loss?最大化还是最小化?)
  • 可选择使用调度程序(scheduler)提前停止搜索并加快实验
  • 与其他配置一起,trainable、search algorithm和scheduler被传递到 tune.run(),它会运行实验并创建试验(trial)。
  • ——>在分析中使用这些试验来检查您的trail结果。

 2 Trainable

Trainable 是一个传递给 Tune 的对象。

Ray Tune 有两种定义可训练对象的方法, Function API 和 Class API。 

假设我们想要优化一个简单的目标函数,例如 a(x^2+b),其中 a 和 b 是我们想要调整以最小化目标的超参数。 由于目标也有一个变量 x,我们需要测试不同的 x 值。 给定 a、b 和 x 的具体选择,我们可以评估目标函数并获得最小化分数。

2.1 Function API

创建一个接收超参数字典的函数(在下面的例子中是trainable函数,pytorch 笔记:使用Tune 进行调参_UQI-LIUWJ的博客-CSDN博客_pytorch 自动调参 中是train函数)。

这个函数在“训练”的过程中中计算一个分数,并将这个分数报告给 Tune:

from ray import tune


def objective(x, a, b): 
    return a * (x ** 0.5) + b
#目标函数


def trainable(config):  
    #将超参数字典config作为trainable函数的参数传进来

    for x in range(20):  
        score = objective(x, config["a"], config["b"])

        tune.report(score=score)  # Send the score to Tune.
        #将每一个x对应的score直接传递给tune

上面的代码使用使用 tune.report(...) 来report训练循环中的中间分数,这在许多机器学习任务中很有用。

如果只想在此循环之外报告最终分数,您可以简单地在Trainable函数的末尾使用 return {"score": score} 。

也可以使用 yield {"score": score} 代替 tune.report(score=score)。

2.2 Class API

from ray import tune


def objective(x, a, b):
    return a * (x ** 2) + b
#定义目标函数


class Trainable(tune.Trainable):
    def setup(self, config):
        # config (dict): A dict of hyperparameters
        self.x = 0
        self.a = config["a"]
        self.b = config["b"]

    def step(self): 
        score = objective(self.x, self.a, self.b)
        self.x += 1
        return {"score": score}
        #注:Class API不能用tune.report

3 搜索空间

        为了优化你的超参数,你必须定义一个搜索空间。 搜索空间定义了超参数的有效值,并可以指定这些值的采样方式(例如,从均匀分布或正态分布)。

tune.uniform(a, b)
a,b之间的均匀分布
tune.quniform(a,b,c)
a,b之间的离散均匀分布,以c为增量
tune.loguniform(a,b)
log空间上的均匀分布
tune.qloguniform(a,b,c)
log空间上a,b之间的离散均匀分布,以c为增量
tune.randn(a,b)
以a为均值,b为标准差的正态分布
 tune.qrandn(a,b,c)
以a为均值,b为标准差的离散正态分布,以c为增量
tune.randint(a, b)
a,b之间的随机整数
tune.qrandint(a,b,c)
a,b之间的随机整数(包括b),以c为增量
tune.choice(["a", "b", "c"]
均匀地选择一个
tune.sample_from(
        lambda function
    )
自定义一个分布(建议由前面的那些组成)

4 Trials

使用 tune.run 来执行和管理超参数调整并生成Trial。

 tune.run() 至少接受一个Trainable作为第一个参数,以及一个配置字典来定义搜索空间。

tune.run(
    trainable, 
    config={"a": tune.uniform(-2,2), 
            "b": tune.uniform(-2,2)})

默认情况下,tune.run 将执行,直到所有Trial停止或出错。

可以通过指定样本数 (num_samples) 运行 num_samples次Trial。 Tune 会自动确定并行运行的Trial次数。

4.1 tune.run 的时候发生了什么?

这一小节我们用如下的例子:

space = {"x": tune.uniform(0, 1)}
tune.run(my_trainable, 
        config=space, 
        num_samples=10)

这里 使用不同的超参数(从 uniform(0, 1) 采样)并行对 my_trainable进行多次评估。 

  • 每个 tune.run都由“driver 进程”和许多“worker 进程”组成。
    • “driver 进程”是调用 tune.run 的 python 进程。 Tune 驱动程序进程运行脚本的节点上运行(调用 tune.run的地方)
      • “driver 进程”产生并行“worker 进程”(Ray actor),负责使用其超参数配置和提供的可训练来评估每个Trail
      • 当 Trainable 正在执行时,“driver 进程” 与每个 Actor(“worker 进程”)进行通信,以接收中间训练结果并在一定情况下暂停/停止 Actor
      • 当 Trainable 终止(或停止)时,相应的actor(“worker 进程”) 也终止。
    • 而 Ray Tune 可训练的“worker 进程”在任何节点上运行
      • 当实例化作为 Ray Actor 的类时,Ray 将在同一台机器(或另一台分布式机器,如果运行 Ray 集群)上的单独进程上启动该类的实例。 然后这个actor可以异步执行方法调用并维护它自己的内部状态。
      • Tune 使用 Ray Actor 并行化多个超参数配置的Trail。 每个参与者都是一个 Python 进程,它执行用户提供的 Trainable 的一个实例。
      • 用户提供的 Trainable 的定义发送到每个“worker 进程”。 每个 Ray Actor 将启动一个待执行的 Trainable 实例。
        • 如果 trainable 是函数(Function API),它将在单独的执行线程上的 Ray actor 进程上执行。
        • 每当调用 tune.report 时,执行线程就会暂停,等待“driver 进程” 的结果。如果没有pause或stop,actor 的执行线程会自动恢复。

4.2 Trail的“生命周期”

初始化

Trial 首先作为超参数样本生成,其参数根据 tune.run 中提供的内容进行配置。

然后将Trail放入要执行的队列中(状态为 PENDING)。

PENDING

Pending 的Trail是要在机器上执行的Trail。

只要 Trial 的资源值可用,Tune 就会运行 Trial(通过启动一个持有配置和训练函数的 ray actor)。

RUNNING一个正在运行的 Trial 被分配到一个 Ray Actor。 可以有多个并行运行的Trail。
ERRORED

如果正在运行的 Trial 引发异常,Tune 将捕获该异常并将 Trial 标记为错误。

请注意,异常可以从“worker 进程”传播到主 Tune “driver 进程”。 如果设置了 max_retries,在一定次数后Tune 会将Trail设置回“PENDING”,然后从最后一个检查点开始。

TERMINATED

如果一个 Trial 被 Stopper/Scheduler 停止,它就会被终止。

如果使用函数 API,则在函数停止时也会终止Trail。

PAUSEDTrail scheduler可以暂停Trail。 这意味着这个“worker 进程”将被停止。 稍后可以从最近的checkpoint恢复暂停的Trail。

4.3 恢复一个tune.run()

在tune.run()的过程中,如果摁下ctrl+C暂停,那么Ray Tune会停止训练,并保存当下最终的checkpoint。

那么,有什么办法可以resume嘛

是有的,我们多传入两个参数即可

tune.run(
    train,
    # other configuration
    name="my_experiment",
    resume=True

)

name是 get_best_logdir返回结果父路径类型的内容(往往是带时间后缀的,如my_trainable_2021-01-29_10-16-44)

name的内容在之前ctrl+C之后输出的内容中,也有体现

 4.4 自动停止tune.run()

4.2中使用手动ctrl+C的防止停止tune.run()那么有没有什么方法可以自动停止tune.run()呢?

——>使用字典

在下面的示例中,每次试验将在完成 10 次迭代或达到 0.98 的平均准确度时停止。 假设这些指标正在增加。

tune.run(
    my_trainable,
    #other parameters
    stop={"training_iteration": 10, "mean_accuracy": 0.98}
)

4.4.1 第一次failure之后停下所有的trail 

默认情况下,tune.run 将继续执行,直到所有试验终止或出错。 要在出现任何试用错误时立即停止整个 Tune 运行,可以:

tune.run(trainable, 
        #。。。。
        fail_fast=True)

4.5 设置log文件的位置和trainable的名字 

tune.run(
        trainable,
        name="example-experiment",
        #。。。) 

 

这样出来的文件就不再是默认的那一套字符串了,而是自己指定的内容

tune.run(trainable, 
        num_samples=2, 
        local_dir="./results", 
        name="test_experiment")

 这样两个Trail folder的位置就是

./results/test_experiment/trial_name_1 和 ./results/test_experiment/trial_name_2 

 4.6 设置Trail folder文件的名称

def trial_name_string(trial):

    return str(trial)[:5]

tune.run(
    trainable,
    trial_name_creator=trial_name_string
)

通过传入一个函数名称的方式,来设置Trail folder文件的名称 

4.7 和TensorBoard结合

找到我们要可视化的Trianable的路径

tensorboard --logdir=~/example-experiment

4.8 重定向输出和报错内容的路径

 

tune.run(
    trainable,
    log_to_file=True)

        

通过设置log_to_file=True,stdout和stderr将会被分别写入对应的trial_logdir/stdout和 trial_logdir/stderr

 如果想指定输出文件,可以传递

  • 一个文件名,将存储组合输出的位置,
  • 两个文件名,分别用于 stdout 和 stderr
tune.run(
    trainable,
    log_to_file="std_combined.log")

tune.run(
    trainable,
    log_to_file=("my_stdout.log", "my_stderr.log"))

 4.9 并行和资源相关

        并行度由 resources_per_trial(默认每次Trial使用 1 个 CPU, 0 个 GPU)和 Tune 可用的资源决定

        默认情况下,Tune 会自动运行 N 个并发Trial,其中 N 是机器上的 CPU(内核)数量。

        比如我们的代码是tune.run(trainable, num_samples=10),但我们机子上是4个CPU,那么我们一次是跑4个并行的Trial

这种默认的并行度可以用 resources_per_trial重写

tune.run(trainable, num_samples=10, resources_per_trial={"cpu": 2})
#每个Trial用两块CPU,所以对于四核电脑来说,一次并发两个Trail


tune.run(trainable, num_samples=10, resources_per_trial={"cpu": 4})
#每个Trial用四块CPU,所以对于四核电脑来说,一次并发一个Trail


tune.run(trainable, num_samples=10, resources_per_trial={"cpu": 0.5})
#每个Trial用半块CPU,所以对于四核电脑来说,一次并发八个Trail

4.10 GPU相关

要使用 GPU,必须在 tune.run(resources_per_trial) 中设置 gpu。 这将为每个Trail自动设置 CUDA_VISIBLE_DEVICES。

分配方式和cpu很类似,当然也可以同时设置


tune.run(trainable, num_samples=10, resources_per_trial={"gpu": 1})

tune.run(trainable, num_samples=10, resources_per_trial={"cpu": 2, "gpu": 1})

5 Search Algorithm

  • 要优化训练过程的超参数,可以使用建议超参数配置的搜索算法。
  • 如果不指定搜索算法,Tune 将默认使用随机搜索。
  • 例如,如果要通过 bayesian-optimization 包,通过使用简单的贝叶斯优化来调参(首先需要 pip install bayesian-optimization),我们可以使用 BayesOptSearch 定义一个算法。 只需将 search_alg 参数传递给 tune.run:
from ray.tune.suggest.bayesopt import BayesOptSearch

# 定义搜索空间
search_space = {"a": tune.uniform(0, 1), "b": tune.uniform(0, 20)}

algo = BayesOptSearch(random_search_steps=4)
#贝叶斯优化来进行调参

tune.run(
    trainable,
    config=search_space,
    search_alg=algo
)

所有tune支持的搜索算法如下:

 6 Schedulers

schedulers可以停止、暂停或调整运行试验的超参数,从而可能使超参数调整过程更快。 

要使用schedulers,只需将schedulers参数传递给 tune.run()

最容易的调度程序是 ASHAScheduler,它将积极终止低性能试验。

使用schedulers时,您可能会遇到兼容性问题,如下面的兼容性矩阵所示。 某些schedulers不能与搜索算法一起使用,并且某些schedulers需要实现checkpoint。

 7 Analyses

tune.run 返回一个 ExperimentAnalysis 对象,其中包含可用于分析训练的方法。 

令result是tune.run的返回结果

result.get_best_trial(metric,mode)

最好的trail

get_best_config

调参最好的结果(最佳配置)

get_best_logdir

调参最好的结果对应的路径

trial_dataframes

各trail每一轮epoch的信息 

参考资料

How does Tune work? — Ray 1.13.0

  • 6
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UQI-LIUWJ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值