pei’s blog

情報系の大学を出たSE1年生。主にプログラミング(機械学習寄り)の話題を書いていきます。

pythonで機械学習(kerasのOneHotレイヤーの作り方)

今回はkerasで学習時にOneHotベクトル化するレイヤーの作り方を書きます。

テキスト分類などでは、学習の前に特徴ベクトル化するとメモリを大量に消費してしまい、PCのスペックが高くないとメモリ不足で動かなくなることがあります。それなら学習前はOneHotベクトルのフラグの立つインデックスのみを保持し、学習時にOneHotベクトル化をしたほうがメモリ効率は断然いいです。


実装方法

 Lambdaレイヤは引数に関数オブジェクトを渡し、Layerオブジェクトのような振る舞いをさせるレイヤです。
 Lambdaレイヤにkerasのbackedのone_hot関数を渡すことでデータをOneHot化するレイヤを追加できます。
 Lambdaの引数のarguments['numclasses']は1つのOneHotベクトルの次元数で、input_shapeは1つのデータにOneHotベクトルをいくつ保持するかを表します。そのため、output_shapeは(data_length, vec_size)とします。
 1つの入力データは長さがdata_lengthで、フラグの立つインデックスを保持した配列になります。

  from keras.models import Sequential
  from keras.layers.recurrent import LSTM
  from keras import backend as K
  from keras.layers.core import Lambda, Dense, Activation
  def init_model(self, vec_size, data_length, output_num):
    self.model = Sequential()
    # OneHot化するレイヤー
    self.model.add(Lambda(K.one_hot, dtype='int32', arguments={'num_classes': vec_size},
                                    input_shape=(data_length, ), output_shape=(data_length, vec_size))

    self.model.add(LSTM(output_num, activation='relu', dropout=0.5))
    self.add(Dense(output_num))
    self.model.add(Activation('softmax'))

注意点

 kerasでネットワークモデルを保存するとき、model.saveをすると、紹介したOnehotレイヤは外部の関数(keras.backend.one_hot)を利用しているため、そのような関数はないというエラーがロード時に起こります。
 そのため、モデルを保存したいときはmodel.save_weightでパラメータのみを保存してください。