форма Conv2d в многоклассовой классификации текста

#python #keras #deep-learning #conv-neural-network

#python #keras #глубокое обучение #conv-нейронная сеть

Вопрос:

Я выполняю многоклассовую классификацию текста с помощью сверточной нейронной сети, я применил приведенный ниже код к своим весам для встраивания перчаток, я получил хороший результат, но у меня есть вопрос о форме CONV2D: почему в CONV2D 1 мы получаем conv_1 (None, 407, 1, 64) и соответственно в conv_2: None, 406, 1, 64) и в conv_2:405 ?

                


Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_18 (InputLayer)           (None, 409)          0                                            
__________________________________________________________________________________________________
embedding_17 (Embedding)        (None, 409, 100)     1766600     input_18[0][0]                   
__________________________________________________________________________________________________
reshape_10 (Reshape)            (None, 409, 100, 1)  0           embedding_17[0][0]               
__________________________________________________________________________________________________
conv_1 (Conv2D)                 (None, 407, 1, 64)   19264       reshape_10[0][0]                 
__________________________________________________________________________________________________
conv_2 (Conv2D)                 (None, 406, 1, 64)   25664       reshape_10[0][0]                 
__________________________________________________________________________________________________
conv_3 (Conv2D)                 (None, 405, 1, 64)   32064       reshape_10[0][0]                 
__________________________________________________________________________________________________
max_pooling2d_16 (MaxPooling2D) (None, 1, 1, 64)     0           conv_1[0][0]                     
__________________________________________________________________________________________________
max_pooling2d_17 (MaxPooling2D) (None, 1, 1, 64)     0           conv_2[0][0]                     
__________________________________________________________________________________________________
max_pooling2d_18 (MaxPooling2D) (None, 1, 1, 64)     0           conv_3[0][0]                     
__________________________________________________________________________________________________
concatenate_6 (Concatenate)     (None, 3, 1, 64)     0           max_pooling2d_16[0][0]           
                                                                 max_pooling2d_17[0][0]           
                                                                 max_pooling2d_18[0][0]           
__________________________________________________________________________________________________
flatten_5 (Flatten)             (None, 192)          0           concatenate_6[0][0]              
__________________________________________________________________________________________________
dropout_11 (Dropout)            (None, 192)          0           flatten_5[0][0]                  
__________________________________________________________________________________________________
dense_11 (Dense)                (None, 3)            579         dropout_11[0][0]                 
==================================================================================================
Total params: 1,844,171
Trainable params: 1,844,171
Non-trainable params: 0
__________________________________________________________________________________________________
None
 
 from keras.layers import Dense, Input, GlobalMaxPooling1D
from keras.layers import Conv1D, MaxPooling1D, Embedding
from keras.models import Model
from keras.layers import Input, Dense, Embedding, Conv2D, MaxPooling2D, Dropout,concatenate
from keras.layers.core import Reshape, Flatten
from keras.callbacks import EarlyStopping
from keras.optimizers import Adam
from keras.models import Model
from keras import regularizers

sequence_length = 409
filter_sizes = [3,4,5]
num_filters = 64
drop = 0.5
EMBEDDING_DIM=100


embedding_layer = Embedding(len(tokenizer.word_index)   1,
                            EMBEDDING_DIM,
                            weights=[embedding_matrix],
                            trainable=True)


inputs = Input(shape=(sequence_length,))
embedding = embedding_layer(inputs)
reshape = Reshape((sequence_length,EMBEDDING_DIM,1))(embedding)

conv_0 = Conv2D(num_filters, (filter_sizes[0], EMBEDDING_DIM),activation='relu',kernel_regularizer=regularizers.l2(0.01),name='conv_1')(reshape)
conv_1 = Conv2D(num_filters, (filter_sizes[1], EMBEDDING_DIM),activation='relu',kernel_regularizer=regularizers.l2(0.01),name='conv_2')(reshape)
conv_2 = Conv2D(num_filters, (filter_sizes[2], EMBEDDING_DIM),activation='relu',kernel_regularizer=regularizers.l2(0.01),name='conv_3')(reshape)

maxpool_0 = MaxPooling2D((sequence_length - filter_sizes[0]   1, 1), strides=(1,1))(conv_0)
maxpool_1 = MaxPooling2D((sequence_length - filter_sizes[1]   1, 1), strides=(1,1))(conv_1)
maxpool_2 = MaxPooling2D((sequence_length - filter_sizes[2]   1, 1), strides=(1,1))(conv_2)

merged_tensor = concatenate([maxpool_0, maxpool_1, maxpool_2], axis=1)
flatten = Flatten()(merged_tensor)
reshape = Reshape((3*num_filters,))(flatten)
dropout = Dropout(drop)(flatten)
output = Dense(units=3, activation='softmax',kernel_regularizer=regularizers.l2(0.01))(dropout)

# this creates a model that includes
model = Model(inputs, output)
adam = Adam(lr=1e-3)

model.compile(loss='categorical_crossentropy',
              optimizer=adam,
              metrics=['acc'])
print(model.summary())

 

Ответ №1:

Об этом не о чем беспокоиться. Это основная проблема с любой операцией свертки с ядрами. Размер ядер, свертываемых по изображению, приведет к тому, что несколько пикселей будут пропущены. Вот ссылка, описывающая проблему более подробно.

