標籤:

嘗試克服一下小夥伴對神經網路的恐懼No.26

我是小蕉。

研表究明,這的網官的demo,代碼確實的是己打自的。

這兩天仔細研究了一下神經網路,簡單的結構其實沒想像中那麼恐怖,只是我們自己嚇自己,今天希望能把理解到的東西分享給大家,克服一下大家的恐懼,我使用的框架是Tensorflow。

先提一個概念,placeholder佔位符,這個東西是我們用來進行填坑的東西,也就是我們能在調用的使用傳入的東西,其他的東西在網路編寫完成之後,只能由程序進行變更,我們是不能人為干預的。

數據集是MNIST數據集,一堆的28 * 28像素的圖片以及他們的標籤值,測試集和訓練集是分開的,不知道怎麼下載的自己去官網看。我這裡就直接引入了。

mnist = input_data.read_data_sets(MNIST_data/,one_hot=True)

首先定義兩個大坑。x就是我們的輸入值,可以是測試數據,也可以是訓練數據,也可以是實時的數據。tf.float32代表是,就是字面意義啦。[None,784]以及[None,10]的意思就是,第一個維度的None代表不限制輸入的"行數",也就是不限制輸入的數據集的大小,784代表是784輸入值,10代表10個輸出值。

x = tf.placeholder(tf.float32, [None , 784],name=input_x) y_ = tf.placeholder(tf.float32, [None, 10],name=input_y『)

所以神經網路就是我們先定義好一個網路結構,其中有一個坑x是給我們的輸入的,一個坑y_是給我們打好的標籤。然後用訓練集進行訓練網路,測試集進行測試,如果效果還不錯呢,我們就把這個訓練完網路直接應用到實時預測當中去。再說一遍:訓練完的網路可以直接應用到實時預測中。

那怎麼去構建這個網路以及怎麼訓練呢?我們定義兩個變數,w權重和b偏置值,這裡定義為Variable,代表這兩個變數的值是可以被程序變更的(不是認人為喔),沒辦法就是這麼拖沓。tf.zeros意思是新建一個全0的矩陣。那這裡為什麼w是[784,10]的矩陣,而b是[10]的呢?這是因為我們輸入的維度有784維,而輸出是10維,所以我們的權重有784 * 10這麼多,而輸出值只有0-9,所以偏置項也只有10項。其實就是新建了784 * 10 個 y = wx + b這麼一個線性模型,然後每個模型都能得給當前的y值打一個分數這樣。

w = tf.Variable(tf.zeros([784,10]))b = tf.Variable(tf.zeros([10]))model = tf.matmul(x , w) + b

接下來重頭戲來了,我們得到了10個類別各自的得分,咋辦呢?

結果可能是 [0,0,0,0.5,0.2,0,0,0,0.1,0]這樣。

那我們要選哪一個呢?我們一般來說就直接max選0.5這個啦,但是我們又不希望每次都只選0.5,那咋辦?用softmax回歸來做。

y = tf.nn.softmax(model)

softmax回歸就是logistic回歸在多項分布上的拓展,又加入了soft元素,來使得我們的結果更加具有泛化能力。(這個需要我說的留言,下次立馬說,這裡先不說)。

官網的圖能直接說明他們的關係,這個網路夠複雜了吧?

好啦,定義完網路該開始定義用於訓練的隱藏層了。

一個叫損失函數的原名叫交叉熵小東西出現了,咱整個神經網路的目標,就是把這個值變小變小再變小,越小越好最好全局最小。

cross_entropy = - tf.reduce_sum( y_ * tf.log(y))

怎麼把它變小呢?定義一個訓練的步,專門用來訓練的。有的演算法能概率比較大達到全局最小,有的演算法因為過擬合或者什麼原因只能達到局部最小值。咱這裡定義的就是一個使用以0.01學習率(步長)的梯度下降演算法來最小化我們上面定義的損失函數。

train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

華麗麗的分割線,好了到這裡我們的網路就定義完了,上面的一切都只是定義,並沒有跑起來。該給它投食了,該投多少食自己看著辦,我這裡投1000次,每次投100個數據。訓練的過程就是每次拿一些數據,求損失函數最小值,然後把這個得到最小值的w和b,以加權的形式合併到原有的變數w和b上面去。

初始化一個會話,tensorflow一切一切的操作都只能在用會話來驅動。

sess = tf.Session()

初始化所有的變數,不跑這個,變數是不會自己初始化的喔。

sess.run(tf.initialize_all_variables())

for i in range(1000): batch_xs , batch_ys = mnist.train.next_batch(100) sess.run(train_step , feed_dict={x : batch_xs , y_ : batch_ys})

網路訓練完了,該開始測試了吧?這裡沒啥好說的,有一個地方要特別說一下,tf.argmax(y,1)。這個地方就是說,y值可能是一個十維的向量,找到這個向量裡面的最大值,並把它置為1。這樣就可以對比由網路輸出的y和我們已經打好的標籤y_了。

correct_prediction = tf.equal(tf.argmax(y,1) , tf.argmax(y_,1))accuray = tf.reduce_mean(tf.cast(correct_prediction,"float"))print sess.run(accuray , feed_dict={x:mnist.test.images , y_:mnist.test.labels})

至此,神經網路已經完成啦,接下來如果需要用於實時預測,那麼直接就調用已經訓練好的神經網路就行了。

result = sess.run(tf.argmax(y,1), feed_dict={x:SomeData})

持久化的話,tensorflow提供了saver這個小東西,我會慢慢說噠。

好啦,吾輩笨愚,小夥伴們對神經網路的恐懼有沒有少一丟丟丟呢??


推薦閱讀:

scikit-learn實戰

TAG:機器學習 |