能不能给出一个目标图像,使用神经网络自动提取出它的特征码呢?如果可以,那么我们就可以方便地对这些图像进行编辑,创造出各种各样“酷炫”的风格人像。

这个工作可以分为两步:

(1)先利用StyleGAN生成的特征码和生成的人脸图像训练一个网络,把人脸图像作为输入,把特征码作为输出,理论上可以得到一个StyleGAN的逆向网络模型,如果训练成功的话,这个模型可以自动将人脸图像转换为特征码;
(2)利用真实人脸图像对上面得到的模型进行进一步训练和“微调”,使之能够用于真实人脸的特征码提取。这篇文章先说明第一步的工作。

我们构造了一个如下图所示的神经网络,并计划对它进行训练。这个网络的输入为256x256的图片,输出为18x512的dlatents(StyleGAN的中间数据层,即:w)

神经网络 特征提取的方法 神经网络如何提取特征_神经网络 特征提取的方法

构建这个模型的代码如下,我们这里把这个模型叫做lotus_body():

# 定义StyleGAN的逆向网络模型lotus
# 下面的功能函数均使用keras原生函数构造
def lotus_body(x):
 
    # input: (none, 256, 256, 3), output: (none, 8, 8,2048)
    # 必须设定include_top=False, weights=None, 才能将输入设为256x256x3
    # resnet输出C5,C5的shape是(none, 8, 8, 2048)
    resnet = keras.applications.resnet50.ResNet50(include_top=False, weights=None, input_tensor=x, input_shape=(256,256,3))
    y = resnet.output
    print('ResNet50 C5 shape : ', y.shape)
 
    # output: (none, 8, 8, 144)
    # 输出feature maps = filters = 144, 2D卷积输出的高和宽8 - 1 + 1 = 8
    y = keras.layers.convolutional.Conv2D(144, (1, 1), padding='same', activation='relu')(y)
 
    # output: (none, 96, 96)
    y = keras.layers.Reshape((96, 96))(y)
 
    for i in range(3):
        # output: (none, 96, 96)
        # 输出feature maps = filters = 96, 1D卷积输出的长度96 - 1 + 1 = 96
        y = keras.layers.local.LocallyConnected1D(96, 1)(y)
 
        # output: (none, 96, 96),(2,1)代表将输入的第二个维度重拍到输出的第一个维度,而将输入的第一个维度重排到第二个维度
        y = keras.layers.Permute((2, 1))(y)
 
    # output:(none, 96, 96)
    y = keras.layers.local.LocallyConnected1D(96, 1)(y)
 
    # output: (none, 18, 512)
    y = keras.layers.Reshape((18, 512))(y)
    print('lotus body output shape : ', y.shape)
 
    return y

为了训练这个模型,我们用StyleGAN生成了1200个dlatents以及它们所对应的人脸图片,并记录到文件中,训练时我们从文件中加载数据,并训练lotus模型。

神经网络 特征提取的方法 神经网络如何提取特征_神经网络_02

由于lotus模型输出的不是目标的分类,而是18x512的张量,因此我们使用mean_squared_error作为损失函数loss,优化器(optimizer)使用的是adam,epochs = 503,batch_size = 6,最后训练得到的accuracy = 0.8933。

神经网络 特征提取的方法 神经网络如何提取特征_卷积_03

我们用StyleGAN生成了1280个dlatents以及它们所对应的人脸图片,使用mean_squared_error作为损失函数loss,优化器(optimizer)使用的是adam,epochs = 599,batch_size = 8,最后训练得到的accuracy = 0.9201。

神经网络 特征提取的方法 神经网络如何提取特征_神经网络 特征提取的方法_04