Пользовательский слой TF-Keras работает хуже, чем встроенный слой - PullRequest
0 голосов
/ 14 февраля 2019

Я пишу сеть CNN, используя Tensorflow и API TF-keras, используя пользовательский слой.Этот пользовательский слой выполняет двумерную свертку с дополнительной информацией о маскировании, но дал мне менее желаемый результат (точность ~ 50% с 150 эпохами).

Чтобы проверить мой слой, я сократил его, чтобы выполнить обычную двумерную свертку, иТакже реализована аналогичная сеть с использованием встроенного keras.layers.Conv2D.с моим пользовательским слоем я все еще достигаю точности ~ 50%, но со встроенной функцией я достигаю ~ 97%.Чтобы проверить это дальше, я создал пользовательский слой, который только распространяет значения в сборку в слое Conv2D, но он все еще работает только с точностью около 50%.

Модель со встроенными слоями:

image_input = Input(shape=(32,32,3,),dtype='float32',
    name='Image_Input')
mask_input = Input(shape=(32,32,),dtype='int32',name='Mask_Input')
weight_decay = 1e-4
conv1 = Conv2D(32, kernel_size=(3,3,),padding='same',
    kernel_regularizer=regularizers.l2(weight_decay),
    activation='elu')(image_input)
bn1 = BatchNormalization()(conv1)
conv2 = Conv2D(32, kernel_size=(3,3,),padding='same',
    kernel_regularizer=regularizers.l2(weight_decay),
    activation='elu')(bn1)
bn2 = BatchNormalization()(conv2)
ml1 = MaxPool2D(pool_size=(2,2))(bn2)
do1 = Dropout(0.2)(ml1)

conv3 = Conv2D(64, kernel_size=(3,3,),padding='same',
    kernel_regularizer=regularizers.l2(weight_decay),
    activation='elu')(do1)
bn3 = BatchNormalization()(conv3)
conv4 = Conv2D(64, kernel_size=(3,3,),padding='same'
    kernel_regularizer=regularizers.l2(weight_decay),
    activation='elu')(bn3)
bn4 = BatchNormalization()(conv4)
mp2 = MaxPool2D(pool_size=(2,2))(bn4)
do2 = Dropout(0.3)(mp2)

conv5 = Conv2D(128, kernel_size=(3,3,),padding='same',
    kernel_regularizer=regularizers.l2(weight_decay),
    activation='elu')(do2)
bn5 = BatchNormalization()(conv5)
conv6 = Conv2D(128, kernel_size=(3,3,),padding='same',
    kernel_regularizer=regularizers.l2(weight_decay),
    activation='elu')(bn5)
bn6 = BatchNormalization()(conv6)
mp3 = MaxPool2D(pool_size=(2,2))(bn6)
do3 = Dropout(0.4)(mp3)

flat = Flatten()(do3)
output = Dense(10,activation='softmax')(flat)

model = Model(inputs=[image_input,mask_input],outputs=[output])

Модель с пользовательским слоем:

image_input = Input(shape=(32,32,3,),dtype='float32',
    name='Image_Input')
mask_input = Input(shape=(32,32,), dtype='int32',name='Mask_Input')
weight_decay = 1e-4

ml1 = ML2(32,
    (3,3,),
    padding='same',
    kernel_regularizer=regularizers.l2(weight_decay),
    activation='elu')(image_input)
bn1 = BatchNormalization()(ml1)
ml2 = ML2(32,(3,3,),
    padding='same',
    kernel_regularizer=regularizers.l2(weight_decay),
    activation='elu')(bn1)
bn2 = BatchNormalization()(ml2)
mp1 = MaxPool2D(pool_size=(2,2))(bn2)
do1 = Dropout(0.2)(mp1)

ml3 = ML2(64,(3,3,),
    padding='same',
    kernel_regularizer=regularizers.l2(weight_decay),
    activation='elu')(do1)
bn3 = BatchNormalization()(ml3)
ml4 = ML2(64,(3,3,),
    padding='same',
    kernel_regularizer=regularizers.l2(weight_decay),
    activation='elu')(bn3)
bn4 = BatchNormalization()(ml4)

mp2 = MaxPool2D(pool_size=(2,2))(bn4)
do2 = Dropout(0.3)(mp2)

ml5 = ML2(128,(3,3,),
    padding='same',
    kernel_regularizer=regularizers.l2(weight_decay),
    activation='elu')(do2)
bn5 = BatchNormalization()(ml5)   
ml6 = ML2(128,(3,3,),
    padding='same',
    kernel_regularizer=regularizers.l2(weight_decay),
    activation='elu')(bn5)
bn6 = BatchNormalization()(ml6)
mp3 = MaxPool2D(pool_size=(2,2))(bn6)
do3 = Dropout(0.4)(mp3)

flat = Flatten()(do3)
output = Dense(10, activation='relu')(flat)
model = Model(inputs=[image_input,mask_input], outputs=[output])

Пользовательский слой:

class ML2(Conv2D):
    def __init__(self,
        filters,
        kernel_size,
        strides=1,
        padding='valid',
        data_format=None,
        activation=None,
        dilation_rate=1,
        use_bias=True,
        kernel_initializer='glorot_uniform',
        bias_initializer='zeros',
        kernel_regularizer=None,
        bias_regularizer=None,
        activity_regularizer=None,
        kernel_constraint=None,
        bias_constraint=None,
        trainable=True,
        name=None,
        **kwargs):

        super(ML2,self).__init__(
            filters,
            kernel_size,
            strides=strides,
            padding=padding,
            data_format=data_format,
            activation=activation,
            dilation_rate=dilation_rate,
            use_bias=use_bias,
            kernel_initializer=kernel_initializer,
            bias_initializer=bias_initializer,
            kernel_regularizer=kernel_regularizer,
            bias_regularizer=bias_regularizer,
            activity_regularizer=activity_regularizer,
            kernel_constraint=kernel_constraint,
            bias_constraint=bias_constraint,
            trainable=trainable,
            name=name,
            **kwargs)

В моем понимании обе модели должны делать то же самое.Даже с небольшими ошибками из-за случайности точность обеих моделей должна быть сопоставимой, но с помощью встроенного слоя она достигает почти двойной точности.Это несоответствие согласуется с несколькими прогонами и различными реализациями пользовательского уровня.

Проверяя мои настройки пользовательского уровня с помощью онлайн-ресурсов, мне не удалось обнаружить ошибку реализации или что-либо, говорящее, что пользовательские слои выполняютхуже, чем встроенные.

Я в растерянности и рад за любую идею.Спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...