0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

PyTorch教程-19.4. 多保真超參數(shù)優(yōu)化

jf_pJlTbmA9 ? 來源:PyTorch ? 作者:PyTorch ? 2023-06-05 15:44 ? 次閱讀

即使在中等規(guī)模的數(shù)據(jù)集上,訓(xùn)練神經(jīng)網(wǎng)絡(luò)也可能很昂貴。根據(jù)配置空間(第 19.1.1.2 節(jié)),超參數(shù)優(yōu)化需要數(shù)十到數(shù)百次函數(shù)評估才能找到性能良好的超參數(shù)配置。正如我們在19.3 節(jié)中看到的 ,我們可以通過利用并行資源顯著加快 HPO 的整體時鐘時間,但這并不會減少所需的總計算量。

在本節(jié)中,我們將展示如何加速超參數(shù)配置的評估。隨機搜索等方法為每個超參數(shù)評估分配相同數(shù)量的資源(例如,epoch 數(shù)、訓(xùn)練數(shù)據(jù)點)。圖 19.4.1 描繪了一組使用不同超參數(shù)配置訓(xùn)練的神經(jīng)網(wǎng)絡(luò)的學(xué)習(xí)曲線。經(jīng)過幾個 epoch 之后,我們已經(jīng)能夠在視覺上區(qū)分性能良好和次優(yōu)的配置。然而,學(xué)習(xí)曲線是嘈雜的,我們可能仍然需要全部 100 個 epoch 來確定表現(xiàn)最好的一個。

pYYBAGR9PYOAF8kfAAxEY-DeiWg543.svg

圖 19.4.1隨機超參數(shù)配置的學(xué)習(xí)曲線

多保真超參數(shù)優(yōu)化將更多資源分配給有前途的配置,并盡早停止對性能不佳的配置的評估。這加快了優(yōu)化過程,因為我們可以為相同的資源總量嘗試更多的配置。

更正式地說,我們擴展了第 19.1.1 節(jié)中的定義 ,這樣我們的目標函數(shù) f(x,r)獲得額外的輸入 r∈[rmin,rmax], 指定我們愿意為配置評估花費的資源量x. 我們假設(shè)錯誤 f(x,r)隨著r,而計算成本c(x,r)增加。通常, r表示訓(xùn)練神經(jīng)網(wǎng)絡(luò)的時期數(shù),但它也可以是訓(xùn)練子集大小或交叉驗證折疊數(shù)。

from collections import defaultdict
import numpy as np
from scipy import stats
from d2l import torch as d2l

d2l.set_figsize()

19.4.1。連續(xù)減半

使隨機搜索適應(yīng)多保真度設(shè)置的最簡單方法之一是連續(xù)減半 (Jamieson 和 Talwalkar,2016 年,Karnin等人,2013 年)?;舅枷胧菑腘配置,例如從配置空間隨機采樣,并訓(xùn)練它們中的每一個 rmin只有時代。然后,我們丟棄一部分表現(xiàn)最差的試驗,并對其余試驗進行更長時間的訓(xùn)練。重復(fù)這個過程,更少的試驗運行更長時間,直到至少有一個試驗達到rmax時代。

更正式地說,考慮最低預(yù)算rmin(例如 1 個 epoch),最大預(yù)算rmax,例如 max_epochs在我們之前的例子中,還有一個減半常數(shù) η∈{2,3,…}. 為簡單起見,假設(shè) rmax=rminηK, 和K∈I. 那么初始配置的數(shù)量是N=ηK. 讓我們定義一組梯級 R={rmin,rminη,rminη2,…,rmax}.

一輪連續(xù)減半的過程如下。我們從跑步開始N試驗到第一梯級rmin. 對驗證錯誤進行排序,我們保持頂部1/η分數(shù)(相當于ηK?1配置)并丟棄所有其余的。幸存的試驗被訓(xùn)練用于下一個梯級(rminηepochs),然后重復(fù)該過程。在每個梯級,一個1/η部分試驗存活下來,他們的訓(xùn)練繼續(xù)進行η倍大的預(yù)算。有了這個特別的選擇N, 只有一個試驗將被訓(xùn)練到全部預(yù)算rmax. 一旦這樣一輪連續(xù)的減半完成,我們就會用一組新的初始配置開始下一輪,迭代直到總預(yù)算用完。

