百家號04-16
19:45
前面的文章介紹了gan的原理,但是可以看到gan有乙個很有意思的結果,就是gan可以生成,但是他是在指定學習的一堆原始基礎上,隨機生成的。那麼如何才能夠按照我們指定的意願去生成內容呢?比如,mnist資料集的生產,我希望我能指定生成一些我希望的數字,例如1,或者2等。
這就是條件gan了,即cgan和cdcgan。
我們先來看看原理:
我們知道,對於原來的gan網路(包括dcgan)實際上是包含了兩個網路g(z)生成網路,還有d(x)判別網路,然後由此兩個網路進行相互的博弈,產生對應的結果,最後講訓練好的g(z)網路拿出來,生成。
而對於條件網路,實際上就是在兩個網路的基礎上都要增加新的條件標籤:y。而兩個網路g(z)和d(x)在構造的時候,都帶上條件:g(z,y),d(x,y),這樣訓練出來的結果,帶上y條件,就可以生成條件對應的了。
我們直接看例子:
如果,我們要將乙個gan網路改造成乙個cgan怎麼做呢?
首先要把y定義出來
y = tf.placeholder(tf.float32, shape=[none, y_dim])
然後,改造生成網路
def generator(z, y):
# concatenate z and y
inputs = tf.concat(concat_dim=1, values=[z, y])
g_h1 = tf.nn.relu(tf.matmul(inputs, g_w1) + g_b1)
g_log_prob = tf.matmul(g_h1, g_w2) + g_b2
g_prob = tf.nn.sigmoid(g_log_prob)
return g_prob
可見,生成網路是在維度上直接把條件拼接上去的,就是陣列變「長」了。
再看看判別網路:
def discriminator(x, y):
# concatenate x and y
inputs = tf.concat(concat_dim=1, values=[x, y])
d_h1 = tf.nn.relu(tf.matmul(inputs, d_w1) + d_b1)
d_logit = tf.matmul(d_h1, d_w2) + d_b2
d_prob = tf.nn.sigmoid(d_logit)
return d_prob, d_logit
由此可見,判別網路和生成網路一樣,是將輸入部分和條件標籤拼接在一起,進行統一的學習工作。
中間的計算lost和進行梯度下降這些和原來一樣,不再給出例子了。最後看看訓練部分的偽**:
x_mb, y_mb = mnist.train.next_batch(mb_size)
z_sample = sample_z(mb_size, z_dim)
_, d_loss_curr = sess.run([d_solver, d_loss], feed_dict=)
_, g_loss_curr = sess.run([g_solver, g_loss], feed_dict=)
每次訓練,gan網路,都是公用乙個y標籤進行訓練。
當然使用的時候很簡單,把對應的條件y帶上,就可以獲取到訓練的成果。
到這裡,cgan的設計就結束了,大家可以拿著名的mnist資料集進行測試一下。
下面講講,如果是面對的是dcgan,那麼cdcgan是怎麼處理的呢?
只講核心的,其實也就是在生成網路和判別網路構造的時候有所區別,其他都是一樣的。
先看看生成網路:
def discriminator(x, y_fill, istrain=true, reuse=false):
with tf.variable_scope('discriminator', reuse=reuse):
# initializer
w_init = tf.truncated_normal_initializer(mean=0.0, stddev=0.02)
b_init = tf.constant_initializer(0.0)
# concat layer
cat1 = tf.concat([x, y_fill], 3)
# 1st hidden layer
conv1 = tf.layers.conv2d(cat1, 128, [5, 5], strides=(2, 2), padding='same', kernel_initializer=w_init, bias_initializer=b_init)
lrelu1 = lrelu(conv1, 0.2)
# 2nd hidden layer
conv2 = tf.layers.conv2d(lrelu1, 256, [5, 5], strides=(2, 2), padding='same', kernel_initializer=w_init, bias_initializer=b_init)
lrelu2 = lrelu(tf.layers.batch_normalization(conv2, training=istrain), 0.2)
# output layer
conv3 = tf.layers.conv2d(lrelu2, 1, [7, 7], strides=(1, 1), padding='valid', kernel_initializer=w_init)
o = tf.nn.sigmoid(conv3)
return o, conv3
如上,黑體字部分很關鍵,實際就是將標籤合併到判別網路的原始影象的「深度」上。如此就可以利用y標籤了。
再看看生成網路:
def generator(x, y_label, istrain=true, reuse=false):
with tf.variable_scope('generator', reuse=reuse):
# initializer
w_init = tf.truncated_normal_initializer(mean=0.0, stddev=0.02)
b_init = tf.constant_initializer(0.0)
# concat layer
cat1 = tf.concat([x, y_label], 3)
# 1st hidden layer
deconv1 = tf.layers.conv2d_transpose(cat1, 256, [7, 7], strides=(1, 1), padding='valid', kernel_initializer=w_init, bias_initializer=b_init)
lrelu1 = lrelu(tf.layers.batch_normalization(deconv1, training=istrain), 0.2)
# 2nd hidden layer
deconv2 = tf.layers.conv2d_transpose(lrelu1, 128, [5, 5], strides=(2, 2), padding='same', kernel_initializer=w_init, bias_initializer=b_init)
lrelu2 = lrelu(tf.layers.batch_normalization(deconv2, training=istrain), 0.2)
# output layer
deconv3 = tf.layers.conv2d_transpose(lrelu2, 1, [5, 5], strides=(2, 2), padding='same', kernel_initializer=w_init, bias_initializer=b_init)
o = tf.nn.tanh(deconv3)
return o
其實和cgan的生成網路是一樣的,將y標籤加入到最後乙個維度上,但例子中給了乙個多維度的,其實這個維度定義如下:
z = tf.placeholder(tf.float32, shape=(none, 1, 1, 100))
g_z = generator(z, y_label, istrain)
好,其他就和普通的cgan沒有什麼區別了,大家試試吧。
這裡給出關於cgan的參考:
這篇是原理的介紹
最後,cdcgan的例子和資料相對較少,參見如下,有乙個樣例**:
不過,我先給出結論,機器學習目前平台還是推薦在aws上,這個是最好的,沒有之一!
python學習 條件判斷
計算機之所以能做很多自動化的任務,因為它可以自己做條件判斷。比如,輸入使用者年齡,根據年齡列印不同的內容,在python程式中,用if語句實現 age 20ifage 18 print your age is age print adult 根據python的縮排規則,如果if語句判斷是true,就...
vue學習 條件渲染
v if指令用於條件性地渲染一塊內容。這塊內容只會在指令的表示式返回 truthy 值的時候被渲染。也可以用v else新增乙個 else 塊 因為v if是乙個指令,所以必須將它新增到乙個元素上。但是如果想切換多個元素呢?此時可以把乙個元素當做不可見的包裹元素,並在上面使用v if。最終的渲染結果...
C 學習 條件判斷(三)
今天介紹一下c 中的選擇結構 條件判斷語句 1.if語句 if 條件 2.if語句巢狀 if 條件1 3.if else if 條件 else 條件成立執行else前邊的,不成立執行else後邊的 優化 三元表示式 語法 表示式1 表示式2 表示式3 例如 bool result 5 3?true ...