Sequential
(系列) モデルは層を積み重ねたもの。
Sequential
モデルはコンストラクタに層のインスタンスのリストを与えることで作れる:
from keras.models
import Sequential
from keras.layers
import Dense, Activation
model = Sequential([
Dense(
32, input_dim=
784),
Activation(
'relu'),
Dense(
10),
Activation(
'softmax'),
])
単純に .add()
メソッドを用いて層を追加できる。
model = Sequential()
model.add(Dense(
32, input_dim=
784))
model.add(Activation(
'relu'))
入力の形を指定する
最初の層では入力の形を指定しなければならない (それ以降の層では必要ない) 。 指定する方法は複数ある:
· 最初の層にinput_shape
引数を与える。これは形を表すタプル (タプルの要素は整数かNone
でNone
はどんなサイズでも良いことを表す。) input_shape
にbatchサイズは含まれない。
· 代わりにbatch_input_shape
引数を与える。ここではbatchサイズが含まれる。これは固定長のbatchサイズを指定するときに便利である (例えば stateful RNN) 。
· Dense
などの一部の2Dの層では入力の形をinput_dim
で指定でき、一部の3Dの層ではinput_dim
とinput_length
で指定できる。
したがって、次の3つのコードは等価である。
model = Sequential()
model.add(Dense(
32, input_shape=(
784,)))
model = Sequential()
model.add(Dense(
32, batch_input_shape=(
None,
784)))
# note that batch dimension is "None" here,
# so the model will be able to process batches of any size.
model = Sequential()
model.add(Dense(
32, input_dim=
784))
次の3つのコードも等価である。
model = Sequential()
model.add(LSTM(
32, input_shape=(
10,
64)))
model = Sequential()
model.add(LSTM(
32, batch_input_shape=(
None,
10,
64)))
model = Sequential()
model.add(LSTM(
32, input_length=
10, input_dim=
64))
マージ層
複数のSequential
のインスタンスをマージ層を使って1つの出力にマージできる。出力は新しいSequential
モデルの1層目として使える。 以下は2つの入力がマージされている:
from keras.layers
import Merge
left_branch = Sequential()
left_branch.add(Dense(
32, input_dim=
784))
right_branch = Sequential()
right_branch.add(Dense(
32, input_dim=
784))
merged = Merge([left_branch, right_branch], mode=
'concat')
final_model = Sequential()
final_model.add(merged)
final_model.add(Dense(
10, activation=
'softmax'))
このような2つに分岐したモデルは次のようにして学習できる:
final_model.compile(optimizer=
'rmsprop', loss=
'categorical_crossentropy')
final_model.fit([input_data_1, input_data_2], targets)
# we pass one data array per model input
マージ層にはいくつかの定義されたモードがある。
· sum
(デフォルト): 要素ごとの和
· concat
: テンソル結合。結合する軸はconcat_axis
で指定できる。
· mul
: 要素ごとの積
· ave
: テンソル平均
· dot
: ドット積。ドット積を取る軸はdot_axes
で指定できる。
· cos
: 2Dテンソルで表現されたベクトル間のコサイン類似度。
任意の変換のためにmode
に関数を渡すこともできる。
merged = Merge([left_branch, right_branch], mode=
lambda x, y: x - y)
これでほとんどのモデルをKerasで実装できる。Sequential
やMerge
では表現できないより複雑なモデルはFunctional APIを使って定義できる。.
コンパイル
モデルの学習を始める前にcompile
メソッドを使って学習経過の設定を行う必要がある。compile
は3つの引数を取る:
· 最適化手法: これは定義されている手法 (rmsprop
やadagrad
など) を表す文字列、またはOptimizer
クラスのインスタンス。最適化アルゴリズム。
· 損失関数: これをモデルは最小化する。それは文字列 (例えばcategorical_crossentropy
やmse
) または目的関数。目的関数。
· 評価指標のリスト: 例えば分類問題では正解率 metrics=['accuracy']
。評価指標は文字列 (accuracy
) または自分で定義した関数。
# for a multi-class classification problem
model.compile(optimizer=
'rmsprop',
loss=
'categorical_crossentropy',
metrics=[
'accuracy'])
# for a binary classification problem
model.compile(optimizer=
'rmsprop',
loss=
'binary_crossentropy',
metrics=[
'accuracy'])
# for a mean squared error regression problem
model.compile(optimizer=
'rmsprop',
loss=
'mse')
学習
KerasのモデルはNumpyの配列のデータとラベルを用いて学習する。典型的にはfit
関数を使う。 詳細はドキュメントを 。
# for a single-input model with 2 classes (binary):
model = Sequential()
model.add(Dense(
1, input_dim=
784, activation=
'sigmoid'))
model.compile(optimizer=
'rmsprop',
loss=
'binary_crossentropy',
metrics=[
'accuracy'])
# generate dummy data
import numpy
as np
data = np.random.random((
1000,
784))
labels = np.random.randint(
2, size=(
1000,
1))
# train the model, iterating on the data in batches
# of 32 samples
model.fit(data, labels, nb_epoch=
10, batch_size=
32)
# for a multi-input model with 10 classes:
left_branch = Sequential()
left_branch.add(Dense(
32, input_dim=
784))
right_branch = Sequential()
right_branch.add(Dense(
32, input_dim=
784))
merged = Merge([left_branch, right_branch], mode=
'concat')
model = Sequential()
model.add(merged)
model.add(Dense(
10, activation=
'softmax'))
model.compile(optimizer=
'rmsprop',
loss=
'categorical_crossentropy',
metrics=[
'accuracy'])
# generate dummy data
import numpy
as np
from keras.utils.np_utils
import to_categorical
data_1 = np.random.random((
1000,
784))
data_2 = np.random.random((
1000,
784))
# these are integers between 0 and 9
labels = np.random.randint(
10, size=(
1000,
1))
# we convert the labels to a binary matrix of size (1000, 10)
# for use with categorical_crossentropy
labels = to_categorical(labels,
10)
# train the model
# note that we are passing a list of Numpy arrays as training data
# since the model has 2 inputs
model.fit([data_1, data_2], labels, nb_epoch=
10, batch_size=
32)
例
以下はいくつかの例です。
examplesフォルダには現実的なデータを使ったモデルの例がある。
· CIFAR10 小規模な画像分類: リアルタイムなデータ拡大を用いた畳み込みニューラルネット (CNN)
· IMDB 映画レビューのセンチメント分類: 単語単位のLSTM
· Reuters 記事のトピック分類: 多層パーセプトロン (MLP)
· MNIST 手書き文字認識: MLPとCNN
· LSTMを用いた文字単位の文章生成
...など
多層パーセプトロン (MLP) を用いた多値分類:
from keras.models
import Sequential
from keras.layers
import Dense, Dropout, Activation
from keras.optimizers
import SGD
model = Sequential()
# Dense(64) is a fully-connected layer with 64 hidden units.
# in the first layer, you must specify the expected input data shape:
# here, 20-dimensional vectors.
model.add(Dense(
64, input_dim=
20, init=
'uniform'))
model.add(Activation(
'tanh'))
model.add(Dropout(
0.5))
model.add(Dense(
64, init=
'uniform'))
model.add(Activation(
'tanh'))
model.add(Dropout(
0.5))
model.add(Dense(
10, init=
'uniform'))
model.add(Activation(
'softmax'))
sgd = SGD(lr=
0.1, decay=
1e-6, momentum=
0.9, nesterov=
True)
model.compile(loss=
'categorical_crossentropy',
optimizer=sgd,
metrics=[
'accuracy'])
model.fit(X_train, y_train,
nb_epoch=
20,
batch_size=
16)
score = model.evaluate(X_test, y_test, batch_size=
16)
別実装によるMLP:
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(
10, activation=
'softmax'))
model.compile(loss=
'categorical_crossentropy',
optimizer=
'adadelta',
metrics=[
'accuracy'])
MLPによる二値分類:
model = Sequential()
model.add(Dense(
64, input_dim=
20, init=
'uniform', 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'])
VGG風 のCNN:
from keras.models
import Sequential
from keras.layers
import Dense, Dropout, Activation, Flatten
from keras.layers
import Convolution2D, MaxPooling2D
from keras.optimizers
import SGD
model = Sequential()
# input: 100x100 images with 3 channels -> (3, 100, 100) tensors.
# this applies 32 convolution filters of size 3x3 each.
model.add(Convolution2D(
32,
3,
3, border_mode=
'valid', input_shape=(
3,
100,
100)))
model.add(Activation(
'relu'))
model.add(Convolution2D(
32,
3,
3))
model.add(Activation(
'relu'))
model.add(MaxPooling2D(pool_size=(
2,
2)))
model.add(Dropout(
0.25))
model.add(Convolution2D(
64,
3,
3, border_mode=
'valid'))
model.add(Activation(
'relu'))
model.add(Convolution2D(
64,
3,
3))
model.add(Activation(
'relu'))
model.add(MaxPooling2D(pool_size=(
2,
2)))
model.add(Dropout(
0.25))
model.add(Flatten())
# Note: Keras does automatic shape inference.
model.add(Dense(
256))
model.add(Activation(
'relu'))
model.add(Dropout(
0.5))
model.add(Dense(
10))
model.add(Activation(
'softmax'))
sgd = SGD(lr=
0.1, decay=
1e-6, momentum=
0.9, nesterov=
True)
model.compile(loss=
'categorical_crossentropy', optimizer=sgd)
model.fit(X_train, Y_train, batch_size=
32, nb_epoch=
1)
LSTMを用いた系列データの分類:
from keras.models
import Sequential
from keras.layers
import Dense, Dropout, Activation
from keras.layers
import Embedding
from keras.layers
import LSTM
model = Sequential()
model.add(Embedding(max_features,
256, input_length=maxlen))
model.add(LSTM(output_dim=
128, activation=
'sigmoid', inner_activation=
'hard_sigmoid'))
model.add(Dropout(
0.5))
model.add(Dense(
1))
model.add(Activation(
'sigmoid'))
model.compile(loss=
'binary_crossentropy',
optimizer=
'rmsprop',
metrics=[
'accuracy'])
model.fit(X_train, Y_train, batch_size=
16, nb_epoch=
10)
score = model.evaluate(X_test, Y_test, batch_size=
16)
CNNとGated Recurrent Unitを用いた画像の説明文生成モデル
(単語単位のembeddingを使い、説明文は最大で16文字)
良い結果を得るためには事前学習で得られた重みで初期化されたより大きいCNNが必要。
max_caption_len =
16
vocab_size =
10000
# first, let's define an image model that
# will encode pictures into 128-dimensional vectors.
# it should be initialized with pre-trained weights.
image_model = Sequential()
image_model.add(Convolution2D(
32,
3,
3, border_mode=
'valid', input_shape=(
3,
100,
100)))
image_model.add(Activation(
'relu'))
image_model.add(Convolution2D(
32,
3,
3))
image_model.add(Activation(
'relu'))
image_model.add(MaxPooling2D(pool_size=(
2,
2)))
image_model.add(Convolution2D(
64,
3,
3, border_mode=
'valid'))
image_model.add(Activation(
'relu'))
image_model.add(Convolution2D(
64,
3,
3))
image_model.add(Activation(
'relu'))
image_model.add(MaxPooling2D(pool_size=(
2,
2)))
image_model.add(Flatten())
image_model.add(Dense(
128))
# let's load the weights from a save file.
image_model.load_weights(
'weight_file.h5')
# next, let's define a RNN model that encodes sequences of words
# into sequences of 128-dimensional word vectors.
language_model = Sequential()
language_model.add(Embedding(vocab_size,
256, input_length=max_caption_len))
language_model.add(GRU(output_dim=
128, return_sequences=
True))
language_model.add(TimeDistributed(Dense(
128)))
# let's repeat the image vector to turn it into a sequence.
image_model.add(RepeatVector(max_caption_len))
# the output of both models will be tensors of shape (samples, max_caption_len, 128).
# let's concatenate these 2 vector sequences.
model = Sequential()
model.add(Merge([image_model, language_model], mode=
'concat', concat_axis=-
1))
# let's encode this vector sequence into a single vector
model.add(GRU(
256, return_sequences=
False))
# which will be used to compute a probability
# distribution over what the next word in the caption should be!
model.add(Dense(vocab_size))
model.add(Activation(
'softmax'))
model.compile(loss=
'categorical_crossentropy', optimizer=
'rmsprop')
# "images" is a numpy float array of shape (nb_samples, nb_channels=3, width, height).
# "captions" is a numpy integer array of shape (nb_samples, max_caption_len)
# containing word index sequences representing partial captions.
# "next_words" is a numpy float array of shape (nb_samples, vocab_size)
# containing a categorical encoding (0s and 1s) of the next word in the corresponding
# partial caption.
model.fit([images, partial_captions], next_words, batch_size=
16, nb_epoch=
100)
多層LSTMによる系列分類
このモデルでは3つのLSTM層を積み重ねることでより高いレベルの系列表現を学習できる。
最初の2層は全系列を返すが最後の層は最終時刻の出力だけを返す (言い換えれば入力系列を1つのベクトルに変換する) 。
from keras.models
import Sequential
from keras.layers
import LSTM, Dense
import numpy
as np
data_dim =
16
timesteps =
8
nb_classes =
10
# expected input data shape: (batch_size, timesteps, data_dim)
model = Sequential()
model.add(LSTM(
32, return_sequences=
True,
input_shape=(timesteps, data_dim)))
# returns a sequence of vectors of dimension 32
model.add(LSTM(
32, return_sequences=
True))
# returns a sequence of vectors of dimension 32
model.add(LSTM(
32))
# return a single vector of dimension 32
model.add(Dense(
10, activation=
'softmax'))
model.compile(loss=
'categorical_crossentropy',
optimizer=
'rmsprop',
metrics=[
'accuracy'])
# generate dummy training data
x_train = np.random.random((
1000, timesteps, data_dim))
y_train = np.random.random((
1000, nb_classes))
# generate dummy validation data
x_val = np.random.random((
100, timesteps, data_dim))
y_val = np.random.random((
100, nb_classes))
model.fit(x_train, y_train,
batch_size=
64, nb_epoch=
5,
validation_data=(x_val, y_val))
同じLSTMのモデルを"stateful"に
stateful な再帰型モデルは、あるbatchを処理した後の内部の状態を次のbatchを処理するときの初期状態として再利用する。こうすることでより長い系列を扱うことができる。
from keras.models
import Sequential
from keras.layers
import LSTM, Dense
import numpy
as np
data_dim =
16
timesteps =
8
nb_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'])
# generate dummy training data
x_train = np.random.random((batch_size *
10, timesteps, data_dim))
y_train = np.random.random((batch_size *
10, nb_classes))
# generate dummy validation data
x_val = np.random.random((batch_size *
3, timesteps, data_dim))
y_val = np.random.random((batch_size *
3, nb_classes))
model.fit(x_train, y_train,
batch_size=batch_size, nb_epoch=
5,
validation_data=(x_val, y_val))
2つの系列データをそれぞれ別のLSTM encoderに渡し、その結果をマージして分類
このモデルでは2つの入力系列が別々のLSTMによってベクトルにencodeされる。 これら2つのベクトルを結合した1つのベクトルを使って全結合層で学習が行われる。
from keras.models
import Sequential
from keras.layers
import Merge, LSTM, Dense
import numpy
as np
data_dim =
16
timesteps =
8
nb_classes =
10
encoder_a = Sequential()
encoder_a.add(LSTM(
32, input_shape=(timesteps, data_dim)))
encoder_b = Sequential()
encoder_b.add(LSTM(
32, input_shape=(timesteps, data_dim)))
decoder = Sequential()
decoder.add(Merge([encoder_a, encoder_b], mode=
'concat'))
decoder.add(Dense(
32, activation=
'relu'))
decoder.add(Dense(nb_classes, activation=
'softmax'))
decoder.compile(loss=
'categorical_crossentropy',
optimizer=
'rmsprop',
metrics=[
'accuracy'])
# generate dummy training data
x_train_a = np.random.random((
1000, timesteps, data_dim))
x_train_b = np.random.random((
1000, timesteps, data_dim))
y_train = np.random.random((
1000, nb_classes))
# generate dummy validation data
x_val_a = np.random.random((
100, timesteps, data_dim))
x_val_b = np.random.random((
100, timesteps, data_dim))
y_val = np.random.random((
100, nb_classes))
decoder.fit([x_train_a, x_train_b], y_train,
batch_size=
64, nb_epoch=
5,
validation_data=([x_val_a, x_val_b], y_val))
0 件のコメント:
コメントを投稿