poYBAGR9PYmAFbkqAAozwWvrwco526.svg

圖 19.4.2隨機超參數(shù)配置的學(xué)習(xí)曲線。

我們將第 19.2 節(jié)HPOScheduler的基類子類化 ,以實現(xiàn)連續(xù)減半,允許通用 對象對配置進行采樣(在我們下面的示例中,它將是 a )。此外,用戶必須通過最少的資源HPOSearcherRandomSearcherrmin, 最大資源 rmax和η作為輸入。在我們的調(diào)度程序中,我們維護一個配置隊列,這些配置仍需要針對當前梯級進行評估ri. 每次我們跳到下一個梯級時,我們都會更新隊列。

class SuccessiveHalvingScheduler(d2l.HPOScheduler): #@save
  def __init__(self, searcher, eta, r_min, r_max, prefact=1):
    self.save_hyperparameters()
    # Compute K, which is later used to determine the number of configurations
    self.K = int(np.log(r_max / r_min) / np.log(eta))
    # Define the rungs
    self.rung_levels = [r_min * eta ** k for k in range(self.K + 1)]
    if r_max not in self.rung_levels:
      # The final rung should be r_max
      self.rung_levels.append(r_max)
      self.K += 1
    # Bookkeeping
    self.observed_error_at_rungs = defaultdict(list)
    self.all_observed_error_at_rungs = defaultdict(list)
    # Our processing queue
    self.queue = []

一開始我們的隊列是空的,我們用 n=prefact?ηK配置,首先在最小的梯級上進行評估rmin. 這里, prefact允許我們在不同的上下文中重用我們的代碼。出于本節(jié)的目的,我們固定 prefact=1. 每次資源可用并且HPOTuner對象查詢suggest函數(shù)時,我們都會從隊列中返回一個元素。一旦我們完成一輪連續(xù)減半,這意味著我們評估了最高資源級別上的所有幸存配置rmax并且我們的隊列是空的,我們用一組新的、隨機采樣的配置重新開始整個過程??。

@d2l.add_to_class(SuccessiveHalvingScheduler) #@save
def suggest(self):
  if len(self.queue) == 0:
    # Start a new round of successive halving
    # Number of configurations for the first rung:
    n0 = int(self.prefact * self.eta ** self.K)
    for _ in range(n0):
      config = self.searcher.sample_configuration()
      config["max_epochs"] = self.r_min # Set r = r_min
      self.queue.append(config)
  # Return an element from the queue
  return self.queue.pop()

當我們收集到一個新的數(shù)據(jù)點時,我們首先更新搜索器模塊。之后我們檢查我們是否已經(jīng)收集了當前梯級上的所有數(shù)據(jù)點。如果是這樣,我們對所有配置進行排序并推頂 1η配置到隊列中。

@d2l.add_to_class(SuccessiveHalvingScheduler) #@save
def update(self, config: dict, error: float, info=None):
  ri = int(config["max_epochs"]) # Rung r_i
  # Update our searcher, e.g if we use Bayesian optimization later
  self.searcher.update(config, error, additional_info=info)
  self.all_observed_error_at_rungs[ri].append((config, error))
  if ri < self.r_max:
    # Bookkeeping
    self.observed_error_at_rungs[ri].append((config, error))
    # Determine how many configurations should be evaluated on this rung
    ki = self.K - self.rung_levels.index(ri)
    ni = int(self.prefact * self.eta ** ki)
    # If we observed all configuration on this rung r_i, we estimate the
    # top 1 / eta configuration, add them to queue and promote them for
    # the next rung r_{i+1}
    if len(self.observed_error_at_rungs[ri]) >= ni:
      kiplus1 = ki - 1
      niplus1 = int(self.prefact * self.eta ** kiplus1)
      best_performing_configurations = self.get_top_n_configurations(
        rung_level=ri, n=niplus1
      )
      riplus1 = self.rung_levels[self.K - kiplus1] # r_{i+1}
      # Queue may not be empty: insert new entries at the beginning
      self.queue = [
        dict(config, max_epochs=riplus1)
        for config in best_performing_configurations
      ] + self.queue
      self.observed_error_at_rungs[ri] = [] # Reset

