如何用 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:唯物 |