DCGAN生成動漫頭像(附程式碼)
DCGAN。顧名思義,就是深度卷積生成對抗神經網路,也就是引入了卷積的,但是它用的是反捲積,就是卷積的反操作。
我們看看DCGAN的圖:
生成器開始輸入的是噪聲資料,然後經過一個全連線層,再把全連線層的輸出reshape,然後經過反捲積,
判別器就是卷積層,最後一個全連線層,用sigmoid啟用函式。
DCGAN注意事項:
生成器的全部啟用函式用relu,除了最後一層用tanh函式
判別器的啟用函式都是LeakyRelu,最後一層是sigmoid、
生成器和判別器都是用BN層,
在判別器中只需要一層全連線層用於最後的分類,不要接太多,一個就好
訓練的時候需要將原始輸入影象resize到[-1,1]
生成器最後一層不使用BN層,判別器第一層不使用BN層
然後將下DCGAN的網路結構:
首先是生成網路:
第一層:全連線層,輸出神經元個數64×8×影象長×影象寬,這個地方的長和寬是要原始圖片反推過來的,然後reshape成[batch_size,影象長,影象寬,64×8],然後接著relu啟用函式
第二層:反捲積層(deconv),卷積核大小[5,5],步長2,權重使用高斯分佈,同時權重的初始化標準差stddev=0.02,輸出通道數64×4,後面接BN層,然後使用relu作為啟用函式
第三層:也是反捲積層,引數和上面的一樣,輸出通道數是64×2,也是BN加relu
第四層:也是反捲積層,引數和上面的一樣,輸出通道數是64×1,也是BN加relu
第五層:反捲積層,輸出通道數為3,後面接relu(沒有BN層)
第三層:卷積層,卷積核大小:[5,5],權重初始化使用高斯分佈,標準差為stddev=0.02,輸出的通道數為64×4,然後接BN層,BN層後面是LeakyRelu,相當於tf.maximum(x*0.2,x),使用斜率為0.2
第四層:卷積層,卷積核大小:[5,5],權重初始化使用高斯分佈,標準差為stddev=0.02,輸出的通道數為64×8,然後接BN層,BN層後面是LeakyRelu,相當於tf.maximum(x*0.2,x),使用斜率為0.2
然後是將第四層的輸出reshape,拉平, 第五層:全連線層,輸出神經元個數1,卷積核大小:[5,5],權重初始化使用高斯分佈,標準差為stddev=0.02,
然後看我實現的程式碼:
匯入相關的庫
import matplotlib.pyplot as plt
import tensorflow as tf
from scipy import misc
import os
import numpy as np
%matplotlib inline
這個是顯示圖片,方便訓練過程中檢視
def vis_img(batch_size,samples):
fig,axes = plt.subplots(figsize=(7,7),nrows=8,ncols=8,sharey=True,sharex=True)
for ax,img in zip(axes.flatten(),samples[batch_size]):
#print(img.shape)
ax.xaxis.set_visible(False)
ax.yaxis.set_visible(False)
im = ax.imshow(img.reshape((32, 32,3)), cmap='Greys_r')
plt.show()
return fig, axes
得到batch
import os
from scipy import misc
import numpy as np
def read_img(path):
img = misc.imresize(misc.imread(path),size=[32,32])
return img
def get_batch(path,batch_size):
img_list = [os.path.join(path,i) for i in os.listdir(path)]
n_batchs = len(img_list)//batch_size
img_list = img_list[:n_batchs*batch_size]
for ii in range(n_batchs):
tmp_img_list = img_list[ii*batch_size:(ii+1)*batch_size]
img_batch = np.zeros(shape=[batch_size, 32, 32, 3])
for jj,img in enumerate(tmp_img_list):
img_batch[jj] = read_img(img)
yield img_batch
構建生成網路
def generator(inputs,stddev=0.02,alpha=0.2,name='generator',reuse=False):
with tf.variable_scope(name,reuse=reuse) as scope:
fc1 = tf.layers.dense(gen_input,64*8*6*6,name='fc1')
re1 = tf.reshape(fc1, (-1, 6, 6, 512),name='reshape')
bn1 = tf.layers.batch_normalization(re1,name='bn1')
#ac1 = tf.maximum(alpha * bn1, bn1,name='ac1')
ac1 = tf.nn.relu(bn1,name='ac1')
de_conv1 = tf.layers.conv2d_transpose(ac1,256,kernel_size=[5,5],padding='same',strides=2,kernel_initializer=tf.random_normal_initializer(stddev=stddev),name='decov1')
bn2 = tf.layers.batch_normalization(de_conv1,name='bn2')
#ac2 = tf.maximum(alpha * bn2, bn2,name='ac2')
ac2 = tf.nn.relu(bn2,name='ac2')
de_conv2 = tf.layers.conv2d_transpose(ac2, 128, kernel_size=[5, 5],padding='same',kernel_initializer=tf.random_normal_initializer(stddev=stddev),strides=2, name='decov2')
bn3 = tf.layers.batch_normalization(de_conv2,name='bn3')
#ac3 = tf.maximum(alpha * bn3, bn3,name='ac3')
ac3 = tf.nn.relu(bn3,name='ac3')
de_conv3 = tf.layers.conv2d_transpose(ac3, 64, kernel_size=[5, 5],padding='same',kernel_initializer=tf.random_normal_initializer(stddev=stddev), strides=2, name='decov3')
bn4 = tf.layers.batch_normalization(de_conv3,name='bn4')
#ac4 = tf.maximum(alpha * bn4, bn4,name='ac4')
ac4 = tf.nn.relu(bn4,name='ac4')
logits = tf.layers.conv2d_transpose(ac4, 3, kernel_size=[5, 5], padding='same',kernel_initializer=tf.random_normal_initializer(stddev=stddev), strides=2,name='logits')
output = tf.tanh(logits)
return output
構建判別網路:
def discriminator(inputs,stddev=0.02,alpha=0.2,batch_size=64,name='discriminator',reuse=False):
with tf.variable_scope(name,reuse=reuse) as scope:
conv1 = tf.layers.conv2d(inputs,64,(5,5),(2,2),padding='same',kernel_initializer=tf.random_normal_initializer(stddev=stddev),name='conv1')
ac1 = tf.maximum(alpha*conv1,conv1,name='ac1')
conv2 = tf.layers.conv2d(ac1, 128, (5,5), (2, 2), padding='same',
kernel_initializer=tf.random_normal_initializer(stddev=stddev), name='conv2')
bn2 = tf.layers.batch_normalization(conv2, name='bn2')
ac2 = tf.maximum(alpha * bn2, bn2, name='ac2')
conv3 = tf.layers.conv2d(ac2, 256, (5,5), (2, 2), padding='same',
kernel_initializer=tf.random_normal_initializer(stddev=stddev), name='conv3')
bn3 = tf.layers.batch_normalization(conv3, name='bn3')
ac3 = tf.maximum(alpha * bn3, bn3, name='ac3')
conv4 = tf.layers.conv2d(ac3, 512, (5,5), (2, 2), padding='same',
kernel_initializer=tf.random_normal_initializer(stddev=stddev), name='conv4')
bn4 = tf.layers.batch_normalization(conv4, name='bn4')
ac4 = tf.maximum(alpha * bn4, bn4, name='ac4')
flat = tf.reshape(ac4,shape=[batch_size,6*6*512],name='reshape')
fc2 = tf.layers.dense(flat, 1, kernel_initializer=tf.random_normal_initializer(stddev=stddev), name='fc2')
return fc2
lr = 0.0002
epochs = 100
batch_size = 64
alpha = 0.2
with tf.name_scope('gen_input') as scope:
gen_input = tf.placeholder(dtype=tf.float32,shape=[None,100],name='gen_input')
with tf.name_scope('dis_input') as scope:
real_input = tf.placeholder(dtype=tf.float32,shape=[None,96,96,3],name='dis_input')
gen_out = generator(gen_input,stddev=0.02,alpha=alpha,name='generator',reuse=False)
real_logits = discriminator(real_input,alpha=alpha,batch_size=batch_size)
fake_logits = discriminator(gen_out,alpha=alpha,reuse=True)
#var_list_gen = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES,scope='generator')
#var_list_dis = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES,scope='discriminator')
train_var = tf.trainable_variables()
var_list_gen = [var for var in train_var if var.name.startswith('generator') ]
var_list_dis = [var for var in train_var if var.name.startswith('discriminator')]
with tf.name_scope('metrics') as scope:
loss_g = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=tf.ones_like(fake_logits)*0.9,logits=fake_logits))
loss_d_f = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=tf.zeros_like(fake_logits),logits=fake_logits))
loss_d_r = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=tf.ones_like(real_logits)*0.9,logits=real_logits))
loss_d = loss_d_f + loss_d_r
gen_optimizer = tf.train.AdamOptimizer(0.0002,beta1=0.5).minimize(loss_g,var_list=var_list_gen)
dis_optimizer = tf.train.AdamOptimizer(0.0002,beta1=0.5).minimize(loss_d, var_list=var_list_dis)
訓練神經網路:
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(sess=sess, coord=coord)
writer = tf.summary.FileWriter('./graph/DCGAN',sess.graph)
saver = tf.train.Saver()
for epoch in range(epochs):
total_g_loss = 0
total_d_loss = 0
KK = 0
for batch in get_batch('./faces/',batch_size):
x_real = batch
x_real = x_real/127.5 - 1
x_fake = np.random.uniform(-1,1,size=[batch_size,100])
KK += 1
_,tmp_loss_d= sess.run([dis_optimizer,loss_d],feed_dict={gen_input:x_fake,real_input:x_real})
total_d_loss += tmp_loss_d
_, tmp_loss_g = sess.run([gen_optimizer,loss_g],feed_dict={gen_input:x_fake})
_, tmp_loss_g = sess.run([gen_optimizer,loss_g],feed_dict={gen_input:x_fake})
total_g_loss += tmp_loss_g
if epoch % 10 == 0:
x_fake = np.random.uniform(-1,1,[64,100])
samples = sess.run(gen_out,feed_dict={gen_input:x_fake})
samples = (((samples - samples.min()) * 255) / (samples.max() - samples.min())).astype(np.uint8)
vis_img(-1, [samples])
print('epoch {},loss_g={}'.format(epoch, total_g_loss/2/KK))
print('epoch {},loss_d={}'.format(epoch, total_d_loss/KK))
writer.close()
saver.save(sess, "./checkpoints/DCGAN")
結果展示:
相關推薦
DCGAN生成動漫頭像(附程式碼)
DCGAN。顧名思義,就是深度卷積生成對抗神經網路,也就是引入了卷積的,但是它用的是反捲積,就是卷積的反操作。 我們看看DCGAN的圖: 生成器開始輸入的是噪聲資料,然後經過一個全連線層,再把全連線層的輸出reshape,然後經過反捲積, 判別器就是卷積層,最後一個全連線
教你用TensorFlow和自編碼器模型生成手寫數字(附程式碼)
來源:機器之心 本文長度為1876字,建議閱讀4分鐘 本文介紹瞭如何使用 TensorFlow 實現變分自編碼器(VAE)模型,並通過簡單的手寫數字生成案例一步步引導讀者實現這一強大的生成模
生成對抗網路GAN---生成mnist手寫數字影象示例(附程式碼)
Ian J. Goodfellow等人於2014年在論文Generative Adversarial Nets中提出了一個通過對抗過程估計生成模型的新框架。框架中同時訓練兩個模型:一個生成模型(generative model)G,用來捕獲資料分佈;一個判別模型(discri
轉:生成對抗網路GANs理解(附程式碼)
from:http://blog.csdn.net/sxf1061926959/article/details/54630462 author:DivinerShi 生成模型和判別模型 理解對抗網路,首先要了解生成模型和判別模型。判別模型比較好理解,就像分類一樣,
半邊資料結構與網格細分演算法Loop subdivision(附程式碼)
網格細分的原理其實並不難理解,它的難點主要在於如何實現。在看過無數有原理無程式碼的部落格後,終於決定寫一寫我的實現方法,並附上程式碼供大家參考。c++寫的可能比較笨拙,望見諒。 1.半邊資料結構 很好理解,就是把網格的每一條邊分成兩個半邊,半邊是有方向的同一條邊的兩個半邊方向相反。並且一條邊
ROI Align 在 R-FCN 中的推廣:PSROI-Align(附程式碼)
ROI Align 在 R-FCN 中的推廣:PSROI-Align(附程式碼) 1. Position Sensitive ROI-Pooling 簡介 原文:https://blog.csdn.net/Bruce_0712/article/details/80287355 原始碼解析
如何在python中實現整數的二進位制迴圈移位(附程式碼)
【時間】2018.11.03 【題目】如何在python中實現整數的二進位制迴圈移位(附程式碼) 概述 在python中,可以通過<<以及>>運算子實現二進位制的左移位以及右移位,然而並沒有實現迴圈移位的運算子,暫時也找不到可以實現迴圈移位的函式,所以在本文中,主
在python中使用opencv將RGB影象轉換為HSV及YCrCb影象(附程式碼)
【時間】2018.11.01 【題目】在python中使用opencv將RGB影象轉換為HSV及YCrCb影象(附程式碼) 目錄 概述 一、程式碼實現 二、執行結果 三、關於HSV及YCrCb的一點補充 3.1HSV顏色空間 3.2 YCRCBA顏色空間
VC++6.0下基於MFC框架利用CInternetSession和CHttpFile獲取網頁資料(附程式碼)
例:從網站http://qq.ip138.com/weather/guangdong/GuangZhou.htm獲取近三天的日期、天氣、溫度、風向,程式碼如下: //新增標頭檔案 #include <afxinet.h> //獲取網路資料 void CSensorSysDlg:
獨家 | 手把手教你用Python進行Web抓取(附程式碼)
作為一名資料科學家,我在工作中所做的第一件事就是網路資料採集。使用程式碼從網站收集資料,當時對我來說是一個完全陌生的概念,但它是最合理、最容易獲取的資料來源之一。經過幾次嘗試,網路抓取已經成為我的第二天性,也是我幾乎每天使用的技能之一。 在本教程中,我將介紹一個簡單的例子,說明如何抓取一個網站,
機器學習中的優化演算法(附程式碼)
摘要 > 優化演算法指通過改善訓練方式,來最小化(或最大化)損失函式E(x) 區域性最優問題 區域性最優與鞍點。在神經網路中,最小化非凸誤差函式的另一個關鍵挑戰是避免陷於多個其他區域性最小值中。實際上,問題並非源於區域性極小值,而是來自鞍點,即一個維度向上傾斜且
神經網路之過擬合(附程式碼)
摘要 監督機器學習問題無非就是“minimizeyour error while regularizing your parameters”,也就是在規則化引數的同時最小化誤差。最小化誤差是為了讓我們的模型擬合我們的訓練資料,而規則化引數是防止我們的模型過分擬合我們的訓練資料
神經網路之權重初始化(附程式碼)
摘要 神經網路/深度學習模型訓練的過程本質是對權重進行更新,在對一個新的模型進行訓練之前,需要每個引數有相應的初始值。對於多層神經網路/深度學習而言,如何選擇引數初始值便成為一個值得探討的問題。本文從實現啟用值的穩定分佈角度來探討神經網路的效率優化問題 權重在
Android 載入或多次載入(附程式碼)
這篇帖子主要說一下列表載入的問題,上個星期開發了幾個列表,開發完以後發現有個bug,就是重複載入,而且載入完第一次以後,跳到第二個上面,然後就卡在第二次載入上,其實資料已經加載出來了,只需要退出本次載入就行,然後多次核對程式碼後發現是因為在一個列
Android 獲取位置資訊(經緯度)(附程式碼)
獲取位置資訊主要通過GPS和網路位置兩種方法,優先順序還是GPS,有點就不多說了,下面說一下我做的方法及附程式碼,有疑問可在下方留言。 思路便是GPS優先,但在GPS訊號弱的情況下采取拿
Android 動態獲取儲存、位置、電話的許可權(附程式碼)
今天客戶提出上傳資訊時需攜帶經緯度,且需要兩種獲取位置的方式;故經思考使用了GPS和網路獲取位置,但在經過實地測試的時候才發現沒寫獲取許可權。 便在登入介面加上獲取許可權程式碼,此次獲取的是儲存、位置
《Python程式設計從入門到實踐》第9章類課後習題(附程式碼)
目錄 9-1(9-2) 餐館 9-3 使用者 9-4 就餐人數 9-5 嘗試登陸次數 9-6 冰淇淋小店 9-7 管理員 9-8 許可權 9-10 匯入Restaurant類 9-11 匯入Admin類 9-12 多個模組 9-1(9-2) 餐館
Mybatis第一個專案嘗試(附程式碼)
一、專案佈局如下: 我在mysql資料庫建立的資料庫名為:mybatis 在mybatis建立了一個表,名為users 二、sql檔案users.sql內容如下: DROP TABLE IF EXISTS `users`; CREATE TABLE `users` ( &nbs
《Python程式設計從入門到實踐》第10章檔案和異常動手試一試答案(附程式碼)
目錄 10-3 訪客 10-4 訪客名單 10-6 加法運算 10-7 加法計算器 10-8 貓和狗 10-9 沉默的貓和狗 10-3 訪客 #!/usr/bin/env python # -*- coding:utf-8 -*- user = input
Python爬蟲實戰:抓取並儲存百度雲資源(附程式碼)
尋找並分析百度雲的轉存api 首先你得有一個百度雲盤的賬號,然後登入,用瀏覽器(這裡用火狐瀏覽器做示範)開啟一個分享連結。F12開啟控制檯進行抓包。手動進行轉存操作:全選檔案->儲存到網盤->選擇路徑->確定。點選【確定】前建議先清空一下抓包記錄,這樣可以精確定位到轉存的api,這就是