<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          工具介紹:使用 Optuna 進行超參數(shù)調(diào)優(yōu)

          共 7209字,需瀏覽 15分鐘

           ·

          2022-01-19 21:21

          在機器學習中,除了一般可學習的參數(shù)外,還有一些參數(shù)需要預先設置,稱為超參數(shù)。

          超參數(shù)的值對于模型的性能至關重要,尋找在驗證集上性能最佳的超參數(shù)稱為超參數(shù)優(yōu)化,然而這并不是一項簡單的任務。

          可以通過搜索方法來選擇比較好的超參數(shù)。比如,Grid Search?和?Random Search?之類的方法。后者貌似帶有一定隨機性,但往往表現(xiàn)得比前者好。因為它以不均勻的間隔搜索超參數(shù)空間,避免了?Grid Search?的很多冗余操作。

          除了這種搜索方式,我們還可以使用像 Optuna 這樣的更加靈活強大的工具來應對這項任務。先安裝它,

          pip?install?optuna

          1流程及簡例

          一個典型的 Optuna 的優(yōu)化程序中只有三個最核心的概念,

          • objective,負責定義待優(yōu)化的目標函數(shù)并指定參數(shù)的范圍。

          • trial,對應目標函數(shù) objective 的單次試驗。

          • study,負責管理整個優(yōu)化過程,決定優(yōu)化的方式、總試驗的次數(shù)、試驗結(jié)果的記錄等功能。

          .簡例 .

          例如,在定義域 內(nèi)估計函數(shù) 的最小值及其對應的

          我們就用這個例子來練練手,代碼如下。

          import?optuna
          ?
          def?objective(trial):
          ????x?=?trial.suggest_uniform('x',?0,?1)
          ????y?=?trial.suggest_uniform('y',?0,?1)
          ????return?(x?+?y)?**?2
          ?
          study?=?optuna.create_study(direction='minimize')
          study.optimize(objective,?n_trials=100)
          ?
          print(study.best_params)
          print(study.best_value)
          {'x': 0.00136012038661543, 'y': 0.0003168904600867363}
          2.8123653799567168e-06
          • 首先,定義一個 objective 函數(shù),即 ,其參數(shù) 采樣自兩個均勻分布。

          • 然后,Optuna 創(chuàng)建了一個 study,指定了優(yōu)化的方式為最小化并且最大實驗次數(shù)為 100,然后將目標函數(shù)傳入其中,開始優(yōu)化過程。

          • 最后,輸出在 100 次試驗中找到的最佳參數(shù)組合。

          注意,上面例子是拿來演示它的使用流程,并不是拿它去解一般的最優(yōu)化問題。

          .可視化 .

          study 結(jié)束,下一步就是查看結(jié)果,可以使用 Optuna 的內(nèi)置可視化函數(shù)來查看 study 的各項進度。

          下面用 plotly 來作多個方式的可視化。如果沒有安裝過,則安裝它 pip install plotly

          下圖顯示了模型在多次迭代中的性能演化。預期的行為是模型性能隨著搜索次數(shù)的增加而提高。

          study.optimize 執(zhí)行結(jié)束以后,調(diào)用 plot_contour,并將 study 和需要可視化的參數(shù)傳入該方法,Optuna 將返回一張等高線圖。

          例如,當在上面的例子中,我們想要查看參數(shù) 的關系以及它們對于函數(shù)值的共同貢獻,只需要下面的語句即可:

          optuna.visualization.plot_contour(study,?params=['x',?'y'])

          還有其他形式的一些圖,如通過展示超參數(shù)重要性可以了解到哪些超參數(shù)對模型的性能影響較大。

          optuna.visualization.plot_param_importances(study)

          2CNN 超參數(shù)優(yōu)化例子

          本文接下來結(jié)合 PyTorchOptuna,來實驗 CNN 模型在 MNIST 數(shù)據(jù)集上的超參數(shù)優(yōu)化。

          import?matplotlib.pyplot?as?plt
          import?numpy?as?np

          import?torch
          import?torch.nn?as?nn
          import?torch.optim?as?optim
          from?torch.utils.data?import?Dataset,?DataLoader,TensorDataset,random_split,SubsetRandomSampler,?ConcatDataset
          from?torch.nn?import?functional?as?F
          import?torchvision
          from?torchvision?import?datasets,transforms
          import?torchvision.transforms?as?transforms
          import?optuna
          import?os

          DEVICE?=?torch.device("cuda:0"?if?torch.cuda.is_available()?else?"cpu")
          CLASSES?=?10
          DIR?=?os.getcwd()
          EPOCHS?=?10
          LOG_INTERVAL?=?10
          train_dataset?=?torchvision.datasets.MNIST('classifier_data',?train=True,?download=True)
          m=len(train_dataset)

          transform?=?torchvision.transforms.Compose([
          ????torchvision.transforms.ToTensor()
          ])

          train_dataset.transform=transform

          定義具體的卷積神經(jīng)網(wǎng)絡,并增加參數(shù) trial 來設置要采樣的超參數(shù)。

          class?ConvNet(nn.Module):
          ????def?__init__(self,?trial):
          ????????#?We?optimize?dropout?rate?in?a?convolutional?neural?network.
          ????????super(ConvNet,?self).__init__()

          ????????self.conv1?=?nn.Conv2d(in_channels=1,?out_channels=16,?kernel_size=5,?stride=1,?padding=2)

          ????????self.conv2?=?nn.Conv2d(in_channels=16,?out_channels=32,?kernel_size=5,?stride=1,?padding=2)
          ????????dropout_rate?=?trial.suggest_float("dropout_rate",?0,?0.5,step=0.1)
          ????????self.drop1=nn.Dropout2d(p=dropout_rate)???
          ????????
          ????????fc2_input_dim?=?trial.suggest_int("fc2_input_dim",?32,?128,32)
          ????????self.fc1?=?nn.Linear(32??7??7,?fc2_input_dim)
          ????????dropout_rate2?=?trial.suggest_float("dropout_rate2",?0,?0.3,step=0.1)
          ????????self.drop2=nn.Dropout2d(p=dropout_rate2)

          ????????self.fc2?=?nn.Linear(fc2_input_dim,?10)

          ????def?forward(self,?x):
          ????????x?=?F.relu(F.max_pool2d(self.conv1(x),kernel_size?=?2))

          ????????x?=?F.relu(F.max_pool2d(self.conv2(x),kernel_size?=?2))
          ????????x?=?self.drop1(x)

          ????????x?=?x.view(x.size(0),-1)

          ????????x?=?F.relu(self.fc1(x))
          ????????x?=?self.drop2(x)

          ????????x?=?self.fc2(x)

          ????????return?x

          定義函數(shù)來獲取訓練集中不同 batch_size 大小的批次數(shù)據(jù)。它將 train_datasetbatch_size 作為輸入,并返回訓練和驗證數(shù)據(jù)加載器對象。

          def?get_mnist(train_dataset,batch_size):

          ????train_data,?val_data?=?random_split(train_dataset,?[int(m-m0.2),?int(m0.2)])
          ????#?The?dataloaders?handle?shuffling,?batching,?etc...
          ????train_loader?=?torch.utils.data.DataLoader(train_data,?batch_size=batch_size)
          ????valid_loader?=?torch.utils.data.DataLoader(val_data,?batch_size=batch_size)
          ????return?train_loader,?valid_loader

          接下來是定義目標函數(shù),它通過采樣程序來選擇每次試驗的超參數(shù)值,并返回在該試驗中驗證集上的準確度。

          def?objective(trial):

          ????#?Generate?the?model.
          ????model?=?ConvNet(trial).to(DEVICE)

          ????#?Generate?the?optimizers.

          ????#?try?RMSprop?and?SGD
          ????'''
          ????optimizer_name?=?trial.suggest_categorical("optimizer",?["RMSprop",?"SGD"])
          ????momentum?=?trial.suggest_float("momentum",?0.0,?1.0)
          ????lr?=?trial.suggest_float("lr",?1e-5,?1e-1,?log=True)
          ????optimizer?=?getattr(optim,?optimizer_name)(model.parameters(),?lr=lr,momentum=momentum)
          ????'''

          ????#try?Adam,?AdaDelta?adn?Adagrad
          ????
          ????optimizer_name?=?trial.suggest_categorical("optimizer",?["Adam",?"Adadelta","Adagrad"])
          ????lr?=?trial.suggest_float("lr",?1e-5,?1e-1,log=True)
          ????optimizer?=?getattr(optim,?optimizer_name)(model.parameters(),?lr=lr)
          ????batch_size=trial.suggest_int("batch_size",?64,?256,step=64)

          ????criterion=nn.CrossEntropyLoss()

          ????#?Get?the?MNIST?imagesset.
          ????train_loader,?valid_loader?=?get_mnist(train_dataset,batch_size)
          ????
          ????#?Training?of?the?model.
          ????for?epoch?in?range(EPOCHS):
          ????????model.train()
          ???????
          ????????for?batch_idx,?(images,?labels)?in?enumerate(train_loader):
          ????????????#?Limiting?training?images?for?faster?epochs.
          ????????????#if?batch_idx?*?BATCHSIZE?>=?N_TRAIN_EXAMPLES:
          ????????????#????break

          ????????????images,?labels?=?images.to(DEVICE),?labels.to(DEVICE)

          ????????????optimizer.zero_grad()
          ????????????output?=?model(images)
          ????????????loss?=?criterion(output,?labels)
          ????????????loss.backward()
          ????????????optimizer.step()

          ????????#?Validation?of?the?model.
          ????????model.eval()
          ????????correct?=?0
          ????????with?torch.no_grad():
          ????????????for?batch_idx,?(images,?labels)?in?enumerate(valid_loader):
          ????????????????#?Limiting?validation?images.
          ???????????????#?if?batch_idx?*?BATCHSIZE?>=?N_VALID_EXAMPLES:
          ????????????????#????break
          ????????????????images,?labels?=?images.to(DEVICE),?labels.to(DEVICE)
          ????????????????output?=?model(images)
          ????????????????#?Get?the?index?of?the?max?log-probability.
          ????????????????pred?=?output.argmax(dim=1,?keepdim=True)
          ????????????????correct?+=?pred.eq(labels.view_as(pred)).sum().item()

          ????????accuracy?=?correct?/?len(valid_loader.dataset)

          ????????trial.report(accuracy,?epoch)

          ????????#?Handle?pruning?based?on?the?intermediate?value.
          ????????if?trial.should_prune():
          ????????????raise?optuna.exceptions.TrialPruned()

          ????return?accuracy

          接著,創(chuàng)建一個 study 對象來最大化目標函數(shù),然后使用 optimize 來展開試驗,實驗次數(shù)設為 20 次。

          study?=?optuna.create_study(direction='maximize')
          study.optimize(objective,?n_trials=20)

          trial?=?study.best_trial

          print('Accuracy:?{}'.format(trial.value))
          print("Best?hyperparameters:?{}".format(trial.params))
          Accuracy: 0.98925
          Best hyperparameters: {'dropout_rate': 0.0, 'fc2_input_dim': 64, 'dropout_rate2': 0.1, 'optimizer': 'Adam', 'lr': 0.006891576863485639, 'batch_size': 256}
          df?=?study.trials_dataframe().drop(['state','datetime_start','datetime_complete','duration','number'],?axis=1)
          df.tail(5)

          3可視化 study

          先通過下面代碼看一下各超參數(shù)的總體優(yōu)化進展情況。

          optuna.visualization.plot_optimization_history(study)

          以及還可以查看不同超參數(shù)組合的等值線圖,下圖中只關注批次大小和學習率。

          .超參數(shù)重要性 .

          查看各個超參數(shù)對目標值的影響大小。

          optuna.visualization.plot_param_importances(study)

          .單個超參數(shù)切片 .

          查看不同的單個超參數(shù)在多次試驗中的變化情況,顏色對應試驗次數(shù)。

          optuna.visualization.plot_slice(study,?params=['dropout_rate',?'batch_size',?'lr'])

          4小結(jié)

          Optuna 基于貝葉斯方法來進行超參數(shù)優(yōu)化,提供了一種有效的搜索結(jié)構(gòu)化,為模型超參數(shù)的選取提供了一種較為理想的解決方案,大家不妨在實踐中增加對它的理解。

          參考資料



          瀏覽 270
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  婷婷视频| 99在线精品视频在线观看 | 中文字幕三级小说 | 亚洲自拍小视频 | 91欧美福利 |