從 TensorFlow 入門機器學習

寫在前面:緊跟時代步伐,開始學習機器學習,抱着爭取在畢業以前多看看各個方向是什麼樣子的心態,發現這是一個頗有潛力也頗有趣的領域(keng)。// 而後就開始補數學了……html

0 TensorFlow 介紹

剛剛入門的小白,理解不深,直接看官方的介紹吧python

GitHub Description: Computation using data flow graphs for scalable machine learning算法

官網: TensorFlow^{^{TM}}是一個使用數據流圖進行數值計算的開源軟件庫。圖中的節點表明數學運算, 而圖中的邊則表明在這些節點之間傳遞的多維數組(張量)。數組

0.1 什麼是 TensorFlow ?

Tensor 是張量的意思,Flow 是流的意思。因此能夠直接看作利用張量組成的數據流圖進行計算的一個開源庫。瀏覽器

0.2 TensorFlow 能夠作什麼 ?

目前主要是用於機器學習,這樣說有點不親民,筆者理解是能夠將數據轉化爲向量描述而且構建相應的計算流圖都是可使用的。 舉個例子吧,雖然不知道恰不恰當。 好比咱們在計算 (1 + 2)*3-4 時,能夠構建一個二叉樹數據結構

這棵二叉樹的中序遍歷就是上面的表達式,也就是說這個表達式能夠轉化成一個形如二叉樹的圖,而 TensorFlow 正好能夠計算這個圖。下面給出代碼,看不懂不要緊,只要理解代碼流程是對圖(二叉樹)的計算就能夠了,下一章會介紹如何使用TensorFlow機器學習

# coding: utf-8
import tensorflow as tf

a, b, c, d = tf.constant(1), tf.constant(2), tf.constant(3),tf.constant(4)
add = tf.add(a,b)
mul = tf.multiply(add, c)
sub = tf.subtract(mul, d)
with tf.Session() as sess:
    print(sess.run(sub))
# output: 
# 5
複製代碼

0.3 TensorFlow 安裝

這裏就不作詳細介紹了,相信點開這篇文章的你應該有了運行環境。若是沒有這裏推薦兩個網站英文:官網中文:**學院翻譯 而後介紹一下個人環境:Anaconda + PyCharmide

注意 PyCharm:\ Project\ Interpreter 設置爲 Conda\ Environment 才能跑 TensorFlow。若是不會能夠多看看網上的教程,能對虛擬環境加深瞭解。函數

1 初識 TensorFlow

好了,有前面的介紹,你應該有可以使用 TensorFlow 的環境了,下面開始介紹如何編碼。工具

1.1 基礎語法

其實說語法是不許確的,語法就是 Python 的語法(這裏使用 Python),主要是介紹調用這個計算庫來實現這個特殊的計算。一樣擺上官網教程

1.1.1 計算單元介紹

能夠看到在計算圖中,有兩個主要的內容是點(葉子和非葉子節點)和線。個人理解是點表明數據,線表明操做。不知道對不對,不過下面就按照這樣思路介紹了。 下面開始介紹有哪些經常使用的「點」:

常量

c = tf.constant(2)
複製代碼

變量

v = tf.Variable(2)
複製代碼

佔位符

p = tf.placeholder(tf.float32)
複製代碼

以上代碼都是以最小能用原則傳的參,感興趣的能夠去看看源碼,這裏主要是往 Python 語法上拉,先使用起來再之後本身深究爲何要設計成這樣的數據結構對計算圖是必須的。

接下來就是有哪些「線」:

四則運算

add = tf.add(a, b)
sub = tf.subtract(a, b)
mul = tf.multiply(a, b)
div = tf.divide(a, b)
複製代碼

其餘的就再也不介紹了,詳情可看 XXX\_ ops.py 的源碼。好比以上的操做定義在 math\_ ops.py

1.1.2 計算流程介紹

知道了常見數據和計算方法下面介紹計算流程:

