AI系基盤技術と、オープンソースを用いた機械学習による特許文書解析(補足3)

2020年10月18日
アジア特許情報研究会 西尾 潤

本稿は特技懇誌 No.298, pp.25-37 (2020) に収録できなかった内容を追記するものです。

本稿(補足3)では、ニューラルネットワークを用いた機械学習の例をソースコードを交えて紹介します。

特技懇誌投稿記事の図4のうち、下図のように濃色で示す部分に当たり、処理の流れは ラベル作成 → 機械学習 となります。

オープンソースを用いた機械学習による特許文書解析(補足2)を読む

ニューラルネットワーク

ここではニューラルネットワークを用いた4値分類を紹介します。ニューラルネットワークによる他のタスクは次回の記事で紹介します。

ニューラルネットワークを動かすことができる基本プログラム群を「フレームワーク」といい、python 上で import することにより導入できます。

Tensorflow-Keras の場合
import tensorflow as tf
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Dense, Reshape, Conv1D, Activation
from tensorflow.keras.optimizers import SGD, RMSprop, Adagrad, Adadelta, Adam, Adamax, Nadam
from tensorflow.keras import losses
pytorch の場合

import torch
import torch.nn as nn
import torch.nn.functional as F
import torchtext

レイヤー

ニューラルネットワークはレイヤー(層)を重ねることでデータから特徴量を抽出することができます。

添付のソースコードで使用したCNNを含む4値分類用のモデルを示し解説します。

  inputs = Input(shape=x.shape[1])
 h = Reshape((x.shape[1], 1), input_shape=(x.shape[1],))(inputs)
 h2 = Conv1D(8, 2, activation='relu')(h)
 h2 = SpatialDropout1D(0.2)(h2)
 h2 = MaxPooling1D(3)(h2)
 h3 = Conv1D(8, 3, activation='relu')(h)
 h3 = SpatialDropout1D(0.2)(h3)
 h3 = MaxPooling1D(3)(h3)
 h4 = Conv1D(8, 4, activation='relu')(h)
 h4 = SpatialDropout1D(0.2)(h4)
 h4 = MaxPooling1D(3)(h4)
 h5 = Conv1D(8, 5, activation='relu')(h)
 h5 = SpatialDropout1D(0.2)(h5)
 h5 = MaxPooling1D(3)(h5)
 h = Concatenate(axis=1)([h2, h3, h4, h5])
 h = Flatten()(h)
 h = Dense(512, activation='relu')(h)
 h0 = Dense(16, activation='relu')(h)
 h1 = Dense(16, activation='relu')(h)
 h2 = Dense(16, activation='relu')(h)
 h3 = Dense(16, activation='relu')(h)
 out_0 = Dense(1, activation='sigmoid', name='out_0')(h0)
 out_1 = Dense(1, activation='sigmoid', name='out_1')(h1)
 out_2 = Dense(1, activation='sigmoid', name='out_2')(h2)
 out_3 = Dense(1, activation='sigmoid', name='out_3')(h3)

  model = Model(inputs=inputs, outputs=[out_0, out_1, out_2, out_3])
ここではkeras API を使った記述を使用していますが、
 
h0 = Dense(16, activation='relu')(h)
のように、層を関数のように記述します。
この例はh0という名前の16次元の全結合層であり、前段のhという名前の層の出力をh0に入力します。
ニューラルネットワークの入力は1次元CNNの入力に合わせるようにReshapeでベクトルを成形しています。
1次元CNN層はウインドウサイズが2,3,4,5の4層を並列に用い、Concatenateで集約し、Flattenで平滑化します。
 
CNN層は通常プーリング層でデータサイズを縮小します。
Dropout層は指定した確率で出力を止めることによってデータの多様性を生み出し、過学習を抑制する効果を生みます。
 
出力は4値分類のため、途中で4つに分岐し、出力が1次元になるよう徐々に層の全結合層の次元を小さくします。
4つの出力層のそれぞれは活性化関数に sigmoid関数 を使用することによって、それぞれ0-1の出力となり、独立した4つの確率として扱うことができます。
このモデルを学習するためには出力に合わせたラベルを用意する必要があり、4次元の one-hot ベクトルを入力すればよいことになります。
記述したモデルを図示すると、次のようになります。

