生成對抗網路,AI將圖片轉成漫畫風格

張哥說技術發表於2022-12-19

哈嘍,大家好。

最近大家都在玩 AI 繪畫,我在 GitHub 上找了一個開源專案,給大家分享一下。

生成對抗網路,AI將圖片轉成漫畫風格

今天分享的這個專案是用 GAN 生成對抗網路實現的,關於GAN的原理和實戰我們之前分享過很多文章,想了解的朋友可以去翻歷史文章。

原始碼和資料集文末獲取,下面分享如何訓練、執行專案。

1. 準備環境

安裝 tensorflow-gpu 1.15.0,GPU顯示卡使用2080Ti,cuda版本10.0

git下載專案AnimeGANv2原始碼。

搭建好環境後,還需要準備資料集和vgg19

生成對抗網路,AI將圖片轉成漫畫風格

下載dataset.zip壓縮檔案,裡面包含 6k 張真實圖片和2k張漫畫圖片,用於GAN的訓練。

生成對抗網路,AI將圖片轉成漫畫風格

vgg19是用來計算損失的,下面會有詳細介紹。

2. 網路模型

生成對抗網路需要定義兩個模型,一個是生成器,一個是判別器。

生成器網路定義如下:

with tf.variable_scope('A'):
    inputs = Conv2DNormLReLU(inputs, 327)
    inputs = Conv2DNormLReLU(inputs, 64, strides=2)
    inputs = Conv2DNormLReLU(inputs, 64)

with tf.variable_scope('B'):
    inputs = Conv2DNormLReLU(inputs, 128, strides=2)
    inputs = Conv2DNormLReLU(inputs, 128)

with tf.variable_scope('C'):
    inputs = Conv2DNormLReLU(inputs, 128)
    inputs = self.InvertedRes_block(inputs, 22561'r1')
    inputs = self.InvertedRes_block(inputs, 22561'r2')
    inputs = self.InvertedRes_block(inputs, 22561'r3')
    inputs = self.InvertedRes_block(inputs, 22561'r4')
    inputs = Conv2DNormLReLU(inputs, 128)

with tf.variable_scope('D'):
    inputs = Unsample(inputs, 128)
    inputs = Conv2DNormLReLU(inputs, 128)

with tf.variable_scope('E'):
    inputs = Unsample(inputs,64)
    inputs = Conv2DNormLReLU(inputs, 64)
    inputs = Conv2DNormLReLU(inputs, 327)
with tf.variable_scope('out_layer'):
    out = Conv2D(inputs, filters =3, kernel_size=1, strides=1)
    self.fake = tf.tanh(out)

生成器中主要的模組是反向殘差塊

生成對抗網路,AI將圖片轉成漫畫風格

判別器網路結構如下:

def D_net(x_init,ch, n_dis,sn, scope, reuse):
    channel = ch // 2
    with tf.variable_scope(scope, reuse=reuse):
        x = conv(x_init, channel, kernel=3, stride=1, pad=1, use_bias=False, sn=sn, scope='conv_0')
        x = lrelu(x, 0.2)

        for i in range(1, n_dis):
            x = conv(x, channel * 2, kernel=3, stride=2, pad=1, use_bias=False, sn=sn, scope='conv_s2_' + str(i))
            x = lrelu(x, 0.2)

            x = conv(x, channel * 4, kernel=3, stride=1, pad=1, use_bias=False, sn=sn, scope='conv_s1_' + str(i))
            x = layer_norm(x, scope='1_norm_' + str(i))
            x = lrelu(x, 0.2)

            channel = channel * 2

        x = conv(x, channel * 2, kernel=3, stride=1, pad=1, use_bias=False, sn=sn, scope='last_conv')
        x = layer_norm(x, scope='2_ins_norm')
        x = lrelu(x, 0.2)

        x = conv(x, channels=1, kernel=3, stride=1, pad=1, use_bias=False, sn=sn, scope='D_logit')

        return x

3. 損失

計算損失之前先用VGG19網路將圖片向量化。這個過程有點像NLP中的Embedding操作。

Eembedding是講詞轉化成向量,VGG19是講圖片轉化成向量。

生成對抗網路,AI將圖片轉成漫畫風格

計算損失部分邏輯如下:

def con_sty_loss(vgg, real, anime, fake):

    # 真實圖片向量化
    vgg.build(real)
    real_feature_map = vgg.conv4_4_no_activation

    # 生成圖片向量化
    vgg.build(fake)
    fake_feature_map = vgg.conv4_4_no_activation

    # 漫畫風格向量化
    vgg.build(anime[:fake_feature_map.shape[0]])
    anime_feature_map = vgg.conv4_4_no_activation

    # 真實圖片與生成圖片的損失
    c_loss = L1_loss(real_feature_map, fake_feature_map)
    # 漫畫風格與生成圖片的損失
    s_loss = style_loss(anime_feature_map, fake_feature_map)

    return c_loss, s_loss

這裡使用vgg19分別計算真實圖片(引數real)生成的圖片(引數fake)的損失,生成的圖片(引數fake)漫畫風格(引數anime)的損失。

c_loss, s_loss = con_sty_loss(self.vgg, self.real, self.anime_gray, self.generated)
t_loss = self.con_weight * c_loss + self.sty_weight * s_loss + color_loss(self.real,self.generated) * self.color_weight + tv_loss

最終給這兩個損失不同的權重,這樣是的生成器生成的圖片,既保留了真實圖片的樣子,又向漫畫風格進行遷移

4. 訓練

在專案目錄下執行以下命令開始訓練

python train.py --dataset Hayao --epoch 101 --init_epoch 10

執行成功後,可以看到一下資料。

生成對抗網路,AI將圖片轉成漫畫風格

同時,也可以看到損失在不斷下降。

如果大家覺得本文對你有用就點個 在看 鼓勵一下吧,後續我會持續分享優秀的 Python+AI 專案。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024923/viewspace-2928608/,如需轉載,請註明出處,否則將追究法律責任。

相關文章