# coding: utf-8
import tensorflow as tf

# Step1: 建立數據
a, b, c, d = tf.constant(1), tf.constant(2), tf.constant(3),tf.constant(4)

# Step2: 構造計算圖
add = tf.add(a,b)
mul = tf.multiply(add, c)
sub = tf.subtract(mul, d)

# Step3: 進行計算
with tf.Session() as sess:
    print(sess.run(sub))
複製代碼

上面這個例子是一個標準的常量計算過程,你能夠試着 print(a, add) 看看你建立的是個什麼東西,你會發現他是一個 Tensor 並且裏面的值是 0。能夠猜想,這裏只打印不計算,看 Tensor 源碼:

# ops.py
def __repr__(self):
    return "<tf.Tensor '%s' shape=%s dtype=%s>" % (self.name, self.get_shape(),self._dtype.name)

@property
def name(self):
    """The string name of this tensor."""
    if not self._op.name:
        raise ValueError("Operation was not named: %s" % self._op)
    return "%s:%d" % (self._op.name, self._value_index)
複製代碼

學會了計算常量,變量是否是也同樣?若是你試過就知道是不同的,變量須要初始化操做。

v = tf.Variable(2)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(v, sess.run(v))
複製代碼

到這裏可能會疑問,那變量和常量有什麼區別?從字面意思能夠知道變量應該是可變的,方便咱們在計算過程當中隨時調整參數,下面經過一段代碼介紹如何使用。

v = tf.Variable(2)
# 將 v 的值自乘 2
update = tf.assign(v, tf.multiply(v, tf.constant(2)))
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for _ in range(4):
        print("-----------------------")
        print "Before : ", sess.run(v)
        sess.run(update)
        print "After : ", sess.run(v)

# output:
# -----------------------
# Before : 2
# After : 4
# -----------------------
# Before : 4
# After : 8
# -----------------------
# Before : 8
# After : 16
# -----------------------
# Before : 16
# After : 32
複製代碼

可是若是咱們不想每次都設置-更新-計算-更新-計算……而是直接把數據寫入計算,那佔位符就起做用了。一樣舉個小例子。

c = tf.constant(2)
# 注意類型一致,這裏是 tf.int32
p = tf.placeholder(tf.int32)
mul = tf.multiply(c, p)
with tf.Session() as sess:
    # tmp = 2 至關於上一個例子變量的初始值是 2
    tmp = 2;
    for _ in range(4):
        # 直接填充 feed_dict
        tmp = sess.run(mul, feed_dict={p:tmp})
        print tmp

# output:
# 4
# 8
# 16
# 32
複製代碼

下面總結下計算過程:

  • 建立數據:能夠建立常量、變量和佔位符。
  • 構建圖:經過前面的數據構建一張圖。
  • 初始化:把變量初始化。
  • 計算:必須經過開啓一個 Session 來計算圖

1.2 可視化

TensorFlow提供了一個可視化工具——TensorBoard,下面開始介紹如何使用。

這裏對上面二叉樹的例子進行可視化處理。

# coding: utf-8
import tensorflow as tf

a, b, c, d = tf.constant(1), tf.constant(2), tf.constant(3),tf.constant(4)
add = tf.add(a,b)
mul = tf.multiply(add, c)
sub = tf.subtract(mul, d)
with tf.Session() as sess:
    writer = tf.summary.FileWriter('./graphs', sess.graph)
    print(sess.run(sub))
writer.close()
複製代碼

而後使用命令行到存儲 graphs 的文件夾下執行 tensorboard --logdir="./graphs" 命令,而後按照提示在瀏覽器中打開 http://localhost:6006 若是成功顯示 TensorBoard 界面就說明成功了。

2 利用 TensorFlow 進行機器學習

這裏也算是機器學習的入門介紹吧。直接介紹機器學習相關知識可能不太現實,並且筆者也是在學習階段,因此舉一些小例子來體會機器學習的過程吧。

