Keras : Getting started : Keras Sequential モデル

Keras : Getting Started : Keras Sequential モデル (翻訳/解説)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 06/13/2018 (2.2.0)

* 本ページは、Keras 本家サイトの – Getting started with the Keras Sequential model を
動作確認・翻訳した上で適宜、補足説明したものです:

* Keras 本家サイトには日本語訳も用意されていますが、それとは無関係に翻訳したものです。
* サンプルコードの動作確認はしておりますが、適宜、追加改変している場合もあります。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

本文

Sequential モデルは層の線形スタックです。

層インスタンスのリストをコンストラクタに渡すことによって Sequential モデルを作成することができます :

from keras.models import Sequential
from keras.layers import Dense, Activation

model = Sequential([
    Dense(32, input_shape=(784,)),
    Activation('relu'),
    Dense(10),
    Activation('softmax'),
])

単純に .add() メソッドを通して層を追加することもできます :

model = Sequential()
model.add(Dense(32, input_dim=784))
model.add(Activation('relu'))

 

入力 shape を指定する

モデルはそれが想定すべき入力 shape が何であるかを知る必要があります。このため、Sequential モデルの最初の層は (そして最初だけ、何故ならば続く層は自動 shape 推定を遂行できます) その入力 shape についての情報を受け取る必要があります。これを行なうための幾つかの可能な方法があります :

  • 最初の層に input_shape 引数を渡します。これは shape タプルです (整数のタプルか None エントリ、ここで None は任意の正の数字が想定可能であることを示します)。input_shape では、batch 次元は含まれません。
  • Dense のような幾つかの 2D 層は、引数 input_dim を通じてそれらの入力 shape の仕様をサポートし、そして幾つかの 3D temporal 層は引数 input_dim と input_length をサポートします。
  • もし入力のために固定バッチサイズを指定する必要さえある場合 (これは stateful リカレント・ネットワークのために有用です)、層に batch_size 引数を渡すことができます。もし batch_size=32 と input_shape=(6, 8) の両者を層に渡す場合、それは総ての入力バッチがバッチ shape (32, 6, 8) を持つことを想定するでしょう。

というわけで、次のスニペットは厳密に同値です :

model = Sequential()
model.add(Dense(32, input_shape=(784,)))
model = Sequential()
model.add(Dense(32, input_dim=784))

 

コンパイル

モデルを訓練する前に、学習プロセスを configure する必要があります、これは compile メソッドを通して成されます。それは 3 つの引数を受け取ります :

  • optimizer: これは (rmsprop や adagrad のような) 既存の optimizer の文字列識別子か、Optimizer クラスのインスタンスです。optimizers 参照。
  • 損失関数: これはモデルが最小化しようとする目的です。それは (categorical_crossentropy や mse のような) 既存の損失関数の文字列識別子か、目的関数です。losses 参照。
  • メトリクスのリスト。任意の分類問題に対してこれを metrics=[‘accuracy’] と設定することを望むでしょう。メトリックは既存のメトリックの文字列識別子かカスタム・メトリック関数です。
# 多クラス分類問題に対して
model.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# 二値分類問題に対して
model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy'])

# 平均二乗誤差 (= mean squared error) 回帰問題に対して。
model.compile(optimizer='rmsprop',
              loss='mse')

# カスタム・メトリクスに対して。
import keras.backend as K

def mean_pred(y_true, y_pred):
    return K.mean(y_pred)

model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy', mean_pred])

 

訓練

Keras モデルは入力データとラベルの Numpy 配列上で訓練されます。モデルを訓練するためには、典型的には fit 関数を使用します。ここのそのドキュメントを読んでください

# 2 クラスを持つシングル入力モデルのために (二値分類) :

model = Sequential()
model.add(Dense(32, activation='relu', input_dim=100))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy'])

# ダミーデータを生成する。
import numpy as np
data = np.random.random((1000, 100))
labels = np.random.randint(2, size=(1000, 1))

