編者按:Google Brain機(jī)器學(xué)習(xí)開發(fā)者hardmu使用TensorFlow,基于CPPN網(wǎng)絡(luò)生成了許多有趣的高分辨率抽象藝術(shù)圖片。一起來看看他是怎么做的吧。
鉆石恒久遠(yuǎn)
本文嘗試使用TensorFlow探索復(fù)合模式生成網(wǎng)絡(luò)(Compositional pattern-producing networks)。相關(guān)代碼放在github上。乍看起來,用TensorFlow實現(xiàn)CPPN是高射炮打蚊子,因為用numpy就可以實現(xiàn)CPPN。不過,用TensorFlow方便我們以后進(jìn)一步擴(kuò)展。
介紹
近來,基于神經(jīng)網(wǎng)絡(luò)的圖像生成技術(shù)通常使用嘗試一次性繪制整個圖像的生成網(wǎng)絡(luò)。例如,如果輸出圖像的目標(biāo)分辨率是256x256,那么神經(jīng)網(wǎng)絡(luò)的最后一層會有65536個值(黑白圖像)。由于內(nèi)存和這些算法的可擴(kuò)展性方面的限制,將輸出分辨率提高到現(xiàn)代圖像的分辨率(2880x1800)可能是不可行的。
在這篇文章中,我將描述一個非常簡單的生成高分辨率的圖像的方法。神經(jīng)網(wǎng)絡(luò)并不一次性生成所有像素,而是根據(jù)像素的位置生成單個像素的亮度或顏色。然后,為目標(biāo)輸出圖像中的每個像素查詢一次網(wǎng)絡(luò),從而生成整個圖像。這種方法可以用來生成高分辨率的圖像,圖像的分辨率大小將僅僅受限于內(nèi)存,同時提供了一個縮放圖像的優(yōu)雅方式,并且圖像會具有一些分形特性。
網(wǎng)上已經(jīng)有一些demo試驗了這一技術(shù),包括karpathy基于convnetjs的繪圖demo,以及生成式神經(jīng)網(wǎng)絡(luò)藝術(shù)和Neurogram的javascript實現(xiàn)。
在這篇文章中,我將介紹如何基于TensorFlow實現(xiàn)這個簡單的技術(shù),以生成隨機(jī)的抽象藝術(shù)。我想使用TensorFlow來實現(xiàn)這個功能,是因為它可以作為基礎(chǔ),在未來利用TensorFlow的機(jī)器學(xué)習(xí)能力做些更有趣的事情。這種類型的生成網(wǎng)絡(luò)還可以用來創(chuàng)建非隨機(jī)圖片,我將在以后的帖子中討論這一點(diǎn)。
復(fù)合模式生成網(wǎng)絡(luò)
我們定制的CPPN的語義
我在以前的一個帖子中介紹過CPPN的基礎(chǔ)情況,其中使用CPPN結(jié)合NEAT算法來演化生成式神經(jīng)網(wǎng)絡(luò)。
本質(zhì)上,CPPN只是一個函數(shù),c=f(x, y),該函數(shù)定義了空間中每個點(diǎn)的圖像亮度。這使得CPPN很適合生成高分辨率的圖像,因為,給定像素的位置,你可以直接調(diào)用這個函數(shù)來獲取每個像素的顏色或亮度。
f(x, y)這個函數(shù)可以通過很多數(shù)學(xué)運(yùn)算構(gòu)建,也可以通過神經(jīng)網(wǎng)絡(luò)來表示,該神經(jīng)網(wǎng)絡(luò)包含一個連接激活門的權(quán)重集合,其中的權(quán)重在繪制圖像時保持不變。因此整個圖像可以被定義為f(w, x, y)。
我們的TensorFlow實現(xiàn)將與之前基于CPPN-NEAT的工作略有不同。像之前的工作一樣,f(x, y)將返回一個0到1之間的實數(shù),以定義該點(diǎn)處的圖像亮度(結(jié)果將是灰度圖像)或一個三維向量,向量的每個值在(0, 1)之內(nèi),以表示彩色亮度(紅、綠、藍(lán))。此外,與CPPN-NEAT類似,為了使圖像更有趣,我們還將每個點(diǎn)到原點(diǎn)的距離作為輸入(r = sqrt(x^2+y^2)),因此CPPN函數(shù)為f(w, x, y, r)。神經(jīng)網(wǎng)絡(luò)的權(quán)重w將被初始化為單位高斯分布的隨機(jī)值。
與CPPN-NEAT不同,我們要在這個實現(xiàn)中使用的神經(jīng)網(wǎng)絡(luò)將僅僅是一個由用戶定義的多層前饋網(wǎng)絡(luò)。例如,用戶可以修改TensorFlow代碼,使f(w, x, y, r)成為由雙曲線正切、relu、softplus、正弦曲線等定義的前饋神經(jīng)網(wǎng)絡(luò)。每一層還將有一個額外的偏置輸入,出于簡明的考慮,圖中省略了這個偏置輸入。
我們還將在CPPN函數(shù)中添加一個稱為潛向量的額外輸入z,這是一個包含n個實數(shù)的向量(n通常遠(yuǎn)小于網(wǎng)絡(luò)中加權(quán)連接的總數(shù)),所以我們的生成網(wǎng)絡(luò)定義為f(w, z, x, y, r)。修改z的值會導(dǎo)致我們的網(wǎng)絡(luò)產(chǎn)生不同的圖像,而通過改變z的值我們的網(wǎng)絡(luò)可能生成的整個圖像空間被稱為潛空間。從某種意義上說,z可以被解釋為基于n個實數(shù)對最終圖像的壓縮描述。由于網(wǎng)絡(luò)是一個連續(xù)的函數(shù),如果我們稍微調(diào)整z的值,那么輸出圖像也只會稍微變化,所以我們也可以通過使用一個從z1緩慢地移動到z2的潛向量z生成一系列圖像,從而可視化潛空間中的一張圖像如何緩慢地漸變?yōu)橥粷摽臻g中的另一張圖像。
注意,示意圖中的空白層只是在進(jìn)入第一個隱藏層之前,應(yīng)用縮放因子至x、y、r和z的一個預(yù)處理層。
我們本可以逐漸調(diào)整權(quán)重來獲得不同的輸出圖像,之所以需要一個額外的潛向量輸入,是因為,一個復(fù)雜的生成式網(wǎng)絡(luò)可能有成百上千的權(quán)重,并且在許多生成應(yīng)用中,我們希望將潛向量的數(shù)量控制在一個很小的值。當(dāng)我們最終在大型數(shù)據(jù)集上進(jìn)行訓(xùn)練時,潛向量不僅可以控制正在繪制的對象,還可以控制圖像的特定風(fēng)格。使用概率論的一些工具,我們甚至可以強(qiáng)制z具有良好的性質(zhì),例如獨(dú)立和單位高斯。例如,z的一個子集可以表示個人性別,另一個子集可以表示由生成算法繪制的人臉的情緒。在后續(xù)的帖子中,我們會試圖訓(xùn)練這類CPPN來書寫數(shù)字,也可能會繪制臉部、動物、汽車、廁所,等等。
探索神經(jīng)網(wǎng)絡(luò)的潛空間
生成.png和.gif圖像的CPPN模型和代碼可以在github上找到。我將使用代碼作為參考,以通過IPython會話生成圖像。
在代碼倉庫中,model.py包含使用TensorFlow庫常規(guī)生成圖像的CPPN類。如果你打算嘗試修改CPPN的神經(jīng)網(wǎng)絡(luò)架構(gòu),可以查看一下generator方法。其中有一些替代架構(gòu)被注釋掉了,這些架構(gòu)可供嘗試。我們將使用sampler.py文件中的Sampler類,這允許我們互動請求IPython會話內(nèi)的圖像。
在IPython會話內(nèi),我們首先進(jìn)入倉庫目錄并運(yùn)行:
%run -i sampler.py
sampler = Sampler(z_dim = 8, scale = 10.0, net_size = 32)
Sampler將生成一個CPPN模型,該模型使用包含8個實數(shù)的潛向量,10倍放大,在每個神經(jīng)網(wǎng)絡(luò)層包含32個激活函數(shù)。注意這些是默認(rèn)值,因此我們下次也可以直接使用sampler = Sampler()。
為了生成圖像,我們需要生成一個包含8個實數(shù)的隨機(jī)潛向量z:
z1 = sampler.generate_z()
之后我們可以將z傳遞給生成函數(shù)以查看輸出圖像。img_data是一個包含圖像數(shù)據(jù)的numpy數(shù)列。
img_data = sampler.generate(z1)
sampler.show_image(img_data)
輸出
調(diào)用reinit()方法可以重置和隨機(jī)化神經(jīng)網(wǎng)絡(luò)的權(quán)重:
sampler.reinit()
sampler.show_image(sampler.generate(z1))
輸出
注意,隨著網(wǎng)絡(luò)權(quán)重的改變,潛空間改變了,因此盡管我們傳入了相同的z向量,我們會看到一個不同的輸出。
我們可以通過sampler.save_png(img_data, 'output.png')保存文件。
穿越潛空間
在同一潛空間中生成另一張隨機(jī)圖像:
z2 = sampler.generate_z()
sampler.show_image(sampler.generate(z2))
輸出
上面的兩種圖像均屬于同一潛空間,同時能以矢量格式緊湊地表示。如果我們從z1一點(diǎn)點(diǎn)地移動到z2,然后在每步生成一個圖像,我們可以看到由z1定義的圖像是如何漸變?yōu)橛蓏2定義的圖像。我創(chuàng)建了一個如上所述生成.gif圖像的方法。該方法有一些可供調(diào)整的設(shè)置,用于調(diào)節(jié)時間和每幀的大小。默認(rèn)值將生成約5M大的.gif文件。
sampler.save_anim_gif(z1, z2, 'output.gif')
輸出
著色
重置IPython會話,將c_dim設(shè)置為3后可以生成彩色圖像。
%run -i sampler.py
sampler = Sampler(z_dim = 8, c_dim = 3, scale = 10.0, net_size = 32)
我們可以讓CPPN在每個像素的位置輸出3個值,為每個像素定義RGB值。然而,我個人覺得,對于使用隨機(jī)權(quán)重的生成式網(wǎng)絡(luò)而言,黑白版本更為優(yōu)雅。
修改網(wǎng)絡(luò)架構(gòu)
我們也可以修改model.py內(nèi)的generate方法來修改CPPN網(wǎng)絡(luò)的架構(gòu)。
默認(rèn)架構(gòu)是若干包含雙曲正切函數(shù)的神經(jīng)網(wǎng)絡(luò)層。
H = tf.nn.tanh(U)
for i in range(3):
H = tf.nn.tanh(fully_connected(H, net_size, 'g_tanh_'+str(i)))
output = tf.sigmoid(fully_connected(H, self.c_dim, 'g_final'))
例子
我們也可以在tanh層中混入softplus層:
H = tf.nn.tanh(U)
H = tf.nn.softplus(fully_connected(H, net_size, 'g_softplus_1'))
H = tf.nn.tanh(fully_connected(H, net_size, 'g_tanh_2'))
H = tf.nn.softplus(fully_connected(H, net_size, 'g_softplus_2'))
output = tf.sigmoid(fully_connected(H, self.c_dim, 'g_final'))
例子
我們甚至可以加入正弦激活函數(shù):
H = tf.nn.tanh(U)
H = tf.nn.softplus(fully_connected(H, net_size, 'g_softplus_1'))
H = tf.nn.tanh(fully_connected(H, net_size, 'g_tanh_2'))
H = tf.nn.softplus(fully_connected(H, net_size, 'g_softplus_2'))
output = 0.5 * tf.sin(fully_connected(H, self.c_dim, 'g_final')) + 0.5
例子
我也嘗試了絕對值函數(shù)、平方根、自己實現(xiàn)的高斯激活函數(shù),和殘差結(jié)構(gòu)。
CPPN相當(dāng)泛化,并具備同時生成大批量圖片的能力。未來我們想讓CPPN為我們生成一些有趣的東西時,批量處理對基于GPU的神經(jīng)網(wǎng)絡(luò)訓(xùn)練非常有用。
結(jié)論
TensorFlow庫提供了執(zhí)行向量運(yùn)算的高效方法,可用于不需要梯度運(yùn)算的任務(wù)。但是這意味著未來可以利用深度學(xué)習(xí)功能擴(kuò)展各種各樣的工作。像本文中的例子一樣,我們以后可以使用這些代碼,并嘗試訓(xùn)練我們的CPPN做一些有趣的事情,比如,繪制某類圖像、字體或不同風(fēng)格的數(shù)字,這些都在高分辨率的條件下完成。
-
神經(jīng)網(wǎng)絡(luò)
+關(guān)注
關(guān)注
42文章
4797瀏覽量
102324 -
圖像生成
+關(guān)注
關(guān)注
0文章
24瀏覽量
6982 -
tensorflow
+關(guān)注
關(guān)注
13文章
330瀏覽量
60934 -
cppn
+關(guān)注
關(guān)注
0文章
2瀏覽量
2267
原文標(biāo)題:基于TensorFlow生成抽象紋理
文章出處:【微信號:jqr_AI,微信公眾號:論智】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
ADC信噪比要怎么分析?高速高分辨率ADC電路要怎么實現(xiàn)?
如何設(shè)計高速高分辨率ADC電路?
單片機(jī)內(nèi)置ADC實現(xiàn)高分辨率采樣的方法
超高分辨率圖像實時顯示系統(tǒng)設(shè)計
數(shù)碼相機(jī)最高分辨率
垂直分辨率與使用高分辨率示波器測量微小信號的介紹

結(jié)合CLC和NCO實現(xiàn)高分辨率PWM

太秀了!單片機(jī)內(nèi)置ADC實現(xiàn)高分辨率采樣?

評論