2.1 線性迴歸

這裏咱們使用最熟悉的線性迴歸來體會一下機器學習的過程:

2.1.1 準備數據

這裏很簡單,就是模擬一個線性迴歸,因此咱們直接本身擬定一些數據好預測結果和本身設想的是否一致。

train_X = numpy.asarray([1.1, 1.8, 3.2, 4.7, 5.9, 6.7])
train_Y = numpy.asarray([1.2, 2.1, 3.1, 4.6, 5.5, 6.9])
複製代碼

2.1.2 構建模型

咱們採用佔位符的形式進行計算,在運算時直接導入數據即可。 這裏由於咱們採用線性迴歸,因此目標函數是形如 Y = XW + b 的形式的一次函數。也就是說,咱們經過給出的點去擬合一條比較符合這些點分佈的直線。

X = tf.placeholder(tf.float32)
Y = tf.placeholder(tf.float32)

W = tf.Variable(-1., name="weight")
b = tf.Variable(-1., name="bias")

# linear model 
# activation = X*W + b
activation = tf.add(tf.multiply(X, W), b)
複製代碼

2.1.3 參數評估

咱們採用每一個點給出的縱座標和線性模型算出的縱座標的差(activation - Y)的平方和(tf.reduce\_ sum(tf.pow(activation - Y, 2)))做爲損失函數,在訓練中採用梯度降低算法儘可能使和最小,學利率選擇 0.01。其中的數學原理這裏就不介紹了,之後會寫關於機器學習算法的相關文章。 通常選取損失函數和經過某些最優化手段更新權重是這裏的一大難點,若是要知道原理,須要學習大量數學基礎知識(機率論,線性代數,微積分……)。

learning_rate = 0.01

cost = tf.reduce_sum(tf.pow(activation - Y, 2))
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
複製代碼

2.1.4 訓練數據

這裏就是取數據,餵給圖中的輸入節點,而後模型會本身進行優化,能夠將數據屢次迭代使得擬合函數可以更好的適應這些數據點。

training_epochs = 2000
display_step = 100

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for epoch in range(training_epochs):
        for (x, y) in zip(train_X, train_Y):
            sess.run(optimizer, feed_dict={X: x, Y: y})
        if epoch % display_step == 0:
            print("Epoch:", '%04d' % (epoch + 1), "cost=",
                  "{:.9f}".format(sess.run(cost, feed_dict={X: train_X, Y: train_Y})), "W=", sess.run(W), "b=",
                  sess.run(b))
    print("Optimization Finished!")
    print("cost=", sess.run(cost, feed_dict={X: train_X, Y: train_Y}), "W=", sess.run(W), "b=", sess.run(b))
複製代碼

2.1.5 可視化

能夠直接繪製二維圖形看結果。不熟悉的能夠參考Matplotlib 教程

writer = tf.summary.FileWriter('./graphs', sess.graph)

    plt.scatter(train_X, train_Y, color='red', label='Original data')
    plt.plot(train_X, sess.run(W) * train_X + sess.run(b), color='blue', label='Fitted line')
    plt.show()
writer.close()
複製代碼

二維圖:

數據流圖:

2.1.6 小結

其實整個過程若是不深究其中的原理,仍是很好理解的,無非就是提供數據-選取擬合函數-構建圖-選取損失函數-最優化-訓練數據(更新權重)-得出結論。這個過程符合咱們對線性迴歸這個問題解決的基本思路的預期。固然,筆者認爲這只是開始,要想深刻,學習必要的數學知識是機器學習的必經之路。

這裏能夠參考TensorFlow 入門 總體代碼:

# coding: utf-8
from __future__ import print_function
import tensorflow as tf
import numpy
import matplotlib.pyplot as plt