配置根據(jù)其在當前梯級上觀察到的性能進行排序。

@d2l.add_to_class(SuccessiveHalvingScheduler) #@save
def get_top_n_configurations(self, rung_level, n):
  rung = self.observed_error_at_rungs[rung_level]
  if not rung:
    return []
  sorted_rung = sorted(rung, key=lambda x: x[1])
  return [x[0] for x in sorted_rung[:n]]

讓我們看看在我們的神經(jīng)網(wǎng)絡(luò)示例中連續(xù)減半是如何進行的。我們將使用rmin=2,η=2, rmax=10, 所以梯級是2,4,8,10.

min_number_of_epochs = 2
max_number_of_epochs = 10
eta = 2
num_gpus=1

config_space = {
  "learning_rate": stats.loguniform(1e-2, 1),
  "batch_size": stats.randint(32, 256),
}
initial_config = {
  "learning_rate": 0.1,
  "batch_size": 128,
}

我們只是用新的 SuccessiveHalvingScheduler.

searcher = d2l.RandomSearcher(config_space, initial_config=initial_config)
scheduler = SuccessiveHalvingScheduler(
  searcher=searcher,
  eta=eta,
  r_min=min_number_of_epochs,
  r_max=max_number_of_epochs,
)
tuner = d2l.HPOTuner(
  scheduler=scheduler,
  objective=d2l.hpo_objective_lenet,
)
tuner.run(number_of_trials=30)

  error = 0.1623382568359375, runtime = 84.38501596450806

poYBAGR9PYuAUAhrAADuoiC26CU128.svg

pYYBAGR9PY2AT4SaAADuUFisjOQ145.svg

poYBAGR9PY-ARLW4AADuLkO_Mbo735.svg

pYYBAGR9PZGAeIEqAADt5hd506s949.svg

poYBAGR9PZOAAzaCAADt9GSOkOs988.svg

pYYBAGR9PZaAR-EdAADty-t9uFQ695.svg

poYBAGR9PZiAUnHgAADuQ6P9Gco390.svg

pYYBAGR9PZqAQFCCAADuI3eePhM029.svg

poYBAGR9PZ2ARC0bAAD8XQ_0wwE803.svg

pYYBAGR9PZ-AFo_yAADw6F47HCA645.svg

poYBAGR9PaOALcNOAADv4XdqzxY437.svg

pYYBAGR9PaWAK-0UAADxaRuWu1w366.svg

poYBAGR9PaiAMYSbAAE_tpJYd2c110.svg

pYYBAGR9PauATIsuAAE_dQNveV4670.svg

pYYBAGR9Pa2AKKxIAAF89ODTDLM921.svg

pYYBAGR9PbGAfqizAADuLZQ8urI734.svg

poYBAGR9PbOAXS-1AADfvmtq5Z0829.svg

poYBAGR9PbaAWpilAADuTPmX5fY655.svg

pYYBAGR9PbiAG3vbAADuLCjSQ0U293.svg

poYBAGR9PbuAEkilAADuK8v1jj8162.svg

pYYBAGR9Pb2AVcGuAADuRnZy_5Y411.svg

pYYBAGR9PcCAdU5_AADuQJ9KLCE625.svg

poYBAGR9PcKAbpc3AADuMlnHPs4175.svg

pYYBAGR9PcSATFXhAADwmrw0vWo534.svg

pYYBAGR9PceAEELxAADkRicCDPw706.svg

poYBAGR9PcmAQ6ccAADjq4kuymM166.svg

poYBAGR9PcuAZekgAADkcV12zHU605.svg

pYYBAGR9Pc6AHm8LAAE0otUMuSQ870.svg

pYYBAGR9PdCAIpwsAAFCYIMbcMc691.svg

poYBAGR9PdKAD7JFAAF0dI8QEpI748.svg

我們可以可視化我們評估的所有配置的學(xué)習(xí)曲線。大多數(shù)配置會提前停止,只有性能較好的配置會存活到rmax. 將此與香草隨機搜索進行比較,后者將分配rmax到每個配置。