Предполагая , что входная форма равна 𝑛ℎ×𝑛𝑤 и форма ядра свертки 𝑘ℎ×𝑘𝑤 равна , тогда выходная форма будет (𝑛ℎ−𝑘ℎ 1)×(𝑛𝑤−𝑘𝑤 1)

введите описание изображения здесь

Один из способов справиться с этим — установить padding параметр в слое как 'same' .

 tf.keras.layers.Conv2D(
    filters, kernel_size, strides=(1, 1), padding='same', data_format=None,
    dilation_rate=(1, 1), groups=1, activation=None, use_bias=True,
    kernel_initializer='glorot_uniform', bias_initializer='zeros',
    kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None,
    kernel_constraint=None, bias_constraint=None, **kwargs
)
 

С заполнением = ‘действительный’

 > input_shape = (4, 28, 28, 3)
> x = tf.random.normal(input_shape)
> y = tf.keras.layers.Conv2D(2, 3, activation='relu', input_shape=input_shape[1:])(x)
> print(y.shape)
(4, 26, 26, 3)
 

С заполнением = ‘то же самое’

 > input_shape = (4, 28, 28, 3)
> x = tf.random.normal(input_shape)
> y = tf.keras.layers.Conv2D(2, 3, activation='relu', padding="same", input_shape=input_shape[1:])(x)
> print(y.shape)
(4, 28, 28, 3)
 

РЕДАКТИРОВАТЬ: вам лучше использовать conv1d для текстовых / временных данных вместо многократного изменения формы для использования conv2d. Вот ваша архитектура модели с 1D свертками.

Однако я не совсем понимаю, почему вы делаете то, что делаете для слоев maxpooling. Я в основном пытался сохранить те же самые прямые вычисления, но вы должны посмотреть на эти слои и посмотреть, имеют ли они смысл.

 from tensorflow.keras import layers, Model, regularizers

vocab_size = 1000

inp = layers.Input(shape=(409,))
emb = layers.Embedding(vocab_size, 100)(inp)
conv1 = layers.Conv1D(64, 3, padding='same')(emb)
conv2 = layers.Conv1D(64, 4, padding='same')(emb)
conv3 = layers.Conv1D(64, 5, padding='same')(emb)

max1 = layers.MaxPool1D(409, strides=1)(conv1)
max2 = layers.MaxPool1D(409, strides=1)(conv2)
max3 = layers.MaxPool1D(409, strides=1)(conv3)

conc = layers.concatenate([max1, max2, max3])
flat = layers.Flatten()(conc)
drop = layers.Dropout(0.5)(flat)
out = layers.Dense(3, activation='softmax', kernel_regularizer='l2')(drop)

model = Model(inp,out)
model.summary()
 
 __________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_21 (InputLayer)           [(None, 409)]        0                                            
__________________________________________________________________________________________________
embedding_20 (Embedding)        (None, 409, 100)     100000      input_21[0][0]                   
__________________________________________________________________________________________________
conv1d_50 (Conv1D)              (None, 409, 64)      19264       embedding_20[0][0]               
__________________________________________________________________________________________________
conv1d_51 (Conv1D)              (None, 409, 64)      25664       embedding_20[0][0]               
__________________________________________________________________________________________________
conv1d_52 (Conv1D)              (None, 409, 64)      32064       embedding_20[0][0]               
__________________________________________________________________________________________________
max_pooling1d_39 (MaxPooling1D) (None, 1, 64)        0           conv1d_50[0][0]                  
__________________________________________________________________________________________________
max_pooling1d_40 (MaxPooling1D) (None, 1, 64)        0           conv1d_51[0][0]                  
__________________________________________________________________________________________________
max_pooling1d_41 (MaxPooling1D) (None, 1, 64)        0           conv1d_52[0][0]                  
__________________________________________________________________________________________________
concatenate_11 (Concatenate)    (None, 1, 192)       0           max_pooling1d_39[0][0]           
                                                                 max_pooling1d_40[0][0]           
                                                                 max_pooling1d_41[0][0]           
__________________________________________________________________________________________________
flatten_5 (Flatten)             (None, 192)          0           concatenate_11[0][0]             
__________________________________________________________________________________________________
dropout_4 (Dropout)             (None, 192)          0           flatten_5[0][0]                  
__________________________________________________________________________________________________
dense_3 (Dense)                 (None, 3)            579         dropout_4[0][0]                  
==================================================================================================
Total params: 177,571
Trainable params: 177,571
Non-trainable params: 0
 

Комментарии:

1. спасибо, когда я добавляю padding=»то же самое», ошибка: общий размер нового массива должен быть неизменным

2. Не имеет значения, текст это или изображение, это просто естественная вещь, которая происходит со свертками. Кроме того, я вижу, что вы используете conv2d, но все еще свертываетесь в одном измерении. Почему бы просто не использовать conv1d? Это то, что обычно используется при классификации текста.

3. Кроме того, проблема, с которой вы столкнулись, больше связана с немного странной формой ядра, используемой здесь.

4. Вместо изменения формы и добавления нового измерения просто используйте conv1d. Это привело бы к свертке над внедрением, аналогичной тому, что вы сейчас делаете.

5. большое вам спасибо, можете ли вы помочь мне, как это реализовать? Я новичок в python и cnn..