train_X = numpy.asarray([1.1, 1.8, 3.2, 4.7, 5.9, 6.7])
train_Y = numpy.asarray([1.2, 2.1, 3.1, 4.6, 5.5, 6.9])

X = tf.placeholder(tf.float32)
Y = tf.placeholder(tf.float32)

W = tf.Variable(-1., name="weight")
b = tf.Variable(-1., name="bias")

activation = tf.add(tf.multiply(X, W), b)

learning_rate = 0.01

cost = tf.reduce_sum(tf.pow(activation - Y, 2))
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)

training_epochs = 2000
display_step = 100

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for epoch in range(training_epochs):
        for (x, y) in zip(train_X, train_Y):
            sess.run(optimizer, feed_dict={X: x, Y: y})
        if epoch % display_step == 0:
            print("Epoch:", '%04d' % (epoch + 1), "cost=",
                  "{:.9f}".format(sess.run(cost, feed_dict={X: train_X, Y: train_Y})), "W=", sess.run(W), "b=",
                  sess.run(b))
    print("Optimization Finished!")
    print("cost=", sess.run(cost, feed_dict={X: train_X, Y: train_Y}), "W=", sess.run(W), "b=", sess.run(b))
    
    writer = tf.summary.FileWriter('./graphs', sess.graph)

    plt.scatter(train_X, train_Y, color='red', label='Original data')
    plt.plot(train_X, sess.run(W) * train_X + sess.run(b), color='blue', label='Fitted line')
    plt.show()
writer.close()

# output:
# Epoch: 0001 cost= 0.785177052 W= 1.07263 b= -0.448403
# Epoch: 0101 cost= 0.440001398 W= 1.02555 b= -0.0137608
# Epoch: 0201 cost= 0.437495589 W= 1.02078 b= 0.0176154
# Epoch: 0301 cost= 0.437433660 W= 1.02043 b= 0.0199056
# Epoch: 0401 cost= 0.437430561 W= 1.02041 b= 0.0200727
# Epoch: 0501 cost= 0.437429130 W= 1.0204 b= 0.0200851
# Epoch: 0601 cost= 0.437429696 W= 1.0204 b= 0.0200854
# Epoch: 0701 cost= 0.437429696 W= 1.0204 b= 0.0200854
# Epoch: 0801 cost= 0.437429696 W= 1.0204 b= 0.0200854
# Epoch: 0901 cost= 0.437429696 W= 1.0204 b= 0.0200854
# Epoch: 1001 cost= 0.437429696 W= 1.0204 b= 0.0200854
# Epoch: 1101 cost= 0.437429696 W= 1.0204 b= 0.0200854
# Epoch: 1201 cost= 0.437429696 W= 1.0204 b= 0.0200854
# Epoch: 1301 cost= 0.437429696 W= 1.0204 b= 0.0200854
# Epoch: 1401 cost= 0.437429696 W= 1.0204 b= 0.0200854
# Epoch: 1501 cost= 0.437429696 W= 1.0204 b= 0.0200854
# Epoch: 1601 cost= 0.437429696 W= 1.0204 b= 0.0200854
# Epoch: 1701 cost= 0.437429696 W= 1.0204 b= 0.0200854
# Epoch: 1801 cost= 0.437429696 W= 1.0204 b= 0.0200854
# Epoch: 1901 cost= 0.437429696 W= 1.0204 b= 0.0200854
# Optimization Finished!
# cost= 0.43743 W= 1.0204 b= 0.0200854
# 能夠看到迭代次數到 500 次左右數據就穩定了。
複製代碼

3 總結

其實這只是一個開始,還有好多好多東西要去學習。愈來愈以爲基礎的重要性,不只僅是計算機基礎,數學基礎也是同等重要,特別是將來的物聯網趨勢,可能編碼這種專業愈來愈淡化,只是做爲某些專業人員的一種工具/技能使用。立刻面臨畢業,只能本身慢慢啃這些東西了……

4 參考資料

相關文章
相關標籤/搜索