자세한 GAN 네트워크는 코드와 대결를 생성

1.GAN 기본 원리는 예를 들어 그림을 생성하기 위해 여기에, 사실은 매우 간단합니다. 우리는 두 네트워크, G (발전기)와 D (차별)가 가정하자. 이름에서 알 수 있듯이, 그 기능은 다음과 같습니다 :

  • G는 네트워크에서 생성 된 이미지를, 그 랜덤 노이즈 Z를 수신하고, 화상에 의해 생성 된 잡음은, G (Z)를 나타낸다.

  • D는 차별 네트워크, 사진이 아닌 결정이다 "진짜." 입력 파라미터 (X)이며, 화상의 X 담당자 출력은 D (x)는 x가 실제 사진 일 확률을 나타내는 것이 1 인 경우, 상기 실제 화상의 100 %이고, 출력은 사실 대표 될 수없고, 0 사진.

훈련하는 동안, 네트워크는 G의 목표는 차별 네트워크 D.을 속이기 위해 사실적인 이미지를 만들려고하는 것입니다 생성 목표는 D G 이미지를 생성하고 실제 이미지가 열려하려고하는 것입니다. 따라서, G와 D는 동적 "게임 이론"구성

마지막으로 게임의 결과는 무엇인가? 이상적인 상태에서는, G 충분한 "실제 사람"화상 G (z)가 생성 할 수있다. D의 경우, 따라서, D (G (z)) = 0.5 G 생성 이미지가 참인지 여부를 확인하기 어렵고,.

우리의 목적에 도달 할 수 있도록 : 우리는 생식 모델 G를 가지고, 이미지를 생성 할 수 있습니다.

이 GaN의 바로 핵심 원칙보다 조금 더 말하기 일반적 방법을 설명하는 수학적 언어를 사용 하는가? 직접 인용 한 논문 식 여기 :

(1) 최적화 D :

 

입력 노이즈 Z 거짓 샘플 G (z) 가능한 한 작게 생성 된 상기 제 1 최적화 입력 샘플 (X), 더 나은 결과가 참일 때

(2) 최적 G :

 

