ありまっくすのへっぽこ日記

アラフォーでへっぽこエンジニアをしております。へっぽこなりに頑張っています。

DeepLearning講座(第7回)を受けてきたよ

7/6(金)にDeepLearning講座の第7回目を受けてきました。

今日の内容はEncoder Decoderの実装とLSTMによる文書分類のアーキテクチャでした。

コードを実際に書いている時間が長かったです。

Encoder Decoder Model

 Encoder部分とDecoder部分に分けて処理をすること。アルゴリズムではなく考え方。

2つの部分に分けることで、いろいろなことが出来ます。(例:画像→文章)

 

seq2seq

Encoder Decoder Modelの一つ。下の図のように英語(単語)を入力して、フランス語(単語)を出力します。EncoderもDecoderも可変長にすることが可能です。

f:id:ari_max:20180705070709p:plain

seq2seq

入力は単語単位でなくてはならないの?

文字単位に入力しても構わないが、単語の概念を学習する必要があります。('a' の後に'm'が入力されたら'am'だよね。というように区切りを学習する)ただし、日本語のように単語と単語をスペースで区切らない言語は難しいと言えます。

単語で区切った方がいいのか、それとも1文字ずつ区切った方がいいのかは議論になっているそうです。

実装のポイント

  1. 入力値は固定次元にする(プログラムとしてやりにくい)
  2. Encoderは普通のLSTM
  3. Decoderはちょっとややこしい(RepeatVector,TimeDistributed,ReturnSequence)
  • ReturnSequence→trueにすると全ての結果が出てくる
  • RepeatVector→出力されたものを入力として使ってくれる
  • TimeDistributed→同じネットワークを全てに適用してくれる

 処理フロー

Encode
  1. 入力値はそのままでは扱えないので、数字に変換する
  2. 単語の類似度を反映した単語ベクトルに変換する(Kerasだと、Embedという層を入れると勝手にやってくれる)
  3. 単語ベクトルから内部ベクトルに変換する
Decode
  1. "ここからがDecoderですよ(GO)"というフラグが来たら、Decodeを開始する
  2. 内部ベクトルから単語ベクトルに変換
  3. 変換したベクトルとEncodeから変換した単語ベクトルに一番近い出力値を選ぶ
  4. 出力値を単語ベクトルから変換して、出力する

コードをKerasで書くと、こんな感じ。

EncoderはシンプルにLSTM。

# Encoder
model.add(LSTM(n_hidden, input_shape=(input_digits, n_in)))

Decoderはちょっと複雑。ここではRepeatVectorを指定

# Decoder
model.add(RepeatVector(output_digits))
model.add(LSTM(n_hidden, return_sequences = True))
model.add(TimeDistributed(Dense(n_out)))

モデルの学習

# モデルの学習
model.compile(loss='categorical_crossentropy',optimizer=Adam(lr=0.001,beta_1=0.9,beta_2=0.999),metrics=['accuracy'])
h = model.fit(X_train, Y_train, batch_size=batch_size, epochs=epochs, validation_data=(X_validation, Y_validation))

モデルを使って予測

prediction = model.predict_classes(question, verbose=0)

次回からはGitHubにコードあげようかな。