LoginSignup
4
3

More than 5 years have passed since last update.

【fast.ai】 text API解説

Posted at

概要

本記事はfast.aiのwikiのTextページの要約となります。

筆者の理解した範囲内で記載します。

Text モデル、データ、トレーニング

fast.aiライブラリのText モジュールは、DatasetをNLP (Natural Language Processing)目的へ最適化するための関数を多数備えています。具体的には:

  • text.transform にてデータの前処理実施し、テキストをidへと変換する
  • text.data にて TextDataBunch を用いてNLPに必要なDatasetのクラスを規定する
  • text.learner にて素早くlanguage model や RNN classifierを作成できる

上のリンクを辿って各モジュールのAPIを参考にしてみて下さい。

早速やってみる: ULMFiTIでimdbの感情modelを鍛える

早速fast.ai textモジュールを使ってみましょう。以下の例では名の知れたimdbデータを用いて、感情分類モデルを4ステップで鍛えていきます。

1) Imdbデータを読み込み俯瞰する
2) データをモデルに最適化する
3) language modelをfine-tuneする
4) 分類モデルを作成する

1) Imdbデータを読み込み俯瞰する

text に必要なパッケージを読み込みましょう。

from fastai.text import *

画像認識とは異なり、テキストは直接モデルに読み込むことができません。従って、最初にデータを前処理してテキストをトークンへと変換して(tokenization)それを数字へと変換する(numericalization)必要があります。これらの数字 embedding layer へと引き渡されることで浮動小数点の配列へと変換されます。

これらトークンを浮動小数点へと変換するWord Embeddingsはweb上で掲載されています。これらのWord Embeddingsはwikipediaなどの膨大なサイズのcorpusで鍛えられたものです。ULMFiTの手法を用いて、fast.aiライブラリはpre-trained Language Modelsを用いて、fine-tuneすることに焦点を絞っています。Word embeddingsとは、具体的に300から400の小数点を異なる単語を表すために鍛えられたもので、pre-trained language model はこれらの特性を備えているだけではなく、文や文章を表現する性質も備わっております。

注記: ライブラリは以下の3ステップで構成されています。

  1. データを最小限のコードで前処理を済ませる
  2. pre-trained された language model をベースに、データセットを用いてfine-tuneする
  3. 分類器などのモデルをlanguage modelの上に載せる。

1000レビューに抽出されたIMDBデータセットを用いる(陽性または陰性)

path = untar_data(URLs.IMDB_SAMPLE)
path

PosixPath('/home/ubuntu/.fastai/data/imdb_sample')

データセットをテキストから作成するには以下の方法がベストです

  • ImageNet スタイルにフォルダへ整理されている
  • csv ファイルへラベルの欄とテキスト欄へ整理されている

こちらの例ではimdbをtexts.csvファイルから読み込んで以下のようになっております。

df = pd.read_csv(path/'texts.csv')
df.head()
label text is_valid
0 negative Un-bleeping-believable! Meg Ryan doesn't even ...
1 positive This is a extremely well-made film. The acting...
2 negative Every once in a long while a movie will come a...
3 positive Name just says it all. I watched this movie wi...
4 negative This movie succeeds at being one of the most u...

2) データをモデルに最適化する

DataBunchを準備するためには、複数のfactory methodsがデータの構成に応じて存在します。詳細はtext.data。こちらではfrom_csvメソッドを用いてTextLMDataBunch(Language Modelのためのデータ処理)とTextClasDataBunch(Text Classifierのためのデータ処理)クラスを用います。

# Language model データ処理
data_lm = TextLMDataBunch.from_csv(path, 'texts.csv')
# Classifier model データ処理
data_clas = TextClasDataBunch.from_csv(path, 'texts.csv', vocab=data_lm.train_ds.vocab, bs=32)

これで必要なデータの前処理がなされます。分類器には、vocabulary(wordからidを引き渡す役目)を引き渡すことによって、data_clasがdata_lmと同じdictionaryを用いる点は注意して下さい。

この処理は時間がかかるため、結果を保存するために以下のコードを実行しましょう。

data_lm.save('data_lm_export.pkl')
data_clas.save('data_clas_export.pkl')

これで全ての結果を保存するためのtmpdirectoryが作成されます。ロードするためには以下のコードを実行しましょう。

data_lm = load_data(path, fname='data_lm_export.pkl')
data_clas = load_data(path, fname='data_clas_export.pkl', bs=16)