# 32 サンプルのバッチのデータ上で反復し、モデルを訓練する。
model.fit(data, labels, epochs=10, batch_size=32)
# 10 クラスを持つシングル入力モデルのために (カテゴリー分類) :

model = Sequential()
model.add(Dense(32, activation='relu', input_dim=100))
model.add(Dense(10, activation='softmax'))
model.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# ダミーデータを生成する。
import numpy as np
data = np.random.random((1000, 100))
labels = np.random.randint(10, size=(1000, 1))

# ラベルをカテゴリー one-hot エンコーディングに変換する
one_hot_labels = keras.utils.to_categorical(labels, num_classes=10)

# 32 サンプルのバッチのデータ上で反復し、モデルを訓練する。
model.fit(data, one_hot_labels, epochs=10, batch_size=32)

 

サンプル

貴方が始めるための幾つかのサンプルがここにあります!

examples フォルダ では、現実のデータセットのためのサンプル・モデルもまた見い出すでしょう :

  • CIFAR10 small 画像分類: リアルタイム・データ増強を伴う畳み込みニューラルネットワーク (CNN)
  • IMDB 映画レビュー感情分類: 単語のシークエンスに渡る LSTM
  • ロイター・ニュースワイヤーのトピック分類: 多層パーセプトロン (MLP)
  • MNIST 手書き数字分類: MLP & CNN
  • LSTM による文字レベル・テキスト生成

…and more.

 

多クラス softmax 分類のための多層パーセプトロン (MLP)

import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation
from keras.optimizers import SGD

# ダミーデータを生成する
import numpy as np
x_train = np.random.random((1000, 20))
y_train = keras.utils.to_categorical(np.random.randint(10, size=(1000, 1)), num_classes=10)
x_test = np.random.random((100, 20))
y_test = keras.utils.to_categorical(np.random.randint(10, size=(100, 1)), num_classes=10)

model = Sequential()
# Dense(64) は 64 隠れユニットを持つ完全結合層。
# 最初の層では、想定する入力データ shape を指定しなければなりません :
# ここでは、20-次元ベクトルです。
model.add(Dense(64, activation='relu', input_dim=20))
model.add(Dropout(0.5))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))

sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy',
              optimizer=sgd,
              metrics=['accuracy'])

model.fit(x_train, y_train,
          epochs=20,
          batch_size=128)
score = model.evaluate(x_test, y_test, batch_size=128)

 

二値分類のための MLP

import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Dropout

# ダミーデータを生成する。
x_train = np.random.random((1000, 20))
y_train = np.random.randint(2, size=(1000, 1))
x_test = np.random.random((100, 20))
y_test = np.random.randint(2, size=(100, 1))

model = Sequential()
model.add(Dense(64, input_dim=20, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

model.fit(x_train, y_train,
          epochs=20,
          batch_size=128)
score = model.evaluate(x_test, y_test, batch_size=128)

 

VGG-ライク convnet

import numpy as np
import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.optimizers import SGD

# ダミーデータを生成する。
x_train = np.random.random((100, 100, 100, 3))
y_train = keras.utils.to_categorical(np.random.randint(10, size=(100, 1)), num_classes=10)
x_test = np.random.random((20, 100, 100, 3))
y_test = keras.utils.to_categorical(np.random.randint(10, size=(20, 1)), num_classes=10)

model = Sequential()
# 入力: 3 チャネルを持つ 100x100 画像 -> (100, 100, 3) tensor。
# これは各々サイズ 3x3 の畳み込みフィルタを適用します。
model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(100, 100, 3)))
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))

sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd)

model.fit(x_train, y_train, batch_size=32, epochs=10)
score = model.evaluate(x_test, y_test, batch_size=32)

 

LSTM によるシークエンス分類

from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.layers import Embedding
from keras.layers import LSTM

model = Sequential()
model.add(Embedding(max_features, output_dim=256))
model.add(LSTM(128))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

