学习日记2:Gram Loss与纹理生成(DL作业回顾)

    xiaoxiao2023-10-23  180

    学习日记2:Gram Loss

    Gram MatrixGram Loss纹理生成实验

    Gram Matrix

    首先,Gram矩阵可以看做是矩阵的向量与其转置的内积,即:给定一个实矩阵 A,矩阵 A T A {A^T}A ATA是A的列向量的格拉姆矩阵,而矩阵 A A T A{A^T} AAT是A的行向量的格拉姆矩阵。 作业要求是实现: G i j l = ∑ m , n F i , m , n l F j , m , n l G_{ij}^l = \sum\limits_{m,n} {F_{i,m,n}^l} F_{j,m,n}^l Gijl=m,nFi,m,nlFj,m,nl 其中 F i , m , n l {F_{i,m,n}^l} Fi,m,nl代表着层l输出的第i个feature-map中位置(m,n)的像素点。

    而实际在python+TensorFlow的操作中,采用这样的方式实现一个Gram矩阵函数:

    shape = source_feature.get_shape().as_list() N = shape[3] M = shape[1] * shape[2] F_s = tf.reshape(source_feature, (-1, N)) Gram_s = (tf.matmul(tf.transpose(F_s), F_s) / (N * M))

    作业要求的feature-map是从vgg16中build出来的,为了对每个conv-layer都输出一个feature-map。在train.py里面使用

    image_model.get_layer(layer)

    或者是,简单点的方法是可以使用getattr函数:

    source_feature = getattr(source, layer)

    就避免了提取layer报错的情况。 至于M和N,N代表feature-map的个数,M代表feature-map的size。

    Gram Loss

    基于Gram-Matrix,定义Gram-Loss: L o s s = ∑ l w l 1 4 N l 2 M l 2 ∑ i , j ( G i j l − G i j l ^ ) 2 Loss = \sum\limits_l {{w_l}\frac{1}{{4N_l^2M_l^2}}} {\sum\limits_{i,j} {\left( {G_{ij}^l - \widehat {G_{ij}^l}} \right)} ^2} Loss=lwl4Nl2Ml21i,j(GijlGijl )2 在不考虑权重 w l {w_l} wl的情况下,应写为:

    def get_l2_gram_loss_for_layer(noise, source, layer): source_feature = getattr(source, layer) noise_feature = getattr(noise, layer) shape = source_feature.get_shape().as_list() N = shape[3] M = shape[1] * shape[2] F_s = tf.reshape(source_feature, (-1, N)) Gram_s = (tf.matmul(tf.transpose(F_s), F_s) / (N * M)) F_n = tf.reshape(noise_feature, (-1, N)) Gram_n = tf.matmul(tf.transpose(F_n), F_n) / (N * M) loss = tf.nn.l2_loss((Gram_s-Gram_n))/2 return loss

    纹理生成实验

    对于网络整体的Gram-Loss,所给的参考code中写的是:

    def get_gram_loss(noise, source): with tf.name_scope('get_gram_loss'): gram_loss = [get_l2_gram_loss_for_layer(noise, source, layer) for layer in GRAM_LAYERS] return tf.reduce_mean(tf.convert_to_tensor(gram_loss))

    对图像1做纹理生成: 用以上Gram-loss得到的结果为: 将这部分代码进行修改:

    def get_gram_loss(noise, source): with tf.name_scope('get_gram_loss'): loss_sum = 0. for layer in GRAM_LAYERS: loss_sum = tf.add(loss_sum,weight*get_l2_gram_loss_for_layer(noise, source, layer)) return loss_sum

    得到:

    带上权重后:

    def get_gram_loss(noise, source): with tf.name_scope('get_gram_loss'): loss_sum = 0. weight = 1. for layer in GRAM_LAYERS: weight = weight*10 loss_sum = tf.add(loss_sum,weight*get_l2_gram_loss_for_layer(noise, source, layer)) return loss_sum

    生成结果如下:

    最新回复(0)