【问题标题】:Question about creating a CNN in a certain way (without model.add)关于以某种方式创建CNN的问题(没有model.add)
【发布时间】:2019-11-26 23:45:34
【问题描述】:

我对以下 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 中的层是如何构建的。当我用我的数据初始化模型时,模型摘要如下所示;

我很难理解这个模型的结构,以及它是如何构建的。例如,sequence_input 和变量有什​​么作用?为什么有一个似乎创建 Conv1D 层和 GlobalMaxPooling1D 层的 for 循环,但它们似乎没有添加到任何地方?为什么有一个变量 x 被重新声明了 3 次(对于 dropout、dense 和 dropout 层),以及所有层都添加到哪里?

【问题讨论】:

    标签: python keras conv-neural-network


    【解决方案1】:

    一一回答你的问题:

    sequence_input 和变量有什​​么作用?

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

    为什么会有一个似乎创建 Conv1D 层的 for 循环和 GlobalMaxPooling1D 层,但它们似乎没有添加到任何地方?

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

    [参考章节:

    l_merge = concatenate(convs, axis=1)
    
        x = Dropout(0.1)(l_merge)  
    

    ]

    为什么有一个变量 x 被重新声明了 3 次(对于 dropout、dense 和 dropout 层),

    它没有被声明 3 次,但创建了一个顺序模型,并且定义的每个层都被添加到堆栈中。 [如果有助于解释,请考虑一个指针概念: 在第一步中,假设 a = b+c,然后假设 a 指向 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 的上一层操作正在作为输入传递给您执行的当前操作层再次作为输入传递给下一层。所以本质上我们创建了一个层链。

    我希望它能回答您的疑问。如果不能随意问更多,会尽力帮助:)

    【讨论】:

    • 谢谢!明确答复!你能详细说明一下 conv-global 最大池设置吗?在模型总结中,为什么卷积层出现在最大池化层之前?通常你首先有一个卷积层,然后是一个最大池化层,然后是一个卷积层,对吧?
    • 是的,理想情况下,池化用于对卷积层的输出进行下采样。在这里,保留这么多池化层实际上并没有多大帮助。保持它的更好方法,例如 conv -> pooling -> conv-> pooling 等等
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-06
    • 2017-12-30
    • 2014-05-03
    相关资源
    最近更新 更多