model.fit(x_train, y_train, batch_size=16, epochs=10)
score = model.evaluate(x_test, y_test, batch_size=16)

 

1D 畳み込みによるシークエンス分類

from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.layers import Embedding
from keras.layers import Conv1D, GlobalAveragePooling1D, MaxPooling1D

model = Sequential()
model.add(Conv1D(64, 3, activation='relu', input_shape=(seq_length, 100)))
model.add(Conv1D(64, 3, activation='relu'))
model.add(MaxPooling1D(3))
model.add(Conv1D(128, 3, activation='relu'))
model.add(Conv1D(128, 3, activation='relu'))
model.add(GlobalAveragePooling1D())
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

model.fit(x_train, y_train, batch_size=16, epochs=10)
score = model.evaluate(x_test, y_test, batch_size=16)

 

シークエンス分類のための Stacked LSTM

このモデルでは、3 つの LSTM 層を重なり合うようにスタックして、モデルがより高位な時間表現 (= temporal representations) を学習できるようにします。

最初の 2 つの LSTM はそれらの完全な出力シークエンスを返しますが、最後の一つはその出力シークエンスの最後のステップを返し、そして時間次元を落とします (i.e. 入力シークエンスを単一ベクトルに変換します)。

from keras.models import Sequential
from keras.layers import LSTM, Dense
import numpy as np

data_dim = 16
timesteps = 8
num_classes = 10

# 想定する入力データ shape : (batch_size, timesteps, data_dim)
model = Sequential()
model.add(LSTM(32, return_sequences=True,
               input_shape=(timesteps, data_dim)))  # 次元 32 のベクトルのシークエンスを返す。
model.add(LSTM(32, return_sequences=True))  # 次元 32 のベクトルのシークエンスを返す。
model.add(LSTM(32))  # 次元 32 の単一のベクトルを返す。
model.add(Dense(10, activation='softmax'))

model.compile(loss='categorical_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

# ダミー訓練データを生成する。
x_train = np.random.random((1000, timesteps, data_dim))
y_train = np.random.random((1000, num_classes))

# ダミー検証データを生成する。
x_val = np.random.random((100, timesteps, data_dim))
y_val = np.random.random((100, num_classes))

model.fit(x_train, y_train,
          batch_size=64, epochs=5,
          validation_data=(x_val, y_val))

 

「ステートフル」な同じ stacked LSTM モデル

ステートフルなリカレント・モデルは、サンプルのバッチ処理後に得られた内部状態 (メモリ) が次のバッチのサンプルのための初期状態として再利用されるものです。これは計算の複雑さを管理可能なものとして保持しながらより長いシークエンスを扱うことを可能にします。

ステートフル RNN については FAQ で更に読むことができます

from keras.models import Sequential
from keras.layers import LSTM, Dense
import numpy as np

data_dim = 16
timesteps = 8
num_classes = 10
batch_size = 32

# Expected input batch shape: (batch_size, timesteps, data_dim)
# Note that we have to provide the full batch_input_shape since the network is stateful.
# the sample of index i in batch k is the follow-up for the sample i in batch k-1.
model = Sequential()
model.add(LSTM(32, return_sequences=True, stateful=True,
               batch_input_shape=(batch_size, timesteps, data_dim)))
model.add(LSTM(32, return_sequences=True, stateful=True))
model.add(LSTM(32, stateful=True))
model.add(Dense(10, activation='softmax'))

model.compile(loss='categorical_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

# ダミー訓練データを生成する。
x_train = np.random.random((batch_size * 10, timesteps, data_dim))
y_train = np.random.random((batch_size * 10, num_classes))

# ダミー検証データを生成する。
x_val = np.random.random((batch_size * 3, timesteps, data_dim))
y_val = np.random.random((batch_size * 3, num_classes))

model.fit(x_train, y_train,
          batch_size=batch_size, epochs=5, shuffle=False,
          validation_data=(x_val, y_val))

 

 

以上