学習

学習の基本となるコマンドは次の行です。

# 学習
training = model.fit(x_train, {'out_0':y_train[:,0], 'out_1':y_train[:,1],
                                        'out_2':y_train[:,2], 'out_3':y_train[:,3]},
    batch_size=batch_size,
    initial_epoch=initial_epoch, epochs=initial_epoch+epochs, verbose=1,
    validation_data=(x_valid, {'out_0':y_valid[:,0], 'out_1':y_valid[:,1],
                                          'out_2':y_valid[:,2], 'out_3':y_valid[:,3]}))

入力データとして教師用の文書ベクトル x_train 、教師用のラベル y_train 、検証用の文書ベクトル x_valid 、検証用のラベル y_valid を使用します。

 

ラベルは出力が4ノードのため、4つに分けています。

batch_size は膨大なデータをミニバッチに分けてその都度精度を計算することで効率的に学習を進める工夫で、通常32です。

epoch はミニバッチのデータが一巡してすべてのデータを1回使用することを指し、繰り返し学習させる回数を指定します。 initial_epoch  と epochs を使って、途中でデータを交換しながら学習を進める芸当も可能です。

 model.fit 関数は training として取り出されますが、この中には training.history として、 epoch ごとの学習状況が記録されているので、これを取り出して解析が可能です。

誤差逆伝播学習法

レイヤーは入力x、重みw、バイアスbからなる1次元の線形代数で表される形式ニューロンの集合体です。学習は各ニューロンの重みとバイアスを調整する作業です。

学習はニューラルネットワークの出力とラベルとの差異が小さくなるように調整しますが、その差異を誤差関数で定義します。二乗誤差が代表的なものです。

誤差関数で計算されて得た誤差の値を使って重みを更新しますが、層の出力側から入力側に向かって順番に重みを更新していくことを誤差逆伝播学習法とよび、これが機械学習の主流になっています。

誤差逆伝播学習法の問題としては入力側に向かうにしたがって誤差の計算がやりにくくなる、勾配消失問題、勾配爆発問題がおきますが、これを解消するために中間層の活性化関数に relu という直線の関数が用いられます。

推論

推論はコマンド1行です。

pred_data = model.predict(x_test, batch_size=batch_size, verbose=1, steps=None)
学習に用いなかったデータ x_test をモデルに投入すると出力が得られます。
モデルの精度を確認するときは、出力値とラベルとを直接比較することが可能です。

過学習

過学習は「過剰適合」とも呼ばれるもので、学習データによく追従するが、未知のデータには適合しない状態を指します。未知のデータに適合する能力を「汎化性能」が高い/低いと表現します。

過学習の特徴

1.検証データの損失が教師データの損失よりかなり大きい(教師データの精度は高いが検証データの精度はそれほど高くない)

2.予測データの損失が学習時よりかなり大きい(学習時の検証データの精度に比べて明らかに低い)

3.学習を重ねるにつれて損失が徐々に大きくなっていく

右側のグラフの状態が過学習であることがわかります。

過学習の抑制方法

1.モデルを小さくする

2.epoch を減らす

3.文書ベクトルの作成方法を見直す

4.教師データのラベルを見直す

5.データ数を増やす

データサイズに適したモデルに調整した後にラベルを見直すようにすることがコツです。

添付ファイルの例ではCNN層を有するネットワークで過学習が起きていますが、CNN層を取り払って全結合層だけにする対策をとりました。

また、交差検証の際にデータを教師と検証の間で使いまわすことでデータ数を増やして学習時の過学習がみられなくなりました。

しかし、未知のデータには適合できていません。ラベルを見直すことで精度が向上しましたが、不十分な結果で終わりました。

具体的には、カテゴリ分けを筆頭FIで行いましたが、ある特定の筆頭FIの中に、独立請求項の文章から判断されるカテゴリが複数混在するものがあり、そのFIをカテゴリ分類に使用しないこととしました。

教師なし学習で分けたカテゴリを教師ありデータに使うと精度が向上することが知られています。

ソースコード

google Colaboratory で使用可能な jupyter notebook 形式で配布しています。

 

AI系基盤技術と、オープンソースを用いた機械学習による特許文書解析(補足4・終) をみる