このリンクを使用して、テキスト分類のマルチチャネルCNNモデルを理解します。
コードはこのチュートリアルに基づいています。
私はほとんどのことを理解しましたが、Kerasが特定のレイヤーの出力形状をどのように定義するかを理解できません。
コードは次のとおりです。
4グラム、6グラム、および8グラムの映画レビューテキストを処理するための3つの入力チャネルを持つモデルを定義します。
#Skipped keras imports
# load a clean dataset
def load_dataset(filename):
return load(open(filename, 'rb'))
# fit a tokenizer
def create_tokenizer(lines):
tokenizer = Tokenizer()
tokenizer.fit_on_texts(lines)
return tokenizer
# calculate the maximum document length
def max_length(lines):
return max([len(s.split()) for s in lines])
# encode a list of lines
def encode_text(tokenizer, lines, length):
# integer encode
encoded = tokenizer.texts_to_sequences(lines)
# pad encoded sequences
padded = pad_sequences(encoded, maxlen=length, padding='post')
return padded
# define the model
def define_model(length, vocab_size):
# channel 1
inputs1 = Input(shape=(length,))
embedding1 = Embedding(vocab_size, 100)(inputs1)
conv1 = Conv1D(filters=32, kernel_size=4, activation='relu')(embedding1)
drop1 = Dropout(0.5)(conv1)
pool1 = MaxPooling1D(pool_size=2)(drop1)
flat1 = Flatten()(pool1)
# channel 2
inputs2 = Input(shape=(length,))
embedding2 = Embedding(vocab_size, 100)(inputs2)
conv2 = Conv1D(filters=32, kernel_size=6, activation='relu')(embedding2)
drop2 = Dropout(0.5)(conv2)
pool2 = MaxPooling1D(pool_size=2)(drop2)
flat2 = Flatten()(pool2)
# channel 3
inputs3 = Input(shape=(length,))
embedding3 = Embedding(vocab_size, 100)(inputs3)
conv3 = Conv1D(filters=32, kernel_size=8, activation='relu')(embedding3)
drop3 = Dropout(0.5)(conv3)
pool3 = MaxPooling1D(pool_size=2)(drop3)
flat3 = Flatten()(pool3)
# merge
merged = concatenate([flat1, flat2, flat3])
# interpretation
dense1 = Dense(10, activation='relu')(merged)
outputs = Dense(1, activation='sigmoid')(dense1)
model = Model(inputs=[inputs1, inputs2, inputs3], outputs=outputs)
# compile
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
# summarize
print(model.summary())
plot_model(model, show_shapes=True, to_file='multichannel.png')
return model
# load training dataset
trainLines, trainLabels = load_dataset('train.pkl')
# create tokenizer
tokenizer = create_tokenizer(trainLines)
# calculate max document length
length = max_length(trainLines)
# calculate vocabulary size
vocab_size = len(tokenizer.word_index) + 1
print('Max document length: %d' % length)
print('Vocabulary size: %d' % vocab_size)
# encode data
trainX = encode_text(tokenizer, trainLines, length)
print(trainX.shape)
# define model
model = define_model(length, vocab_size)
# fit model
model.fit([trainX,trainX,trainX], array(trainLabels), epochs=10, batch_size=16)
# save the model
model.save('model.h5')
コードの実行:
最初に例を実行すると、準備されたトレーニングデータセットの概要が出力されます。最大ドキュメント長:1380語彙サイズ:44277(1800、1380)
____________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
====================================================================================================
input_1 (InputLayer) (None, 1380) 0
____________________________________________________________________________________________________
input_2 (InputLayer) (None, 1380) 0
____________________________________________________________________________________________________
input_3 (InputLayer) (None, 1380) 0
____________________________________________________________________________________________________
embedding_1 (Embedding) (None, 1380, 100) 4427700 input_1[0][0]
____________________________________________________________________________________________________
embedding_2 (Embedding) (None, 1380, 100) 4427700 input_2[0][0]
____________________________________________________________________________________________________
embedding_3 (Embedding) (None, 1380, 100) 4427700 input_3[0][0]
____________________________________________________________________________________________________
conv1d_1 (Conv1D) (None, 1377, 32) 12832 embedding_1[0][0]
____________________________________________________________________________________________________
conv1d_2 (Conv1D) (None, 1375, 32) 19232 embedding_2[0][0]
____________________________________________________________________________________________________
conv1d_3 (Conv1D) (None, 1373, 32) 25632 embedding_3[0][0]
____________________________________________________________________________________________________
dropout_1 (Dropout) (None, 1377, 32) 0 conv1d_1[0][0]
____________________________________________________________________________________________________
dropout_2 (Dropout) (None, 1375, 32) 0 conv1d_2[0][0]
____________________________________________________________________________________________________
dropout_3 (Dropout) (None, 1373, 32) 0 conv1d_3[0][0]
____________________________________________________________________________________________________
max_pooling1d_1 (MaxPooling1D) (None, 688, 32) 0 dropout_1[0][0]
____________________________________________________________________________________________________
max_pooling1d_2 (MaxPooling1D) (None, 687, 32) 0 dropout_2[0][0]
____________________________________________________________________________________________________
max_pooling1d_3 (MaxPooling1D) (None, 686, 32) 0 dropout_3[0][0]
____________________________________________________________________________________________________
flatten_1 (Flatten) (None, 22016) 0 max_pooling1d_1[0][0]
____________________________________________________________________________________________________
flatten_2 (Flatten) (None, 21984) 0 max_pooling1d_2[0][0]
____________________________________________________________________________________________________
flatten_3 (Flatten) (None, 21952) 0 max_pooling1d_3[0][0]
____________________________________________________________________________________________________
concatenate_1 (Concatenate) (None, 65952) 0 flatten_1[0][0]
flatten_2[0][0]
flatten_3[0][0]
____________________________________________________________________________________________________
dense_1 (Dense) (None, 10) 659530 concatenate_1[0][0]
____________________________________________________________________________________________________
dense_2 (Dense) (None, 1) 11 dense_1[0][0]
====================================================================================================
Total params: 14,000,337
Trainable params: 14,000,337
Non-trainable params: 0
____________________________________________________________________________________________________
そして
Epoch 6/10
1800/1800 [==============================] - 30s - loss: 9.9093e-04 - acc: 1.0000
Epoch 7/10
1800/1800 [==============================] - 29s - loss: 5.1899e-04 - acc: 1.0000
Epoch 8/10
1800/1800 [==============================] - 28s - loss: 3.7958e-04 - acc: 1.0000
Epoch 9/10
1800/1800 [==============================] - 29s - loss: 3.0534e-04 - acc: 1.0000
Epoch 10/10
1800/1800 [==============================] - 29s - loss: 2.6234e-04 - acc: 1.0000
レイヤーと出力形状の私の解釈は次のとおりです。多次元で失われているので、それが正しいかどうかを理解するのを手伝ってください。
input_1(InputLayer)(None、1380):--->1380
は、データポイントごとの特徴(つまり、1380個の入力ニューロン)の総数です。1800
ドキュメントまたはデータポイントの総数です。
embedding_1(Embedding)(None、1380、100)4427700 ---->埋め込みレイヤーは、特徴(単語)として1380であり、各特徴は次元100のベクトルです。
ここでのパラメータの数はどのくらいです4427700
か?
conv1d_1(Conv1D)(None、1377、32)12832 ------> Conv1dはですkernel size=4
。1*4
使用32
回数はフィルターですか。では、どのようにして次元がパラメータ(None, 1377, 32)
とともになったの12832
でしょうか?
max_pooling1d_1(MaxPooling1D)(None、 688、32 ) with MaxPooling1D(pool_size = 2)ディメンションはどのようになりました(None, 688, 32)
か?flatten_1(Flatten)(None、22016)これは688、32の掛け算ですか?
**すべてのエポックで一度に1800のデータポイントがトレーニングされますか?**
出力寸法の計算方法を教えてください。任意の参照またはヘルプをいただければ幸いです。
以下の回答をご覧ください。
input_1 (InputLayer) (None, 1380)
:---> 1380は、データポイントごとの特徴(つまり、1380個の入力ニューロン)の総数です。1800は、ドキュメントまたはデータポイントの総数です。
はい。model.fit([trainX,trainX,trainX], array(trainLabels), epochs=10, batch_size=16)
つまり、ネットワークでトレーニングデータセット全体をサイズ16のバッチで10回(10エポック)トレーニングする必要があるということです。
これは、16データポイントごとにバックプロパゲーションアルゴリズムが起動され、重みが更新されることを意味します。これは1800/16
何度も起こり、エポックと呼ばれます。
1380
は第1層のニューロンの数です。
embedding_1 (Embedding) (None, 1380, 100) | 4427700
---->埋め込み層は特徴(単語)として1380であり、各特徴は次元100のベクトルです。
1380は入力のサイズ(前の層のニューロンの数)であり、100は埋め込みベクトルのサイズ(長さ)です。
ここでのパラメーターの数は、100個のパラメーターをトレーニングするために必要なvocabulary_size * 100
それぞれのものv in vocabulary
です。埋め込み層は、実際には、サイズ100のvocabulary_sizeベクトルで構築された行列であり、各行は、語彙からの各単語のベクトル表現を表します。
conv1d_1 (Conv1D) (None, 1377, 32) | 12832
------> Conv1dのカーネルサイズは4です。32回使用するのは1 * 4フィルターですか。では、12832個のパラメーターでディメンションがどのように(なし、1377、32)になったのでしょうか。
カーネルのサイズにより、1380は1377になります。サイズ4のカーネルを使用した次の入力(簡略化するためにサイズ10)を想像してみてください。
0123456789 #input
KKKK456789
0KKKK56789
12KKKK6789
123KKKK789
1234KKKK89
12345KKKK9
123456KKKK
カーネルはこれ以上右に移動できないため、入力サイズ10とカーネルサイズ4の場合、出力形状は7になります。一般に、nの入力形状とkのカーネル形状の場合、出力形状は次のようになります。n - k + 1
そこらのn=1380, k=4
結果です1377
。
パラメータの数がに等しいため、パラメータの量は12832に等しくなりoutput_channels * (input_channels * window_size + 1)
ます。あなたの場合は32*(100*4 + 1)
です。
max_pooling1d_1 (MaxPooling1D) (None, 688, 32) with MaxPooling1D(pool_size=2)
次元はどのようになりました(None, 688, 32)
か?
max_pooling
あなたがで終わるので、2つのずつ連続した番号を取り、それらの最大値に置き換えoriginal_size/pool_size
た値。
flatten_1 (Flatten) (None, 22016)
これは688、32の掛け算ですか? `
はい、これは688と32の乗算にすぎません。これは、flatten操作が次のことを行うためです。
1234
5678 -> 123456789012
9012
したがって、すべての次元からすべての値を取得し、それを1次元ベクトルに入れます。
すべてのエポックで一度に1800のデータポイントがトレーニングされますか?
いいえ。最初の回答で指摘したように、16個のバッチでそれらを取ります。各エポックは、16個のデータポイントのバッチでランダムな順序で1800個のデータポイントを取ります。エポックとは、ある期間を意味する用語であり、その後、データの読み取りを再開します。
編集:
1d畳み込み層が埋め込み層に適用される場所を明確にします。
幅1380および100チャネルのベクトルとして解釈する必要がある埋め込みレイヤーの出力。
入力に3つのチャネルがあるRGB画像がある2D画像と同様に、32個のフィルターで構築された畳み込みレイヤーを適用するとその形状は(幅、高さ、3)になり(フィルターサイズは関係ありません)、畳み込み操作が同時に適用されますすべてのチャネルに適用され、出力形状は(new_width、new_height、32)になります。出力形状がフィルターの数と同じであることに注意してください。
例に戻ります。埋め込みレイヤーからの出力形状を(幅、チャネル)として扱います。したがって、32個のフィルターと4に等しいカーネルサイズを持つ1d畳み込み層が、ベクトル1380と深さ100に適用されます。その結果、形状(1377、32)の出力が得られます。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加