初探Keras&神經網路
註:在寫這篇之前筆者考慮了很久到底要寫哪些東西,本著填補R在DL上工程的空缺的初心,決定幾乎不講太多演算法和理論;文章也更會更偏重R的工程上一些;因此希望讀者最好是:
熟練的R使用者;了解基本的機器學習演算法;希望學習/探討DL在R的工程上的方法和問題
Keras
1. Keras是什麼
摘一段書上的原話:
Keras是一個深度學習框架,能夠為定義和訓練幾乎所有類型的深度學習模型提供更快捷的辦法。Keras主要是為研究者提供快速的模型實現而開發的。
Keras是一個高層的API,後端是基於Tensorflow(Google),CNTK(Microsoft),以及Theano(U Montreal).其設計的重心也放在模型的快速開發快速迭代上。總的來說作為初學者,Keras作為上手相當不錯。
2. 為什麼用&不用Keras
原作者們的意見(Keras的開發者之一&TF和Keras的R介面作者)
Keras主要有以下幾個特徵:
它允許一段代碼在CPU和GPU上無縫切換。它的用戶友好的API讓深度學習模型得以快速開發迭代。它對於CNN,RNN,以及他們的任意組合都有良好的內置的支持。它支持任何網路結構:多輸入或多輸出模型,共享層,共享模型等等。這意味著Keras對於構建任何深度學習模型,無論是生成對抗網路還是生成神經圖靈機。
一些反對聲音:
慢:因為是上層API,是不可能不慢的。至於慢到什麼樣的程度以及一些解決方法,以後有機會單獨講(包括R環境下的速度提升)。
過於簡單而忽略了底層的一些實現:就好比ML的調包,這些封裝好的東西是為了快速實現避免重複造輪子,是工程上的一些優化。我個人認為新手上路從『調包』開始沒什麼不好,工程上可以一點點深入下去:從調包到看包里的源碼,再到自己實現。至於模型原理沒什麼好說的,不懂的話工程上有太多問題沒法解決了。
3. R和Keras
在R上安裝Keras:
install.packages(keras)library(keras)install_keras()#CPUinstall.keras(tensorflow = gpu)#GPU,需要本機有GPU以及CUDA和cuDNN
R在深度學習上的工具相對較少,比較有名的框架可能就是TF,Keras,H20.包的話還有MXNet,deepnet,darch等等。
開幾個傳送門(其他的自行google):
Package H20
Deep Learning in R libraries
MXNet - R API - mxnet documentation
還有一些其他的詳見Quora:
https://www.quora.com/What-are-the-best-packages-for-deep-learning-in-R
4. 在EC2上部署Rstudio server以及Keras
可以在AWS上安裝R和Rstudio server同時配置CUDA。在Rstudio server里像本機安裝keras一樣把keras安裝到server上就可以啦。
註:作者特別提到比較推薦使用一個SSH通道來遠程訪問Rstudio server。
基本數據操作
1. 張量(tensor)
Tensorflow的取名就是Tensor+flow,很好地反映了深度學習的一個整體感覺:張量通過網路不斷流動來得到結果。輸入的數據一般就是一些張量:0~2維的張量分別對應標量、向量、矩陣。拿威化餅乾來舉例說,假設威化上的一個小方格是最小單位,那麼這一個方格對應一個標量,一條方格就對應一個向量,同理一薄片威化就對應了一個矩陣。再拿圖像來說,一般來說都還有channel這個維度即R,G,B三層:好比威化薄片1,夾心,薄片合在一起。
一般來說,帶有時間序列的數據基本上都是三維張量及以上。在處理視頻文件的時候會比圖像再多一層維度,一般都會達到5維張量。
2. 張量操作(運算)
如果把張量固定為2D,張量運算似乎就變成了向量運算,那麼向量的+-/也對張量試用。這裡有一個特別的內積:在R里是使用『%*%』。比如一個向量a(1,2,3)和自己做內積就變成了14。同樣的,也可以擴展到高維:
(a, b, c, d) %*% (d) -> (a, b, c)(a, b, c, d) %*% (d, e) -> (a, b, c, e)
當然還有變換維度的操作:reshape(a為行數b為列數)
x <- array_reshape(x, dim= c(a, b))
使用t(x)可以直接做轉置。
最後講一下不同維度的張量之間的操作:sweep可以讓你在高低維張量之間做運算,比如:
x<-array(runif(1000,3,9),dim=c(12,14,3,50)y<-array(5,dim=c(14,3))z<-sweep(x, c(2,3), y, pmax)
sweep(x, a, y, b) 中:a代表制定的某幾個維度,b代表執行的計算;在這個例子中,x是隨機生成的3-9之間數,後面是其維度;y是14*3的全是5的矩陣;z就變成了在中間兩個維度上和y對齊進行pmax操作:所有小於5的都會被濾成5。
網路結構
一個簡單的網路結構
上圖就是一個非常簡潔和簡單的神經網路的流程圖了,在這裡註明幾個點:
Layer:在神經網路中最基本的數據結構就是一層(Layer),每一層可以接收多輸出也可以進行多輸出。層的權重參數是網路學習的張量,它們一起存儲著網路學習到的內容。作者用樂哥積木來比喻網路中的Layer:不同類型的層試用於不同類型的問題;層和層之間互相匹配,接收並輸出數據(tensor)形成數據流(flow)。
Models:圖形的網路。一般來說都是有向無環圖,還有比如Two-branch networks/Multihead networks 等等。
Loss function:學過ML對這個一定已經很明確了,表現了這個網路在這個數據集上的學習表現。比如最小二乘里的(Y-f(x))^2等等。
Optimizer: 選擇怎樣的優化演算法或優化器來進行網路的更新。比如隨機梯度下降,mini-batch等等,具體可以參考文檔。
Input,Metrics之類的不說了。
簡單的MNIST例子
就拿最簡單的MNIST例子(識別手寫數字),非常簡單,幾乎感受不到是在用框架什麼的。
數據輸入&初始化:
library(keras)mnist <- dataset_mnist() train_images <- mnist$train$xtrain_images <- array_reshape(train_images, c(60000,28 * 28))train_images <- train_images /255test_images <- mnist$test$xtest_images <- array_reshape(test_images, c(60000,28 * 28))test_images <- test_images /255train_labels <- mnist$train$ytrain_labels <- to_categorical(train_labels)test_labels <- mnist$test$ytest_labels <- to_categorical(test_labels)
網路結構:
network <- keras_model_sequential() %>% layer_dense(units = 512, activation = "relu", input_shape= c(28 * 28)) %>% layer_dense(units = 10, activation = "softmax")
編譯步驟:
network %>% compile( optimizer = "rmsprop", loss = "categorical_crossentropy", metrics = c("accuracy"))
訓練&檢驗:
network %>% fit(train_images, train_labels, epochs = 5, batch_size = 128)metrics <- network %>% evaluate(test_images, test_labels, verbose = 0)metrics$loss[1] 0.06711107$acc[1] 0.9807
當然你也可以用network %>% predict_classes(test_images)來查看輸出的數字。
可以說是非常簡單了。書里作者在一開始就用這個例子無非就是不想嚇跑很多小小白讀者,看到這裡那麼筆者也可以恭喜你從一個小小白變成了一個小白:)
希望大家多拍磚/交流!
Reference:
1.Deep Learning with R, Chapter 2-3
2.Package Keras
題圖來自http://Amazon.com
推薦閱讀:
TAG:R編程語言 | 深度學習DeepLearning | Keras |