---
type: slides
---

# トレーニングの設定と実行方法

Notes: さて、学習データを作り方をみてきたので、さっそくパイプラインの訓練とその
設定方法をみていきましょう。

このレッスンでは、spaCy のトレーニングコンフィグの詳細や作り方、そしてコマンドラ
インでパイプラインを訓練・検証する方法を学びます。

---

# トレーニングコンフィグ

- 訓練に使う設定ファイル
- 設定の信頼できる唯一の情報源
- ファイル名は通常`config.cfg`
- `nlp`オブジェクトを初期化するための情報が記述されている
- 全てのコンポネントとモデルの設定
- 訓練のハイパーパラメータなども
- トレーニングの再現性を高める

Notes: spaCy は普段`config.cfg`と呼ばれている設定ファイルを「信頼できる唯一の情
報源」に用いています。このコンフィグファイルには`nlp`オブジェクトの初期化に必要
な情報やどのコンポネントを含む、その実装の詳細などの設定が記述されています。他に
はハイパーパラメターなどトレーニングに使う全ての設定と学習データの読み込み方法も
含まれています。

コマンドラインで多くの引数に頼るやコードないで多くの細かい設定を指定することなく
、この設定ファイル一つを spaCy のトレーニングコマンドに指定することだけで訓練を
行うことができます。

更に、設定ファイルは訓練の再現性を高めます。全ての設定を一箇所に揃うことで、訓練
時の設定を忘れる恐れがなくなります。git に保存して、どなたでも同じモデルを再現で
きるように他人と共有することもできます。

---

# トレーニングコンフィグ (2)

```ini
[nlp]
lang = "ja"
pipeline = ["tok2vec", "ner"]
batch_size = 1000

[nlp.tokenizer]
@tokenizer = "spacy.ja.JapaneseTokenizer"

[components]

[components.ner]
factory = "ner"

[components.ner.model]
@architectures = "spacy.TransitionBasedParser.v2"
hidden_width = 64
# などなど…
```

Notes: これは固有表現抽出器(NER)を含むパイプラインに使われた設定ファイルの一部で
す。設定ファイルはセクションに分かれていて、他のセクションに含まれているサブセク
ションはドットで定義されています。例えば`[components.ner.model]`では NER のモデ
ルの設定が記述されています。

設定ファイルは`@`記号を用いることで Python の関数を参照することもできます。例え
ば、トークナイザーは登録済みのトークナイザー関数を参照しています。この機能を使用
することで別のトークナイザーや自作のモデルを用いるなど、`nlp`オブジェクトや訓練
をカスタマイズできます。しかしカスタマイズの話は別の話にして、このレッスンでは
spaCy に含まれている機能だけを使います。

---

# 設定ファイルの作成方法