최적화 및 샘플별로 중요하지 않고 생성이를 고려할 필요가 없다이 때에만 거짓 샘플이지만 D (G (z) 가능한 한 크게는 1을 최소화하도록 발전기 (근접 1) 가능한 거짓 샘플 현실적인 소망 -D (G (z))

 

 2.GAN 기능 :

    (1) 기존 모델에 비해, 그는 오히려 하나의 네트워크에 비해 두 개의 서로 다른 네트워크를 가지고 있으며, 교육 방법은 전투 훈련 방법에 사용되는

    (2)가 아니라 데이터 샘플에서보다 판별 D로부터 GAN 구배 G를 업데이트

3. GAN의 장점 :

    생성 된 다른 모델 (볼츠만 머신과 GSNs)에 비해 (1) GAN은 생성 적 모델은 복잡한 마르코프 연쇄 않고, 역 전파를 사용하여

    (2) 모든 다른 모델에 비해, GAN은 선명하고 실제 시료 결과

    (3) GAN은 널리 자율 학습 및 반지도 학습 영역에서 사용할 수있는 자율 학습 교육에 사용된다

    그들 자체보다는 낮은 로그 우도 바인딩 가능성에 대해 최적화되어 있기 때문에, 결정적 바이어스를 도입 (4)는 인코더로부터의 변동에 비하여, 어떤 결정적인 간스는 (결정적 바이어스) 오프셋을 도입하지 않고, 변분있어서 어느 생성 표시는 간스보다 더 흐려 VAEs 예를 리드

    (5) VAE에 비해 판별이 잘 훈련 된 경우 간 스는 더 변분 하한, 다음 발전기는 간스가 점진적으로 일관, 즉. 훈련의 분포를 완벽하게 배울 수 있지만, VAE의 편차가있다

    (6) GAN은에 기능 디자인 어려움의 손실, 단지 할 일, 한 참조가 존재하는 한, 직접 차별을 방지하기 위해 같은 그림 스타일의 마이그레이션, 슈퍼 해상도, 이미지 완성, 잡음 제거 등의 장면 중 일부에 적용 장치, 전투 훈련에 나머지.

 4. GAN의 단점 :

    (1) 교육 GAN 필요가 발견, 그라데이션 하강 방법을 수행 할 수 있습니다 때로는 없습니다. 우리는 내쉬 균형을 달성 할 수있는 좋은 방법이 없어 때로는 내쉬 균형에 도달하고,이 VAE 교육 GAN과 비교가 불안정하거나 PixelRNN입니다 하지만 난 그게 훨씬 더 안정적인 훈련 볼츠만 기계보다 실제로 생각

    (2) GAN은 텍스트로, 별도의 형태로 데이터 처리에 적합하지 않다

    (3) GAN 교육 그라데이션 사라지고, 불안정한 존재, 패턴 붕괴 문제 (지금 해결)

5. 왜 GAN은 최적화 SGD에서 사용되지 않습니다

    충격에 (1) SGD 쉽게, GAN 교육 불안정성을 쉽게,

    (2) GAN의 목표는 높은 차원이 아닌 볼록 매개 변수 공간에서 내쉬 균형 지점을 찾을 수 있습니다, 내쉬 평형 점 GAN 안장 포인트이지만, SGD가 문제의 최소 찾고가 해결 때문에 SGD 만, 지역의 최소를 찾을 것입니다, GAN은 게임 문제입니다.

6. 교육 GAN의 몇 가지 팁

(개시를 제외하고) (1) 입력 활성화 함수를 사용 TANH 마지막 층 사이 (1,1)로 정규화

(2) 사용 wassertein의 GAN 손실 함수 ,

레이블 데이터 레이블을 사용하려고이있는 경우 (3), 라벨은 부드럽고 매끄러운 일방적 또는 양자 라벨 태그 부드러운 라벨을 사용하는 것 외에도, 좋은 역 효과를 사용하는 것이 제안되었다

(4). 使用mini-batch norm, 如果不用batch norm 可以使用instance norm 或者weight norm

(5). 避免使用RELU和pooling层,减少稀疏梯度的可能性,可以使用leakrelu激活函数

(6). 优化器尽量选择ADAM,学习率不要设置太大,初始1e-4可以参考,另外可以随着训练进行不断缩小学习率,

(7). 给D的网络层增加高斯噪声,相当于是一种正则

 

7.GAN实战

import tensorflow as tf #导入tensorflow
from tensorflow.examples.tutorials.mnist import input_data #导入手写数字数据集
import numpy as np #导入numpy
import matplotlib.pyplot as plt #plt是绘图工具,在训练过程中用于输出可视化结果
import matplotlib.gridspec as gridspec #gridspec是图片排列工具,在训练过程中用于输出可视化结果
import os #导入os
 
    
def xavier_init(size): #初始化参数时使用的xavier_init函数
    in_dim = size[0] 
    xavier_stddev = 1. / tf.sqrt(in_dim / 2.) #初始化标准差
    return tf.random_normal(shape=size, stddev=xavier_stddev) #返回初始化的结果

X = tf.placeholder(tf.float32, shape=[None, 784]) #X表示真的样本(即真实的手写数字)

D_W1 = tf.Variable(xavier_init([784, 128])) #表示使用xavier方式初始化的判别器的D_W1参数,是一个784行128列的矩阵
D_b1 = tf.Variable(tf.zeros(shape=[128])) #表示全零方式初始化的判别器的D_1参数,是一个长度为128的向量 
D_W2 = tf.Variable(xavier_init([128, 1])) #表示使用xavier方式初始化的判别器的D_W2参数,是一个128行1列的矩阵
D_b2 = tf.Variable(tf.zeros(shape=[1])) ##表示全零方式初始化的判别器的D_1参数,是一个长度为1的向量
theta_D = [D_W1, D_W2, D_b1, D_b2] #theta_D表示判别器的可训练参数集合

Z = tf.placeholder(tf.float32, shape=[None, 100]) #Z表示生成器的输入(在这里是噪声),是一个N列100行的矩阵
 
G_W1 = tf.Variable(xavier_init([100, 128])) #表示使用xavier方式初始化的生成器的G_W1参数,是一个100行128列的矩阵
G_b1 = tf.Variable(tf.zeros(shape=[128])) #表示全零方式初始化的生成器的G_b1参数,是一个长度为128的向量 
G_W2 = tf.Variable(xavier_init([128, 784])) #表示使用xavier方式初始化的生成器的G_W2参数,是一个128行784列的矩阵
G_b2 = tf.Variable(tf.zeros(shape=[784])) #表示全零方式初始化的生成器的G_b2参数,是一个长度为784的向量
theta_G = [G_W1, G_W2, G_b1, G_b2] #theta_G表示生成器的可训练参数集合

def sample_Z(m, n): #生成维度为[m, n]的随机噪声作为生成器G的输入
    return np.random.uniform(-1., 1., size=[m, n])

def generator(z): #生成器,z的维度为[N, 100]
    G_h1 = tf.nn.relu(tf.matmul(z, G_W1) + G_b1) #输入的随机噪声乘以G_W1矩阵加上偏置G_b1,G_h1维度为[N, 128]
    G_log_prob = tf.matmul(G_h1, G_W2) + G_b2 #G_h1乘以G_W2矩阵加上偏置G_b2,G_log_prob维度为[N, 784]
    G_prob = tf.nn.sigmoid(G_log_prob) #G_log_prob经过一个sigmoid函数,G_prob维度为[N, 784] 
    return G_prob #返回G_prob

def discriminator(x): #判别器,x的维度为[N, 784]
    D_h1 = tf.nn.relu(tf.matmul(x, D_W1) + D_b1) #输入乘以D_W1矩阵加上偏置D_b1,D_h1维度为[N, 128]
    D_logit = tf.matmul(D_h1, D_W2) + D_b2 #D_h1乘以D_W2矩阵加上偏置D_b2,D_logit维度为[N, 1]
    D_prob = tf.nn.sigmoid(D_logit) #D_logit经过一个sigmoid函数,D_prob维度为[N, 1]
    return D_prob, D_logit #返回D_prob, D_logit

G_sample = generator(Z) #取得生成器的生成结果
D_real, D_logit_real = discriminator(X) #取得判别器判别的真实手写数字的结果
D_fake, D_logit_fake = discriminator(G_sample) #取得判别器判别的生成的手写数字的结果

#对判别器对真实样本的判别结果计算误差(将结果与1比较)
D_loss_real = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=D_logit_real, targets=tf.ones_like(D_logit_real))) 
#对判别器对虚假样本(即生成器生成的手写数字)的判别结果计算误差(将结果与0比较)
D_loss_fake = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=D_logit_fake, targets=tf.zeros_like(D_logit_fake))) 
#判别器的误差
D_loss = D_loss_real + D_loss_fake 
#生成器的误差(将判别器返回的对虚假样本的判别结果与1比较)
G_loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=D_logit_fake, targets=tf.ones_like(D_logit_fake))) 

