TensorFlow 如何入門?
我本科不是學計算機的,現在在入門深度學習,因此我現在在對比 TensorFlow 中英文文檔在學(一個是英文官方,一個是極客學院的中文文檔):
https://www.tensorflow.org/versions/master/tutorials/index.html
TensorFlow官方文檔中文版_TensorFlow中文教程_TensorFlow開發中文手冊[PDF]下載
然後我發現看教程時,原理都看得懂,但看代碼時,TensorFlow每一個教程的代碼的實現方式都不一樣,沒有標準(估計是不同的人寫的),而且還涉及很多底層的東西,進度很慢。上上周發現了 TensorLayer,它的教程其實就是TensorFlow官方教程的模塊化實現:
GitHub - zsdonghao/tensorlayer: TensorLayer: Deep learning and Reinforcement learning library for Researchers and Engineers.
Welcome to TensorLayer
看這個庫速度很快,一下子就學會演算法原理和如何實現了,但是用這個庫的話,感覺很多TensorFlow 底層原理就學不到了,比如 TensorFlow 源代碼里的 Queue,看了很久很久都不懂(畢竟俺沒有正式學過計算機工程)。還有翻譯例子裡面,它直接用 embedding_attention_seq2seq() 函數,而不是每個部分獨立一種layer,不太明白裡面的細節。不知道大家在看 TensorFlow 教程時是怎麼看的呢?
有沒有其他一些資源可以學習?
可以學一下斯坦福新開的課程,cs20si,http://web.stanford.edu/class/cs20si/index.html,國內可以看b站的視頻,CS 20SI: Tensorflow for Deep Learning Research,通過這個課程,能夠對tensorflow有個全面的了解,從最基本的計算圖開始,到如何結構化模型,了解最新的seq2seq,neural style等前沿演算法的實現。
我準備寫一個課程筆記,這是第一篇筆記
以上
李沐大神說過,深度學習框架就是丹爐.
- google丹爐的使用說明書:確實是很完善,從最開始出來到現在一直在更新,有段時間不看文檔,發現對了好多contrib的文檔內容(這個特別棒,建議持續關注),所以,所以一直要持續的關注/學習;
- 煉丹友的反饋:做實驗用第三方框架 tflearn, tensorlayer都很好,不過個人感覺還是要先猜猜原生tensorflow源碼的坑,所以在github上,watch tensorflow這個項目是必須的,尤其是沒事看看別人提的issue,很多時候會避免在之後你用到的問題;
- 定位自己的方向:就是你做的這塊的內容在tensorflow的體現,比如本人做cv的,會去關注tensorflow/model下的各種cv方向的tensorflow/models,會去讀它的代碼實現,google的工程實現確實很厲害,代碼很完善,看著很漂亮,是種享受,還有就是github其他的基於tensorflow的cv下的內容,挑star高的去看下,過不了多久,你就會慢慢模仿著用來寫自己的model,而且會顯得很專業;
- 關注丹方: TensorFlow就是一套工具,無論是mxnet、torch、paddle,真正我們要做的是用某套工具把我們熟悉,了解的丹方煉出來,google model下tensorflow/models裡面很最新的image下的丹方,建議多熟悉熟悉,如果發現其他框架比如tflearn,tensorlayer,mxnet上沒有的可以去嘗試用別的丹爐煉出來,這個很有用的,本人用tflearn寫過googlenet,inception-resnet-v2,用mxnet寫過inception-resnet-v2,難度不大但你會學到從頭到尾去熟悉丹爐;
- 第三方支持框架: tensorflow出來後有很多高級的第三方包,例如tflearn,keras,tensorlayer,提供高級的api用來快速實現某些功能,但是我覺得更大的好處其實不是快速寫好某個模型,而是其內部專業的高級api的代碼實現,極其值得參考,本人比較熟悉tflearn,tflearn裡面的各種layer的寫法簡直是教科書級別的,童靴們在寫tensorflow源碼的時候完全可以拿來參考
- 金丹使用: model訓練出來,如何使用?做inference還是保存下來對新的task做pretrained+fine-tuning,這些都要關注,具體可以去看看例如neural style的model還有一些圖像分類比賽使用pretrained model的源碼;
- 框架底層的學習: 本人在這塊不熟悉,但是個人覺得還是很有必要掌握這些,我之後會在一段時間好好關注下這部分,讀讀輕量級框架pjreddie/darknet,tiny-dnn/tiny-dnn的源碼
最後不要臉地推薦下我博客的幾篇相關文章:
TensorFlow入門一-小石頭的碼瘋窩
TensorFlow之深入理解Neural Style
TensorFlow之深入理解AlexNet-小石頭的碼瘋窩
TensoFlow之深入理解GoogLeNet-小石頭的碼瘋窩
TensorFlow之深入理解VGGResidual Network
TensorFlow之深入理解Fast Neural Style
風格畫之最後一彈MRF-CNN-小石頭的碼瘋窩
深度學習之Neural Image Caption
MXnet初體驗之inception-resnet-v2從Model到Predict-小石頭的碼瘋窩
Tensorflow作為Google花大力構建維護的項目,擁有一套異常完善的Tutorial。對初學者來說,可能完善到讓人不知道該從哪裡下手,相信看過它的網站的同學們都能感覺得到。但既然是開源項目,要學習它肯定是從官方的Document下手,這裡也感謝極客學院的大佬們細心翻譯,方便了小白們入坑。
首先,要想應用這種深度學習包,需要你對機器學習這方面有一個理論上的了解,完全不會ML、DL的純小白也不可能看得懂這些文檔和演算法,文檔里的介紹大部分都是在應用層面上的指導。我在這之前對ML和DL算有一定的基礎,精看過幾本書,亂看過幾個系列的網課,刷了Ufldl,啃過一些經典的paper,看題主的提問水平相信基礎知識也很紮實。
考慮到,這個項目開源也沒多久,所以也沒有什麼統一認可的學習方法。我自己開始是同時看極客學院和原版的文檔,開始的MNIST肯定是要完全吃透的,這裡邊有兩種代碼,Deep MNIST for Experts是初級的(雖然是For Experts但確實很初級),比較好理解,簡單實現了MNIST卷積神經網路,也沒有模塊化;這後面的一章TensorFlow Mechanics 101 在之前一章的基礎上實現了模塊封裝,算是一個稍微有模有樣的代碼。我當時把這一章的代碼拿出來各種亂改,實現不同的功能,搞懂了這一塊才基本算入門了。
這之後硬啃下了CIFAR10的卷積實現的代碼,這期間接觸了不少新函數,不明白了就看文檔的API或者上CSDN上看博客之類的,個人認為這是一個比較重要的時間段,對整個Tensorflow的架構有了一個更加系統的認識。說實話過程還是挺痛苦的,因為文檔從這裡開始不再細緻的講解,而是為學習者拓寬Tensorflow的使用方式。有時想吃透一些細節就必須耗很久。我個人非常建議在這個階段多自己上手寫程序,當然,我們可能還達不到完全自己寫出來的水平,那就拆人家的輪子然後改,在自己寫的過程中,會遇到一些經典的問題,最後發現人家的方法確實好,確實有這麼做的道理。這個過程大概花了兩周的時間,也算是在圖像處理上有一些想法和閱歷了。
上一個階段結束之後就開始有一些自己的想法,然後就決定自己上手寫一個小程序。因為之前剛剛學過OpenCV,對裡面人臉識別印象比較深刻,於是接受了ML前輩的意見,自己用Tensorflow寫了一個輸入照片判斷性別的程序。這裡面就要涉及到之前學過看過的所有知識,雖然很簡單,但也編了整整一周,人臉數據集用的是IMDB WIKI的數據,這個數據集還可以做蠻多事情的,因為數據集里是帶有年齡標記的,還可以寫判斷年齡的程序,是自己上手的不錯選擇。這同時開始看paper,邊看輪子邊拆輪子,有時間自己造一些輪子。然後就沒有然後了,我也是剛剛走到這一步
還可以看其他一些工具包的Document,比如Theano,caffe,雖然實現方法都不一樣,但還是有很多相似之處的,具體幫助大不大我也說不上來,不妨試一試分享一篇文章面向普通開發者的機器學習入門,作者@狸小華
前言
最近在摸索這方面相關的知識,本著整理鞏固,分享促進的精神。所以有了這篇博文。
需要注意的是,本文受眾:對機器學習感興趣,且願意花點時間學習的應用(業務)程序員
我本意是盡量簡單,易於理解,快速上手,短時間能跑出來東西,這樣子才能正向激勵我們的學習慾望。
基於上述條件,需要你已經有一定的開發經驗,微不足道的數學能力,以及善用搜索引擎的覺悟。開發環境搭建
開發環境搭建
首先,我希望你是Linux系用戶,如果你是巨硬黨,裝一個VirtualBox吧,然後再裝個ubuntu,由於我們只是入個門,對性能要求不高的。
機器學習相關的框架也很多,我這裡選擇了Keras,後端採用的Tensorflow 。那麼理所當然的,會用到python來開發,沒有python經驗也莫慌,影響並不大。
1.ubuntu自帶python 我就不介紹怎麼安裝了吧?
先安裝pip(-dev
我用的python2.7,後文統一)打開你的終端,輸入這個:(我建議更換下apt-get為國內鏡像,安裝完pip後也更換為國內鏡像吧)
sudo apt-get install python-pip python
2.安裝tensorflow和keras,matplotlib
還是打開終端,輸入輸入
pip install tensorflow
pip install matplotlib
pip install keras
安裝完輸入 python 然後import測試下
你也可以測試下tensorflow,下面是個標準hello world
import tensorflow as tf
hello = tf.constant("Hello, TensorFlow!")
sess = tf.Session()
print(sess.run(hello))
你看,ubuntu下安裝環境這麼簡單,我不知道你為什麼不嘗試下。
卷積神經網路CNN淺析
我建議你先把CNN當作一個黑盒子,不要關心為什麼,只關心結果。
這裡借用了一個分辨X和o的例子來這裡看原文,就是每次給你一張圖,你需要判斷它是否含有"X"或者"O"。並且假設必須兩者選其一,不是"X"就是"O"。
下面看一下CNN是怎麼分辨輸入的圖像是x還是o,如果需要你來編程分辨圖像是x還是o,你會怎麼做?可能你第一時間就想到了逐個像素點對比。但是,如果圖片稍微有點變化呢?像是下面這個x,它不是標準的x,我們可以分辨它是x,但是對於計算機而言,它就只是一個二維矩陣,逐個像素點對比肯定是不行的。
CNN就是用於解決這類問題的,它不在意具體每個點的像素,而是通過一種叫卷積的手段,去提取圖片的特徵。
什麼是特徵?
特徵就是我們用於區分兩種輸入是不是同一類的分辨點,像是這個XXOO的例子,如果要你描述X和O的區別,你會怎麼思考?X是兩條線交叉,O是封閉的中空的。。。
我們來看個小小的例子,如果下面兩張圖,需要分類出喜歡和不喜歡兩類,那麼你會提取什麼作為區分的特徵?(手動滑稽)
卷積層
所以對於CNN而言,第一步就是提取特徵,卷積就是提取猜測特徵的神奇手段。而我們不需要指定特徵,任憑它自己去猜測,就像上圖,我們只需要告訴它,我們喜歡左邊的,不喜歡右邊的,然後它就去猜測,區分喜不喜歡的特徵是黑絲,還是奶子呢?
假設,我們上面這個例子,CNN對於X的猜測特徵如上,現在要通過這些特徵來分類。
計算機對於圖像的認知是在矩陣上的,每一張圖片有rgb二維矩陣(不考慮透明度)所以,一張圖片,應該是3x高度x寬度的矩陣。而我們這個例子就只有黑白,所以可以簡單標記1為白,-1為黑。是個9x9的二維矩陣。
我們把上面的三個特徵作為卷積核(我們這裡是假設已經訓練好了CNN,訓練提出的特徵就是上面三個,我們可以通過這三個特徵去分類 X ),去和輸入的圖像做卷積(特徵的匹配)。
看完上面的,估計你也能看出特徵是如何去匹配輸入的,這就是一個卷積的過程,具體的卷積計算過程如下(只展示部分):
把計算出的結果填入新的矩陣
其他部分也是相同的計算
最後,我們整張圖用卷積核計算完成後:
三個特徵都計算完成後:
不斷地重複著上述過程,將卷積核(特徵)和圖中每一塊進行卷積操作。最後我們會得到一個新的二維數組。其中的值,越接近為1表示對應位置的匹配度高,越是接近-1,表示對應位置與特徵的反面更匹配,而值接近0的表示對應位置沒有什麼關聯。
以上就是我們的卷積層,通過特徵卷積,輸出一個新的矩陣給下一層。
池化層
在圖像經過以上的卷積層後,得到了一個新的矩陣,而矩陣的大小,則取決於卷積核的大小,和邊緣的填充方式,總之,在這個XXOO的例子中,我們得到了7x7的矩陣。池化就是縮減圖像尺寸和像素關聯性的操作,只保留我們感興趣(對於分類有意義)的信息。
常用的就是2x2的最大池。
看完上面的圖,你應該知道池化是什麼操作了。
通常情況下,我們使用的都是2x2的最大池,就是在2x2的範圍內,取最大值。因為最大池化(max-pooling)保留了每一個小塊內的最大值,所以它相當於保留了這一塊最佳的匹配結果(因為值越接近1表示匹配越好)。這也就意味著它不會具體關注窗口內到底是哪一個地方匹配了,而只關注是不是有某個地方匹配上了。
這也就能夠看出,CNN能夠發現圖像中是否具有某種特徵,而不用在意到底在哪裡具有這種特徵。這也就能夠幫助解決之前提到的計算機逐一像素匹配的死板做法。
同樣的操作以後,我們就輸出了3個4x4的矩陣。
全連接層
全連接層一般是為了展平數據,輸出最終分類結果前的歸一化。 我們把上面得到的4x4矩陣再卷積+池化,得到2x2的矩陣
全連接就是這樣子,展開數據,形成1xn的"條"型矩陣。
然後再把全連接層連接到輸出層。之前我們就說過,這裡的數值,越接近1表示關聯度越大,然後我們根據這些關聯度,分辨到底是O還是X.
看上圖(圈圈裡面的幾個關鍵信息點),這裡有個新的圖像丟進我們的CNN了,根據卷積&>池化&>卷積&>池化&>全連接的步驟,我們得到了新的全連接數據,然後去跟我們的標準比對,得出相似度,可以看到,相似度是X的為0.92 所以,我們認為這個輸入是X。
一個基本的卷積神經網路就是這樣子的。回顧一下,它的結構:
Relu是常用的激活函數,所做的工作就是max(0,x),就是輸入大於零,原樣輸出,小於零輸出零,這裡就不展開了。
CNN實現手寫數字識別
感覺,這個mnist的手寫數字,跟其他語言的helloworld一樣了。我們這裡來簡單實現下。首先,我建議你先下載好數據集,keras的下載太慢了(下載地址)。
下載好以後,按下面的位置放,你可能要先運行下程序,讓他自己創建文件夾,不然,你就手動創建吧。
新建個python文件,test.py然後輸入下面的內容
#coding: utf-8 from keras.datasets import mnist
import matplotlib.pyplot as plt
# 載入數據
(X_train, y_train), (X_test, y_test) = mnist.load_data()
# 展示下第一張圖
plt.imshow(X_train[0], cmap=plt.get_cmap("PuBuGn_r"))
plt.show()
運行後出來張圖片,然後關掉就行,這裡只是看看我們載入數據有沒有問題。
x_train,x_test是我們的圖像矩陣數據,是28x28大小,然後有12500條吧好像。然後y_train,y_test都是標籤數據,標明這張圖代表是數字幾。
#coding: utf-8 #Simple CNN import numpy
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.utils import np_utils
seed = 7
numpy.random.seed(seed)
#載入數據
(X_train, y_train), (X_test, y_test) = mnist.load_data()
# reshape to be [samples][channels][width][height] X_train = X_train.reshape(X_train.shape[0],28, 28,1).astype("float32")
X_test = X_test.reshape(X_test.shape[0],28, 28,1).astype("float32")
# normalize inputs from 0-255 to 0-1 X_train = X_train / 255 X_test = X_test / 255 # one hot encode outputs y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)
num_classes = y_test.shape[1]
# 簡單的CNN模型
def baseline_model():
# create model model = Sequential()
#卷積層
model.add(Conv2D(32, (3, 3), padding="valid", input_shape=(28, 28,1), activation="relu")) #池化層
model.add(MaxPooling2D(pool_size=(2, 2)))
#卷積
model.add(Conv2D(15, (3, 3), padding="valid" ,activation="relu")) #池化
model.add(MaxPooling2D(pool_size=(2, 2)))
#全連接,然後輸出
model.add(Flatten())
model.add(Dense(128, activation="relu"))
model.add(Dense(num_classes, activation="softmax")) # Compile model
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
return model
# build the model model = baseline_model()
# Fit the model
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=10, batch_size=128, verbose=2)
代碼也挺簡單,因為keras也是封裝的挺好的了。基本你看懂了前面的就沒問題。
Epoch 1/10 3s - loss: 0.2791 - acc: 0.9203 - val_loss: 0.1420 - val_acc: 0.9579
Epoch 2/10 3s - loss: 0.1122 - acc: 0.9679 - val_loss: 0.0992 - val_acc: 0.9699
Epoch 3/10 3s - loss: 0.0724 - acc: 0.9790 - val_loss: 0.0784 - val_acc: 0.9745
Epoch 4/10 3s - loss: 0.0509 - acc: 0.9853 - val_loss: 0.0774 - val_acc: 0.9773
Epoch 5/10 3s - loss: 0.0366 - acc: 0.9898 - val_loss: 0.0626 - val_acc: 0.9794
Epoch 6/10 3s - loss: 0.0265 - acc: 0.9930 - val_loss: 0.0639 - val_acc: 0.9797
Epoch 7/10 3s - loss: 0.0185 - acc: 0.9956 - val_loss: 0.0611 - val_acc: 0.9811
Epoch 8/10 3s - loss: 0.0150 - acc: 0.9967 - val_loss: 0.0616 - val_acc: 0.9816
Epoch 9/10 4s - loss: 0.0107 - acc: 0.9980 - val_loss: 0.0604 - val_acc: 0.9821
Epoch 10/10 4s - loss: 0.0073 - acc: 0.9988 - val_loss: 0.0611 - val_acc: 0.9819
然後你就能看到這些輸出,acc就是準確率了,看後面的val_acc就行。
其他的參數那些,我建議你看看keras的文檔。然後,入門就結束了。如果你感興趣的話,就自己去摸索吧,後續我也可能會繼續分享相關的內容。
作者:矽谷周邊
鏈接:如何高效的學習TensorFlow代碼? - 矽谷周邊的回答
來源:知乎
著作權歸作者所有,轉載請聯繫作者獲得授權。
Google發布了Tensorflow遊樂場。Tensorflow是Google今年推出的機器學習開源平台。而有了Tensorflow遊樂場,我們在瀏覽器中就可以訓練自己的神經網路,還有酷酷的圖像讓我們更直觀地了解神經網路的工作原理。今天,就讓矽谷周邊帶你一起去Tensorflow遊樂場快樂地玩耍吧!
昨天,Google深度學習部門Google Brain的掌門人,也是Google里受萬眾景仰的神級別工程師Jeff Dean,在Google Plus上發布了Tensorflow遊樂場的消息:
於是小夥伴們都十分激動地去Tensorflow的網站上玩神經網路了!遊樂場的地址是:http://playground.tensorflow.org。讓我們快點一起去看看遊樂場里有哪些好玩的東東吧。
一打開網站,就看見上面的標語:
「在你的瀏覽器中就可以玩神經網路!不用擔心,怎麼玩也玩不壞哦!」
這簡直太令人振奮了!面對這麼多可以隨便點的按鈕,咱們從哪兒開始呢?
首先讓我們來看看數據。在這個遊樂場中,我們有4種不同形態的數據可以玩:
每組數據,都是不同形態分布的一群點。每一個點,都與生俱來了2個特徵:x1和x2,表示點的位置。而我們數據中的點有2類:橙色和藍色。我們的神經網路的目標,就是通過訓練,知道哪些位置的點是橙色、哪些位置的點是藍色。
如果橙色是橙子,藍色是藍莓。假設我們有2000個散落在各處的橙子和藍莓。前1000個,我們知道坐標(1,1)的是藍莓,(2,2)的是橙子,(0.5,0.5)的是藍莓等等。我們要用這些信息來訓練我們的神經網路,讓它能夠準確地預測出後1000個哪些是橙子、哪些是藍莓。
看上面的4組數據,我們會發現,前3中都能相對簡單地區分開,而最後一組螺旋數據會是最難的。
Tensorflow遊樂場中的數據十分靈活。我們可以調整noise(干擾)的大小,還可以改變訓練數據和測試數據的比例多少。下圖是不同noise的數據分布。
當我們把每一個數據點的信息餵給機器學習系統時,我們需要做feature extraction,也就是特徵提取。如果我們真的是在區分藍莓和橙子的話,大小、顏色等等都會是我們的特徵。而這裡,每一個點都有x1和x2兩個特徵。除此之外,由這兩個特徵還可以衍生出許多其他特徵:
抽象來說,我們的機器學習classifier(分類器)其實是在試圖畫一條或多條線。如果我們能夠100%正確地區分藍色和橙色的點,藍色的點會在線的一邊,橙色的會在另一邊。
上面這些圖其實非常的直觀。第一張圖中,如果x1作為我們的唯一特徵,我們其實就是在畫一條和x1軸垂直的線。當我們改變參數時,其實就是在將這條線左右移動。其他的特徵也是如此。
很容易可以看出,我們需要智能地結合這其中一種或多種的特徵,才能夠成功地將藍色點和橙色點分類。這樣的feature extraction,其實往往是機器學習應用中最難的部分。好在我們有神經網路,它能夠幫我們完成大部分的任務。
如果我們選定x1和x2作為特徵,我們神經網路的每一層的每個神經元,都會將它們進行組合,來算出結果:
而下一層神經網路的神經元,會把這一層的輸出再進行組合。組合時,根據上一次預測的準確性,我們會通過back propogation給每個組合不同的weights(比重)。這裡的線越粗,就表示比重越大:
下面就讓我們用最難的螺旋形數據,來試試這個神經網路的表現吧!
在神經網路出現前,我們往往會竭盡所能地想出儘可能好的特徵,把它們全都餵給系統。而系統會是個十分淺的系統,往往只有一層。用這樣的方法來完成分類。
讓我們先來實驗傳統的方法。在這裡,我們將所有能夠想到的7個特徵都輸入系統,並選擇只有1層的神經網路:
最後的結果是這樣的,可以看出我們的單層神經系統幾乎完美地分離出了橙色點和藍色點:
接下來,讓我們來體驗神經網路真正的魔法。神經網路最大的魔力,就在於我們根本不需要想出各種各樣的特徵,用來輸入給機器學習的系統。我們只需要輸入最基本的特徵x1, x2, 只要給予足夠多層的神經網路和神經元,神經網路會自己組合出最有用的特徵。
在這次試驗中,我們只輸入x1, x2,而選擇1個6層的,每層有8個神經元的神經網路:
最後的結果是這樣的。我們發現,通過增加神經元和神經網路的層數,即使沒有輸入許多特徵,我們也能夠成功地分類:
神經網路的偉大之處就在於此。當我們在解決分類橙色點和藍色點這樣的簡單問題時,想出額外的特徵似乎並不是難事。但是,當我們要處理的問題越來越複雜,想出有用的特徵就變成了最最困難的事。比如說,當我們需要識別出哪張圖片是貓,哪張圖片是狗時,哪些特徵是真正有效的呢?
而當我們有了神經網路,我們的系統自己就能學習到哪些特徵是有效的、哪些是無效的,這就大大提高了我們解決複雜機器學習問題的能力,簡直是太酷啦!
看了以上的文章,你是不是對神經網路有了更直觀的認識呢?好奇的小夥伴們,歡迎去http://playground.tensorflow.org/自己試試看,真的非常好玩!
http://weixin.qq.com/r/2Dno8IjEWNUnrcyT92zK (二維碼自動識別)
日本東京 TensorFlow 聚會聯合組織者 Hin Khor 曾寫過關於 TensorFlow 系列的介紹文章,前兩個部談到了單一特徵問題的線性回歸問題以及訓練(training)的含義,後兩個部分講解 了TensorFlow(TF)進行多個特徵的線性回歸和邏輯回歸。比較適合入門學習者閱讀。機器之心進行了完整的編譯,貼到這裡,希望對大家有幫助。原文鏈接點這裡。
(一)機器學習敲門磚:任何人都能看懂的TensorFlow介紹
(二)入門級解讀:小白也能看懂的TensorFlow介紹
第一部分
引言
我們要解決的是一個過於簡單且不現實的問題,但其好的一面是便於我們了解機器學習和 TensorFlow 的概念。我們要預測一個基於單一特徵(房間面積/平方米)的單標量輸出(房價/美元)。這樣做消除了處理多維數據的需要,使我們能夠在 TensorFlow 中只專註於確定、實現以及訓練模型。
機器學習簡介
我們從一組收集到的數據點開始(見下圖),每個數據點代表兩個值之間的關係——輸出(房價)與影響因素(房子面積)。
然而我們無法預測沒有數據點的特徵的值(見下圖)。
我們可以使用機器學習來挖掘它們之間的關係(見下圖的「最佳擬合預測曲線」),即給定一個不屬於數據點的特徵值,我們可以準確地預測出輸出(特徵值和預測線的交點)。
步驟一:選擇一個模型
1.模型種類
為了使用機器學習來做預測,我們需要選擇一個能夠擬合收集到的數據的最佳模型。
我們可以選擇一個線性(直線)模型,並通過改變其陡度/梯度和位置對其進行調整,從而匹配數據點。
我們也可以選擇一個指數(曲線)模型,並通過改變其曲率(curvature)和位置對其進行調整,從而匹配同一數據點集。
2.成本函數
為了比較哪個模型擬合得更嚴密,數學上我們將最佳擬合定義為一個需要被最小化的成本函數。 成本函數的一個簡單樣例是每個數據點所代表的實際輸出與預測輸出之間偏差的絕對值總和(實際結果到最佳擬合曲線的垂直投影)。用圖表表示,成本函數被描述為下表中藍色線段的長度和。
注意:更準確地說,成本函數往往是實際輸出和預測輸出之間的方差,因為差值有時是負數;這也稱為最小二乘法。
3.線性模型簡介
秉持簡潔精神,我們將使用線性模型來對數據點進行建模。線性模型的數學表示是:
y= W.x + b
Where:
x: house size, in sqm
y: predicted house price, in $
為了調整模型來更好地擬合數據點,我們可以這樣做:
- 調整 W 來改變線性模型的梯度
- 調整 b 來改變線性模型的位置
通過使用許多個 W、b 的值,最終我們可以找到一個最佳擬合線性模型,能夠將成本函數降到最小。
除了隨機嘗試不同的值,有沒有一個更好的方法來快速找到 W、b 的值?
4.梯度下降
如果你試圖從山上下降到最低點,你的視角就是這個樣子。
下降趨勢並不明顯!其最佳方式是執行梯度下降:
- 在當前位置以最陡的下降梯度確定方向
- 在該方向上採取步長 X
- 重複 刷新;這就是訓練過程
最小化成本函數是類似的,因為成本函數就像是起伏的山,我們想要找到其中的最低點,我們可以通過梯度下降類似地實現。
現在我們有了線性模型、成本函數和梯度下降的概念,可以開始使用 TensorFlow 了。
步驟二:在TensorFlow 中建立模型
1.TensorFlow 中的線性模型
TensorFlow 的2個基本組件是:
- 佔位符(Placeholder):表示執行梯度下降時將實際數據值輸入到模型中的一個入口點。例如房子面積 (x) 和房價 (y_)。
- 變數:表示我們試圖尋找的能夠使成本函數降到最小的「good」值的變數,例如 W 和 b。
然後 TensorFlow 中的線性模型 (y = W.x + b) 就是:
2.TensorFlow 中的成本函數
與將數據點的實際房價 (y_) 輸入模型類似,我們創建一個佔位符。
成本函數的最小方差就是:
3.數據
由於沒有房價(y_) 和房子面積 (x) 的實際數據點,我們就生成它們。
簡單起見,我們將房價 (ys) 設置成永遠是房子面積 (xs) 的 2 倍。
4.梯度下降
有了線性模型、成本函數和數據,我們就可以開始執行梯度下降從而最小化代價函數,以獲得 W、b 的「good」值。
0.00001 是我們每次進行訓練時在最陡的梯度方向上所採取的「步」長;它也被稱作學習率(learning rate)。
步驟三:訓練模型
訓練包含以預先確定好的次數執行梯度下降,或者是直到成本函數低於某個預先確定的臨界值為止。
1.TensorFlow 的怪異
所有變數都需要在訓練開始時進行初始化,否則它們可能會帶有之前執行過程中的殘餘值。
2.TensorFlow 會話
雖然 TensorFlow 是一個 Python 庫,Python 是一種解釋性的語言,但是默認情況下不把 TensorFlow 運算用作解釋性能的原因,因此不執行上面的 init 。相反 TensorFlow 是在一個會話中進行;創建一個會話 (sess) 然後使用 sess.run() 去執行。
類似地我們在一個循環中調用 withinsess.run() 來執行上面的 train_step。
你需要將由 x, y_ 所組成的實際數據輸入再提供給輸入,因為 TensorFlow 將 train_step 分解為它的從屬項:
從屬項的底部是佔位符 x,y_;而且正如我們之前提到的,tf.placeholders 是用來表示所要提供的實際數據點值房價 (y_) 和房子面積 (x) 的位置。
結果
循環中的 print 語句將顯示 TensorFlow 如何在每次迭代中學習 W 和 b 的「good」值。
小結
我們已經以最簡單的形式學習了機器學習;從一個單一特徵預測結果。(為簡單起見)我們選擇了一個線性模型來擬合我們的數據點,定義一個成本函數來表示最佳擬合,並通過反覆調整其梯度變數 W 與位置變數 b 來訓練我們的模型,使成本函數降到最小。
第二部分
簡單回顧
在上一部分,我們使用 TensorFlow 構建並學習了一個帶有單一特徵的線性回歸模型——給定一個特徵值(房屋面積/平方米),我們可以預測輸出(房價/美元)。
下面是一些總結:
- 我們有一些房屋面積和房價的數據(灰色點)
- 我們使用線性回歸對這些數據進行了建模(紅色虛線)
- 我們通過訓練該線性回歸模型的 W(權重)和 b(偏置)找到了最小化「成本」(豎直藍色實線的長度總和,這些藍線代表了預測和實際輸出之間的差異)的「最好」模型
- 給定任意房屋面積,我們可以使用該線性模型預測房價(帶箭頭的藍色虛線)
一張圖解釋線性回歸
在機器學習文獻中,我們常常看到「訓練(training)」這個詞。在這一部分,我們將在 TensorFlow 中理解「訓練」的含義。
線性回歸建模
Linear Model (in TF notation): y = tf.matmul(x,W) + b
線性回歸的目標是尋找 W 和 b,這樣對於給定的任意特徵值 x,我們可以通過將 W、b 和 x 的值代入到模型中得到預測 y。
但是為了找到能準確做出預測的 W 和 b 的值,我們需要使用可用的數據(許多實際特徵 x 和實際輸出 y_ 的配對,注意下劃線)來「訓練」該模型。
解釋「訓練」
為了找到最佳的 W 和 b 值,我們可以從任意的 W 和 b 值開始。我們也需要定義一個成本函數,該函數可以衡量對於一個給定特徵值 x 預測輸出 y 和實際輸出 y_ 之間差異。為了簡單起見,我們使用最簡單的最小均方誤差(MSE:minimum squared error)作為我們的成本函數。
Cost function (in TF notation): tf.reduce_mean(tf.square(y_ - y))
通過最小化成本函數,我們可以得到很好的 W 和 b 值。
我們的訓練代碼實際上非常簡單,並且用 [A, B, C, D] https://github.com/nethsix/gentle_tensorflow/blob/master/code/linear_regression_one_feature_using_mini_batch_with_tensorboard.py
# ... (省略) 變數/常量聲明 ...
# [A] TensorFlow圖
y = tf.matmul(x,W) + b
cost = tf.reduce_mean(tf.square(y_-y))# [B] 用固定「學習率(learn_rate)」訓練
learn_rate = 0.1
train_step =
tf.train.GradientDescentOptimizer(learn_rate).minimize(cost)for i in range(steps):
# [C] 準備數據點
# ... (省略) 準備作為x和y的數據點的代碼 ...# [D] 在每個步驟/epoch將數據送入"train_step"
feed = { x: xs, y_: ys }
sess.run(train_step, feed_dict=feed)
我們的線性模型和成本函數[A]可以表示成下面的 TensorFlow 圖:
創造一個帶有模型和成本函數的 TensorFlow 圖,並使用一些值初始化 W 和 b
接下來,我們選擇一個數據點 (x, y_) [C],然後將其送入[D] TensorFlow 圖,從而得到預測 y 和相應的成本。
使用單個數據點計算預測 y 和成本
為了得到更好的 W 和 b,我們使用TensorFlow 的 tf.train.GradientDescentOptimizer [B]執行梯度下降以降低成本。用非技術的術語來說:給定當前成本,並基於成本歲其它變數(即 W 和 b)的變化方式,優化器(optimizer)將對 W 和 b 執行一些小調整(遞增或遞減)以使我們的預測更好地契合那個單個數據點。
基於當前的成本,決定如何調整 W 和 b 以提升預測 y 和降低成本
訓練周期中的最後步驟是在調整 W 和 b 對它們進行更新。注意這裡的「周期」用機器學習的術語來說是「epoch」。
在下一訓練 epoch 的迭代前,通過調整 W 和 b 對它們進行更新
在下一訓練 epoch 中,重複這些步驟,但使用一個不同的數據點!
使用不同的數據點進行訓練
使用各種數據點泛化(generalize)我們的模型,即學習可被用於預測任何特徵值的 W 和 b 值。注意:
- 在大部分情況下,數據點越多,模型的學習和泛化就越好
- 如果你訓練的 epoch 比數據點還多,你可以重複使用數據點,這不成問題。梯度下降優化總是會同時使用數據點及其成本(根據該 epoch 的 W 和 b 值從數據點中計算得到)來對 W 和 b 值進行調整;該優化器也許之前已經見過了這個數據點,但成本並不一樣,因此它還是可以學到新的東西,並以不同的方式調整 W 和 b 值。
你可以用固定數量的 epoch 訓練一個模型,直到其達到令人滿意的成本閾值。
訓練變數
1.隨機、mini-batch、batch
在上面的訓練中,我們在每個 epoch 送入單個數據點。這被稱為隨機梯度下降(stochastic gradient descent)。我們也可以在每個 epoch 送入一堆數據點,這被稱為 mini-batch 梯度下降,或者甚至在一個 epoch 一次性送入所有的數據點,這被稱為 batch 梯度下降。請看下圖的比較,注意這 3 張圖的 2 處不同:
- 每個 epoch 送入 TensorFlow 圖(TF.Graph)的數據點的數量(圖右上方)
- 梯度下降優化在調整 W 和 b 值時所考慮的數據點的數量(圖右下方)
隨機梯度下降
mini-batch 梯度下降
batch 梯度下降
每張圖中的數據點的數量有 2 個含義。當數據點更多時:
- 計算成本和執行梯度下降所需的計算資源(減法、平方、加法)會增加
- 模型的學習和泛化的速度增加
選擇隨機、mini-batch、batch 梯度下降的優缺點總結在下圖中:
選擇隨機、mini-batch、batch 梯度下降的優缺點
要在隨機/mini-batch/batch 梯度下降之間切換,我們只需要在將數據點送入訓練步驟[D]之前將這些數據點分成不同的 batch 大小,即為 [C] 使用如下的代碼片段:
# * all_xs: 所有的特徵值
# * all_ys: 所有的輸出值
# datapoint_size: all_xs/all_ys 中點/項的數量
# batch_size: 配置如下:
# 1: 隨機模型
# integer &< datapoint_size: mini-batch模式
# datapoint_size: batch模式
# i: 當前epoch數量if datapoint_size == batch_size:
# Batch 模式,所以選擇所有數據點從 index 0 開始
batch_start_idx = 0
elif datapoint_size &< batch_size:
# 不可能
raise ValueError(「datapoint_size: %d, must be greater than
batch_size: %d」 % (datapoint_size, batch_size))
else:
# 隨機/mini-batch模式: 從所有可能的數據點中分批選擇數據點
batch_start_idx = (i * batch_size) % (datapoint_size — batch_size)
batch_end_idx = batch_start_idx + batch_size
batch_xs = all_xs[batch_start_idx:batch_end_idx]
batch_ys = all_ys[batch_start_idx:batch_end_idx]# 將分批的數據點定義為xs, ys, 它們會被送入 "train_step"訓練步驟
xs = np.array(batch_xs)
ys = np.array(batch_ys)
2.學習率變化
學習率(learn rate)是指梯度下降調整 W 和 b 遞增或遞減的速度。學習率較小時,處理過程會更慢,但肯定能得到更小成本;而當學習率更大時,我們可以更快地得到最小成本,但有「衝過頭」的風險,導致我們沒法找到最小成本。
為了克服這一問題,許多機器學習實踐者選擇開始時使用較大的學習率(假設開始時的成本離最小成本還很遠),然後隨每個 epoch 而逐漸降低學習率。
TensorFlow 提供了 2 http://stackoverflow.com/questions/33919948/how-to-set-adaptive-learning-rate-for-gradientdescentoptimizer;但這裡進行了總結。
- 使用梯度下降優化的變體
TensorFlow 帶有多種支持學習率變化的梯度下降優化器,例如 tf.train.AdagradientOptimizer 和 tf.train.AdamOptimizer.
- 使用 tf.placeholder 調整學習率
如同前面所看到的,如果我們在這個例子中聲明了 tf.placeholder 來設置學習率,然後在 tf.train.GradientDescentOptimizer 中使用它,我們可以在每個訓練 epoch 向其送入一個不同的值,這很像我們給 x 和 y_ 送入不同的數據點,這也是每個 epoch 的 tf.placeholders.
我們需要 2 個小修改:
# 修改 [B] ,將 "learn_rate" 設置為"tf.placeholder"
# 並將其提供給"learning_rate"參數名tf.train.GradientDescentOptimizer
learn_rate = tf.placeholder(tf.float32, shape=[])
train_step = tf.train.GradientDescentOptimizer(
learning_rate=learn_rate).minimize(cost)# 修改[D],包含送入一個"learn_rate"值,
# 即 "initial_learn_rate"(初始學習率)除以"i" (當前epoch數)
# 注: 這是過於簡化的,僅用作示例
feed = { x: xs, y_: ys, learn_rate: initial_learn_rate/i }
sess.run(train_step, feed_dict=feed)
小結
我們解釋了機器學習中「訓練(training)」的含義,以及在 TensorFlow 中通過模型和成本定義、然後循環通過訓練步驟(將數據點送入梯度下降優化器)來進行訓練的方式。我們還討論了訓練中的常見變數,即改變模型學習時每個 epoch 所用的數據點的大小和改變梯度下降優化器的學習率。
第三部分:矩陣和多特徵線性回歸
快速回顧
之前文章的前提是:給定特徵——任何房屋面積(sqm),我們需要預測結果,也就是對應房價($)。為了做到這一點,我們:
- 我們找到一條「最擬合」所有數據點的直線(線性回歸)。「最擬合」是當線性回歸線確保實際數據點(灰色點)和預測值(內插在直線上的灰色點)之間的差異最小,即最小化多個藍線之和。
- 使用這條直線,我們可以預測任何房屋的價格。
使用單一特徵線性回歸進行預測
多特徵線性回歸概述
實際上,任何預測都依賴於多個特徵,於是我們從單特徵的線性回歸進階到 帶有兩個特徵的線性回歸;之所以選擇兩個特徵,是為了讓可視化和理解簡明些,但這個思想可以推廣到帶有任何數量特徵的線性回歸。
我們引進一個新的特徵——房間數量。當收集數據點時,現在我們需要在現有特徵「房屋面積」之上收集新特徵「房間數」的值,以及相應的結果「房屋價格」。
我們的圖表變成了 3 維的。
結果「房屋價格」以及 2 個特徵(「房間數」,「房屋面積」)的數據點空間
然後,我們的目標變成:給定「房間數」和「房屋面積」,預測「房屋價格」(見下圖)。
由於缺少數據點,有時無法對給定的 2 個特徵進行預測
在單一特徵的情形中,當沒有數據點時,我們需要使用線性回歸來創建一條直線,以幫助我們預測結果房屋價格。在 2 個特徵的情形中,我們也可以使用線性回歸,但是需要創建一個平面(而不是直線),以幫助我們預測(見下圖)。
使用線性回歸在 2 個特徵空間中的創建一個平面來做預測
多特徵線性回歸模型
回憶單一特徵的線性回歸(見下圖左邊),線性回歸模型結果為 y,權重為 W,房屋大面積為 x,偏差為 b。
對於 2 個特徵的回歸(參見下圖右側),我們引入另一個權重 W2,另一個自變數 x2 來代表房間數的特徵值。
單特徵 vs. 2 個特徵的線性回歸方程
如之前討論的那樣,當我們執行線性回歸時,梯度下降演算法能幫助學習係數 W、W2 和 b 的值。
Tensorflow 的多特徵線性回歸
1.快速回顧
單特徵線性回歸的 TF 代碼由 3 部分組成(見下圖):
- 構建模型(藍色部分)
- 基於模型構建成本函數(紅色部分)
- 使用梯度下降(綠色部分)最小化成本函數
用於單特徵線性回歸的 Tensorflow 代碼
2.Tensorflow 的 2 個特徵的線性回歸
TF 代碼中 2 個特徵的線性回歸方程(如上所述)的變化(相比單特徵)用紅色顯示。
注意,增加新特徵的這種方式效率低;隨著特徵數量的增長,所需的變數係數和自變數的數量會增加。實際的模型有更多的特徵,這惡化了這個問題。那麼,如何能有效地表示特徵呢?
解決方法:矩陣
首先,讓我們將表徵兩個特徵的模型推廣到表徵 n 個特徵的模型:
複雜的 n 特徵公式可以用矩陣簡化,矩陣被內置於 TF 中,這是因為:
- 數據可以用多維表示,這契合我們表徵具有 n 個特徵的數據點(左下方,也稱為特徵矩陣)以及具有 n 個權重模型(右下,也稱為權重矩陣)的方式
單個數據點的 n 個特徵與模型的矩陣形式的 n 個權重
在 TF 中,它們將被寫為:
x = tf.placeholder(tf.float,[1,n])
W = tf.Variable(tf.zeros [n,1])
注意:對於 W,我們使用 tf.zeros,它將所有 W1,W2,...,Wn 初始化為零。
- 在數學上,矩陣乘法是向量乘法的加總;因此自然地,特徵(中間的一個)和權重(右邊的)矩陣之間的矩陣乘法給出(左邊的)結果,即等於 n 個特徵的線性回歸公式的第一部分(如上所述),沒有截距項。
特徵和權重矩陣之間的矩陣乘法給出結果(未添加截距項)
在 TF 中,這種乘法將表示為:
y = tf.matmul(x, W)
- 多行特徵矩陣(每行表示數據點的 n 個特徵)之間的矩陣乘法返回多行結果,每行代表每個數據點的結果/預測(沒有加入截距項);因此一個矩陣乘法就可以將線性回歸公式應用於多個數據點,並對應地產生多個預測(每個數據點對應一個結果)(見下文)
注意:特徵矩陣中的 x 表示變的更複雜,即我們使用 x1.1、x1.2,而不是 x1、x2 等,因為特徵矩陣(中間矩陣)從表示 n 個特徵(1 行 x,n 列)的單個數據點擴展到表示具有 n 個特徵(m 行 x,n 列)的 m 個數據點。因此,我們擴展 x &
具有模型權重的多行矩陣乘法產生矩陣的多個行結果
在 TF 中,它們將被寫為:
x = tf.placeholder(tf.float,[m,n])
W = tf.Variable(tf.zeros [n,1])
y = tf.matmul(x,W)
- 最後,向結果矩陣添加常數,也就是將常數添加到矩陣中的每一行
在 TF 中,用矩陣表示 x 和 W,無論模型的特徵數量或要處理的數據點數量,矩陣都可以簡化為:
b = tf.Variable(tf.zeros[1])
y = tf.matmul(x, W) + b
Tensorflow 的多特徵備忘單
我們做一個從單一特徵到多特徵的線性回歸的變化的並行比較:
Tensorflow 中的單特徵與 n 個特徵的線性回歸模型
總結
在本文中,我們介紹了多特徵線性回歸的概念,並展示了我們如何將模型和 TF 代碼從單特徵的線性回歸模型擴展到 2 個特徵的線性回歸模型,並可以推廣到 n 特徵線性回歸模型。最後我們為多特徵的 TF 線性回歸模型提供了一張備忘單。
第四部分:邏輯回歸
邏輯回歸綜述
我們已經學會了如何使用 Tensorflow(TF)去實現線性回歸以預測標量值得結果,例如給定一組特徵,如住房大小,預測房價。
然而,有時我們需要對事物分類(classify)而不是去預測一個具體的數值,例如給定一張含有數字(0-9 十個數字中的一個)的圖片,我們需要將其分類為 0,1,2,3,4,5,6,7,8,9 十類。或者,我們需要將一首歌曲進行歸類,如歸類為流行,搖滾,說唱等。集合 [0,1,2,...,9]、[流行,搖滾,說唱,等等] 中的每一個元素都可以表示一個類。在計算機中,我們通常用數字對抽象名詞進行表示,比如,pop = 0, rock = 1, 等等。為了實現分類,我們使用 TF 來實現邏輯回歸。
在本文中,我們將使用邏輯回歸將數字圖片歸類為 0,1,2,3,4,5,6,7,8,9 這十類。
邏輯回歸的細節
線性回歸中的許多概念仍然用於邏輯回歸之中。我們可以再次使用公式 y = W.x + b,但是有一些不同的地方。讓我們看看線性回歸和邏輯回歸的公式:
線性回歸與邏輯回歸的區別與相似
區別:
- 結果(y):對於線性回歸,結果是一個標量值(可以是任意一個符合實際的數值),例如 50000,23.98 等;對於邏輯回歸,結果是一個整數(表示不同類的整數,是離散的),例如 0,1,2,... 9。
- 特徵(x):對於線性回歸,特徵都表示為一個列向量;對於涉及二維圖像的邏輯回歸,特徵是一個二維矩陣,矩陣的每個元素表示圖像的像素值,每個像素值是屬於 0 到 255 之間的整數,其中 0 表示黑色,255 表示白色,其他值表示具有某些灰度陰影。
- 成本函數(成本):對於線性回歸,成本函數是表示每個預測值與其預期結果之間的聚合差異的某些函數;對於邏輯回歸,是計算每次預測的正確或錯誤的某些函數。
相似性:
- 訓練:線性回歸和邏輯回歸的訓練目標都是去學習權重(W)和偏置(b)值。
- 結果:線性回歸與邏輯回歸的目標都是利用學習到的權重和偏置值去預測/分類結果。
協調邏輯回歸與線性回歸
為了使邏輯回歸利用 y = W.b + x,我們需要做出一些改變以協調上述差異。
1.特徵變換,x
我們可以將二維的圖片特徵(假設二維特徵有 X 行,Y 列)轉換成一維的行向量:將第一行以外的其它行數值依順序放在第一行後面。
轉換圖像特徵以適用於邏輯回歸公式
2.預測結果轉換,y
對於邏輯回歸,y 不能作為標量,因為預測可能最終為 2.3 或 11,這不在可能的類 [0,1,...,9] 中。
為了解決這個問題,y 應該被轉換成列向量,該向量的每個元素代表邏輯回歸模型認為屬於某個特定類的得分。在下面的示例中,預測結果為類"1",因為它具有最高得分。
每個類的分數和具有最高分數的類成為被預測的類
對於給定的圖片,為求這個分數向量,每個像素都會貢獻一組分數(針對每一類),分數表示系統認為這張圖片屬於某類的可能性,每個像素分數之和成為預測向量。
每個像素提供一個分數向量;每個類別有一個分數,最後變成預測向量。所有預測向量的總和變成最終預測。
3.成本函數的變換
涉及到預測結果和實際結果之間數值距離的任何函數都不能作為成本函數。對於數字圖片「1」,這樣的成本函數將使預測值「7」(7-1=6)更嚴重地懲罰預測值「2」(2-1=1),儘管兩個預測結果都是錯誤的。
我們即將使用的成本函數,交叉熵(H),用以下幾個步驟實現:
1. 將實際圖片的類向量(y")轉化成 one-hot 向量,這是一個概率分布。
2. 將預測類 (y) 轉化成概率分布。
3. 使用交叉熵函數去計算成本函數,這表示的是兩個概率分布函數之間的差異。
第一步:One-hot 向量
由於我們已經將預測 (y) 轉換成分數向量,因此,我們也應該將實際圖片類(y』)轉換成相同維數的向量;one-hot 向量是將對應於實際類的的元素為設為 1,其它元素為 0。下面,我們展示表示 0-9 十個類中一個類的 one-hot 向量。
圖片類和它們的 one-hot 向量表示
假設實際圖像上是數字「1」(y"),它的 one-hot 向量是 [0,1,0,0,0,0,0,0,0,0],假設其預測向量 (y) [1.3, 33, 2, 1.2, 3.2, 0.5, 3, 9.2, 1],繪製比較如下:
真實圖片 one—hot 向量(頂)預測類別概率
第二步:用 softmax 實現概率分布
為了在數學上比較這兩個「圖」的相似性,交叉熵是一個好方法。(這裡是一個很棒但比較長的解釋,如果你對細節感興趣的話。https://colah.github.io/posts/2015-09-Visual-Information/)
然而,為了利用交叉熵,我們需要將實際結果向量(y")和預測結果向量(y)轉換為「概率分布」,「概率分布」意味著:
- 每個類的概率/分數值在 0-1 之間;
- 所以類的概率/分數和必須是 1;
實際結果向量(y")如果是 one-hot 向量,滿足了上述限制。
為預測結果向量(y), 使用 softmax 將其轉換為概率分布:
softmax 函數,這裡 i 是表示 0, 1, 2, …, 9 十類
這個過程只需要簡單的兩步,預測向量(y)中的每個分量是 exp(y_i) 除以所有分量的 exp() 的和。
注意:softmax(y)圖形在形狀上與 prediction (y) 相似,但是僅僅有較大的最大值和較小的最小值
使用 softmax 前後預測(y)曲線
第三步:交叉熵
現在,我們將預測向量分數概率分布(y")和實際向量分數概率分布 (y) 運用交叉熵。
交叉熵公式:
交叉熵作為我們想最小化的成本函數
為了快速理解這個複雜的公式,我們將其分為 3 部分(見下文)。注意,本文中的符號,我們使用 y_i 表示 y 的第 i 個分量。
交叉熵(H)公式可視為三個部分:紅,藍,綠
- 藍:實際圖像類(y")對應的 one-hot 圖,參看 one-hot 向量部分:
- 紅:由預測向量元素(y)經過softmax(y),-og(softmax(y)一系列變化而來:
- 綠:每一圖片類別 i,其中,i = 0, 1, 2, …, 9, 紅藍部分相乘的結果
以下圖例會進一步簡化理解。
藍色製圖只是真實圖片類別(y")one-hot 向量。
每個預測向量元素,y,轉換成 -log(softmax(y),就得到紅圖:
預測類別向量(y)一系列轉換後,得到紅圖
如果你想完全地理解第二個變換 -log(softmax(y)) 與 softmax(y) 為什麼成反比,請點擊 video or slides(參見文末資源部分).
交叉熵(H),這個綠色的部分是每個類別的藍色值和紅色值的乘積和,然後將它們做如下相加:
交叉熵是每個圖像類的藍色值和紅色值的乘積之和。
由於這張藍色圖片對應一個 one-hot 向量,one-hot 向量僅僅有一個元素是 1,它對應一個正確的圖片類,交叉熵的其它所有元素乘積為 0,交叉熵簡化為:
將所有部分放到一起
有了三個轉換後,現在,我們就可以將用於線性回歸的技術用於邏輯回歸。下面的代碼片段展示的是本系列文章第三部分線性回歸代碼和代碼適用邏輯回歸所需要的變化之間的對比。
邏輯回歸的目標是最小化交叉熵(H),這意味著我們只需要最小化 -log(softmax(y_i)項;因為該項與 softmax(y_i)成反比,所以我們實際上是最大化該項。
使用反向傳播去最小化交叉熵 (H ) 將改變邏輯回歸的權重 W 和偏置 b。因此,每張圖片的像素值將會給出對應圖片類最高分數/概率!(最高分數/概率對應於正確的圖片類)
將線性回歸方法用於邏輯回歸之中,「total_class」是欲分類問題的總類數量,例如,在上文手寫數字體識別例子中,total_class=10。
1. 將特徵變換成一維特徵;
2. 將預測結果向量、實際結果向量變化成 one-hot 向量;
3. 將成本函數從平方誤差函數變化到交叉熵。
總結
線性回歸對基於給定特徵的預測(數值)是有幫助的,邏輯回歸根據輸入特徵實現分類是有幫助的。
我們展示了如何調整線性回歸 y = W.x + b 實現邏輯回歸:(1)轉換特徵向量;2)轉換預測/結果向量;(3)轉換成本函數。
當你掌握了 one-hot 向量,softmax,交叉熵的知識,你就可以處理谷歌上針對「初學者」的圖片分類問題。
資源:
- 針對初學者的圖像識別的谷歌代碼:https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/mnist/mnist_softmax.py
- slideshare 上的幻燈片:http://www.slideshare.net/KhorSoonHin/gentlest-introduction-to-tensorflow-part-3
- https://www.youtube.com/watch?v=F8g_6TXKlxw
文章來源於微信公眾號:機器之心(almosthuman2014),如需轉載,請私信聯繫。
TensorFlow基本用法 - 知乎專欄
Tensorflow代碼演示LV1 · 超智能體 (看不了gitbook請看代碼演示LV1)
Tensorflow實現神經網路(2) - 知乎專欄
Tensorflow實現深層學習完備流程 - 知乎專欄
循環神經網路(Recurrent)--介紹 - 知乎專欄
循環神經網路--實現LSTM
循環神經網路--scan實現LSTM
循環神經網路--雙向LSTM、GRU
卷積神經網路--介紹
TensorFlow基本用法
從這裡開始,我們會用神經網路驗證之前討論的內容。用的工具是目前主流的TensorFlow。用tensorflow這樣工具的原因是:它允許我們用計算圖(Computational Graphs)的方式建立網路。同時又可以非常方便的對網路進行操作。下面就是對計算圖的直觀講解。
- 注:看完這部分內容的人,可以緊接著實現一個神經網路:代碼演示LV1。
比喻說明:
- 結構:而計算圖所建立的只是一個網路框架。在編程時,並不會有任何實際值出現在框架中。所有權重和偏移都是框架中的一部分,初始時至少給定初始值才能形成框架。因此需要initialization初始化。
- 比喻:計算圖就是一個管道。編寫網路就是搭建一個管道結構。在投入實際使用前,不會有任何液體進入管道。而神經網路中的權重和偏移就是管道中的閥門,可以控制液體的流動強弱和方向。在神經網路的訓練中,閥門會根據數據進行自我調節、更新。但是使用之前至少要給所有閥門一個初始的狀態才能形成結構。用計算圖又允許我們可以從任意一個節點處取出液體。
用法說明:
請類比管道構建來理解計算圖的用法
構造階段(construction phase):組裝計算圖(管道)
- 計算圖(graph):要組裝的結構。由許多操作組成。
- 操作(ops):接受(流入)零個或多個輸入(液體),返回(流出)零個或多個輸出。
- 數據類型:主要分為張量(tensor)、變數(variable)和常量(constant)
- 張量:多維array或list(管道中的液體)
- 創建語句: tensor_name=tf.placeholder(type, shape, name)
- 變數:在同一時刻對圖中所有其他操作都保持靜態的數據(管道中的閥門)
- 創建語句: name_variable = tf.Variable(value, name)
- 初始化語句:#個別變數
init_op=variable.initializer()
#所有變數
init_op=tf.initialize_all_variables()
#注意:init_op的類型是操作(ops),載入之前並不執行 - 更新語句: update_op=tf.assign(variable to be updated, new_value)
- 常量:無需初始化的變數
- 創建語句:name_constant=tf.constant(value)
執行階段(execution phase):使用計算圖(獲取液體)
- 會話:執行(launch)構建的計算圖。可選擇執行設備:單個電腦的CPU、GPU,或電腦分散式甚至手機。
- 創建語句:#常規
sess = tf.Session()
#交互
sess = tf.InteractiveSession()
#交互方式可用tensor.eval()獲取值,ops.run()執行操作
#關閉
sess.close() - 執行操作:使用創建的會話執行操作
- 執行語句:sess.run(op)
- 送值(feed):輸入操作的輸入值(輸入液體)
- 語句:sess.run([output], feed_dict={input1:value1, input2:value1})
- 取值(fetch):獲取操作的輸出值(得到液體)
- 語句:#單值獲取
sess.run(one op)
#多值獲取
sess.run([a list of ops])
更多內容參考官網文檔
6月26日更新,增加TensoFlow實踐視頻教程:
《如何使用TensorFlow技術基於阿里雲AI實現圖像識別技術?視頻+PPT乾貨奉上》
在5月22日和6月13日,阿里雲機器學習分別在鬥魚直播上分享了如何使用TensorFlow技術實現圖像識別的技術直播。小編特意將視頻地址以及將以PPT在這裡編輯分享出來,本次技術講解分為上下兩部分:基礎篇和高級篇,在機器學習圖像識別初入、進階的同學均適合觀看學習,其中視頻中的PPT講義已經為各位同學保存發布到正文中,可以作為提前預覽:
一、阿里雲AI之圖像識別實踐-基礎篇:
講師簡介:趙昆,阿里巴巴機器學習技術專家
視頻觀看地址:
http://cloud.video.taobao.com/play/u/2339185383/p/1/e/6/t/1/56328343.mp4視頻講義資料:(圖片PPT),請點擊到知乎原文查看:如何使用TensorFlow技術基於阿里雲AI實現圖像識別技術?視頻+PPT乾貨奉上 - 知乎專欄
二、阿里雲AI之圖像識別實踐-高級篇:
視頻觀看地址:
講師簡介:趙昆,阿里巴巴機器學習技術專家
視頻講義資料:(圖片PPT),請點擊到知乎原文查看:如何使用TensorFlow技術基於阿里雲AI實現圖像識別技術?視頻+PPT乾貨奉上 - 知乎專欄
------------------------------華麗的分割線-----------------------------------
如何開始學習使用TensorFlow? Harrison Kinsley ——http://PythonProgramming.net的創始人
TensorFlow官方網站有相當多的文檔和教程,但這些往往認為讀者掌握了一些機器學習和人工智慧知識。除了知道ML和AI,你也應該對Python編程語言非常熟練。因此,在開始學習如何使用TensorFlow前,首先學習更多的Python語言,而不是與機器學習直接相關的任何東西。 1、假設熟練Python,但不會機器學習,那麼可以查看這個機器學習實踐w / Python教程,其中涵蓋了與機器學習相關的概念、演算法、理論、應用程序等; 2、如果已經掌握了Python和機器學習的基礎知識,但還不知道Deep Learning / TensorFlow,那麼可以從神經網路介紹部分開始 。 3、如果已經知道神經網路/深度學習,那麼可以從安裝TensorFlow教程開始,或者可以從TensorFlow基礎教程開始,這將直接導致實際建模一個深層神經網路。
Parag K Mital ——Kadenze Inc.機器智能總監
剛剛推出了一個關於Tensorflow的新課程:使用TensorFlow |創建深度學習應用程序 Kadenze與其他課程不同,這是一個以應用為導向的課程,通過鼓勵探索創造性思維和深層神經網路的創造性應用,教你Tensorflow的基礎知識以及最先進的演算法,強烈鼓勵嘗試這門課程。這是唯一全面的在線課程,將教會你如何使用Tensorflow和開發您的創造潛力,了解如何應用這些技術創建神經網路。
課程資料:
本課程將介紹深度學習:構建人工智慧演算法的最先進的方法。涵蓋深度學習的基本結構、意義,原理並開發必要的代碼搭建各種演算法,如深卷積網路,變分自動編碼器,生成對抗網路和循環神經網路。本課程的主要重點是了解如何構建這些演算法的必要結構以及如何應用它們來探索創意應用程序。
計劃表學期1:Tensorflow簡介
介紹數據與機器和深度學習演算法的重要性,創建數據集的基礎知識,如何預處理數據集,然後跳轉到Tensorflow。此外將學習Tensorflow的基本結構,並了解如何使用它來過濾圖像。
學期2:訓練一個網路W / Tensorflow
將看到神經網路如何工作,網路是如何「訓練」。然後將構建自己的第一個神經網路,並將其用於訓練神經網路如何繪製圖像的應用程序。
學期3:無監督和監督學習
探索能夠編碼大型數據集的深層神經網路,並了解如何使用此編碼來探索數據集的「潛在」維度或生成全新內容。還將學習另一種類型的執行辨別學習的模型,並了解如何使用它來預測圖像的標籤。
學期4:可視化和幻化表示
指導執行一些真正有趣的可視化,包括可以產生無限生成分形的「深度夢想」或者「風格網路」,它允許我們將一個圖像的內容和另一個圖像的風格結合起來自動生成藝術美學。
學期5:生成模型
最後提供了一些未來生成建模方向的預測,包括一些現有技術模型,例如「生成式對抗網路」,以及其在「變分自動編碼器」內的實現等內容。
Antonio Cangiano ——IBM軟體開發和技術推廣
大數據大學剛剛推出了一個免費的深層學習與TensorFlow課程。顯然還有其他有效的資源可用,但建議你看一下本課程。同樣查看目錄中的其他數據科學和機器學習課程。課程是完全免費的,並且許多都有完成證書和IBM支持的開放徽章。
Ian Dewancker ——SigOpt研究工程師
最好的學習方式可能是通過學習和實驗一個工作過的例子。在SigOpt有一個工作是通過TensorFlow示例調整一個卷積神經網路,該工程在github頁面鏈接:sigopt / sigopt-examples 下面簡短的視頻教程講授如何創建一個能夠運行TensorFlow代碼的AWS環境。該視頻還概述了並行探索CNN配置的簡單策略。 https://youtu.be/CGI_RKVnDpE
Ish Girwan ——在印度管理學院學習
作為初學者,可以使用以下資源: 學習TensorFlow aymericdamien / TensorFlow-Examples nlintz / TensorFlow-Tutorials Google TensorFlow教程 機器智能的開源軟體庫
Kuntal Mukherjee ——在Wipro Technologies工作
如果你是初學者,建議按照以下步驟學習: 1 首先快速學習Python。 2 學習AI和機器學習課程,可以嘗試MIT OCW。 3 從TensorFlow網站教程開始。如果你已經在這個領域經歷過,那麼可以去步驟(3)開始學習更高級教程。
Rodolfo Bonnin ——建築機器學習項目與Tensorflor 作家
最簡單的方法之一是查看和修改一些代碼示例與額外的注釋; https://github.com/tobigithub/tensorflow-deep-learning/wiki
Ankit Sachan ——http://Ilenze.com的創始人
在開始的時候遇到了一些與困難。所以創造了一系列的教程。教程在Linkedin計算機視覺組上變得非常流行。 10分鐘實用TensorFlow快速學習教程?CV-Tricks.com
Angel Mario Castro Martinez ——在馬克斯普朗克學會工作
對我來說,最好的起點是主頁本身: http://www.tensorflow.org/versio ... 安裝並習慣了如何處理數據和訓練模型的方式,你可以嘗試MNIST教程或其他幾個教程: https://github.com/kronos-cm/Ten... https://github.com/jasonbaldridg... 如果正在尋找一個壓縮版本的上述主題,可以嘗試: https://medium.com/@ilblackdrago...
Suraj Vantigodi ——在印度班加羅爾理工學院工作
一個有用的鏈接學習TensorFlow,一旦完成後可以去Udacity課程深度學習| Udacity。
Kim Brian ——5年計算機編程經驗
除了使用TensorFlow,有很多其它可能的解決方案。如果你是一個熱心編碼的人,建議不要使用TensorFlow,直到你知道如何編碼基本的AI。 正如Kuntal Mukherjee先生所說,建議從基礎知識中學習。
Chirila Sorina ——在Iasi計算機科學學院學習
請查看以下兩個答案: TensorFlow(開源s / w庫):如何使用張量流,什麼是更好地了解它的最佳方式? 使用TensorFlow處理自然語言的具體步驟有哪些?
Ashwin D Kini ——喜歡閱讀的Web開發人員
猜猜你沒有訪問過這個網站: http://www.tensorflow.org/tutori... 對於初學者: http://www.tensorflow.org/tutori...
Tuan Vu ——數據據科學家
如果你想了解張量流的基本結構,這個網站可能有幫助:學習TensorFlow Kishore Karunakaran ——Vanenburg Software高級軟體工程師 Tensorflow的教程:學習TensorFlow
Lifu Yi ——Mindx.ai的首席執行官
等待下一個更好的版本再學習它,當前版本的結構導致其糟糕的績效考核。
原文鏈接:實踐指南!16位資深行業者教你如何學習使用TensorFlow-博客-雲棲社區-阿里雲
補更,youku可以搜到「tensorflow 莫煩」
============================
親測Youtube視頻,很好理解,正在學習ing:
https://www.youtube.com/watch?v=vZ263nfbh8gindex=2list=PLXO45tsB95cKI5AIlf5TxxFPzb-0zeVZ8
- 視頻是Beginner學習的最佳方式,沒有之一。圖像化的學習方式可以極大的降低cognitive process的壓力,減少cognitive load,增加學習速度。說讀書好用的都是高水平學習者。文字本身就是非常抽象的東西,人腦在理解的時候就是要花費額外的認知資源,用剩下的資源來學習,效果只會事倍功半。
- 每個視頻只講解最基本的東西,時長不到10分鐘,在人的注意力極限範圍當中。
- 視頻是中文的,母語習得的速度肯定比外語的快啊。
- 嫌慢可以雙倍速度。
學這個之前看一下Andrew Ng在coursera上面的Linear Regression, Logistic Regression 和Neuro Network打個基礎就好。
簡單評論一下樓上所有答案,站在一個不懂反向傳播演算法工作原理(看到數學公式會不自主跳過),懂sklearn,並理解了大部分Machine Learning演算法的工作原理的人,你們提的方案大部分學習曲線太陡峭了。我關心的是能像用sklearn一樣上來就能擼,工作原理可以慢慢理解,怎麼高效調參、怎麼配置隱藏層可以以後慢慢學。
看官方文檔?這不跟看高數教材一樣,看不懂的地方都不知道怎麼找資料不說,就算看懂了也不一定能擼出一個能用的東西,很打擊學習積極性的。
玩Tensorflow Playground,是一個很好的開始。能對Tensorflow有一個感性的認識,但還是擼不出東西,除了看著爽,對於真正學懂背後的原理幫助不大。沒有否定playground的意思,在看過Andrew Ng講解神經網路的視頻之後,再玩playground,可以更直觀的了解神經網路的工作原理。但如果不懂,目測也就是玩玩。能理解weight到底是啥么?知道怎麼優化的么?為啥初始化weight的時候最好是ramdomize的?很多問題光玩是想不出來的,只有懂了基本原理才有可能能夠玩出花樣來。
學完了之後補更。入門 !入門 !入門 !為什麼我感覺按照題目下面的這些答案走下來就變成『精通』了呢?當然也可能跑偏了直奔"放棄』那條路上。作為一個貨真價實的渣渣水平,我就要不請自來的談談我的兩周入門過程了。
首先聲明,此答案辭藻不華麗、邏輯不清晰而且極可能有錯誤,結論就是『慎讀』。為啥?因為我剛入門,還沒有大局觀。敬請諒解。
一周之前我連tensorflow、scikit-learn是什麼都不清楚,也不知道數據挖掘分為傳統機器學習(scikit-learn)跟深度學習(tensorflow),但是不重要嘛,偉大的毛主席教導我們「戰略上藐視敵人,戰術上重視敵人」,不就是工具么,不會造輪子了,本姑娘還不會用輪子么?
不知道會不會有人質疑,人家問tensorflow,你說什麼scikit-learn,我回答就是找感覺,畢竟機器學習比深度學習看起來更接地氣一些。我先在我的電腦上安裝了,numpy、scipy、matplotlib這幾個基礎的python庫,然後numpy的基礎用法自己敲了一遍(用Python做科學計算 - 用Python做科學計算)。為啥,因為我首先要知道矩陣也就是所謂的特徵,是個什麼樣子,最基礎的東西吧。順便複習一下高等數據矩陣部分。了解一下scipy裡面的前三個問題『最小二乘擬合、函數最小值、非線形方程組求解』,這個部分會涉及到求導、函數微分的知識。其實我覺得倒數第二部分『濾波器設計』應該也看一下,因為是神經網路很重要的一部分。matplotlib就是圖形化顯示,我覺得會用就行。
我是有條主線,然後不會的就在網上查,博客啊什麼的,有的一個知識點不同人有很多不同的解釋,看不懂那個解釋,就再找另一個解釋,有時候突然就能想通。我之前看過一篇解釋傅立葉變換的文章(如果看了此文你還不懂傅里葉變換,那就過來掐死我吧【完整版】 - 文章 - 伯樂在線),其實說到已經很清楚了,但當時就是轉不過視角來,後來有一天看神經網路的文章,就是解釋關於過濾不重要信息的一個問題,突然兩個解釋一結合,兩個問題都想通了。
我大概學了『協同過濾、主成分分析、k-means、svm、決策樹、線性回歸、邏輯回歸』這幾種演算法
真正項目應該是幾種演算法的協同作戰,比如先用主成分分析找出重要的特徵,在進行下一步的線性擬合等。
我對這幾種演算法的的程度就是能寫出數學公式,以及為什麼要用這個數學公式,比如協同過濾求相似係數有很多中方法,歐幾里得、皮爾遜相似,歐幾里得不說了,兩點間的距離。皮爾遜相似跟歐幾里得比的好處是什麼,以及皮爾遜相似是協方差跟標準差的比,這裡又要複習一下期望、方差、標準差、均值等數學知識。其他類似。
每學到一個演算法都去網上找相應的小例子實現,輔助理解,加深記憶,更重要的是增強自信。而且這樣調用框架的時候就不覺得跟變魔術似的了。打個比方,自己實現決策樹的信息增益比(c4.5)比較麻煩,但是實現一個協同過濾的歐幾里得很簡單吧,但是這樣心裡就會有數,不管看起來多複雜的演算法,就是這樣由一些簡單的數學公式堆砌的。
然後我就安裝了scikit-learn(scikit-learn: machine learning in Python),有個推薦電影的例子,數據集、代碼都是現成的、每個函數都要理解、不會就查,運行出結果我覺得這就算入門啦。
tensorflow好像主要是做用來做神經網路的吧,我就是用cnn實現了一個驗證碼識別,網上有實例。對cnn的理解,網上文章特別多,多看看總能找到一個自己能理解的角度。還有幾種常見的損失函數。為什麼選sigmoid函數,而不選softmax函數,我看過一篇非常好的文章,找不到鏈接了。
當然還有些細節沒提到,但是,我覺得這就算「入門」啦! 至於什麼清洗、特徵選取、調優……來日方長嘛~!
知乎首答。
最高票的師兄已經回答得很好了,我再來稍微補充一些我自己的想法。
Tensorflow的入門基礎版資料肯定是官方文檔:
https://www.tensorflow.org/versions/r0.10/tutorials/index.html
然後其實官方Github裡面有好多地方都有一些簡單的模型例子:
tensorflow/tensorflow/examples/tutorials at master · tensorflow/tensorflow · GitHub
tensorflow/tensorflow/examples/udacity at master · tensorflow/tensorflow · GitHub (這個是Udacity上面對應的深度學習課的練習,以Notebook的形式呈現,更好地分段理解。)
tensorflow/tensorflow/models at master · tensorflow/tensorflow · GitHub (這裡面有很多成熟的例子可以參考)
此外,還有Aymeric Damien的Github下的Tensorflow從入門到精通
GitHub - aymericdamien/TensorFlow-Examples: TensorFlow Tutorial and Examples for beginners
Stackoverflow下也有Tensorflow的版塊,裡面有大量優秀的問題與回答,沒事可以多了解一下。
由於Tensorflow本身是開源的,所以其實可以讀一下源碼。RNN的代碼其實挺好看懂了,沒事可以多琢磨一下然後實現一個自己的版本。
最後再丟一個類似的問題以供參考
如何高效的學習TensorFlow代碼? - 學習方法
現在人工智慧是個大熱點,而人工智慧離不開機器學習,機器學習中深度學習又是比較熱門的方向,以下系列文章就從實戰出發,帶領大家入門深度學習:
深度學習入門實戰(一)-像Prisma一樣演算法生成梵高風格畫像
深度學習入門實戰(二)-用TensorFlow訓練線性回歸
深度學習入門實戰(三)-圖片分類中的邏輯回歸
附TensorFlow基本概念及簡單使用說明
1.placehoder(佔位符)
tf.placeholder(dtype, shape=None, name=None)
Args:
????dtype: The type of elements in the tensor to be fed.
????shape: The shape of the tensor to be fed (optional). If the shape is not specified, you can feed a tensor of any shape.
????name: A name for the operation (optional).
dytpe:佔位符的數據類型
shape:佔位符的緯度,例如[2,2]代表2x2的二維矩陣,None可以代表任意維度,例如[None,2]則代表任意行數,2列的二維矩陣
name:佔位符的名字
變數在定義時要初始化,但可能有些變數我們一開始定義的時候並不一定知道該變數的值,只有當真正開始運行程序的時候才由外部輸入,比如我們需要訓練的數據,所以就用佔位符來佔個位置,告訴TensorFlow,等到真正運行的時候再通過輸入數據賦值。
例如
x = tf.placeholder(tf.float32, [2, 2])
就是生成了一個2x2的二維矩陣,矩陣中每個元素的類型都是tf.float32(也就是浮點型)。
有時候定義需要訓練的參數時候,會定義一個[input_size,output_size]大小的矩陣,其中input_size數輸入數據的維度,output_size是輸出數據的維度
2.Variable(變數)
官方說明 有些長,我就不引用啦,這裡介紹一個簡單的用法,有一點變數在聲明的時候要有一個初始值
x = tf.Variable(tf.zeros([2,2])) # 聲明一個2x2的矩陣,並將矩陣中的所有元素的值賦為0,默認每個元素都是tf.float32類型的數據
y = tf.Variable(1.0, tf.float32) # 聲明一個tf.float32的變數,並將初始值設為1.0
我們一般還需要運行下global_variables_initializer真正在TensorFlow的Session中初始化所有變數,後面的樣例中也會有體現。
3.Constant(常量)
官方說明 同樣不引用啦,這裡介紹一個簡單的用法
x = tf.constant(3.0, tf.float32) # 定義一個值為3.0的浮點型常量
4.Session(會話)
TensorFlow所有的操作都必須在Session中運行,才能真正起作用,可以將Session當作TensorFlow運行的環境,Session運行完需要close~
#用close()關閉
sess = tf.Session()
sess.run(...)
sess.close()
#使用with..as..語句關閉
with tf.Session() as sess:
????sess.run(...)
5.簡單使用
我們介紹下3+5應該如何在TensorFlow中實現
import tensorflow as tf
x = tf.Variable(3, tf.int16) // 聲明一個整型變數3
y = tf.Variable(5, tf.int16) // 聲明一個整型變數5
z = tf.add(x,y) // z = x + y
init = tf.global_variables_initializer() // 初始化變數的操作
with tf.Session() as sess:
sess.run(init) // 在Session中初始化變數
print(sess.run(z)) // 輸出計算出的z值
現在在google做前端,自己也在學習 tensorflow , 也屬於入門階段吧。其他人回答的都說得很好,我補充一些內容,另外也說下我的觀點。
學好tensorflow不難,雖然 tensorflow網站的API 並沒有提供很多的例子,例子都在 tutorial 裡面,cnn,lstm 都有,入門的話真正能搞清楚 cnn, lstm 已經很不錯了。題主提供給的幾個連接也很好,能夠把實現和學習結合起來。
其實深度學習是一門工程性很強的學科,工作中開發的產品也遠遠比 tutorial 的複雜,很多情況是不能用類似keras那種庫實現的,直接用tensorflow寫反而更簡單。所以學習tensorflow,千萬不要因為看tutorial 覺得難,就放棄,轉而直接使用庫來開發,這樣你是學不會東西的。
我們部門有時候回面試一些機器學習工程師,有一些號稱用tensorflow做了幾個項目的人,看了他們的代碼,直接用庫開發的,然後問他們具體的計算公式一點都答不出來,居然給我們HR說「能實現就好了,管他怎麼實現的」,然後HR找懂這個庫的同事去看code,發現lstm 用的方式都不對,嚇蒙的。這事成為我們辦公室一笑話。所以說,學習tensorflow沒捷徑,先把寫代碼能力提高,認認真真看tensorflow tutorial吧。、
---分割線----
另外回答下題主對 tensorflow queue 的問題,現在主要有兩種實現方式,一種是先把數據保存成tfrecord格式然後用 tensorflow讀取,另外一種是對numpy array做實時多線程處理。 發兩個link給你參考一下。
使用 tfrecord : https://github.com/zsdonghao/tensorlayer/blob/master/example/tutorial_cifar10_tfrecord.py
使用對numpy array做多線程:https://github.com/zsdonghao/tensorlayer/blob/master/example/tutorial_image_preprocess.py
其它 tricks: https://github.com/wagamamaz/tensorlayer-tricks
(活久見,本答案的感謝數是贊同數的1/3,看來學渣還是佔大多數,23333)
看了其它的答案,恕我直言,大部分都是垃圾,不是說內容垃圾(很多內容我看不懂),而是說方法垃圾,對於一個不是學計算機而想要入門tensorflow的人,上來講一大堆原理和演算法,有個鳥用,就像對一個想學PHP編程的人,上來就講《編譯原理》或者彙編指令,一輩子都入不了門!
至於題主說學不到原理,或者看不懂源碼,這就不是入門的要求了,這是要深入研究深度學習和tensorflow了,如果不是學術研究和理論研究,我覺得完全沒有必要,能用tensorflow解決你的問題才是最關鍵的。
正好之前我在朋友圈分享了我的「機器學習」學習之路,朋友圈點贊甚多,相信很多人都有同感,這裡也分享一下,希望能對大家有所幫助,
=======以下內容分享給各位學渣,學霸們一笑而過就好==========
1)第一階段:陷入各種演算法:貝葉斯、K近鄰。。。。。。
開始機器學習,上網搜索,發現一堆演算法,於是開始學習各種演算法,花了一定的時間才了解了監督、無監督學習的基本分類和差異,學習過程中遇到幾個主要問題:
- 演算法原理看不懂:大學高數還可以,但現在看完全看不懂
- 不知道演算法有什麼用:例如,購物推薦用了什麼演算法?
- 搞不清這些演算法和深度學習什麼關係
2)第二階段:線性代數、統計
經歷第一階段後,感覺是不是自己的數學基礎太薄弱了,於是開始看線性代數和統計的基礎知識,嘗試了一下,發現簡單一些的還能夠看懂,稍微複雜一些的完全看不懂,遂放棄。。。。。
3)第三階段:人工智慧歷史
由於各種概念和術語混雜,於是想到看看人工智慧歷史,找到了《人工智慧狂潮》一書,詳細的介紹了人工智慧的發展歷史,尤其是對於人工智慧發展的幾個階段,每個階段的特點和不足都解釋的非常清楚,看完後對人工智慧相關的各種概念有了清晰的認識,例如人工智慧第三階段分為「基於特徵的演算法學習」和「無特徵的深度學習」兩部分,一下子將第一階段的各種演算法疑惑解答了。
4)第四階段:《集體智慧編程》
無意中在知乎看到有人推薦這本書,於是買來認真看了一下,發現真是本好書:演算法結合實踐,理解了「基於特徵的演算法學習」在實際業務中的應用,包括商品推薦、方案優化、用戶分組、垃圾郵件過濾,通過《集體智慧編程》這本書發現,其實這些演算法用起來沒那麼複雜。
5)第五階段:keras
由於對演算法基礎和數學實在是沒有興趣和精力深入,於是找到了keras這個開源項目,發現真是神器,封裝非常好,使用非常簡單直觀。使用keras寫一個cnn手寫數字識別程序,簡單直觀,很好理解。
6)第六階段:tensorflow
開始的時候我也是看官方文檔,發現文檔雖然全,但是是從查閱的角度組織的,而不是從教學的角度組織的,先看什麼,後看什麼,流程是什麼。。。。。。看官方文檔會陷進去出不來。於是上網找到了兩本書,強烈推薦,入門神器,不用花費大量時間去搜索亂七八糟的文檔,也不用去吭官方文檔,對照著兩本足夠了。
《TensorFlow實踐》,對TensorFlow的基本原理,實踐步驟講解清晰,沒有太多的演算法和數學公式介紹
《TensorFlow實戰指南》講解了使用TensorFlow來實現各類機器學習演算法,可以與《集體智慧編程》中的python對比來看,看看用tensorflow和普通的python實現同一個演算法差異在哪裡
到目前為止,機器學習和tensorflow我可以說已經基本入門,但如果說要深入的話,相信網易雲課堂的吳恩達教程是不可少的,我看過一些,但是一到演算法和原理我就懵了,看來創造和研究演算法的事情還是交給學霸們就好,我等學渣只需要簡單調用即可。例如:
學霸們請將演算法像tensorflow這樣封裝好,我一行代碼調用就可以了 ,233333 :)
我明白很多入門深度學習者的疑惑。因為當初,我也是關注著這個問題進來的。
其實,我在《TensorFlow技術解析與實戰》當中講解過「深度學習入門的七個步驟」:
要想入門深度學習,需要兩個工具,即演算法知識和大量的數據,外加一台計算機,如果有GPU就更好了,但是因為許多入門初學者的條件有限,沒有GPU也可以,本書的許多講解都是基於Mac筆記本完成的。
我把深度學習的入門過程整理成如圖所示的7個步驟。
下面就來詳細介紹一下這7個步驟。
1.學習或者回憶一些數學知識
因為計算機能做的就只是計算,所以人工智慧更多地來說還是數學問題[1]。我們的目標是訓練出一個模型,用這個模型去進行一系列的預測。於是,我們將訓練過程涉及的過程抽象成數學函數:首先,需要定義一個網路結構,相當於定義一種線性非線性函數;接著,設定一個優化目標,也就是定義一種損失函數(loss function)。
而訓練的過程,就是求解最優解及次優解的過程。在這個過程中,我們需要掌握基本的概率統計、高等數學、線性代數等知識,如果學過就最好,沒學過也沒關係,僅僅知道原理和過程即可,有興趣的讀者可以涉獵一些推導證明。
2.掌握經典機器學習理論與基本演算法
這些基本演算法包括支持向量機、邏輯回歸、決策樹、樸素貝葉斯分類器、隨機森林、聚類演算法、協同過濾、關聯性分析、人工神經網路和BP演算法、PCA、過擬合與正則化等。[2]
在本書「實戰篇」的第8章到第13章的例子中也有貫穿這些演算法知識,保證讀者可以用它寫出一個小的TensorFlow程序。
3.掌握一種編程工具(語言)
Python語言是一種解釋型、面向對象、動態數據類型的高級程序設計語言。Python是很多新入門的程序員的入門編程語言,也是很多老程序員後來必須掌握的編程語言。我們需要重點掌握使用線性代數庫和矩陣的操作,尤其是Numpy、Pandas第三方庫,也要多試試機器學習的庫,如sklearn,做一些SVM及邏輯回歸的練習。這對直接上手寫TensorFlow程序大有裨益。
有些工業及學術領域的讀者還可能擅長MATLAB或R,其實現演算法的思想和Python也很類似。
同時考慮到許多讀者是使用C++、Java、Go語言的,TensorFlow還提供了和Python「平行語料庫」的介面。雖然本書是主要是基於Python講解的,對於其他語言的原理和應用API也都非常類似,讀者把基礎掌握後,只需要花很短的時間就能使用自己擅長的語言開發。另外對於Java語言的同學,本書第18章會講解TensorFlowOnSpark,第19章會講到TensorFlow的移動端開發。
4.研讀經典論文,關注最新動態和研究成果
一些經典論文是必讀的。例如,要做手寫數字識別,若採用LeNet,要先閱讀一下LeNet的學術論文;要做物體目標檢測的訓練,若選定MSCNN框架,可以先讀MSCNN相關的論文。那麼,論文從哪裡找呢?那麼多論文應該讀哪篇呢?
下面以GoogleNet的TensorFlow實現為例。在GitHub[3]上,一般在開頭的描述中就會說明這個模型所依據的論文,如圖所示。
順著這篇論文閱讀,可以大致了解這個網路的實現原理,對迅速上手應用有很大的作用。同時,我在第6章也會對LeNet、AlexNet、ResNet這幾個常見的網路進行講解,幫助讀者舉一反三。
很多做模式識別的工作者之所以厲害,是因為他們有過很多、很深的論文積累,對模型的設計有很獨到的見解,而他們可能甚至一行代碼也不會寫,而工程(寫代碼)能力在工作中很容易訓練。許多工程方向的軟體工程師,工作模式常常在實現業務邏輯和設計架構系統上,編碼能力很強,但卻缺少論文積累。同時具有這兩種能力的人,正是矽谷一些企業目前青睞的人才。
讀者平時還可以閱讀一些博客、筆記,以及微信公眾號、微博新媒體資訊等,往往一些很流行的新訓練方法和模型會很快在這些媒體上發酵,其訓練神經網路採用的一些方法可能有很大的啟發性。
5.自己動手訓練神經網路
接著,就是要選擇一個開源的深度學習框架。選擇框架時主要考慮哪種框架用的人多。人氣旺後,遇到問題很容易找到答案;GitHub上關於這個框架的項目和演示會非常多;相關的論文也會層出不窮;在各個QQ群和微信群的活躍度會高;雜誌、公眾號、微博關注的人也會很多;行業交流和技術峰會討論的話題也多;也能享受到國內外研究信息成果的同步。
目前這個階段,TensorFlow因為背靠谷歌公司這座靠山,再加上擁有龐大的開發者群體,而且採用了稱為「可執行的偽代碼」的Python語言,更新和發版速度著實非常快。目前TensorFlow已經升級到1.0版,在性能方面也有大幅度提高,而且新出現的Debugger、Serving、XLA特性也是其他框架所不及的。此外,一些外圍的第三方庫(如Keras、TFLearn)也基於它實現了很多成果,並且Keras還得到TensorFlow官方的支持。TensorFlow支持的上層語言也在逐漸擴大,對於不同工程背景的人轉入的門檻正在降低。
在GitHub[4]上有一個關於各種框架的比較,從建模能力、介面、模型部署、性能、架構、生態系統、跨平台等7個方面進行比較,TensorFlow也很占綜合優勢。截至2017年1月,TensorFlow的star數已經超過了其他所有框架的總和,如圖1-8所示。
因此,從目前來看,投身TensorFlow是一個非常好的選擇,掌握TensorFlow在找工作時是一個非常大的加分項。
接下來就是找一個深度神經網路,目前的研究方向主要集中在視覺和語音兩個領域。初學者最好從計算機視覺入手,因為它不像語音等領域需要那麼多的基礎知識,結果也比較直觀。例如,用各種網路模型來訓練手寫數字(MNIST)及圖像分類(CIFAR)的數據集。
6.深入感興趣或者工作相關領域
人工智慧目前的應用領域很多,主要是計算機視覺和自然語言處理,以及各種預測等。對於計算機視覺,可以做圖像分類、目標檢測、視頻中的目標檢測等;對於自然語言處理,可以做語音識別、語音合成、對話系統、機器翻譯、文章摘要、情感分析等,還可以結合圖像、視頻和語音,一起發揮價值。
更可以深入某一個行業領域。例如,深入醫學行業領域,做醫學影像的識別;深入淘寶的穿衣領域,做衣服搭配或衣服款型的識別;深入保險業、通信業的客服領域,做對話機器人的智能問答系統;深入智能家居領域,做人機的自然語言交互;等等。
7.在工作中遇到問題,重複前六步
在訓練中,準確率、壞案例(bad case)、識別速度等都是可能遇到的瓶頸。訓練好的模型也不是一成不變的,需要不斷優化,也需要結合具體行業領域和業務進行創新,這時候就要結合最新的科研成果,調整模型,更改模型參數,一步步更好地貼近業務需求。
[1] 這裡,一些人擔心人工智慧超越人類還會產生哲學和倫理問題。我認為做這種討論還為時尚早,嚴謹的數據基礎是要突破的主要方向。
[2] 推薦讀者閱讀李航老師的《統計學習方法》,很快就能入門。
[3] https://github.com/tensorflow/models/tree/master/inception
[4] https://github.com/zer0n/deepframeworks
最後,初學者建議選擇一本權威細緻的TensorFlow教材,比如《TensorFlow技術解析與實戰》。這本書的特點是基於TensorFlow1.1版本,技術講解極為細緻,配合人臉識別、圖像識別、智能機器人的TensorFlow實戰案例,也包攬了所有TensorFlow的高級特性。(《TensorFlow技術解析與實戰》(李嘉璇)【摘要 書評 試讀】- 京東圖書)
2017.8.19 更新:
更新:
基於 LSTM 的學習項目。
TensorFlow-Bitcoin-Robot:Tensorflow 比特幣交易機器人
2017.7.29 更新:
圖片來自網路,侵權刪
FaceRank-人臉打分基於 TensorFlow 的 CNN 模型,這個妹子顏值幾分? FaceRank 告訴你!《周末小福利》
機器學習是不是很無聊,用來用去都是識別字體。能不能幫我找到顏值高的妹子,順便提高一下姿勢水平。
FaceRank 基於 TensorFlow CNN 模型,提供了一些圖片處理的工具集,後續還會提供訓練好的模型。給 FaceRank 一個妹子,他給你個分數。
從此以後篩選簡歷,先把頭像顏值低的去掉;自動尋找女主顏值高的小電影;自動關注美女;自動排除負分滾粗的相親對象。從此以後升職加薪,迎娶白富美,走上人生巔峰。
TensorFlow News
我覺得最好的方式還是理論結合實際,我目前是書+GitHub+code:
1.書 《TensorFlow:實戰Google深度學習框架》,感覺還不錯。
2.GitHub:https://github.com/tensorflow/tensorflow ,還有另外一個 TensorFlow module ,裡面有很多比較成熟的應用代碼。
3.code,盡量多寫點代碼,雖然GitHub clone 一下就有很多。
其他相關鏈接:
Computation using data flow graphs for scalable machine learning http://tensorflow.org
官網:https://www.tensorflow.org/
安裝:
Installing TensorFlow on Mac OS X
https://www.tensorflow.org/install/install_mac
Installing TensorFlow on Ubuntu
https://www.tensorflow.org/install/install_linux
Installing TensorFlow on Windows
https://www.tensorflow.org/install/install_windows
GitHub:https://github.com/tensorflow/tensorflow
視頻教程(深度學習(中/英):https://cn.udacity.com/course/deep-learning–ud730
TensorFlow 博客,記錄一下學習過程:TensorFlow
人工智慧、機器學習和深度學習
在介紹TensorFlow(以下簡稱為TF)之前,我們首先了解一下相關背景。
TF是一種機器學習框架,而機器學習經常和人工智慧,深度學習聯繫在一起,那麼三者到底是什麼關係呢?
簡單來講三者可以理解為包含於被包含的關係。其中最大的是人工智慧(以下簡稱為AI),AI最早起源於1956年的達特茅斯會議,當時AI的幾位先驅在會上展示了最早的AI程序:Logic Theorist,能夠自動推導數學原理第二章前52個定理中的38個,甚至其中一個定理的證明過程比書中給出的還要優雅,他們甚至曾嘗試要發表這一新的證明方式(不過後來被拒了)。總之,簡單來說,AI就是賦予機器以人的智能,讓機器具有學習和認知的能力。
機器學習(以下簡稱為ML)則是實現AI的一種方法。舉個簡單的垃圾郵件過濾的例子,我們人類判斷一個郵件是否是垃圾郵件很簡單,通過標題或內容很快就可以辨別。但是讓機器完成這樣的任務就沒這麼簡單。對於經典的ML演算法,首先需要從原始數據(郵件)中提取特徵,比如發信人地址、郵件標題、郵件內容關鍵詞等,從而將文字的郵件轉換成包含多個特徵的向量,然後利用邏輯回歸演算法在已經標定的數據集上進行訓練,得到每個特徵的權重。這些權重構成我們的預測模型,對於一封新的郵件,就可以用這個模型判斷其是否是垃圾郵件。
傳統的ML最大的問題就是特徵提取。比如讓機器識別照片中的動物是貓還是狗,如何設計特徵?深度學習(以下簡稱為DL)正是為了解決特徵提取的問題,我們不再需要人工設計特徵,而是讓演算法從數據中自動學習特徵,將簡單的特徵組合形成複雜的特徵來解決這些問題,所以DL可以說是實現ML的一種技術。
TensorFlow簡介
TensorFlow是什麼
Tensorflow是一個Google開發的第二代機器學習系統,克服了第一代系統DistBelief僅能開發神經網路演算法、難以配置、依賴Google內部硬體等局限性,應用更加廣泛,並且提高了靈活性和可移植性,速度和擴展性也有了大幅提高。字面上理解,TensorFlow就是以張量(Tensor)在計算圖(Graph)上流動(Flow)的方式的實現和執行機器學習演算法的框架。具有以下特點:
- 靈活性。TensorFlow不是一個嚴格的「神經網路」庫。只要可以將計算表示成數據流圖,就可以使用TensorFlow,比如科學計算中的偏微分求解等。(實際上其官網的介紹中對TF的定位就是基於數據流圖的科學計算庫,而非僅僅是機器學習庫)
- 可移植性。同一份代碼幾乎不經過修改既可以部署到有任意數量CPU、GPU或TPU(Tensor Processing Unit,Google專門為機器學習開發的處理器)的PC、伺服器或移動設備上。
- 自動求微分。同Theano一樣,TensorFlow也支持自動求微分,用戶不需要再通過反向傳播求解梯度。
- 多語言支持。TensorFlow官方支持Python、C++、Go和Java介面,用戶可以在硬體配置較好的機器中用Python進行實驗,在資源較緊張或需要低延遲的環境中用C++進行部署。
- 性能。雖然TensorFlow最開始發布時僅支持單機,在性能評測上並不出色,但是憑藉Google強大的開發實力,TensorFlow性能已經追上了其他框架。
Google為什麼開源Tensorflow
Google第一代分散式機器學習框架DistBelief在內部大規模使用後沒有選擇開源,而第二代TensorFlow於2015年11月在GitHub上開源,並在持續快速開發迭代中。TensorFlow最早由Google Brain的工程師開發,設計初衷是加速機器學習的研究,並快速地將研究原型轉化為產品。Google選擇開源TensorFlow的原因很簡單:第一是希望藉助社區的力量,大家一起完善TensorFlow。第二是回饋社區,Google希望讓這個優秀的工具得到更多的應用,提高學術界和工業界使用機器學習的效率。
自從2015年11月開源以來,TensorFlow迅速在眾多的機器學習框架中脫穎而出,在Github上獲得了最多的Star。下圖統計了Github上流行的機器學習框架的Star數量:
TensorFlow大事記
- 2015年11月9日,Google Research 發布了文章:TensorFlow - Google』s latest machine learning system, open sourced for everyone,正式宣布其新一代機器學習系統開源。
- 2016年4月13日,TensorFlow v0.8發布,提供分散式計算支持。
- 2016年4月29日,開發AlphaGo的DeepMind宣布從Torch7平台轉向TensorFlow。
- 2016年4月12日,基於TensorFlow的世界最準確的語法解析器SyntaxNet宣布開源。
- 2016年6月27日,TensorFlow v0.9發布,提高對移動設備的支持。
- 2016年8月30日,TF-Slim——TensorFlow的高層庫發布,用戶可以更簡單快速地定義模型。
- 2017年2月15日,TensorFlow v1.0發布,提高了速度和靈活性,並且承諾提供穩定的Python API。
TensorFlow架構
TF的系統構架分為兩部分:
- 前端:提供編程模型,負責構造計算圖,提供Python,C++,Java,Go等多種語言支持。
- 後端:提供運行時環境,負責執行計算圖,採用C++實現。
用戶在搭建演算法時,可以根據個人喜好和實際需求採用合適的前端語言來構建計算圖。圖搭建完成後,以Session為橋樑連接TF的後端,啟動並執行圖的計算過程。TF的後端根據當前硬體環境調用Operation的Kernal(Operation在某種硬體設備的特定實現)完成具體的計算。
註:後文對Session,Operation有具體解釋
TensorFlow編程模式
符號式編程 vs 命令式編程
和我們一般常用的命令式(Imperative)編程模式不同,TF採用的是符號式(Symbolic)編程。我們先認識一下兩種編程模式:
命令式編程是很常見的編程模式,大多數Python或C++程序都採用命令式編程。命令式編程明確輸入變數,根據程序邏輯逐步運算。下面是一段命令式編程的Python代碼:
import numpy as np
a = np.ones(10)
b = np.ones(10) * 2
c = b * a
d = c + 1
執行完第一步a = np.ones(10)後,程序得到了輸入變數a,第二句後得到了b,當執行c = b * a時,程序通過乘法計算而得到了c。
符號式編程則將計算過程抽象為計算圖,所有輸入節點、運算節點和輸出節點均符號化處理。將上述命令式編程代碼轉換為符號式編程:
A = Variable("A")
B = Variable("B")
C = B * AD = C + Constant(1)
# compiles the function
f = compile(D)
d = f(A=np.ones(10), B=np.ones(10)*2)
當前四步執行後,程序並沒有A、B、C、D的值,僅僅是構建了由這四個符號構成的計算圖,如下圖所示:
大多數符號式編程的程序中都或顯式或隱式地包含編譯的步驟,將前面定義的計算圖打包成可以調用的函數,而實際的計算則發生在編譯後。
Theano和TensorFlow屬於典型的符號式編程模式,而Torch則是命令式編程模式。在靈活性上,命令式編程模式更優,而在內存和計算上,符號式編程效率更高。
TensorFlow基本概念
要使用TensorFlow,我們必須理解TensorFlow:
- 使用圖(Graph)表示計算流程
- 在會話(Session)中執行圖
- 使用張量(Tensor)表示數據
- 使用變數(Variable)維護狀態
- 使用feed和fetch為任意的操作賦值或從中獲取數據
TF使用graph表示計算流程。圖中的節點稱為操作(Operation,以下簡稱OP)。每個OP接受0到多個Tensor,執行計算,輸出0到多個Tensor。圖是對計算流程的描述,需要在Session中運行。Session將計算圖的OP分配到CPU或GPU等計算單元,並提供相關的計算方法,並且會返回OP的結果。
張量(Tensor)
TF使用Tensor表示所有數據,相當於Numpy中的ndarray,0維的數值、一維的矢量、二維的矩陣到n維數組都是Tensor。相對於Numpy,TensorFlow提供了創建張量函數的方法,以及導數的自動計算。下表對比了Numpy和TensorFlow的基本用法。
變數(Variable)
在訓練模型時,Variable被用來存儲和更新參數。Variable包含張量儲存在內存的緩衝區中,必須顯式地進行初始化,在訓練後可以寫入磁碟。下面代碼中的Variable充當了一個簡單的計數器角色:
# Create a Variable, that will be initialized to the scalar value 0.
state = tf.Variable(0, name="counter")# Create an Op to add one to `state`.
one = tf.constant(1)
new_value = tf.add(state, one)
update = tf.assign(state, new_value)# Variables must be initialized by running an `init` Op after having
# launched the graph. We first have to add the `init` Op to the graph.
init_op = tf.initialize_all_variables()# Launch the graph and run the ops.
with tf.Session() as sess:
# Run the "init" op
sess.run(init_op)
# Print the initial value of "state"
print(sess.run(state))
# Run the op that updates "state" and print "state".
for _ in range(3):
sess.run(update)
print(sess.run(state))# output:
# 0
# 1
# 2
# 3
上述代碼中assign()操作同add()一樣,都是在構建計算圖而沒有執行實際的計算。直到run()函數才會真正執行賦值等計算操作。
一般來說,用戶使用一系列Variable來表示一個統計模型,在訓練過程中運行圖計算來不斷更新,訓練完成後可以使用這些Variable構成的模型進行預測。
Feed
TensorFlow除了可以使用Variable和Constant引入數據外,還提供了Feed機制實現從外部導入數據。一般Feed總是與佔位符placeholder一起使用。
input1 = tf.placeholder(tf.float32)
input2 = tf.placeholder(tf.float32)
output = tf.mul(input1, input2)with tf.Session() as sess:
print(sess.run([output], feed_dict={input1:[7.], input2:[2.]}))# output:
# [array([ 14.], dtype=float32)]
Fetch
要獲取操作的輸出,需要執行會話的run()函數,並且提供需要提取的OP。下面是獲取輸出的典型例子:
input1 = tf.constant([3.0])
input2 = tf.constant([2.0])
input3 = tf.constant([5.0])
intermed = tf.add(input2, input3)
mul = tf.mul(input1, intermed)with tf.Session() as sess:
result = sess.run([mul, intermed])
print(result)# output:
# [array([ 21.], dtype=float32), array([ 7.], dtype=float32)]
圖和會話
由於TF採用符號式編程模式,所以TF程序通常可以分為兩部分:圖的構建和圖的執行。
圖的構建
構建圖的第一步,是創建源OP(source op),源操作不需要任何輸入,例如常量(constant),源操作的輸出被傳遞給其它操作做運算。
Python庫中,OP構造器的返回值代表被構造出的OP的輸出,這些返回值可以傳遞給其它OP構造器作為輸入。
TensorFlow Python庫有一個默認圖 (default graph),OP構造器可以為其增加節點。這個默認圖對許多程序來說已經足夠用了。
import tensorflow as tf
# Create a Constant op that produces a 1x2 matrix. The op is
# added as a node to the default graph.
#
# The value returned by the constructor represents the output
# of the Constant op.
matrix1 = tf.constant([[3., 3.]])# Create another Constant that produces a 2x1 matrix.
matrix2 = tf.constant([[2.],[2.]])# Create a Matmul op that takes "matrix1" and "matrix2" as inputs.
# The returned value, "product", represents the result of the matrix
# multiplication.
product = tf.matmul(matrix1, matrix2)
上面使用TensorFlow提供的默認圖構建了包含三個節點的計算圖:兩個constant()操作和一個matmul()操作。要實際執行矩陣乘法,必須在Session中運行該計算圖。
圖的執行
要執行計算圖,首先需要創建Session對象,如果不提供參數,Session構造器將運行默認圖。
# Launch the default graph.
sess = tf.Session()# To run the matmul op we call the session "run()" method, passing "product"
# which represents the output of the matmul op. This indicates to the call
# that we want to get the output of the matmul op back.
#
# All inputs needed by the op are run automatically by the session. They
# typically are run in parallel.
#
# The call "run(product)" thus causes the execution of three ops in the
# graph: the two constants and matmul.
#
# The output of the op is returned in "result" as a numpy `ndarray` object.
result = sess.run(product)
print(result)
# ==&> [[ 12.]]# Close the Session when we"re done.
sess.close()
Session結束後,需要關閉以釋放資源。用戶也可以使用with控制語句自動關閉會話。
with tf.Session() as sess:
result = sess.run([product])
print(result)
TensorFlow簡單入門--MNIST字元識別
MNIST是一個簡單的計算機視覺數據集,包含共7萬個手寫數字字元,以灰度圖表示:
MNIST同時包含每個手寫字元對應的數字,稱為標籤(label)。上圖對應的標籤為5,0,4,1。
接下來,我們將使用TensorFlow訓練一個字元識別的多分類器,通過字元圖片預測對應的數字,這裡我們使用最簡單的多分類器--Softmax回歸。
MNIST數據集
首先讀取MNIST數據集:
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
MNIST數據集被讀入mnist對象中,分為三部分:55000行的訓練集(mnist.train)、10000行的測試集(mnist.test)和5000行的驗證集(mnist.validation)。這樣的切分很重要,在機器學習模型設計時必須有一個單獨的測試數據集不用於訓練而是用來評估這個模型的性能,從而更加容易把設計的模型推廣到其他數據集上(泛化)。
每個MNIST數據都包含一個字元圖片和對應的label,分別用「x」和「y」表示。每個圖片「x」由2828個像素構成,展開得到長度為784的向量。最後,我們得到的訓練數據集即形狀為[55000, 784]的二維數組以及對應的標籤(0-9)。
為了方便實現,這裡使用「one-hot vector」,即向量中除一個元素為1,其餘均為0。舉個例子:對於標籤3,對應的「one-hot vector」為[0,0,0,1,0,0,0,0,0,0],所以訓練集的標籤mnist.train.labels為形狀為[55000, 10]的二維數組。
Softmax回歸
Softmax回歸是二分類器logistic回歸的推廣,是一種最簡單的多分類器。Softmax回歸分為兩步,首先通過加權求和得到一張給定圖片屬於特定數字類的證據(evidence),如果這個像素具有很強的證據說明這張圖片不屬於該類,那麼相應的權值為負數,相反如果這個像素擁有有利的證據支持這張圖片屬於這個類,那麼權值是正數。
下面的圖片顯示了一個模型學習到的圖片上每個像素對於特定數字類的權值。紅色代表負數權值,藍色代表正數權值。
我們也需要加入一個額外的偏置量(bias),因為輸入往往會帶有一些無關的干擾量。因此對於給定的輸入圖片 x 它代表的是數字 i 的證據可以表示為
其中Wij 為 i 像素對 j字元的權重,bi 為數字類 i 的偏置量,j 代表給定圖片 x 的像素索引用於像素求和。然後用softmax函數可以把這些證據轉換成概率 y:
這裡的softmax可以看成是一個激勵(activation)函數或者鏈接(link)函數,把我們定義的線性函數的輸出轉換成我們想要的格式,也就是關於10個數字類的概率分布。因此,給定一張圖片,它對於每一個數字的吻合度可以被softmax函數轉換成為一個概率值。softmax函數可以定義為:
用矩陣來表示:
實現回歸模型
TF程序可以分為圖的構建和圖的執行兩部分,而圖的構建又可細分為輸入圖、推斷圖、訓練圖和評估圖四部分。
使用TF之前,首先導入它:
import tensorflow as tf
- 輸入圖
x = tf.placeholder("float", [None, 784])
y_ = tf.placeholder("float", [None, 10])
這裡的x和y不是一個特定的值,而是兩個佔位符(placeholder),我們在TF運行計算時輸入這個值。我們希望能夠輸入任意數量的MNIST圖像,每一張圖展平成784維的向量。我們用2維的浮點數張量來表示這些圖片,這個張量的形狀是[None,784]。(這裡的None表示此張量的第一個維度可以是任何長度的。)
- 推斷圖
W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))
y = tf.nn.softmax(tf.matmul(x,W) + b)
對於模型中的權重和偏置量這些參數,我們使用Variable來表示。初始化模型參數,這裡我們用全為零的張量來初始化W和b。因為我們要學習W和b的值,它們的初值可以隨意設置。注意,W的維度是[784,10],因為我們想要用784維的圖片向量乘以它以得到一個10維的證據值向量,每一位對應不同數字類。b的形狀是[10],所以我們可以直接把它加到輸出上面。
我們用tf.matmul(X,W)表示x乘以W,對應之前等式裡面的,這裡x是一個2維張量擁有多個輸入。然後再加上b,把和輸入到tf.nn.softmax函數裡面。這樣就得到了推斷結果y。
- 訓練圖
計算圖的第三個要素是訓練圖。為了訓練我們的模型,我們首先需要定義一個指標來評估這個模型是好的。其實,在機器學習,我們通常定義指標來表示一個模型是壞的,這個指標稱為代價(cost)或損失(loss),然後盡量最小化這個指標。
一個非常常見的代價函數是「交叉熵」(cross-entropy)。交叉熵產生於資訊理論裡面的信息壓縮編碼技術,但是它後來演變成為從博弈論到機器學習等其他領域裡的重要技術手段。它的定義如下:
是我們預測的概率分布,是實際的分布(我們輸入的one-hot vector)。比較粗糙的理解是,交叉熵是用來衡量我們的預測用於描述真相的低效性。
實現交叉熵:
cross_entropy = -tf.reduce_sum(y_*tf.log(y))
首先,用tf.log計算y的每個元素的對數。接下來,我們把y_的每一個元素和tf.log(y_)的對應元素相乘。最後,用tf.reduce_sum計算張量的所有元素的總和。(注意,這裡的交叉熵不僅僅用來衡量單一的一對預測和真實值,而是所有100幅圖片的交叉熵的總和。對於100個數據點的預測表現比單一數據點的表現能更好地描述我們的模型的性能。
現在我們知道我們需要我們的模型做什麼啦,用TensorFlow來訓練它是非常容易的。因為TensorFlow擁有一張描述你各個計算單元的圖,它可以自動地使用反向傳播演算法(backpropagation algorithm)來有效地確定你的變數是如何影響你想要最小化的那個代價函數的。然後,TensorFlow會用你選擇的優化演算法來不斷地修改變數以降低代價函數。
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
在這裡,我們要求TF用梯度下降演算法(gradient descent algorithm)以0.5的學習速率最小化交叉熵。梯度下降演算法(gradient descent algorithm)是一個簡單的學習過程,TF只需將每個變數一點點地往使代價不斷降低的方向移動。當然TF也提供了其他許多優化演算法:只要簡單地調整一行代碼就可以使用其他的演算法。
TF在這裡實際上所做的是,它會在後台給描述你的計算的那張圖裡面增加一系列新的計算操作單元用於實現反向傳播演算法和梯度下降演算法。然後,它返回給你的只是一個單一的操作,當運行這個操作時,它用梯度下降演算法訓練你的模型,微調你的變數,不斷減少代價。
我們現在可以創建一個Session來運行模型,
sess = tf.InteractiveSession()
首先我們需要初始化所有變數,
tf.global_variables_initializer().run()
然後開始訓練模型,這裡我們讓模型循環訓練1000次!
for _ in range(1000):
batch_xs, batch_ys = mnist.train.next_batch(100)
sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})
該循環的每個步驟中,我們都會隨機抓取訓練數據中的100個批處理數據點,然後我們用這些數據點作為參數替換之前的佔位符來運行train_step。
使用一小部分的隨機數據來進行訓練被稱為隨機訓練(stochastic training)- 在這裡更確切的說是隨機梯度下降訓練。在理想情況下,我們希望用我們所有的數據來進行每一步的訓練,因為這能給我們更好的訓練結果,但顯然這需要很大的計算開銷。所以,每一次訓練我們可以使用不同的數據子集,這樣做既可以減少計算開銷,又可以最大化地學習到數據集的總體特性。
- 評估圖
最後,我們要評估模型的性能,還需要構建評估圖。
首先讓我們找出那些預測正確的標籤。tf.argmax 是一個非常有用的函數,它能給出某個tensor對象在某一維上的其數據最大值所在的索引值。由於標籤向量是由0,1組成,因此最大值1所在的索引位置就是類別標籤,比如tf.argmax(y,1)返回的是模型對於任一輸入x預測到的標籤值,而 tf.argmax(y_,1) 代表正確的標籤,我們可以用 tf.equal 來檢測我們的預測是否真實標籤匹配(索引位置一樣表示匹配)。
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
這行代碼會給我們一組布爾值。為了確定正確預測項的比例,我們可以把布爾值轉換成浮點數,然後取平均值。例如,[True, False, True, True] 會變成 [1,0,1,1] ,取平均值後得到 0.75.
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
最後,我們計算所學習到的模型在測試數據集上面的正確率。
print(sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}))
這個最終結果值應該大約是92%。
其他機器學習框架
Caffe
Caffe全稱為Convolutional Architecture for Fast Feature Embedding,目前由BVLC(Berkeley Vision and Learning Center)進行維護。其創始人是加州大學伯克利的Ph.D.賈楊清,後來曾在Google Brain工作,開發TensorFlow。
Caffe優點在於使用配置文件方式定義網路,容易上手。訓練速度快,而且有大量訓練好的經典模型。組件模塊化,方便拓展到新的模型上。
Caffe最開始設計是只是針對圖像,沒有考慮文本、語音或者時間序列的數據,因此對卷積神經網路的支持很好,但是時間序列RNN、LSTM等支持不是很充分。要實現新的神經網路模塊(Layer)時,需要用戶自己寫C++或CUDA代碼實現正向和反向演算法,對新用戶有一定的難度。Caffe沒有原生的分散式支持,官方僅支持單機多CPU的訓練,不過有些第三方的支持,如雅虎開源的CaffeOnSpark,可藉助Spark的分散式框架實現Caffe的大規模分散式訓練。
Torch
Torch的定位是LuaJIT上的高效的科學計算庫,其歷史非常悠久,但真正發揚光大是在Facebook開源了其深度學習的組件之後。Torch與TensorFlow一樣,採用了底層C++加腳本語言調用的方式,不過Torch使用的是Lua,其性能非常優秀,常見的代碼通過JIT優化可以到C的性能的80%,但是相對Python並不是那麼主流,對多數用戶有學習成本。另外,Torch與Theano和TensorFlow採用符號編程模式不同,其採用命令式編程模式,所以實現某些複雜操作以及debug時更方便。
Keras
Keras是一個崇尚極簡、高度模塊化的神經網路庫,使用Python實現,可以運行在TensorFlow或Theano上,旨在讓用戶進行最快速的原型實驗。不同於Theano、TensorFlow等支持通用的數值計算,Keras專註於深度學習,它提供了目前為止最方便的API,用戶只需要將高級的模塊拼在一起,就可以搭建神經網路,大大降低了編程開銷、Keras所有模塊都是簡潔、易懂、完全可配置、可任意插拔的,基本沒有使用限制,神經網路、損失函數、優化器、初始化方法、激活函數和正則化等模塊都可以自由組合。使用Keras,只需要幾行就可以實現一個MLP,十幾行就可以實現一個AlexNet。如果Theano和TensorFlow是深度學習領域的Numpy,那麼Keras就是這個領域的scikit-learn。Keras最大的問題就是目前無法直接使用多GPU,所以對大規模的數據處理速度沒有其他支持多GPU和分散式的框架快。
參考資料
- 官網
- TensorFlow Website(最權威、詳細的文檔)
(https://www.tensorflow.org)
- 視頻教程
- TF開發者Sherry Moore的教程
(https://www.youtube.com/watch?v=Ejec3ID_h0wt=2117s)
- 周莫煩的TF教程
(https://www.youtube.com/watch?v=2FmcHiLCwTUlist=PL2-dafEMk2A7EEME489DsI468AB0wQsMV)
- Siraj的TF教程
(https://www.youtube.com/watch?v=Se9ByBnKb0olist=PLXO45tsB95cJHXaDKpbwr5fC_CCYylw1f)
- 書
- Python Machine Learning(常用機器學習演算法講解與實踐 -- Sebastian Raschka)
(https://www.amazon.com/Python-Machine-Learning-Sebastian-Raschka/dp/1783555130/ref=sr_1_1?ie=UTF8qid=1491489025sr=8-1keywords=python+machine+learning)
- TensorFlow實戰(TensorFlow實現多種機器學習演算法 -- 黃文堅,唐源)
(https://item.jd.com/12125568.html)
- 文章
- 深入淺出Tensorflow(一):深度學習及TensorFlow簡介
(http://www.infoq.com/cn/articles/introduction-of-tensorflow-part01)
- Programming Models for Deep Learning
(http://mxnet.io/architecture/program_model.html#symbolic-and-imperative-programs)
- TensorFlow學習筆記1:入門
(http://www.jeyzhang.com/tensorflow-learning-notes.html)
- 圖解TensorFlow架構與設計
(https://mp.weixin.qq.com/s?__biz=MzAwNDI4ODcxNA==mid=2652244394idx=1sn=8c66795bc0e0d262f8defd18c07165a3)
作者:李選選
我總結了一些使用技巧 :How to use TensorLayer 歡迎補充
------原文----用了 TensorLayer 1.2 版本,感覺不會再用其他框架了。。
能和 TF-Slim, TensorFlow/Model 無縫對接... 其他庫怎麼玩得過。。
近期也關注深度學習,大數據,機械學習這類,看到一篇還不錯的分享,推薦一下
技術分享|TensorFlow初學者在使用過程中可能遇到的問題及解決辦法
看TensorFlow的官方教程是個適合入門的方法。同時較之只看教程,不妨同時看看遇到的每個API及其代碼中的實現,這樣便於理解。
同時,Deep Learning 可以參見 http://www.deeplearningbook.org/ 這本書。
這樣Engineering and theory雙管齊下效果會好。
(當然有個好顯卡就更好了)推薦閱讀:
※可以用 Python 編程語言做哪些神奇好玩的事情?
※Python 的練手項目有哪些值得推薦?
※在大型項目上,Python 是個爛語言嗎?
※對 Quant 而言 Python 的需求高嗎,除 C++ 外還有哪些流行的編程語言?
※使用 Python 會降低程序員的編程能力嗎?
TAG:Python | 科技 | 深度學習(Deep Learning) | TensorFlow | TensorLayer(深度學習庫) |