Formação de uma rede de convolução com 2 operação de convolução com pesos compartilhados que deve manter uma norma de 1

votos
0

Quero treinar uma rede de convolução com 4 operações de convolução com 2 filtros que compartilham pesos, mas com uma norma que fica a 1 entre os elementos dos filtros. Vamos dizer que eu tenho entrada de matriz A e B, e filtro C e D. A operação que eu quero fazer é:

M1 = tf.conv2d (A, C)

M2 = tf.conv2d (B, C)

M3 = tf.conv2d (A, D)

M4 = tf.conv2d (B, D)

Ao mesmo tempo, preciso sqrt (C ^ 2 + D ^ 2) = 1

Eu encontrei uma maneira de compartilhar os pesos entre os diferentes operação de convolução usando a mesma camada duas vezes, como foi perguntado em uma pergunta anterior Como compartilhar kernels convolução entre camadas em keras? .

Mas eu não tenho nenhuma idéia de como formular as restrições da norma para 1.

Valeu!

Tenho tentado introduzir uma camada de entrada que seriam treinados por meio de uma densa camada com a dimensão do meu filtro de kernel, e, em seguida, reformular e dividi-lo em 2 usando cos (x) sin (x) antes da operação de convolução (eu já estou fazer isso no código de modular a imagem de entrada). Em seguida, utilizar uma operação manual de tf.nn.conv2d (). Mas com os kernels eu recebo uma dimensão do lote como a dimensão 0 e isso é incompatível com a dimensão necessária do kernel [filter_height, filter_width, in_channels, out_channels]. Espremendo não vai funcionar.

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)

Este último código funciona bem, mas não terá uma norma de 1 para os weigths das camadas conv2D porque há tais restrições é feita

Publicado 24/10/2019 em 12:52
fonte usuário
Em outras línguas...                            

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more