言語処理100本ノック(2020)-75: 損失と正解率のプロット(TensorFlow)

[言語処理100本ノック 2020 (Rev2)](https://nlp100.github.io/ja/)の[「第8章: ニューラルネット」](https://nlp100.github.io/ja/ch08.html)の[75本目「損失と正解率のプロット」](https://nlp100.github.io/ja/ch08.html#75-%E6%90%8D%E5%A4%B1%E3%81%A8%E6%AD%A3%E8%A7%A3%E7%8E%87%E3%81%AE%E3%83%97%E3%83%AD%E3%83%83%E3%83%88)記録です。今は、コードを3行程度追加するだけでGoogle ColaboratoryでTensorBoard使えるので超楽勝です。

[記事「まとめ: 言語処理100本ノックで学べることと成果」](https://qiita.com/FukuharaYohei/items/6f0af3c4e270d8af2d99)に[言語処理100本ノック 2015](http://www.cl.ecei.tohoku.ac.jp/nlp100/)についてはまとめていますが、追加で差分の[言語処理100本ノック 2020 (Rev2)](https://nlp100.github.io/ja/)についても更新します。

# 参考リンク

|リンク|備考|
|:--|:--|
|[75_損失と正解率のプロット.ipynb](https://github.com/YoheiFukuhara/nlp100-2020/blob/main/08.%E3%83%8B%E3%83%A5%E3%83%BC%E3%83%A9%E3%83%AB%E3%83%8D%E3%83%83%E3%83%88/75_%E6%90%8D%E5%A4%B1%E3%81%A8%E6%AD%A3%E8%A7%A3%E7%8E%87%E3%81%AE%E3%83%97%E3%83%AD%E3%83%83%E3%83%88.ipynb)|回答プログラムのGitHubリンク|
|[言語処理100本ノック 2020 第8章: ニューラルネット](https://qiita.com/nymwa/items/9c8484ff511123e03ba8)|(PyTorchだけど)解き方の参考|
|[【言語処理100本ノック 2020】第8章: ニューラルネット](https://qiita.com/yamaru/items/b54989d772c4323bde69)|(PyTorchだけど)解き方の参考|
|[まとめ: 言語処理100本ノックで学べることと成果](https://qiita.com/FukuharaYohei/items/6f0af3c4e270d8af2d99)|言語処理100本ノックまとめ記事|
|[【Keras入門(3)】TensorBoardで見える化](https://qiita.com/FukuharaYohei/items/fe73cdb63ee82a7ea318)|kerasとTensorBoard|
|[ノートブックで TensorBoard を使用する](https://www.tensorflow.org/tensorboard/tensorboard_in_notebooks?hl=ja)|JupyterでのTensorBoard使い方|

# 環境
後々GPUを使わないと厳しいので、Goolge Colaboratory使いました。Pythonやそのパッケージでより新しいバージョンありますが、新機能使っていないので、プリインストールされているものをそのまま使っています。

|種類|バージョン|内容|
|:--|:--|:--|
|Python|3.7.12|Google Colaboratoryのバージョン|
|google|2.0.3|Google Driveのマウントに使用|
|tensorflow|2.6.0|ディープラーニングの主要処理|

# [第8章: ニューラルネット](https://nlp100.github.io/ja/ch08.html)
## 学習内容
> 深層学習フレームワークの使い方を学び，ニューラルネットワークに基づくカテゴリ分類を実装します．

## ノック内容
> 第6章で取り組んだニュース記事のカテゴリ分類を題材として，ニューラルネットワークでカテゴリ分類モデルを実装する．なお，この章ではPyTorch, TensorFlow, Chainerなどの機械学習プラットフォームを活用せよ．

### [75. 損失と正解率のプロット](https://nlp100.github.io/ja/ch08.html#75-%E6%90%8D%E5%A4%B1%E3%81%A8%E6%AD%A3%E8%A7%A3%E7%8E%87%E3%81%AE%E3%83%97%E3%83%AD%E3%83%83%E3%83%88)
> 問題73のコードを改変し，各エポックのパラメータ更新が完了するたびに，訓練データでの損失，正解率，検証データでの損失，正解率をグラフにプロットし，学習の進捗状況を確認できるようにせよ．

# 回答
## 回答結果
こんな感じで正解率がグラフで表示され、右上のリフレッシュアイコン押せば状況が更新されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134273/6c415d42-1fbe-0f13-82d5-05da3b5d71c5.png)

## 回答プログラム [75_損失と正解率のプロット.ipynb](https://github.com/YoheiFukuhara/nlp100-2020/blob/main/08.%E3%83%8B%E3%83%A5%E3%83%BC%E3%83%A9%E3%83%AB%E3%83%8D%E3%83%83%E3%83%88/75_%E6%90%8D%E5%A4%B1%E3%81%A8%E6%AD%A3%E8%A7%A3%E7%8E%87%E3%81%AE%E3%83%97%E3%83%AD%E3%83%83%E3%83%88.ipynb)
GitHubには確認用コードも含めていますが、ここには必要なものだけ載せています。Jupyterのコードなので、途中に[magics](https://ipython.readthedocs.io/en/stable/interactive/magics.html)を埋め込んでいます。

```python
import tensorflow as tf
from google.colab import drive

drive.mount('/content/drive')

%load_ext tensorboard

def _parse_function(example_proto):
    # 特徴の記述
    feature_description = {
        'title': tf.io.FixedLenFeature([], tf.string),
        'category': tf.io.FixedLenFeature([], tf.string)}
  
  # 上記の記述を使って入力の tf.Example を処理
    features = tf.io.parse_single_example(example_proto, feature_description)
    X = tf.io.decode_raw(features['title'], tf.float32)
    y = tf.io.decode_raw(features['category'], tf.int32)
    return X, y

BASE_PATH = '/content/drive/MyDrive/ColabNotebooks/ML/NLP100_2020/08.NeuralNetworks/'

def get_dataset(file_name):
    ds_raw = tf.data.TFRecordDataset(BASE_PATH+file_name+'.tfrecord')
    return ds_raw.map(_parse_function).shuffle(1000).batch(32)

train_ds = get_dataset('train')
valid_ds = get_dataset('valid')

model = tf.keras.Sequential(
    [tf.keras.layers.Dense(
        4, activation='softmax', input_dim=300, use_bias=False, kernel_initializer='random_uniform') ])
model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['acc'])

%tensorboard --logdir './logs'

model.fit(train_ds, epochs=100, validation_data=valid_ds, 
          callbacks=[tf.keras.callbacks.TensorBoard(log_dir='./logs')])
```

## 回答解説
### TensorBoard Extention読込
[magics](https://ipython.readthedocs.io/en/stable/interactive/magics.html)を使ってTensorBoard の Extentionを読み込みます。

```python:
%load_ext tensorboard
```

### TensorBoard起動
同じく[magics](https://ipython.readthedocs.io/en/stable/interactive/magics.html)を使ってTensorBoard 起動。簡単です。ディレクトリ`.logs`にあるTensorBoardのデータを読み込みます(保存は訓練時に指定します)。
今回は、訓練中にも見られるようにするために訓練開始前に実行しています。

```python:
%tensorboard --logdir './logs'
```

### TensorBoardのコールバック指定
`fit`関数にコールバックでTensorBoardデータを格納するように指定します。当然、TensorBoard起動時とディレクトリを同一にします。
また、今回は`validation_data`も指定しています。

```python:
model.fit(train_ds, epochs=100, validation_data=valid_ds, 
          callbacks=[tf.keras.callbacks.TensorBoard(log_dir='./logs')])
```