ネットワーク型説明アンタゴニストを生成します

どのように何もAIの研究分野の焦点では​​ありません。既存の神経回路網の大半は、動物等の既存の問題は、そのネットワークは、画像内のオブジェクトをするだけでなくを識別できることを行うことができ、現在、さらなる研究で、猫や犬の絵を識別するために、ニューラルネットワークを学ぶ特定し、研究することですだけでなく、それはAI技術の価値が大幅に改善されているように、「創造的」で、画像内のオブジェクトを作成する方法を学びましょう。

グッドフェローは、「生成的な敵対的ネットワーク」の学術報告書と題する論文を提案し、Googleのプロジェクトチームからの脳の研究者である、彼は特定のネットワークアーキテクチャを提案している「創造」の深さの研究に重要な貢献をすると、ネットワークは、2つの部分から構成さ2つの部分は、その「創造」が行った対立関係、ジェネレーターと呼ばれる部分を形成し、例えば、ポートレートやいくつかのデータを提供し、別の部分がdiscrimatorと呼ばれ、それは、検査を「作成」の元の元の作業ですタスクは、その使命は継続的に与えられたデータを識別するために、その検査機能を向上させることである真または偽である、後者による検査のために十分に良い品質の出力を作成することです。

私たちは、鮮やかなメタファーを介してネットワークを理解する必要があります。彼は偽のピカソが得意である芸術家を想像し、目利きで、彼は本物と偽物のトラックを識別することができ、自身が絵を認識する目利き鍛造アーティストは、特定された場合、彼は彼を偽造する能力を向上させるために経験を総括う目利きがこれまでに同定されていないまで、偽造の能力を強化するために引き続き、そうピカソでペイントするアーティストの能力には違いはありません。

コードの練習の最初の気持ちを通過させるのgetは、把握する理論のために良い基礎を築くために、私たちは、ニューラルネットワークの「絵」を構築する方法を学ぶことができます。私たちは、トレーニングデータネットワークを行うには、Googleが提供するデータセット、データダウンロードリンクを使用している:
https://storage.cloud.google.com/quickdraw_dataset/full/numpy_bitmap/camel.npy
まず我々は、メモリにデータをロードする必要があり、コードは次のとおりです。

import os
from os import walk
import numpy as np
def  load_data():
    path = "./data"
    txt_name_list = []
    for (dirpath, dirnames, filenames) in walk(path):
        for f in filenames:
            if f != '.DS_Store':
                txt_name_list.append(f)
                break
    slice_train = int(80000/len(txt_name_list))
    i = 0
    seed = np.random.randint(1, 10e6)
    
    for txt_name in txt_name_list:
        txt_path = os.path.join(path, txt_name)
        x = np.load(txt_path)
        x = (x.astype('float32') - 127.5) / 127.5
        x = x.reshape(x.shape[0], 28, 28, 1)
        
        y = [i] * len(x)
        np.random.seed(seed)
        np.random.shuffle(x)
        np.random.seed(seed)
        np.random.shuffle(y)
        x = x[:slice_train]
        y = y[:slice_train]
        if i != 0:
            xtotal = np.concatenate((x, xtotal), axis = 0)
            ytotal = np.concatenate((y, ytotal), axis = 0)
        else:
            xtotal = x
            ytotal = y
        i += 1
    return xtotal, ytotal
(x_train, y_train) = load_data()
import matplotlib.pyplot as plt
plt.imshow(x_train[200, :, :, 0], cmap = 'gray')

以下の結果が得られた上記のコードを実行した後:
image.png

このデータセットは、Googleのクイックから来て、ドロー!それは手描きの和であり、私たちのタスクはネットワークを訓練することです、それは手描き和の同様のスタイルを生成することができます。我々は2つのネットワークを構築したい次に、陰と陽の性質に属する2つのネットワークが相互に対立の関係です。クリエータと呼ばれる一つのネットワーク、オーセンティケータと呼ばれる別のネットワーク、作成者タスクは、可能な限り画像の上記画像に類似するネットワークを生成することで、タスクは、上記画像の特徴を認識することを学ぶ人々を識別することであり、それは最終的に画像への入力を認識するそこピクチャ構造によって生成された実際の画像が残っているので、2つのネットワーク間の関係は、相互にゲームです。オーセンティケータ、強い識別能力を有する識別、クリエータ内部フィードバック調整ベースオーセンティケータによって識別されるクリエーター生成画像をトレーニングしながら、片手訓練アルゴリズムに、成長している識別するために画像の能力を同定するためそれは識別画像を識別することによって生成された後までのパラメータは彼のより多くの本物の絵のような画像から引き出され続けます。次の図は、以下からなるオーセンティケータによって識別拮抗世代ネットワークの構造を示す図です。

adversarial.png

我々はネットワークによって生成された実装コードを見て次へ:

