Обучение сети свертки с 2 операциями свертки с общими весами, которые должны поддерживать норму 1 - PullRequest
1 голос
/ 24 октября 2019

Я хочу обучить сеть свертки с 4 операциями свертки с 2 фильтрами, которые разделяют веса, но с нормой, которая остается равной 1 между элементами фильтров. Допустим, у меня есть входные матрицы A и B и фильтры C и D. Я хочу выполнить следующую операцию:

M1 = tf.conv2d (A, C)

M2 = tf. conv2d (B, C)

M3 = tf.conv2d (A, D)

M4 = tf.conv2d (B, D)

В то же время янужно sqrt (C ^ 2 + D ^ 2) = 1

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

Но я понятия не имею, как сформулировать ограничения нормы на 1.

Thx!

Я попытался ввести входной слой, который будет обучаться через плотный слой с размером моего фильтра ядра, а затем изменить форму и разделить его на 2, используя cos (x) sin (x) перед операцией свертки (я ужеделать это в коде для модуляции входного изображения). Затем я использую ручную операцию tf.nn.conv2d (). Но с ядрами я получаю измерение пакета в качестве измерения 0, и это несовместимо с требуемым измерением ядра [filter_height, filter_width, in_channels, out_channels]. Сжатие не будет работать.

conv2d_layer_real= Conv2D(1,data_Mat2.shape[1],padding='same',kernel_constraint=max_norm(1),use_bias =False)
conv2d_layer_imag = Conv2D(1,data_Mat2.shape[1],padding='same',kernel_constraint=max_norm(1),use_bias =False)

input_shape = (data_Mat2.shape[1], data_Mat2.shape[1],1);
input_shape2 = (1,);

inputs_r = Input(shape=input_shape)
inputs_r2 = Input(shape=input_shape2)

phase_r2 = Dense(data_Mat2.shape[1]*data_Mat2.shape[1],activation = 'tanh',use_bias =False,kernel_initializer=RandomNormal(mean=0.0, stddev=0.5, seed=None))(inputs_r2)

phase_real = Lambda(lambda x:tf.cos(x*3.1416))(phase_r2)
phase_imag = Lambda(lambda x:tf.sin(x*3.1416))(phase_r2)

phase_real2 = Reshape((data_Mat2.shape[1], data_Mat2.shape[1],1))(phase_real)
phase_imag2 = Reshape((data_Mat2.shape[1], data_Mat2.shape[1],1))(phase_imag)

Mat_real = Multiply()([inputs_r,phase_real2])
Mat_imag = Multiply()([inputs_r,phase_imag2])

out_conv1 = conv2d_layer_real(Mat_real)
out_conv2 = conv2d_layer_real(Mat_imag)

out_conv3 = conv2d_layer_imag(Mat_real)
out_conv4 = conv2d_layer_imag(Mat_imag)

out_real = Add()([out_conv1,-out_conv4])
out_imag = Add()([out_conv2,out_conv3])

image_out = tf.complex(out_real,out_imag)
image_out = tf.square(tf.abs(image_out))

image_out = AveragePooling2D(pool_size=(pool_s, pool_s))(image_out)

vector_out = Reshape((9,))(image_out)

outputs = Softmax()(vector_out)

Этот последний код работает хорошо, но не будет иметь норму 1 для весов слоев conv2D, потому что такие ограничения не установлены

...