for rung_index, rung in scheduler.all_observed_error_at_rungs.items():
  errors = [xi[1] for xi in rung]
  d2l.plt.scatter([rung_index] * len(errors), errors)
d2l.plt.xlim(min_number_of_epochs - 0.5, max_number_of_epochs + 0.5)
d2l.plt.xticks(
  np.arange(min_number_of_epochs, max_number_of_epochs + 1),
  np.arange(min_number_of_epochs, max_number_of_epochs + 1)
)
d2l.plt.ylabel("validation error")
d2l.plt.xlabel("epochs")

Text(0.5, 0, 'epochs')

pYYBAGR9PdWAYdP7AAEO7gPT0n8269.svg

最后,請注意我們在 SuccessiveHalvingScheduler. 假設(shè)一名工人可以自由運行一項工作,并suggest在當前梯級幾乎完全填滿時被調(diào)用,但另一名工人仍在忙于評估。由于我們?nèi)鄙賮碜栽摴ぷ魅藛T的指標值,因此我們無法確定排名靠前的1/η分數(shù)打開下一個梯級。另一方面,我們想給我們的自由工人分配一份工作,這樣它就不會閑著。我們的解決方案是開始新一輪的連續(xù)減半,并??將我們的工人分配到那里的第一次試驗。然而,一旦梯級在 中完成update,我們確保在隊列的開頭插入新配置,因此它們優(yōu)先于下一輪的配置。

19.4.2。概括

在本節(jié)中,我們介紹了多保真超參數(shù)優(yōu)化的概念,我們假設(shè)可以訪問目標函數(shù)的廉價評估近似值,例如在一定數(shù)量的訓(xùn)練時期后的驗證錯誤作為驗證錯誤的代理在全部的紀元之后。多保真超參數(shù)優(yōu)化允許減少 HPO 的整體計算,而不僅僅是減少掛鐘時間。

我們實施并評估了連續(xù)減半,這是一種簡單而高效的多保真 HPO 算法。

Discussions

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 保真
    +關(guān)注

    關(guān)注

    0

    文章

    4

    瀏覽量

    13570
  • pytorch
    +關(guān)注

    關(guān)注

    2

    文章

    795

    瀏覽量

    13081