注記:DataBunchのパラメータを設定できます。(batch size, bptt,...)

3) language modelをfine-tuneする

data_lmを用いてlanguage modelをfine-tuneしましょう。fast.ai は、AWD-LSTM architectureの英語モデルを用意してるので、それとpretrained weightsをダウンロードし、fine-tuneするためのlearnerオブジェクトを作成しましょう

learn = language_model_learner(data_lm, AWD_LSTM, drop_mult=0.5)
learn.fit_one_cycle(1, 1e-2)

Total time:00:13

epoch train_loss valid_loss accuracy
1 4.514897 3.974741 0.282455

画像認識モデルと同様に、モデルをunfreezeすることでさらにfine-tuneすることができます。

learn.unfreeze()
learn.fit_one_cycle(1, 1e-3)

Total time: 00:17

epoch train_loss valid_loss accuracy
1 4.159299 3.886238 0.289092

モデルを評価するために、以下のLearner.predictを実行することで、単語とその数を指定し予測させることができます。

learn.predict("This is a review about", n_words=10)

'This is a review about dog - twist credited , and that , along with'

あまり意味は通じませんが(小さいvocabularyのため)ここでは基本的な文法をmodelが習得していることは驚愕すべきことです。(pretrained modelが可能にしたもの)

最後にencoderを保存して分類モデルに用いるようにできるようにしましょう。

learn.save_encoder('ft_enc')

4) 分類モデルを作成する

ここでは、先述して作成したdata_clasオブジェクトを用いて、分類器をencoderを用いて新たに作成します。learnerオブジェクト自体はたった一行のコードで作成できます。

learn = text_classifier_learner(data_clas, AWD_LSTM, drop_mult=0.5)
learn.load_encoder('ft_enc')
data_clas.show_batch()
text target
xxbos xxmaj raising xxmaj victor xxmaj vargas : a xxmaj review \n \n xxmaj you know , xxmaj raising xxmaj victor xxmaj vargas is like sticking your hands into a big , xxunk bowl of xxunk . xxmaj it 's warm and gooey , but you 're not sure if it feels right . xxmaj try as i might , no matter how warm and gooey xxmaj raising xxmaj negative
xxbos xxmaj now that xxmaj che(2008 ) has finished its relatively short xxmaj australian cinema run ( extremely limited xxunk screen in xxmaj xxunk , after xxunk ) , i can xxunk join both xxunk of " xxmaj at xxmaj the xxmaj movies " in taking xxmaj steven xxmaj soderbergh to task . \n \n xxmaj it 's usually satisfying to watch a film director change his style / negative
xxbos i really wanted to love this show . i truly , honestly did . \n \n xxmaj for the first time , gay viewers get their own version of the " xxmaj the xxmaj xxunk " . xxmaj with the help of his obligatory " hag " xxmaj xxunk , xxmaj james , a good looking , well - to - do thirty - something has the chance negative
xxbos xxmaj to review this movie , i without any doubt would have to quote that memorable scene in xxmaj tarantino 's " xxmaj pulp xxmaj fiction " ( xxunk ) when xxmaj jules and xxmaj vincent are talking about xxmaj mia xxmaj wallace and what she does for a living . xxmaj jules tells xxmaj vincent that the " xxmaj only thing she did worthwhile was pilot " . negative
xxbos xxmaj how viewers react to this new " adaption " of xxmaj shirley xxmaj jackson 's book , which was promoted as xxup not being a remake of the original 1963 movie ( true enough ) , will be based , i suspect , on the following : those who were big fans of either the book or original movie are not going to think much of this one negative
learn.fit_one_cycle(1, 1e-2)

Total time: 00:33

epoch train_loss valid_loss accuracy
1 0.650518 0.599687 0.691542

再度modelをunfreezeしてfine-tuneしましょう。

learn.freeze_to(-2)
learn.fit_one_cycle(1, slice(5e-3/2., 5e-3))

Total time: 00:38

epoch train_loss valid_loss accuracy
1 0.628320 0.563579 0.716418
learn.unfreeze()
learn.fit_one_cycle(1, slice(2e-3/100, 2e-3))

Total time: 00:56

epoch train_loss valid_loss accuracy
1 0.533411 0.539693 0.721393

そして、Learner.predictを用いてテキストを予測してみましょう。

learn.predict("This was a great movie!")

(Category positive, tensor(1), tensor([0.0118, 0.9882]))

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3