更多實時更新的個人學習筆記分享,請關注:
知乎:https://www.zhihu.com/people/yuquanle/columns
微信訂閱號:AI小白入門
ID: StudyForAI
Flair工具使用教程之如何優化自己的模型
-
教程地址:https://github.com/zalandoresearch/flair/blob/master/resources/docs/TUTORIAL_8_MODEL_OPTIMIZATION.md
-
本教程我們通過選擇正確的模型和超參數集來研究如何提高模型的質量。
選擇超參數
-
Flair包含用於衆所周知的超參數選擇工具hyperopt的包裝器。
-
首先,您需要加載語料庫:
from flair.data import TaggedCorpus
from flair.data_fetcher import NLPTaskDataFetcher, NLPTask
# load your corpus
corpus: TaggedCorpus = NLPTaskDataFetcher.load_corpus(NLPTask.AG_NEWS)
- 其次,您需要定義參數的搜索空間。 因此,您可以使用hyperopt定義的所有參數表達式。
from hyperopt import hp
from flair.hyperparameter.param_selection import SearchSpace, Parameter
# define your search space
search_space = SearchSpace()
search_space.add(Parameter.EMBEDDINGS, hp.choice, options=[
[ WordEmbeddings('en') ],
[ CharLMEmbeddings('news-forward'), CharLMEmbeddings('news-backward') ]
])
search_space.add(Parameter.HIDDEN_SIZE, hp.choice, options=[32, 64, 128])
search_space.add(Parameter.RNN_LAYERS, hp.choice, options=[1, 2])
search_space.add(Parameter.DROPOUT, hp.uniform, low=0.0, high=0.5)
search_space.add(Parameter.LEARNING_RATE, hp.choice, options=[0.05, 0.1, 0.15, 0.2])
search_space.add(Parameter.MINI_BATCH_SIZE, hp.choice, options=[8, 16, 32])
注意:您應始終將嵌入添加到搜索空間(如上所示)。 如果您不想測試不同類型的嵌入,只需將一個嵌入選項傳遞給搜索空間,這將在每次測試運行中使用。 例如:
search_space.add(Parameter.EMBEDDINGS, hp.choice, options=[
[ CharLMEmbeddings('news-forward'), CharLMEmbeddings('news-backward') ]
])
- 在最後一步中,您必須創建實際的參數選擇器。 根據您需要定義TextClassifierParamSelector或SequenceTaggerParamSelector並啓動優化。 您可以定義hyperopt應執行的最大評估運行次數(max_evals)。 評估運行執行指定數量的歷元(max_epochs)。 爲了克服噪聲評估分數的問題,我們從評估運行中獲取最後三個評估分數(dev_score或dev_loss)的平均值,它代表最終分數並將傳遞給hyperopt。 此外,您可以指定每次評估運行的次數(training_runs)。 如果指定多個訓練運行,則將執行一次評估運行指定的次數。 最終評估分數將是所有這些運行的平均值。
from flair.hyperparameter.param_selection import TextClassifierParamSelector, OptimizationValue
# create the parameter selector
param_selector = TextClassifierParamSelector(
corpus,
False,
'resources/results',
'lstm',
max_epochs=50,
training_runs=3,
optimization_value=OptimizationValue.DEV_SCORE
)
# start the optimization
param_selector.optimize(search_space, max_evals=100)
參數設置和評估分數將寫入結果目錄中的param_selection.txt。 在選擇最佳參數組合時,我們不會將任何模型存儲到磁盤。 我們也不會在訓練期間執行測試運行,我們只是在針對測井集進行訓練後對模型進行一次評估。
搜索最佳學習率
-
學習率是最重要的超級參數之一,最佳學習將提高您的訓練速度,並希望提供更高性能的模型。
-
通過繪製相對於學習率的損失,我們通常會觀察三個不同的階段:對於低學習率,損失不會改善,最佳學習率範圍,其中損失下降最陡,最後階段,損失隨着學習而爆炸率變得太大了。通過這樣的圖,最佳學習速率選擇就像從最佳階段中選擇最高學習速率一樣容易。
-
爲了運行這樣的實驗,請從初始化的ModelTrainer開始,並使用base_path和文件名調用find_learning_rate(),以記錄學習率和損失。然後通過繪圖儀的plot_learning_rate()函數繪製生成的結果,並查看learning_rate.png圖像以選擇最佳學習率:
from flair.data import TaggedCorpus
from flair.data_fetcher import NLPTaskDataFetcher, NLPTask
from flair.embeddings import TokenEmbeddings, WordEmbeddings, StackedEmbeddings
from flair.trainers import ModelTrainer
from typing import List
# 1. get the corpus
corpus: TaggedCorpus = NLPTaskDataFetcher.load_corpus(NLPTask.CONLL_03).downsample(0.1)
print(corpus)
# 2. what tag do we want to predict?
tag_type = 'ner'
# 3. make the tag dictionary from the corpus
tag_dictionary = corpus.make_tag_dictionary(tag_type=tag_type)
print(tag_dictionary.idx2item)
# 4. initialize embeddings
embedding_types: List[TokenEmbeddings] = [
WordEmbeddings('glove'),
]
embeddings: StackedEmbeddings = StackedEmbeddings(embeddings=embedding_types)
# 5. initialize sequence tagger
from flair.models import SequenceTagger
tagger: SequenceTagger = SequenceTagger(hidden_size=256,
embeddings=embeddings,
tag_dictionary=tag_dictionary,
tag_type=tag_type,
use_crf=True)
# 6. initialize trainer
trainer: ModelTrainer = ModelTrainer(tagger, corpus)
# 7. find learning rate
learning_rate_tsv = ModelTrainer.find_learning_rate('resources/taggers/example-ner',
'learning_rate.tsv')
# 8. plot the learning rate finder curve
plotter = Plotter()
plotter.plot_learning_rate(learning_rate_tsv)
自定義優化工具
- 現在,您可以在初始化ModelTrainer時使用任何PyTorch的優化器進行訓練。 要爲優化器提供任何額外選項,只需使用weight_decay示例指定它:
from torch.optim.adam import Adam
trainer: ModelTrainer = ModelTrainer(tagger, corpus,
optimizer=Adam, weight_decay=1e-4)
-
權重衰減通常由優化方法使用以減少過度擬合,並且它基本上通過優化器的weight_decay參數向損失函數添加權重正則化器。在PyTorch中實現它的方式,這個因素與learning_rate混淆,實質上是實現L2正則化。在亞當的Ilya Loshchilov和Frank Hutter Fixing Weight Decayrization的論文中,作者建議實際上做重量衰減而不是L2正則化,並且他們將他們的方法AdamW和SGDW稱爲相應的Adam和SGD版本。根據經驗,通過這些優化器的結果優於它們相應的L2正則化版本。然而,由於學習速率和權重衰減在這些方法中是分離的,因此任何學習速率調度都必須改變這兩個術語。不用擔心,我們會在使用這些優化器時自動切換執行此操作的調度程序。
-
要使用這些優化器,只需使用AdamW或SGDW創建ModelTrainer以及任何其他選項,如下所示:
from flair.optim import SGDW
trainer: ModelTrainer = ModelTrainer(tagger, corpus,
optimizer=SGDW, momentum=0.9)