- spaCy はデフォルトの設定ファイルを自動に作成できる
- ブラウザーから気軽に使用でき
  る[クイックスタートウィジェット](https://spacy.io/usage/training#quickstart)で
  も作成可能
- コマンドラインで[`init config`](https://spacy.io/api/cli#init-config)でも作成
  可能

```bash
$ python -m spacy init config ./config.cfg --lang ja --pipeline ner
```

- `init config`: 実行するコマンド
- `config.cfg`: 設定ファイルを保存するパス
- `--lang`: 使用する言語（日本語なら"ja"）
- `--pipeline`: 使用するパイプラインのリスト（コンマ区切りで）

Notes: もちろん設定ファイルを手動で作成する必要はありませんし、ほとんどの場合カ
スタマイズしなくても良いです。 spaCy は必要な設定ファイルを完全自動で作成できま
す。

資料にあるクイックスタートウィジェットではインタラクティブに言語や必要なコンポネ
ントを指定しながら設定ファイルを生成します。ウィジェットでハードウェアや最適化関
係の設定も調整できます。

他の選択肢として、コマンドラインを使って、spaCy の`init config`コマンドで設定フ
ァイルを生成することもできます。最初の引数は設定ファイルのファイル名になります。
これは普段`config.cfg`にしています。 `--lang`の引数で使用する言語クラスを指定し
ます。例えば日本語の場合これは`ja`になります。 `--pipeline`の引数では、コンマ区
切りで使用するコンポネントのリストを指定します。このスライドの例では固有表現抽出
器 (`ner`)のみのパイプラインを作成しています。

---

# パイプラインを訓練する (1)

- `config.cfg`と訓練・検証データさえあれば訓練できる
- 設定ファイルの設定はコマンドラインから上書きできる

```bash
$ python -m spacy train ./config.cfg --output ./output --paths.train train.spacy --paths.dev dev.spacy
```

- `train`: 実行するコマンド
- `config.cfg`: 設定ファイルのパス
- `--output`: 訓練完了後、パイプラインを保存するディレクトリーのパス
- `--paths.train`: 訓練データのパスの上書き設定
- `--paths.dev`: 検証データのパスの上書き設定

Note: パイプラインは設定ファイルと訓練・検証データさえあれば訓練できます。ここで
いう「訓練・検証データ」は以前の演習で作成した`.spacy`ファイルのことです。

`spacy train`の最初の引数は設定ファイルのパスです。 `--output`引数で学習を完了し
たパイプラインを保存するパスを指定できます。

設定ファイルの設定はコマンドラインから上書きできます。ここで
は`paths.train`で`train.spacy`を、`paths.dev`で`dev.spacy`を指定しています。

---

# パイプラインを訓練する (2)

```
============================ Training pipeline ============================
ℹ Pipeline: ['tok2vec', 'ner']
ℹ Initial learn rate: 0.001

E    #       LOSS TOK2VEC  LOSS NER  ENTS_F  ENTS_P  ENTS_R  SCORE
---  ------  ------------  --------  ------  ------  ------  ------
  0       0          0.00     26.50    0.73    0.39    5.43    0.01
  0     200         33.58    847.68   10.88   44.44    6.20    0.11
  1     400         70.88    267.65   33.50   45.95   26.36    0.33
  2     600         67.56    156.63   45.32   62.16   35.66    0.45
  3     800        138.28    134.12   48.17   74.19   35.66    0.48
  4    1000        177.95    109.77   51.43   66.67   41.86    0.51
  6    1200         94.95     52.13   54.63   67.82   45.74    0.55
  8    1400        126.85     66.19   56.00   65.62   48.84    0.56
 10    1600         38.34     24.16   51.96   70.67   41.09    0.52
 13    1800        105.14     23.23   56.88   69.66   48.06    0.57

✔ Saved pipeline to output directory
/path/to/output/model-last
```

Notes: 学習中の出力はこんなふうになります。以前この章で、同じデータを繰り返し何
回か学習すると説明しましたが、全データを一回学習で使うことを「エポック(epoch)」
と言います。エポックの数は E のカラムで表示されます。

各エポックで、spaCy は 200 件のデータを処理する度に精度を出力します。この件数は
第二のカラムに表示されます。何件ごとに精度を出力するかは設定ファイルで変更できま
す。行ごとに損失量(loss)と精度が出力されます。

ここで一番重要は数値は右端のカラムの総評価です。このスコアは、検証データの正解を
どの程度予測できたかをもとに計算されています。

学習は総評価が改善しなくなるまで続き、その後自動に終了します。

---

# 学習済みパイプラインの使い方

- 学習後の出力は普通のパイプライン
  - `model-last`: 学習の最後にできたパイプライン
  - `model-best`: 学習中、最もスコアが高かったパイプライン
- `spacy.load`で読み込める

```python
import spacy

nlp = spacy.load("/path/to/output/model-best")
doc = nlp("iPhone 11 vs iPhone 8: What's the difference?")
print(doc.ents)
```

Notes: 学習後保存されるパイプラインは`ja_core_news_sm`などと同じく、普通のパイプ
ラインです。学習の最後に、最後にできたパイプラインとスコアが最も高かったパイプラ
インが出力ディレクトリーに保存されます。

学習済みのパイプラインは`spacy.load`にパスを指定することで読み込めます。読み込み
後、他のパイプラインと同様にテキストを処理・解析できます。

---

# ヒント: パイプラインのパッケージ化

- [`spacy package`](https://spacy.io/api/cli#package)でインストールできる Python
  のパッケージを作成できる
- バージョン管理・デプロイともに簡単

```bash
$ python -m spacy package /path/to/output/model-best ./packages --name my_pipeline --version 1.0.0
```

```bash
$ cd ./packages/ja_my_pipeline-1.0.0
$ pip install dist/ja_my_pipeline-1.0.0.tar.gz
```

インストール後、パッケージをこうして読み込めます。

```python
nlp = spacy.load("en_my_pipeline")
```

Notes: 自作のパイプラインを使いやすくするために、spaCy にはパイプラインをパッケ
ージ化する便利なコマンドがあります。 `spacy package`はパイプラインのパスと出力デ
ィレクトリーの引数を取り、パイプラインを含む Python パッケージを生成します。この
パッケージは`.tar.gz`ファイルで、pip などで簡単にインストールできます。

コマンドラインで任意にパッケージ名とバージョン番号を指定することもできます。これ
を利用して複数のバージョンや環境ごとにパッケージをカスタマイズすることができます
。後にデータを追加したり、設定を変更したりした場合には便利です。

このパッケージは他の Python パッケージと何も変わりません。インストール後、名前を
指定することでパイプラインをロードできます。ただし、spaCy はパイプラインの名前の
先頭に言語コードを追加することには注意してください。例えば、日本語の場
合`my_pipeline`はロードするとき`ja_my_pipeline`となります。

---

# 練習しましょう！

Notes: では早速パイプラインを学習させましょう！これから固有表現抽出器のパイプラ
インの設定ファイルを生成し、以前の演習で作った学習データを使ってパイプラインを学
習させます。
