Зернистый выход из деконволюционной сети - PullRequest
0 голосов
/ 06 сентября 2018

Я пытался реализовать сверточный автоэнкодер, который принимает лицо в качестве входного сигнала, извлекает из него элементы и возвращает изображение, используя деконволюцию из этих элементов. Программа была написана на TensorFlow и работала на графическом процессоре GeForce GTX1080. На выходе получаются чистые зерна (https://imgur.com/a/KxxQUco - выходное изображение и изображение лица). Вот соответствующие функции:

def res_block(self, inp, num, in_c, mid_c, f, t):
    with tf.variable_scope(t+'_res_'+str(num)):
        w1 = tf.Variable(tf.truncated_normal(shape=[f, f, in_c, mid_c], stddev=0.1),
                    name=t+'_res_w1_'+str(num))
        conv1 = tf.nn.conv2d(inp,
                            filter=w1,
                            strides=(1,1,1,1),
                            padding="SAME",
                            name=t+'_res_conv1_'+str(num))
        b1 = tf.Variable(tf.truncated_normal(shape=tf.shape(conv1), stddev=0.1),
                    name=t+'_res_b1_'+str(num))
        conv1_ = tf.nn.relu(conv1+b1, name=t+'_res_conv1_'+str(num)+'_')

        w2 = tf.Variable(tf.truncated_normal(shape=[f, f, mid_c, in_c], stddev=0.1),
                    name=t+'_res_w2_'+str(num))
        conv2 = tf.nn.conv2d(conv1_,
                            filter=w2,
                            strides=(1,1,1,1),
                            padding="SAME",
                            name=t+'_res_conv2_'+str(num))

    conv_out = tf.add(inp, conv2)
    return conv_out

def encoder(self, image, reuse_in):
    # Start of feature extraction network

    with tf.variable_scope('e_conv'):
        w1 = tf.Variable(tf.truncated_normal(shape=[5, 5, 3, 40], stddev=1.0),
                    name='e_w1')
        conv1 = tf.nn.conv2d(image,
                            filter=w1,
                            strides=(1,2,2,1),
                            padding="VALID",
                            name='e_conv1')
        b1 = tf.Variable(tf.truncated_normal(shape=tf.shape(conv1), stddev=0.1),
                    name='e_b1')
        conv1_ = tf.nn.relu(conv1+b1, name='e_conv1_')

    res11 = self.res_block(conv1_, 1, 40, 40, 5, 'e')
    res12 = self.res_block(res11, 2, 40, 40, 5, 'e')

    with tf.variable_scope('e_conv'):
        w2 = tf.Variable(tf.truncated_normal(shape=[5, 5, 40, 64], stddev=0.1),
                    name='e_w2')
        conv2 = tf.nn.conv2d(res12,
                            filter=w2,
                            strides=(1,2,2,1),
                            padding="VALID",
                            name='e_conv2')
        b2 = tf.Variable(tf.truncated_normal(shape=tf.shape(conv2), stddev=0.1),
                    name='e_b2')
        conv2_ = tf.nn.relu(conv2+b2, name='e_conv2_')

    res21 = self.res_block(conv2_, 3, 64, 64, 5, 'e')
    res22 = self.res_block(res21, 4, 64, 64, 5, 'e')

    with tf.variable_scope('e_conv'):
        w3 = tf.Variable(tf.truncated_normal(shape=[3, 3, 64, 64], stddev=0.1),
                    name='e_w3')
        conv3 = tf.nn.conv2d(res22,
                            filter=w3,
                            strides=(1,2,2,1),
                            padding="VALID",
                            name='e_conv3')
        b3 = tf.Variable(tf.truncated_normal(shape=tf.shape(conv3), stddev=0.1),
                    name='e_b3')
        conv3_ = tf.nn.relu(conv3+b3, name='conv3_')

    res31 = self.res_block(conv3_, 5, 64, 64, 3, 'e')

    return res31

    # End of encoder

def decoder(self, img, reuse_in):
    img1 = self.res_block(img, 8, 64, 64, 3, 'd')

    with tf.variable_scope('d_conv'):
        w2 = tf.Variable(tf.truncated_normal(shape=[2, 2, 64, 64], stddev=0.1),
                    name='d_w2')
        img2 = tf.nn.relu(tf.nn.conv2d_transpose(img1,
                                        filter=w2,
                                        output_shape=[self.batch_size, 15, 15, 64],
                                        strides=(1,1,1,1),
                                        padding="VALID",
                                        name='d_deconv2'))

    img31 = self.res_block(img2, 9, 64, 64, 3, 'd')
    img32 = self.res_block(img31, 10, 64, 64, 3, 'd')

    with tf.variable_scope('d_conv'):
        w4 = tf.Variable(tf.truncated_normal(shape=[3, 3, 64, 64], stddev=0.1),
                    name='d_w4')
        img4 = tf.nn.relu(tf.nn.conv2d_transpose(img32,
                                        filter=w4,
                                        output_shape=[self.batch_size, 31, 31, 64],
                                        strides=(1,2,2,1),
                                        padding="VALID",
                                        name='d_deconv4'))

    img51 = self.res_block(img4, 11, 64, 64, 3, 'd')
    img52 = self.res_block(img51, 12, 64, 64, 3, 'd')

    with tf.variable_scope('d_conv'):
        w6 = tf.Variable(tf.truncated_normal(shape=[3, 3, 64, 64], stddev=0.1),
                    name='d_w6')
        img6 = tf.nn.relu(tf.nn.conv2d_transpose(img52,
                                        filter=w6,
                                        output_shape=[self.batch_size, 63, 63, 64],
                                        strides=(1,2,2,1),
                                        padding="VALID",
                                        name='d_deconv6'))

    with tf.variable_scope('d_conv'):
        w7 = tf.Variable(tf.truncated_normal(shape=[3, 3, 3, 64], stddev=0.1),
                    name='d_w7')
        img7 = tf.nn.conv2d_transpose(img6,
                                        filter=w7,
                                        output_shape=[self.batch_size, 128, 128, 3],
                                        strides=(1,2,2,1),
                                        padding="VALID",
                                        name='d_deconv7')

    return tf.sigmoid(img7)

Вот детали обучения.

self.fc1 = self.encoder(self.img_noisy, False)
self.img_dec = self.decoder(self.fc1, False)

self.img_loss = tf.reduce_mean(tf.losses.mean_squared_error(self.img_dec, self.img_front))

self.imge_graph = tf.summary.scalar("encoder-decoder MSE", self.img_loss)
self.loss = self.img_loss
self.optim = tf.train.AdamOptimizer(learning_rate=self.lr).minimize(self.loss)

Я пытался использовать tf.layers.conv2d_transpose(), включая потери градиента, используя tf.image.image_gradients().

Я заметил это явление в каком-то другом коде с деконволюционными слоями для аналогичной цели. Заранее спасибо.

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