我使用 tqdm 打印带有 hyperopt 的长时间运行优化过程的进度条。这个过程调用一个函数 500 次,每次调用大约需要 10 到 20 分钟,所以我开始让进度显示更精细一点,并tqdm.update在循环中添加了一些 -语句,逐步推进进度条以避免有两个嵌套的进度条,同时仍然能够立即看到到目前为止执行了多少函数调用。
现在丑陋的结果是这样的:
15%|???? | 73.69999999999993/500 [7:40:31<102:54:08, 868.98s/it, evaluating fold 2 of 2 folds...]Iteration 1, loss = 2.50358388
Run Code Online (Sandbox Code Playgroud)
你可以在上面看到,这是函数的第 73 次调用,第 73 次函数调用大约完成了 70%。事实上,我只是估计了m函数中子步骤的数量(可能因调用而异)并使用分数1/m来更新进度条。然后在函数调用之后,我只是将进度条同步回一个完整的整数,以避免添加舍入错误。
当然,准确性在这里根本不是问题。但我想显示 73.70 而不是 73.69999999999993。我已经尝试将我的更新值四舍五入到两个小数位,这并不能解决问题,因为浮点数的精度问题,如果一个数字不能完全用浮点数表示,那么它又变得丑陋了。根据tqdm的文档,这部分隐藏在r_bar整个格式字符串的部分中,但我找不到设置它的方法。你能帮我解决这个问题吗?
根据文档r_bar默认为:
r_bar='| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, '
Run Code Online (Sandbox Code Playgroud)
这是我的代码:
with tqdm(iterable=None, initial=num_trials, maxinterval=maxinterval, total=max_evals, ascii=False, disable=show_progressbar is False) as progress_bar:
def fn_to_minimize(*args, **kwargs):
return fn(*args, **kwargs, _progress_bar=progress_bar)
for num_trials in range(num_trials, max_evals):
progress_bar.n=float(num_trials)
progress_bar.refresh()
best = fmin(**kwargs, fn=fn_to_minimize, trials=trials, max_evals=num_trials+1)
# do some other stuff here
Run Code Online (Sandbox Code Playgroud)
在被调用的函数(kwargs顺便说一句中的条目之一)中,我像这样更新进度条:
_progress_bar.update(round(update_value, 2))
Run Code Online (Sandbox Code Playgroud)
对于 中的舍入问题tqdm,您可以直接编辑 中的格式r_bar作为 中的参数之一bar_format。例如:
from tqdm import trange
for i in trange(int(7e7), bar_format = "{desc}: {percentage:.3f}%|{bar}| {n_fmt}/{total_fmt} [{elapsed}<{remaining}"):
pass
Run Code Online (Sandbox Code Playgroud)
对于 2 位小数,您可以简单地将 编辑{n_fmt}为{n:.2f}。您还可以编辑其他参数,例如{desc}或向percentage.
from tqdm import trange
for i in trange(int(7e7), bar_format = "{desc}: {percentage:.10f}%|{bar}| {n:.2f}/{total_fmt} [{elapsed}<{remaining}"):
pass
Run Code Online (Sandbox Code Playgroud)
查看 的源代码后tqdm,n_fmt实际上指向str(n),因此传入 的格式化版本n可以绕过其内在格式。
if unit_scale:
n_fmt = format_sizeof(n, divisor=unit_divisor)
total_fmt = format_sizeof(total, divisor=unit_divisor) \
if total is not None else '?'
else:
n_fmt = str(n)
total_fmt = str(total) if total is not None else '?'
try:
postfix = ', ' + postfix if postfix else ''
except TypeError:
pass
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2435 次 |
| 最近记录: |