基礎Gan代碼解析


initializer總結:

#f.constant_initializer(value)

變量初始化為給定的常量,初始化一切所提供的值。


#tf.random_normal_initializer(mean,stddev)

功能是將變量初始化為滿足正態分布的隨機值,主要參數(正太分布的均值和標准差),用所給的均值和標准差初始化均勻分布


#tf.truncated_normal_initializer(mean,stddev,seed,dtype)

mean:用於指定均值; stddev用於指定標准差;

seed:用於指定隨機數種子; dtype:用於指定隨機數的數據類型。

功能:將變量初始化為滿足正態分布的隨機值,但如果隨機出來的值偏離平均值超過2個標准差,那么這個數將會被重新隨機,通常只需要設定一個標准差stddev這一個參數就可以。 #tf.random_uniform_initializer(a,b,seed,dtype) #從a到b均勻初始化,將變量初始化為滿足平均分布的隨機值,主要參數(最大值,最小值)


優化器構造:

1).compute_gradients(loss,var_list=None,gate_gradients=GATE_OP,aggregation_method=None,colocate_gradients_with_ops=False,grad_loss=None)

作用:對於在變量列表(var_list)中的變量計算對於損失函數的梯度,這個函數返回一個(梯度,變量)對的列表,其中梯度就是相對應變量的梯度了。這是minimize()函數的第一個部分,

參數:

loss: 待減小的值

var_list: 默認是在GraphKey.TRAINABLE_VARIABLES.

2).apply_gradients(grads_and_vars,global_step=None,name=None)

作用:把梯度“應用”(Apply)到變量上面去。其實就是按照梯度下降的方式加到上面去。這是minimize()函數的第二個步驟。 返回一個應用的操作。

參數:

grads_and_vars: compute_gradients()函數返回的(gradient, variable)對的列表

global_step: Optional Variable to increment by one after the variables have been updated.

3).minimize(loss,global_step=None,var_list=None,gate_gradients=GATE_OP,aggregation_method=None,colocate_gradients_with_ops=False,name=None,grad_loss=None)

變量初始化:

sess.run(tf.global_variables_initializer())

函數中調用了 variable_initializer() 和 global_variables()

global_variables() 返回一個 Variable list ,里面保存的是 gloabal variables。variable_initializer() 將 Variable list 中的所有 Variable 取出來,將其 variable.initializer 屬性做成一個 op group。然后看 Variable 類的源碼可以發現, variable.initializer 就是一個 assign op。

所以: sess.run(tf.global_variables_initializer()) 就是 run了所有global Variable 的 assign op,這就是初始化參數的本來面目。

廢話不多說,上代碼。

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import os
from tensorflow.examples.tutorials.mnist import input_data

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

sess = tf.InteractiveSession()

mb_size = 128
Z_dim = 100
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)#mnist數據集 one_hot是為了讓標簽二元,即只有0和1.

def weight_var(shape, name): #定義權重,傳入權重shape和name
    return tf.get_variable(name=name, shape=shape, initializer=tf.contrib.layers.xavier_initializer())
def bias_var(shape, name):#定義偏置,傳入偏置shape和name
    return tf.get_variable(name=name, shape=shape, initializer=tf.constant_initializer(0))
# discriminater net
X = tf.placeholder(tf.float32, shape=[None, 784], name='X') #樣本x的shape是【batchsize】【784】
D_W1 = weight_var([784, 128], 'D_W1') #D的中間層的w1
D_b1 = bias_var([128], 'D_b1')
D_W2 = weight_var([128, 1], 'D_W2')#D的輸出層的w2
D_b2 = bias_var([1], 'D_b2')
theta_D = [D_W1, D_W2, D_b1, D_b2]#D的參數列表

# generator net
Z = tf.placeholder(tf.float32, shape=[None, 100], name='Z')#隨機噪聲向量z的shape是【batchsize】【100】
G_W1 = weight_var([100, 128], 'G_W1')#D的中間層的w1
G_b1 = bias_var([128], 'G_B1')
G_W2 = weight_var([128, 784], 'G_W2')#D的輸出層的w2
G_b2 = bias_var([784], 'G_B2')
theta_G = [G_W1, G_W2, G_b1, G_b2]#G的參數列表

def generator(z): #定義G,傳入隨機噪聲z,返回G的輸出。
    G_h1 = tf.nn.relu(tf.matmul(z, G_W1) + G_b1) #G_h1中間層經過激活函數后的輸出。
    G_log_prob = tf.matmul(G_h1, G_W2) + G_b2 #G輸出層沒有經過激活函數的輸出。
    G_prob = tf.nn.sigmoid(G_log_prob)#G輸出層經過激活函數后的輸出。
    return G_prob

