哈嘍,大家好。
最近大家都在玩 AI 繪畫,我在 GitHub 找了一個開源項目,跟大家分享一下。
今天分享的這個專案是用 GAN 生成對抗網路實現的,關於GAN的原理和實戰我們之前分享過很多文章,想了解的朋友可以去翻歷史文章。
原始碼和資料集文末獲取,以下分享如何訓練、運行專案。
安裝 tensorflow-gpu 1.15.0,GPU顯示卡使用2080Ti,cuda版本10.0。
git下載項目AnimeGANv2原始碼。
建置好環境後,還需要準備資料集和vgg19。
下載dataset.zip壓縮文件,裡麵包含 6k 張真實圖片和2k張漫畫圖片,用於GAN的訓練。
vgg19是用來計算損失的,下面會有詳細介紹。
產生對抗網路需要定義兩個模型,一個是生成器,一個是判別器。
生成器網路定義如下:
with tf.variable_scope('A'): inputs = Conv2DNormLReLU(inputs, 32, 7) 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, 2, 256, 1, 'r1') inputs = self.InvertedRes_block(inputs, 2, 256, 1, 'r2') inputs = self.InvertedRes_block(inputs, 2, 256, 1, 'r3') inputs = self.InvertedRes_block(inputs, 2, 256, 1, '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, 32, 7) with tf.variable_scope('out_layer'): out = Conv2D(inputs, filters =3, kernel_size=1, strides=1) self.fake = tf.tanh(out)
生成器中主要的模組是反向殘差區塊
殘差結構( a)與反向殘差塊(b)
判別器網路結構如下:
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
計算損失之前先用VGG19網路將圖片向量化。這個過程有點像是NLP中的Embedding操作。
Eembedding是講詞轉換成向量,VGG19是講圖片轉換成向量。
VGG19定義
計算損失部分邏輯如下:
def con_sty_loss(vgg, real, anime, fake): # 真实生成對抗網絡,AI將圖片轉成漫畫風格向量化 vgg.build(real) real_feature_map = vgg.conv4_4_no_activation # 生成生成對抗網絡,AI將圖片轉成漫畫風格向量化 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 # 真实生成對抗網絡,AI將圖片轉成漫畫風格与生成生成對抗網絡,AI將圖片轉成漫畫風格的损失 c_loss = L1_loss(real_feature_map, fake_feature_map) # 漫画风格与生成生成對抗網絡,AI將圖片轉成漫畫風格的损失 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
最終給這兩個損失不同的權重,這樣是的生成器生成的圖片,既保留了真實圖片的樣子,又向漫畫風格進行遷移
在專案目錄下執行以下命令開始訓練
python train.py --dataset Hayao --epoch 101 --init_epoch 10
運行成功後,可以看到資料。
同時,也可以看到損失不斷下降。
原始碼和資料集都已經打包好了,需要的朋友留言區留言即可。
如果大家覺得本文對你有用就點個 在看 鼓勵一下吧,後續我會持續分享優秀的 Python AI 專案。
以上是生成對抗網絡,AI將圖片轉成漫畫風格的詳細內容。更多資訊請關注PHP中文網其他相關文章!