class Model(tf.keras.Model):
    def  __init__(self):
        super(Model, self).__init__()
        self.layers = []
        self.weight_init = tf.keras.initializers.RandomNormal(mean = 0., stddev = 0.2) #用于初始化网络层参数
    def  get_activation(self, activation): #选定网络层的激活函数
        if  activation == 'leaky_relu':
            layer =  tf.keras.layers.LeakyReLU(alpha = 0.2)()
        else:
            layer = tf.keras.layers.Activation(activation)()
        return layer
     def  call(self, x):
        for layer in self.generator_layers:
            x = layer(x)
        return x    
          
class  Generator(Model):
    def  __init__(self, generator_params):
        super(Generator, self).__init__()
        self.generator_layers = []
        self.weight_init = tf.keras.initializers.RandomNormal
        self.generator_layers.append(tf.keras.layers.Dense(units = generator_params.generator_initial_dense_layer_size,
                                                           kernel_initializer = self.weight_init))
        if  generator_params.generator_batch_norm_momentun:
            self.generator_layers.append(
                tf.keras.layers.BatchNormalization(momentum = self.generator_batch_nrom_momentun)
            )
        self.generator_layers.append(self.get_activation(generator_params.generator_activation))

        self.generator_layers.append(tf.keras.layers.Reshape(generator_params.generator_initial_dense_layer_size))

        if generator_params.generator_dropout_rate:
            self.generator_layers.append(tf.keras.layers.Dropout(generator_params.generator_dropout_rate))
        for i in range(generator_params.n_layers_generator):
            if  generator_params.generator_upsample[i] == 2:
                '''
                UpSampling2D会将像素点在前后左右进行复制,例如:
                Input = [1,2
                         3,4]  经过计算后得:
                output = [1, 1, 2, 2
                          1, 1, 2, 2
                          3, 3, 4, 4,
                          3, 3, 4, 4]
                Conv2DTranspose同样会把输入扩展为原来的2倍,只不过新增加的像素点并不是直接复制而是
                通过训练后网络寻找出最合适的像素点值
                '''
                self.generator_layers.append(tf.keras.UpSampleing2D()) 
                self.generator_layers.append(
                    tf.keras.layers.Conv2D(filters = generator_params.generator_conv_filters[i],
                                           kernel_size = generator_params.generator_conv_kernel_size[i],
                                           padding = 'same',
                                           name = 'generator_conv_' + str(i),
                                           kernel_initializer = self.weight_init
                                           )
                )
            else:
                self.generator_layers.append(
                    tf.keras.layers.Conv2DTranspose(
                        filters = generator_params.generator_conv_filters[i],
                        kernel_size = generator_params.generator_conv_kernel_size[i],
                        padding = 'same',
                        strides = generator_params.generator_conv_strides[i],
                        name = "generator_conv_" + str(i),
                        kernel_initializer = self.weight_init
                    )
                )
            if  i < generator_params.n_layer_generator - 1:
                if  generator_batch_norm_momentum:
                    self.generator_layers.append(
                        tf.keras.layers.BatchNormalization(momentum = generator_params.generator_batch_norm_momentum)
                    )
                self.generator_layers.append(
                    self.get_activation(generator_params.generator_activation)
                )
            else: #最后生成图像的像素点值在[-1,1]之间后面会进一步把像素点值改为[0,1]之间
                self.generator_layers.append(
                    tf.keras.Activation('tanh')
                )    
          
        self.layers = self.generator_layers

ネットワークの創造主があまりにも配布され、その後、対応する画像へのベクターは、後で私たちは、標準のベクトルを取得する与えられたコンポーネントを含む高次元のキーベクトルを受け、クリエーターネットワークは、実際に標準を学ぶ意味タスクがあまりにも分布であります各点は、所与のスタイルの画像にマッピングされます。次に、我々はネットワークの実装を識別するためのコードを見て:

class Discriminator(Model):
    def __init__(self, params):
        super(Discriminator, self).__init__()
        self.dsicriminator_layers = []
        self.weight_init = tf.keras.initializers.RandomNormal
        for i in range(params.n_layers_discriminator):
            self.dsicriminator_layers.append(
                tf.keras.layers.Conv2D(
                    filters = params.discriminator_conv_filters[i],
                    kernel_size = params.discriminator_conv_kernel_size[i],
                    strides = params.discriminator_conv_strides[i],
                    padding = 'same',
                    name = 'discriminator_conv_' + str(i),
                    kernel_initializer = self.weight_init
                )
            )
            if  params.discriminator_batch_norm_momentum and i > 0:
                self.discriminator_layers.append(
                    tf.keras.layers.BatchNormalization(momentum = params.discriminator_batch_norm_momentun)
                )
            self.discriminator_layers.append(self.get_activation(params.discrimator_activation))
            if  params.discriminator_dropout_rate:
                self.discriminator_layers.append(
                    tf.keras.layers.Dropout(rate = params.discriminator_dropout_rate)
                )
        self.discriminator_layers.append(
            tf.keras.layers.Flatten()
        )        
        self.discriminator_layers.append(
            tf.keras.layers.Dense(units = 2, activation = 'softmax', 
                                  kernel_initializer = self.weight_init)#计算输入数据为真或假的概率
        )
        self.discriminator_layers.append(
            tf.argmax
        )

        self.layers = self.discriminator_layers