def discriminator(x):#定義D,傳入樣本x,返回D的輸出和沒有經過激活函數的輸出。
    D_h1 = tf.nn.relu(tf.matmul(x, D_W1) + D_b1)#D_h1中間層經過激活函數后的輸出
    D_logit = tf.matmul(D_h1, D_W2) + D_b2#D輸出層沒有經過激活函數的輸出
    D_prob = tf.nn.sigmoid(D_logit)#D輸出層經過激活函數后的輸出
    return D_prob, D_logit

G_sample = generator(Z) #調用generator(z)生成G樣本
D_real, D_logit_real = discriminator(X)#discriminator(x)辨別樣本
D_fake, D_logit_fake = discriminator(G_sample)

# D_loss = -tf.reduce_mean(tf.log(D_real) + tf.log(1. - D_fake))
# G_loss = -tf.reduce_mean(tf.log(D_fake))

D_loss_real = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(
    logits=D_logit_real, labels=tf.ones_like(D_logit_real))) #使用交叉熵代價函數,D的目標:對於真實樣本,target=1
tf.summary.scalar("D_loss_real", D_loss_real)

D_loss_fake = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(
    logits=D_logit_fake, labels=tf.zeros_like(D_logit_fake)))#使用交叉熵代價函數,D的目標:對於生成器生成的樣本,target=0
tf.summary.scalar("D_loss_fake", D_loss_fake)
D_loss = D_loss_real + D_loss_fake #D最后的損失函數為D(真)+D(假)

G_loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(
    logits=D_logit_fake, labels=tf.ones_like(D_logit_fake)))#使用交叉熵代價函數,G的目標:對於生成器生成的樣本,target=1
tf.summary.scalar("G_loss", G_loss)

D_optimizer = tf.train.GradientDescentOptimizer(0.002).minimize(D_loss, var_list=theta_D)
G_optimizer = tf.train.GradientDescentOptimizer(0.002).minimize(G_loss, var_list=theta_G)

# init variables
sess.run(tf.global_variables_initializer())
def sample_Z(m, n):#隨機噪聲向量的生成,維度為m*n
    return np.random.uniform(-1., 1., size=[m, n])

def plot(samples):#畫圖
    fig = plt.figure(figsize=(4, 4))
    gs = gridspec.GridSpec(4, 4)
    gs.update(wspace=0.05, hspace=0.05)
    for i, sample in enumerate(samples):  # [i,samples[i]] imax=16
        ax = plt.subplot(gs[i])
        plt.axis('off')
        ax.set_xticklabels([])
        ax.set_yticklabels([])
        ax.set_aspect('equal')
        plt.imshow(sample.reshape(28, 28), cmap='Greys_r')
    return fig

if not os.path.exists('out/'):
    os.makedirs('out/')
i = 0

summary_op = tf.summary.merge_all()
writer = tf.summary.FileWriter("E:\Program Files\PycharmProjects\mnist_gan",sess.graph)

for it in range(1000000):
    if it % 1000 == 0:
        samples = sess.run(G_sample, feed_dict={
                           Z: sample_Z(16, Z_dim)})#生成一個維度為16*100的向量,其值是-1.——1.的隨機值。
        fig = plot(samples)
        plt.savefig('out/{}.png'.format(str(i).zfill(3)), bbox_inches='tight')
        i += 1
        plt.close(fig)

    X_mb, _ = mnist.train.next_batch(mb_size)#調用了mnist里的方法,返回x和label

    _, D_loss_curr = sess.run([D_optimizer, D_loss], feed_dict={#run(D_optimizer),開始進行梯度下降。#run(D_loss),獲得d_loss值
                                  X: X_mb, Z: sample_Z(mb_size, Z_dim)}) #D喂入x樣本和Z樣本

    _, G_loss_curr = sess.run([G_optimizer, G_loss], feed_dict={
                                  Z: sample_Z(mb_size, Z_dim)})#G喂入x樣本和Z樣本
    result = sess.run(summary_op, feed_dict={X: X_mb, Z: sample_Z(mb_size, Z_dim)})
    writer.add_summary(result, i)
    if it % 1000 == 0:
        print('Iter: {}'.format(it)) #用format()里的數字來替換“{}”
        print('D_loss: {:.4}'.format(D_loss_curr))
        print('G_loss: {:.4}'.format(G_loss_curr))
        print()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM