机器学习与数据挖掘

实践随笔之TensorFlow 生成分形图案

2017-09-13  本文已影响0人  升维洞察

认识分形
据芒德布罗教授自己说,fractal一词是1975年夏天的一个寂静夜晚,他在冥思苦想之余偶翻他儿子的拉丁文字典时,突然想到的。此词源于拉丁文形容词fractus,对应的拉丁文动词是frangere(“破碎”、“产生无规碎片”)。此外与英文的fraction(“碎片”、“分数”)及fragment(“碎片”)具有相同的词根。在70年代中期以前,芒德布罗一直使用英文fractional一词来表示他的分形思想。因此,取拉丁词之头,撷英文之尾的fractal,本意是不规则的、破碎的、分数的。芒德布罗是想用此词来描述自然界中传统欧几里德几何学所不能描述的一大类复杂无规的几何对象。例如,弯弯曲曲的海岸线、起伏不平的山脉,粗糙不堪的断面,变幻无常的浮云,九曲回肠的河流,纵横交错的血管,令人眼花缭乱的满天繁星等。它们的特点都是,极不规则或极不光滑。直观而粗略地说,这些对象都是分形。
朱利亚集合
朱利亚集合是一个在复平面上形成分形的点的集合。以法国数学家加斯顿·朱利亚(Gaston Julia)的名字命名。
朱利亚集合可以由下式进行反复迭代得到:

对于固定的复数c,取某一z值(如z = z0),可以得到序列


这一序列可能反散于无穷大或始终处于某一范围之内并收敛于某一值。我们将使其不扩散的z值的集合称为朱利亚集合。
更多介绍自己查阅更多资料,例如这篇文章(http://www.kuqin.com/math/20110901/264161.html),下面让我们动手生成分形艺术图案~
安装PIL库
安装图像处理PIL库,几乎木有人可以直接pip install PIL安装成功,所以需要自己先去下载对应的文件。下载地址如下(http://www.lfd.uci.edu/~gohlke/pythonlibs/#pillow),然后可以使用pip install 文件路径进行安装。安装结果如下图:

代码说明

import tensorflow as tf
import numpy as np
from PIL import Image

R = 4
ITER_NUM = 200


def get_color(bg_ratio, ratio):
    def color(z, i):
        if abs(z) < R:
            return 0, 0, 0
        v = np.log2(i + R - np.log2(np.log2(abs(z)))) / 5
        if v < 1.0:
            return v**bg_ratio[0], v**bg_ratio[1], v ** bg_ratio[2]
        else:
            v = max(0, 2 - v)
            return v**ratio[0], v**ratio[1], v**ratio[2]
    return color


def gen_julia(Z, c, bg_ratio, ratio):
    #定义2个变量一个常量 xs=c,zs=Z,ns=0+0i
    xs = tf.constant(np.full(shape=Z.shape, fill_value=c, dtype=Z.dtype))
    zs = tf.Variable(Z)
    ns = tf.Variable(tf.zeros_like(xs, tf.float32))
    with tf.Session():
        #初始化变量
        tf.global_variables_initializer().run()
        #zs_=Z^2+c ,if|Z|< R
        zs_ = tf.where(tf.abs(zs) < R, zs**2 + xs, zs)
        not_diverged = tf.abs(zs_) < R
        #迭代赋值计算zs <- zs_
        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()
    r, g, b = np.frompyfunc(get_color(bg_ratio, ratio), 2, 3)(final_z, final_step)
    img_array = np.dstack((r, g, b))
    return Image.fromarray(np.uint8(img_array * 255))


if __name__ == '__main__':
    start_x = -1.9  # x range
    end_x = 1.9
    start_y = -1.1  # y range
    end_y = 1.1
    width = 1200  # image width
    c = -0.835 - 0.2321 * 1j
    bg_ratio = (4, 2.5, 1)
    ratio = (0.7, 0.6, 0.5)

    step = (end_x - start_x) / width
    Y, X = np.mgrid[start_y:end_y:step, start_x:end_x:step]
    Z = X + 1j * Y

    img = gen_julia(Z, c, bg_ratio, ratio)
    img.save('julia.png')

运行效果
在 Julia 集相关领域中,有一个非常漂亮而且非常重要的定理叫做 fundamental dichotomy theorem ,它告诉我们,一个 Julia 集要么是完全连通的,任意两点间都有一条通路;要么是完全不连通的,整个图形全是一个个孤立的点。下面两幅图片就是连通和不连通两种结果。通过调节c= -0.835-0.2321*1j会得到不同的结果,理论依据参考上面的链接。

上一篇下一篇

猜你喜欢

热点阅读