Я пишу сеть 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)
В моем понимании обе модели должны делать то же самое.Даже с небольшими ошибками из-за случайности точность обеих моделей должна быть сопоставимой, но с помощью встроенного слоя она достигает почти двойной точности.Это несоответствие согласуется с несколькими прогонами и различными реализациями пользовательского уровня.
Проверяя мои настройки пользовательского уровня с помощью онлайн-ресурсов, мне не удалось обнаружить ошибку реализации или что-либо, говорящее, что пользовательские слои выполняютхуже, чем встроенные.
Я в растерянности и рад за любую идею.Спасибо