mnist = input_data.read_data_sets('../../MNIST_data', one_hot=True) #mnist是手写数字数据集

D_solver = tf.train.AdamOptimizer().minimize(D_loss, var_list=theta_D) #判别器的训练器
G_solver = tf.train.AdamOptimizer().minimize(G_loss, var_list=theta_G) #生成器的训练器

mb_size = 128 #训练的batch_size
Z_dim = 100 #生成器输入的随机噪声的列的维度
  
sess = tf.Session() #会话层
sess.run(tf.initialize_all_variables()) #初始化所有可训练参数

def plot(samples): #保存图片时使用的plot函数
    fig = plt.figure(figsize=(4, 4)) #初始化一个4行4列包含16张子图像的图片
    gs = gridspec.GridSpec(4, 4) #调整子图的位置
    gs.update(wspace=0.05, hspace=0.05) #置子图间的间距
    for i, sample in enumerate(samples): #依次将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


path = '/data/User/zcc/' #保存可视化结果的路径
i = 0 #训练过程中保存的可视化结果的索引 
for it in range(1000000): #训练100万次
    if it % 1000 == 0: #每训练1000次就保存一下结果
        samples = sess.run(G_sample, feed_dict={Z: sample_Z(16, Z_dim)})
        fig = plot(samples) #通过plot函数生成可视化结果
        plt.savefig(path+'out/{}.png'.format(str(i).zfill(3)), bbox_inches='tight') #保存可视化结果
        i += 1
        plt.close(fig)
 
    X_mb, _ = mnist.train.next_batch(mb_size) #得到训练一个batch所需的真实手写数字(作为判别器的输入)
 
    #下面是得到训练一次的结果,通过sess来run出来
    _, D_loss_curr, D_loss_real, D_loss_fake, D_loss = sess.run([D_solver, D_loss, D_loss_real, D_loss_fake, D_loss], feed_dict={X: X_mb, Z: sample_Z(mb_size, Z_dim)})
    _, G_loss_curr = sess.run([G_solver, G_loss], feed_dict={Z: sample_Z(mb_size, Z_dim)})
 
    if it % 1000 == 0: #每训练1000次输出一下结果
        print('Iter: {}'.format(it))
        print('D loss: {:.4}'. format(D_loss_curr))
        print('G_loss: {:.4}'.format(G_loss_curr))
        print()

 参考博客:

https://blog.csdn.net/m0_37407756/article/details/75309670

https://blog.csdn.net/jiongnima/article/details/80033169

추천

출처www.cnblogs.com/USTC-ZCC/p/11236847.html