收藏 人收藏

    評論

    相關(guān)推薦

    proteus仿真超聲波倒車雷達

    `proteus仿真超聲波倒車雷達`
    發(fā)表于 08-24 16:12

    Pytorch模型訓(xùn)練實用PDF教程【中文】

    ?模型部分?還是優(yōu)化器?只有這樣不斷的通過可視化診斷你的模型,不斷的對癥下藥,才能訓(xùn)練出一個較滿意的模型。本教程內(nèi)容及結(jié)構(gòu):本教程內(nèi)容主要為在 PyTorch 中訓(xùn)練一個模型所可能涉及到的方法及函數(shù),并且
    發(fā)表于 12-21 09:18

    PyTorch如何入門

    PyTorch 入門實戰(zhàn)(一)——Tensor
    發(fā)表于 06-01 09:58

    pytorch模型轉(zhuǎn)換需要注意的事項有哪些?

    ,并且可以更積極地進行優(yōu)化。 支持什么格式的pytorch模型? 答:Sophon的PyTorch模型編譯工具BMNETP只接受PyTorch的JIT模型JIT模型(TorchScri
    發(fā)表于 09-18 08:05

    基于PyTorch的深度學(xué)習(xí)入門教程之DataParallel使用GPU

    講到DataParallel使用GPU。 在PyTorch中使用GPU比較簡單,可以這樣把模型放到GPU上。 model.gpu() 還可以復(fù)制所有的tensors到GPU上。 mytensor = my_ten
    的頭像 發(fā)表于 02-15 09:55 ?4034次閱讀

    PyTorch教程6.2之參數(shù)管理

    電子發(fā)燒友網(wǎng)站提供《PyTorch教程6.2之參數(shù)管理.pdf》資料免費下載
    發(fā)表于 06-05 15:24 ?0次下載
    <b class='flag-5'>PyTorch</b>教程6.2之<b class='flag-5'>參數(shù)</b>管理

    PyTorch教程12.1之優(yōu)化和深度學(xué)習(xí)

    電子發(fā)燒友網(wǎng)站提供《PyTorch教程12.1之優(yōu)化和深度學(xué)習(xí).pdf》資料免費下載
    發(fā)表于 06-05 15:08 ?0次下載
    <b class='flag-5'>PyTorch</b>教程12.1之<b class='flag-5'>優(yōu)化</b>和深度學(xué)習(xí)

    PyTorch教程13.7之參數(shù)服務(wù)器

    電子發(fā)燒友網(wǎng)站提供《PyTorch教程13.7之參數(shù)服務(wù)器.pdf》資料免費下載
    發(fā)表于 06-05 14:22 ?0次下載
    <b class='flag-5'>PyTorch</b>教程13.7之<b class='flag-5'>參數(shù)</b>服務(wù)器

    PyTorch教程14.7之單發(fā)框檢測

    電子發(fā)燒友網(wǎng)站提供《PyTorch教程14.7之單發(fā)框檢測.pdf》資料免費下載
    發(fā)表于 06-05 14:17 ?0次下載
    <b class='flag-5'>PyTorch</b>教程14.7之單發(fā)<b class='flag-5'>多</b>框檢測

    PyTorch教程19.1之什么是超參數(shù)優(yōu)化

    電子發(fā)燒友網(wǎng)站提供《PyTorch教程19.1之什么是超參數(shù)優(yōu)化.pdf》資料免費下載
    發(fā)表于 06-05 10:25 ?0次下載
    <b class='flag-5'>PyTorch</b>教程19.1之什么是超<b class='flag-5'>參數(shù)</b><b class='flag-5'>優(yōu)化</b>

    PyTorch教程19.2之超參數(shù)優(yōu)化API

    電子發(fā)燒友網(wǎng)站提供《PyTorch教程19.2之超參數(shù)優(yōu)化API.pdf》資料免費下載
    發(fā)表于 06-05 10:27 ?0次下載
    <b class='flag-5'>PyTorch</b>教程19.2之超<b class='flag-5'>參數(shù)</b><b class='flag-5'>優(yōu)化</b>API

    PyTorch教程19.4之多保真超參數(shù)優(yōu)化

    電子發(fā)燒友網(wǎng)站提供《PyTorch教程19.4之多保真超參數(shù)優(yōu)化.pdf》資料免費下載
    發(fā)表于 06-05 10:45 ?0次下載
    <b class='flag-5'>PyTorch</b>教程<b class='flag-5'>19.4</b>之多<b class='flag-5'>保真超</b><b class='flag-5'>參數(shù)</b><b class='flag-5'>優(yōu)化</b>

    HT6873丨3.5W高保真超低EMI防削頂單聲道D類音頻功率放大器

    HT6873是一款高保真超低EMI的,具有防削頂失真功能的單聲道免濾波D類音頻功率放大器。在5V電源,10%?THD+N,4Ω負載條件下,輸出3.5W高功率,在各類音頻終端應(yīng)用中維持高效率并提供AB
    的頭像 發(fā)表于 07-06 15:51 ?748次閱讀
    HT6873丨3.5W高<b class='flag-5'>保真超</b>低EMI防削頂單聲道D類音頻功率放大器

    2.0優(yōu)化PyTorch推理與AWS引力子處理器

    2.0優(yōu)化PyTorch推理與AWS引力子處理器
    的頭像 發(fā)表于 08-31 14:27 ?550次閱讀
    2.0<b class='flag-5'>優(yōu)化</b><b class='flag-5'>PyTorch</b>推理與AWS引力子處理器

    如何使用PyTorch建立網(wǎng)絡(luò)模型

    PyTorch是一個基于Python的開源機器學(xué)習(xí)庫,因其易用性、靈活性和強大的動態(tài)圖特性,在深度學(xué)習(xí)領(lǐng)域得到了廣泛應(yīng)用。本文將從PyTorch的基本概念、網(wǎng)絡(luò)模型構(gòu)建、優(yōu)化方法、實際應(yīng)用等多個方面,深入探討使用
    的頭像 發(fā)表于 07-02 14:08 ?309次閱讀