有关以某种方式创建CNN的问题(无model.add)

时间:2019-11-26 15:27:43

标签: python keras conv-neural-network

我对以下CNN有疑问。我习惯于使用keras代码,通常情况下,当我看到模型是按照以下方式构建的:

def foo_model():
    # create model
    model = Sequential()
    model.add(Convolution2D(30, (5,5), kernel_initializer='normal', padding='valid', input_shape=(1, 28, 28), activation='relu'))
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Convolution2D(15, (3,3), kernel_initializer='normal', padding='valid', input_shape=(1,28,28)))
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Dropout(0.2))
    model.add(Flatten())
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    return model

因此,基本上,初始化模型的类型,然后继续添加层(逐层),编译模型,然后将其返回。我正在进行情感分析,偶然发现了以下CNN:

def ConvNet(embeddings, max_sequence_length, num_words, embedding_dim, labels_index):

    embedding_layer = Embedding(num_words,
                            embedding_dim,
                            weights=[embeddings],
                            input_length=max_sequence_length,
                            trainable=False)

    sequence_input = Input(shape=(max_sequence_length,), dtype='int32')
    embedded_sequences = embedding_layer(sequence_input)

    convs = []
    filter_sizes = [2,3,4,5,6]

    for filter_size in filter_sizes:
        l_conv = Conv1D(filters=200, kernel_size=filter_size, activation='relu')(embedded_sequences)
        l_pool = GlobalMaxPooling1D()(l_conv)
        convs.append(l_pool)


    l_merge = concatenate(convs, axis=1)

    x = Dropout(0.1)(l_merge)  
    x = Dense(128, activation='relu')(x)
    x = Dropout(0.2)(x)
    preds = Dense(labels_index, activation='sigmoid')(x)

    model = Model(sequence_input, preds)
    model.compile(loss='binary_crossentropy',
                  optimizer='adam',
                  metrics=['acc'])
    model.summary()
    return model

我在了解如何在此CNN中构建图层时遇到了麻烦。当我用数据初始化模型时,模型摘要如下:

fetch_array

我很难理解此模型的结构,因此很难了解它的构建方式。例如,sequence_input和变量做什么?为什么会有一个for循环似乎创建了Conv1D层和GlobalMaxPooling1D层,但是似乎没有在任何地方添加它们?为什么要对变量x重新声明3次(对于dropout,density和dropout层),以及将所有层添加到哪里?

1 个答案:

答案 0 :(得分:2)

一个接一个地回答您的问题:

  

sequence_input和变量做什么?

无论何时定义模型(特别是深度神经网络模型),我们都必须声明输入维。由于在这种情况下,输入是长度为50的数组/列表。如果输入是图像数据,则该输入可能是该图像的(250,250,3)或(length,width,number_of_channels)。

  

为什么会有for循环似乎创建了Conv1D层,   GlobalMaxPooling1D图层,但是似乎没有在任何地方添加它们吗?

在此示例中,据我了解,方法是使用多个过滤器/内核大小创建的模型,这些大小在列表中定义。因此,对于每种尺寸,都将CNN层与池化层一起应用,然后将所有内容作为列表追加,最后将其合并或堆叠在一起以形成CNN层

[参考部分:

l_merge = concatenate(convs, axis=1)

    x = Dropout(0.1)(l_merge)  

]

  

为什么变量x被重新声明了3次(对于辍学层,密集层和辍学层),

它没有被声明3次,但是创建了一个顺序模型,并且将定义的每个层都添加到了堆栈中。 [考虑一个指针概念,如果它有助于解释: 在第一步中,假设a = b + c,然后假设一个指向m(a-> m)的点,其中m = m * m,所以从本质上讲,您要做的是(b + c)*(b + c)直到此步骤。]

  

在哪里添加所有图层

在以下步骤中:

 l_merge = concatenate(convs, axis=1)

    x = Dropout(0.1)(l_merge)  
    x = Dense(128, activation='relu')(x)
    x = Dropout(0.2)(x)
    preds = Dense(labels_index, activation='sigmoid')(x)

仅说明一下,当您执行x = { some_operation }(x)时,这意味着x的上一层操作将作为输入传递给您当前操作的那一层再次作为输入传递到下一层。因此,从本质上讲,我们创建了一层链。

我希望它能回答您的问题。如果不愿意提出更多要求,请尝试提供帮助:)