이 링크를 통해 텍스트 분류를위한 다중 채널 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 ----> Embedding layer is : 1380 as features (words) and each feature is a vector of dimension 100.
여기서 매개 변수의 수는 4427700
?
conv1d_1 (Conv1D) (없음, 1377, 32) 12832 ------> Conv1d가 kernel size=4
. 시간을 1*4
사용 하는 필터입니다 32
. 그런 차원이 된 방법 (None, 1377, 32)
으로 12832
매개 변수?
max_pooling1d_1 (MaxPooling1D) (None, 688, 32) MaxPooling1D (pool_size = 2)와 함께 치수가 (None, 688, 32)
어떻게 되었습니까? flatten_1 (Flatten) (없음, 22016) 이것은 단지 688, 32의 곱셈입니까?
** 모든 Epoch가 한 번에 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
첫 번째 계층에있는 뉴런의 수입니다.
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 매개 변수로 어떻게 (None, 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를 곱한 것입니다. 플랫 화 작업이 다음을 수행하기 때문입니다.
1234
5678 -> 123456789012
9012
따라서 모든 차원의 모든 값을 가져와 1 차원 벡터에 넣습니다.
모든 시대가 한 번에 1800 개의 데이터 포인트를 훈련합니까?
아니요. 첫 번째 답변에서 지적한대로 16 개씩 일괄 처리합니다. 각 Epoch는 16 개의 데이터 포인트 배치에서 무작위 순서로 1800 개의 데이터 포인트를 사용합니다. 에포크는 기간을 의미하는 용어로, 그 후 데이터를 다시 읽기 시작합니다.
편집하다:
임베딩 레이어에 1d 컨벌루션 레이어가 적용되는 위치를 설명하겠습니다.
Embedding 레이어의 출력은 너비가 1380이고 채널이 100 개인 벡터로 해석해야합니다.
입력에 채널이 3 개인 RGB 이미지가있는 2d 이미지와 마찬가지로 32 개의 필터로 구성된 컨볼 루션 레이어를 적용하면 모양이 (너비, 높이, 3) (필터 크기는 무관), 컨볼 루션 연산이 동시에 적용됩니다. 모든 채널에 적용되며 출력 형태는 (new_width, new_height, 32)가됩니다. 출력 모양은 필터 수와 동일합니다.
귀하의 예로 돌아갑니다. 임베딩 레이어의 출력 모양을 (너비, 채널)로 처리합니다. 따라서 32 개의 필터와 커널 크기가 4 인 1d 컨벌루션 계층이 벡터 1380 및 깊이 100에 적용됩니다. 결과적으로 shape (1377, 32)의 출력을 얻을 수 있습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다