如何在Keras中实现并行卷积层?

25

我对神经网络和Keras还不是很熟悉。我有一些尺寸为6*7的图像,过滤器的大小为15。我想要几个过滤器,然后分别在每个上训练卷积层,最后将它们组合起来。我已经看了这里的一个例子:

model = Sequential()
model.add(Convolution2D(nb_filters, kernel_size[0], kernel_size[1],
                    border_mode='valid',
                    input_shape=input_shape))
model.add(Activation('relu'))
model.add(Convolution2D(nb_filters, kernel_size[0], kernel_size[1]))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=pool_size))
model.add(Dropout(0.25))
model.add(Flatten(input_shape=input_shape))
model.add(Dense(128))
model.add(Activation('relu'))
model.add(Dense(128))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(nb_classes))
model.add(Activation('tanh'))

这个模型只使用了一个卷积核。有没有人可以给我一些提示,如何修改模型以使用平行的卷积层。

谢谢

2个回答

43

这是一个在Keras 2版本中设计卷积和子采样层的并行网络的示例。我希望这可以解决您的问题。

rows, cols = 100, 15
def create_convnet(img_path='network_image.png'):
    input_shape = Input(shape=(rows, cols, 1))

    tower_1 = Conv2D(20, (100, 5), padding='same', activation='relu')(input_shape)
    tower_1 = MaxPooling2D((1, 11), strides=(1, 1), padding='same')(tower_1)

    tower_2 = Conv2D(20, (100, 7), padding='same', activation='relu')(input_shape)
    tower_2 = MaxPooling2D((1, 9), strides=(1, 1), padding='same')(tower_2)

    tower_3 = Conv2D(20, (100, 10), padding='same', activation='relu')(input_shape)
    tower_3 = MaxPooling2D((1, 6), strides=(1, 1), padding='same')(tower_3)

    merged = keras.layers.concatenate([tower_1, tower_2, tower_3], axis=1)
    merged = Flatten()(merged)

    out = Dense(200, activation='relu')(merged)
    out = Dense(num_classes, activation='softmax')(out)

    model = Model(input_shape, out)
    plot_model(model, to_file=img_path)
    return model

这个网络的图像将看起来像输入图像说明


1
这正是我正在寻找的。如果您仍然活跃,可以在此回复几个问题吗? - Ansh David
卷积神经网络中的特征提取是如何实现的? - Ansh David
嘿@durjoy,你能否看一下这个问题https://stackoverflow.com/q/61734815/10665645? - monica

20

我的方法是创建另一个模型,定义所有并行卷积和池化操作,并将所有并行结果张量拼接为单个输出张量。现在,您可以将这个并行模型图像添加到您的顺序模型中,就像图层一样。这是我的解决方案,希望它能解决您的问题。

# variable initialization 
from keras import Input, Model, Sequential
from keras.layers import Conv2D, MaxPooling2D, Concatenate, Activation, Dropout, Flatten, Dense

nb_filters =100
kernel_size= {}
kernel_size[0]= [3,3]
kernel_size[1]= [4,4]
kernel_size[2]= [5,5]
input_shape=(32, 32, 3)
pool_size = (2,2)
nb_classes =2
no_parallel_filters = 3

# create seperate model graph for parallel processing with different filter sizes
# apply 'same' padding so that ll produce o/p tensor of same size for concatination
# cancat all paralle output

inp = Input(shape=input_shape)
convs = []
for k_no in range(len(kernel_size)):
    conv = Conv2D(nb_filters, kernel_size[k_no][0], kernel_size[k_no][1],
                    border_mode='same',
                         activation='relu',
                    input_shape=input_shape)(inp)
    pool = MaxPooling2D(pool_size=pool_size)(conv)
    convs.append(pool)

if len(kernel_size) > 1:
    out = Concatenate()(convs)
else:
    out = convs[0]

conv_model = Model(input=inp, output=out)

# add created model grapg in sequential model

model = Sequential()
model.add(conv_model)        # add model just like layer
model.add(Conv2D(nb_filters, kernel_size[1][0], kernel_size[1][0]))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=pool_size))
model.add(Dropout(0.25))
model.add(Flatten(input_shape=input_shape))
model.add(Dense(128))
model.add(Activation('relu'))
model.add(Dense(128))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(nb_classes))
model.add(Activation('tanh'))

如需更多信息,请参考类似的问题:将多个模型的输出合并为一个模型


1
我认为这很有用。我一定会尝试一下。只是一个快速的问题,Model是包含顺序模型的另一个类吗?输出应该是什么? - ida
1
不,它不是顺序的。顺序模型定义简单的网络结构,它接收单个输入并产生单个输出,并按顺序将其传递到下一层,张量的维度取决于模型中的层。要定义复杂的架构,您需要使用其他功能API来创建模型。您可以在Keras文档中找到更多详细信息:https://keras.io/getting-started/functional-api-guide/ - Nilesh Birari

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接