0または1で与えられ、対応する二次元アレイを受信し、そしてネットワークピクチャ識別は、入力画像が真の画像である、レッツは、訓練のために2つのネットワークを接続することを示しています。

class GAN():
     def  __init__(self, discrimiator_params, generator_params, z_dim):
         self.d_losses = []
         self.g_losses = []
         self.epoch = 0
         self.z_dim = z_dim  #关键向量的维度
         #设置生成者和鉴别者网络的优化函数
         self.discriminator_optimizer = tf.train.AdamOptimizer(discriminator_params.learning_rate)
         self.generator_optimizer = tf.train.AdamOptimizer(generator_params.learning_rate)
         generator_params.n_layers_generator = len(generator_params.generator_conv_filters)
         self.generator = Generator(generator_params)
         discriminator_params.n_layers_discriminator = len(discriminator_params.discriminator_conv_filters)
         self.discriminator = Discriminator(discriminator_params)
         self.build_adversarial()
   
    def  train_discriminator(self, x_train, batch_size, using_generator):
        '''
        训练鉴别师网络,它的训练分两步骤,首先是输入正确图片,让网络有识别正确图片的能力。
        然后使用生成者网络构造图片,并告知鉴别师网络图片为假,让网络具有识别生成者网络伪造图片的能力
        '''
        valid = np.ones((batch_size, 1))
        fake = np.zeros((batch_size, 1))
        if using_generator:#使用数据加载器
            true_imgs = next(x_train)[0] #读入图片数据
            if true_imgs.shape[0] != batch_size:
                true_imgs = next(x_train)[0]
        else:#之间从文件系统读取训练数据
            idx = np.random.randint(0, x_train.shape[0], batch_size)
            true_imgs = x_train[idx]
        noise = np.random.normal(0, 1, (batch_size, self.z_dim))
        gen_imgs = self.generator(noise) #让生成者网络根据关键向量生成图片
        real_accuracy = tfe.metrics.Accuracy()  #计算网络识别正确图片的成功率
        fake_accuracy = tfe.metrics.Accuracy() #计算网络识别构造图片的成功率
        
        with tf.GradientTape(watch_accessed_variables=False) as tape: #只修改鉴别者网络的内部参数
            tape.watch(self.discriminator.trainable_variables)
            d_loss_real = tf.keras.losses.BinaryCrossentropy(y_true = valid, self.discriminator(true_imgs))
        grads = tape.gradients(d_loss_real, self.discriminator.trainable_variables)
        self.discriminator_optimizer.apply_gradients(zip(grads, self.discriminator.trainbale_variables)) #改进鉴别者网络内部参数
        d_acc_real = real_accuracy(labels = valid, predictions = self.discriminator(true_imgs)).result().numpy() #计算训练后网络识别真图片的正确率
        
        with tf.GradientTape(watch_accessed_variables=False) as tape: #只修改鉴别者网络的内部参数
            tape.watch(self.discriminator.trainable_variables)
            d_loss_fake = tf.keras.losses.BinaryCrossentropy(y_true = fake,
                                                             y_pred = self.discriminator(gen_imgs))
        grads = tape.gradients(d_loss_fake, self.discriminator.trainbale_variables)
        self.discriminator_optimizer.apply_gradients(ziep(grads, self.discriminator.trainable_variables))
        d_acc_fake = fake_accuracy(labels = fake, predictions = self.discriminator(gen_imgs)).result().numpy() #计算鉴别者网络识别虚假图片的正确率
        
        d_loss = 0.5*(d_loss_real + d_loss_fake)
        d_acc = 0.5 * (d_acc_fake + d_acc_real)

        return [d_loss, d_loss_real, d_loss_fake, d_acc, d_acc_real, d_acc_fake]

    def  train_generator(self, batch_size): #训练生成者网络
        '''
        生成者网络训练的目的是让它生成的图像尽可能通过鉴别者网络的审查
        '''
        valid = np.ones((batch_size, 1)) #希望生成的图片尽可能多通过鉴别者网络的鉴定
        noise = np.random.normal(0, 1, (batch_size, self.z_dim)) #随机生成关键向量
        with tf.GradientTape(watch_accessed_variables=False) as tape: #只能修改生成者网络的内部参数不能修改鉴别者网络的内部参数
            tape.watch(self.generator.trainbale_variables)
            gen_imgs = self.generator(noise) #生成伪造的图片
            verify_results = self.discriminator(gen_imgs)
            verify_loss = tf.keras.keras.BinaryCrossentropy(y_true = valid,
                                                            y_pred = verify_results)
        grads = tape.gradients(verify_loss, self.generator.trainable_variables) #调整生成者网络内部参数使得它生成的图片尽可能通过鉴别者网络的识别
        self.generator_optimizer.apply_gradients(zip(grads, self.generator.trainable_variables))
        pass_accuracy = tfe.metrics.Accuracy() #计算生成者网络能通鉴定的成功率
        gen_imgs = self.generator(noise)
        verify_results = self.discriminator(gne_imgs)
        accuracy = pass_accuracy(labels = valid, predictions = verify_results).result().numpy()#检验训练后生成者网络的成功率
        return verify_loss, accuracy
    def  train(self, x_train, batch_size, epochs, run_folder, print_every_n_batches = 50,
               using_generator = False):#启动训练流程
         for  epoch in range(self.epoch, self.epoch + epoches):
             d = self.train_discriminator(x_train, batch_size, using_generator)
             g = self.train_generator(batch_size)
             print("%d [D loss: (%.3f)(R %.3f, F %.3f)] [D acc: (%.3f)(%.3f, %.3f)] [G loss: %.3f] [G acc: %.3f]" % 
                   (epoch, d[0], d[1], d[2], d[3], d[4], g[0], g[1]))
             if epoch % print_every_n_batches == 0:
                 self.sample_images(run_folder) #将生成者构造的图像绘制出来
                 self.save_model(run_folder) #存储两个网络的内部参数
            self.epoch + 1
    def  sample_images(self, run_folder): #绘制生成者构建的图像
        r, c = 5,5
        noise = np.random.normal(0, 1, (r * c, self.z_dim)) #构建关键向量
        gen_imgs = self.generator(noise)
        gen_imgs = 0.5 * (gen_imgs + 1) 
        gen_imgs = np.clip(gen_imgs, 0, 1) #将图片像素点转换到[0,1]之间
        fig, axs = plt.subplots(r, c, figsize = [15, 15])
        cnt = 0

        for i in range(r):
            for j in range(c):
                axs[i, j].imshow(np.squeeze(gen_imgs[cnt, :,:,:]), cmap = 'gray')
                axs[i,j].axis('off')
                cnt += 1
        fig.savefig(os.path.join(run_folder, 'images/sample%d.png' % self.epoch))
        plt.close()
    def  save_model(self, run_folder): #保持网络内部参数
        self.discriminator.save_weights(os.path.join(run_folder, 'discriminator.h5'))
        self.generator.save_weights(os.path.join(run_folder, 'generator.h5'))
    def  load_model(self, run_folder):
        self.discriminator.load_weights(os.path.join(run_folder, 'discriminator.h5'))
        self.generator.load_weights(os.path.join(run_folder, 'generator.h5'))

