當前位置:
首頁 > 最新 > 如何用 TensorFlow 生成令人驚艷的分形圖案

如何用 TensorFlow 生成令人驚艷的分形圖案

本文作者

何之源

,原文載於知乎專欄

AI Insight

,AI研習社獲其授權發布。

今天來介紹一個小項目:在 TensorFlow 中生成分形圖案。分形本身只是一個數學概念,與機器學習並無太大關係,但是通過分形的生成,我們可以了解怎麼在 TensorFlow 中進行數學計算,以及如何進行基本的流程式控制制,是學習 TensorFlow 的一個非常好的練手項目。

在開始之前,需要說明的是,TensorFlow 官方也提供了一個生成分形圖案的教程 (地址:www.tensorflow.org/tutorials/mandelbrot),然而官方教程中生成的圖像實在是太丑了,而且只能生成一種圖案,我對官方的代碼做了一些改進,並且加入了多種類型的分形,此外,不僅可以生成圖像,還可以製作 gif 動畫,代碼已經放到了 Github 上:https://github.com/hzy46/tensorflow-fractal-playground,主要的程序只有 50 行,歡迎大家參考。

Mandelbrot 集合

Mandelbrot 集合是分形中最經典的一個例子。考慮迭代公式(z 和 c 都是複數)。當為 0 時,得到的值可以組成一個數列,依次為。當該數列發散到無窮時,對應的點就屬於 Mandelbrot 集合。

如時,顯然數列永遠是 0,並不發散,因此 0 不屬於 Mandelbrot 集合。

又如時,對應的數列為,數字越來越龐大,因此 3i 就屬於 Mandelbrot 集合。

在二維平面上,將所有不屬於 Mandelbrot 集合的點標記為黑色,將所有屬於 Mandelbrot 集合的點按照其發散速度賦予不同的顏色,就可以得到 Mandelbrot 的經典圖像:

上面這張圖完全是使用 TensorFlow 進行計算的,類似的圖大家應該在網上也見過好多了,在 TensorFlow 中,我們定義下面的計算步驟:

xs = tf.constant(Z.astype(np.complex64))

zs = tf.Variable(xs)

ns = tf.Variable(tf.zeros_like(xs, tf.float32)) with tf.Session():

tf.global_variables_initializer().run()

zs_ = tf.where(tf.abs(zs) < R, zs**2 + xs, zs)

not_diverged = tf.abs(zs_) < R

step = tf.group(

zs.assign(zs_),

ns.assign_add(tf.cast(not_diverged, tf.float32))

for i in range(ITER_NUM): step.run()

final_step = ns.eval()

final_z = zs_.eval()

zs 就對應我們之前迭代公式的 z,而 xs 就對應迭代公式中的 c。為了方便起見,只要計算時數值的絕對值大於一個事先指定的值 R,就認為其發散。每次計算使用 tf.where 只對還未發散的值進行計算。結合 ns 和 zs_就可以計算顏色,得到經典的 Mandelbrot 圖像。

Julia 集合

Julia 集合和 Mandelbrot 集合差不多,但這次我們固定 c,轉而計算髮散的 z 的值。即 c 是固定的常數(可以任取),數列變成。如果該數列發散,對應的 z 就屬於 Julia 集合。對此,我們只要在原來的程序中修改兩行內容,就可以生成 Julia 集合:

xs = tf.constant(np.full(shape=Z.shape, fill_value=c, dtype=Z.dtype))

zs = tf.Variable(Z)

我們在 fill_value=c 處指定了 Julia 集合中的 c 值,只要使用不同的 c 值,就可以生成完全不同的 Julia 集合!

默認::

將 c 值變為,並調整顏色(調整方法參考 Github 頁面的說明):

選用,圖案又變得完全不同:

生成 Julia 集合的動畫

在 Julia 集合中,每次都對 c 的值進行微小的改變,並將依次生成圖片製作為 gif,就可以生成如下所示的動畫,對應的代碼為 julia_gif.py:

GIF/251K

這裡由於上傳 gif 有大小限制的關係,只展示了一個小尺寸的動畫圖像。程序中提供了一個 width 參數,可以修改它以生成更大尺寸,質量更高的動畫圖像。

探索 Mandelbrot 集合

(注意:下面的圖片可能對密集恐懼症患者不太友好。。。因此慎重翻頁。。)

在前面生成的 Mandelbrot 集合中,我們可以將圖像放大,選取某些區域進行生成,就可以得到格式各樣造型迥異的分形圖案,對應的程序為 mandelbrot_area.py。

在 Mandelbrot 集合中,有很多地方圖案比較奇特,如下圖中的 9 個位置。

其中編號為 2 的地方被稱為 「Elephant Valley」,因為此處的圖案與大象很像,直接運行 mandelbrot_area.py 就可以得到該區域的圖像:

編號為 3 的地方被稱為 「Triple Spiral Valley」(三重螺旋),在 mandelbrot_area.py 修改一下坐標位置為 (ratio 調整的是顏色):

start_x = -0.090# x range

end_x = -0.086

start_y = 0.654# y range

end_y = 0.657

width = 1000

ratio1, ratio2, ratio3 = 0.2, 0.6, 0.6

就可以得到該處的圖案:

最後編號為 1 的地方被稱為 「Seahorse Valley」(海馬山谷),對應的坐標為:

start_x = -0.750# x range

end_x = -0.747

start_y = 0.099# y range

end_y = 0.102

width = 1000

ratio1, ratio2, ratio3 = 0.1, 0.1, 0.3

圖像如下,確實和海馬有一點神似:

生成更多的圖案

項目提供了兩個 jupyter notebook:Mandelbrot.ipynb 和 Julia.ipynb 可以對 Mandelbrot 集合、Julia 集合做更方便的探索。其中,Mandelbrot 集的更多坐標位置可以參考Quick Guide to the Mandelbrot Set(http://www.nahee.com/Derbyshire/manguide.html),Julia 集中更多有趣的 c 值可以參考Julia set - Wikipedia(https://en.wikipedia.org/wiki/Julia_set#Quadratic_polynomials)。網上類似的資源還有很多。

最後再安利一下項目地址:https://github.com/hzy46/tensorflow-fractal-playground。如果代碼有什麼問題可以直接發在評論里或者在 Github 上提出 issue:)

AI 研習社長期接受優秀文章投稿

同時免費為優質企業推廣招聘信息

有意者請聯繫 jiazhilong@leiphone.com

新人福利

關注 AI 研習社(okweiwu),回復1領取

【超過 1000G 神經網路 / AI / 大數據,教程,論文】

如何使用高大上的方法調參數

點擊展開全文

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 唯物 的精彩文章:

劉凱:解讀生物醫學圖像論文(上)
2017 知乎看山杯從入門到第二
孫嘉睿:解讀 2017CVPR 獲獎論文
說到修圖這件事,你還真是比不上AI
最全面超大規模數據集下載鏈接匯總

TAG:唯物 |