如何在LeNet5体系结构的两个不同的keras层之间创建自定义连接?

时间:2018-12-22 22:28:16

标签: tensorflow machine-learning keras neural-network data-science

我正在研究LeNet5体系结构。我想在C3和S2层之间实现自定义连接,如here所述。如果要按照here的说明实施自定义连接,如何在“ CODE-1 ”和“ CODE-2 ”中定义模型。我应该在“ CODE-2 ”中使用多少个过滤器。任何类型的帮助将不胜感激。

s2的输出为14 * 14 * 6,这6个特征图上需要应用16个过滤器。但是,不是将所有6个S2映射都映射到c3的16个神经元,而是将C3层映射中的大多数神经元仅连接到三个或四个S2映射中的神经元。更多详细信息可以在图像2和3中找到。 c3层具有16个尺寸为5×5且步幅为1的特征图。在此层中,只有16个特征图中的10个连接到s2的6个特征图。

如果您注意到图像3,则c3的神经元0连接到s2的0、1和2特征图。如何实现这种连接。

我的代码如下所示:

from keras.models import Model
from tensorflow.keras.layers import Conv2D, Input, Concatenate, Lambda

CODE-1

inputTensor = Input(shape=(14, 14, 6))
group0 = Lambda(lambda x: x[:,:,:3], output_shape=((10, 10, 1)))(inputTensor)
group1 = Lambda(lambda x: x[:,:,1:4], output_shape=((10, 10, 1)))(inputTensor)
group2 = Lambda(lambda x: x[:,:,2:5], output_shape=((10, 10, 1)))(inputTensor)
group3 = Lambda(lambda x: x[:,:,3:6], output_shape=((10, 10, 1)))(inputTensor)
# all 16 layers of c3 (of the Custom Connections image)

CODE-2

conv_group0 = Conv2D(1, kernel_size=[5,5], strides=(stride,stride), padding="valid", activation = 'tanh')(group0)
conv_group1 = Conv2D(1, kernel_size=[5,5], strides=(stride,stride), padding="valid", activation = 'tanh')(group1)
conv_group2 = Conv2D(1, kernel_size=[5,5], strides=(stride,stride), padding="valid", activation = 'tanh')(group2)
#all 16 layers convolution

output_layer = Concatenate()([conv_group0,conv_group1,conv_group2,conv_group3,conv_group4,conv_group5,conv_group6,conv_group7,
                         conv_group8,conv_group9,conv_group10,conv_group11,conv_group12,conv_group13,conv_group14,conv_group15])
Mymodel = Model(inputTensor,output_layer)

1 个答案:

答案 0 :(得分:0)

您可以创建以下自定义图层类:

CustomLayer(tf.keras.layers.Layer):
""" Custom layer with initialize matrix = connect_matrix. """
def __init__(self,  activation, units, connect_matrix):
    super(CustomLayer, self).__init__()
    self.units = units
    self.connect_matrix = np.asarray(connect_matrix, dtype='float32')
    self.activation = tf.keras.activations.get(activation)
def build(self, input_shape):
    self.w = self.add_weight(shape=(input_shape[-1], self.units), initializer=tf.constant_initializer(value=self.connect_matrix), trainable=True)
    self.b = self.add_weight(shape=(self.units,), initializer="zeros", trainable=True)
    self.m = self.add_weight(shape=(input_shape[-1], self.units), initializer=tf.constant_initializer(value=self.connect_matrix), trainable=False)
    #super().build(batch_input_shape)
def call(self, inputs):
    wm = tf.math.multiply(self.w, self.m)
    out_lin = tf.matmul(inputs, wm) + self.b
    return self.activation(out_lin)
def get_config(self):
    base_config = super().get_config()
    return {**base_config, "units": self.units, "activation": keras.activations.serialize(self.activation)}

将您的连接矩阵另存为 2D numpy 数组 A,然后使用 自定义层(单位,激活,connect_matrix=A) 像往常一样 tf.keras.layer 您可以在以下链接中找到更多信息: CustomTF2KerasObjects

相关问题