了解Keras层的形状

我正在通过此链接了解文本分类的多渠道cnn模型。

代码基于this tutorial.

我已经了解了大多数事情,但是我不明白Keras如何定义某些图层的输出形状。

代码如下:

定义一个具有三个输入通道的模型,以处理4克,6克和8克电影评论文本。

#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,100)     4427700     input_2[0][0]
____________________________________________________________________________________________________
embedding_3 (Embedding)          (None,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,32)      0           conv1d_1[0][0]
____________________________________________________________________________________________________
dropout_2 (Dropout)              (None,32)      0           conv1d_2[0][0]
____________________________________________________________________________________________________
dropout_3 (Dropout)              (None,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,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)(无,1380):---> 1380是每个数据点的特征总数(即1380个输入神经元)。 1800是文档或数据点的总数。

embedding_1(嵌入)(无,1380,100)4427700 ---->嵌入层是:1380个特征(单词),每个特征都是一个尺寸为100的向量。

这里的参数数量为4427700

conv1d_1(Conv1D)(无,1377,32)12832 ------> Conv1d的名称为kernel size=4。是1*4次使用的32过滤器。那么维度如何通过(None,32)参数变成12832

max_pooling1d_1(MaxPooling1D)(无,688,32)与MaxPooling1D(pool_size = 2)的尺寸如何变为(None,32) flatten_1(平坦)(无,2016年2月),这仅仅是688、32的乘积吗?

**每个纪元都一次训练1800个数据点吗?**

请让我知道如何计算输出尺寸。任何参考或帮助,将不胜感激。

huminyan 回答:了解Keras层的形状

请查看以下答案:

  

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是嵌入向量的大小(长度)。

此处的参数数量为vocabulary_size * 100,因为您需要训练100个参数,每个v in vocabulary。嵌入层实际上是一个由大小为100的vocabulary_size向量构建的矩阵,其中每一行代表该词汇表中每个单词的向量表示形式。

  

conv1d_1 (Conv1D) (None,1377,32) | 12832 ------> Conv1d的内核大小为4。是使用过32次的1 * 4过滤器。那么尺寸如何变成带有12832个参数的(无,1377、32)?

1380由于内核大小而变成1377。想象下面的输入(为简化起见,大小为10),内核为4:

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,32)

max_pooling每隔两个连续的数字取一个,并用一个最大值替换它们,因此最终得到original_size/pool_size个值。

  

flatten_1 (Flatten) (None,22016)这只是688、32的乘积?

是的,这只是688和32的乘积。这是因为flatten操作执行以下操作:

1234
5678   -> 123456789012
9012

因此它将所有维度的所有值都放入一维向量中。

  

每个纪元一次训练1800个数据点吗?

不。如第一个答案中指出的那样,它们需要分16批进行。每个时期以16个数据点为批次,以随机顺序获取1800个数据点。 epoch是一个时期,意味着一段时间后,我们将再次开始读取数据。

编辑:

我将阐明将1d卷积层应用于嵌入层的位置。

您应将“嵌入”层的输出解释为宽度为1380和100通道的向量。

类似于2d图像,其中输入中具有三个通道的RGB图像,当您应用由32个滤镜构建的卷积层(滤镜大小无关)时,其形状为(宽度,高度,3),进行卷积运算同时应用于所有通道,输出形状将为(new_width,new_height,32)。请注意,输出形状与过滤器的数量相同。

回到您的示例。将嵌入层的输出形状视为(宽度,通道)。因此,将具有32个滤镜且内核大小等于4的1d卷积层应用于矢量1380和深度100。结果,将得到形状的输出(1377,32)。

本文链接:https://www.f2er.com/3112114.html

大家都在问