ビューのコードポイントからは、訓練は2つの異なるネットワークを処理します。写真の2種類を入力するオーセンティケータネットワークの必要性1が本物の絵で、それが写真の特長は、特性の真の姿を把握認識することを学ぶことです、他の絵のネットワーク構造の作成者である、それが生成され、ネットワークの構成となるよう内部パラメータを訓練することです写真付きの身分はfalseです。むしろ特別生成されたネットワークのトレーニング、それは訓練するためにネットワークによって識別と組み合わせる必要があり、それは最初のキーから受け取る分布ベクトルすぎると、画像出力し、その画像をネットワーク認証に入力され、結果はに従って与えられていますクリエイター場合は内部パラメータを調整し、そのようにネットワーク出力による識別の結果が真であることを、私たちは訓練プロデューサーネットワークでは、これらのネットワークを識別するために凍結された内部パラメータが存在しなければならないことに注意すべきパラメータを調整することが可能ですが、またトレーニングにオーセンティケータの内部パラメータを変更し、全体の運動が収束しないでしょう。

トレーニングプロセス対立世代のネットワークがより複雑であるので、コードのこのセクションは、ネットワーク、私たちはどのように効果的なトレーニング二つのネットワークを見て、次のセクションを達成するためにのみ与えられているので、個々に焦点を当てていることが必要です。

プレゼンテーション中に、より詳細な説明と、コードのデバッグには、リンクをクリックしてください

オペレーティング・システム、コンパイラ、インタビューアルゴリズム、機械学習、人工知能などの詳細な技術情報については、私の公共の番号の世話をしてください。
書き込み絵は、ここで説明しました

346元記事公開 ウォンの賞賛290 ビューに40万+を

おすすめ

転載: blog.csdn.net/tyler_download/article/details/104362952