Autoencoder及tensorflow實現
來自專欄 機器學習
為了在論文中應用自編碼解碼來進行異常檢測,寫了這篇博客,主要從梁斌博士的博客上面複製過來的,並且參考chen_h的博文 Tensorflow 重新實現了博客中的代碼,後期會放入github中
深度學習有一個重要的概念叫 autoencoder ,這是個什麼東西呢,本文通過一個例子來普及這個術語。
簡單來說 autoencoder 是一個壓縮編碼器,也就是對 input 通過變換,輸出和 input 一樣的東西。例如 input 是一個雞, output 也是一個雞, input 是一個鴨, output 也是一個鴨。學術一點說就是找到一個函數能夠使得 Function(input) = input ,叫做 identity function 。如上圖所示,即學習 .
但這和深度學習有什麼關係呢? 這就要說到壓縮編碼,我們都知道input需要有一種編碼形式,如果我們能在函數內部找到一個更簡潔的編碼形式,那麼這個變換過程就等價於學習到了一種壓縮表示的函數,能夠少量的存儲形式來表示原本較複雜的但信息冗餘較大的表示形式。
我們下面的代碼中舉了一個精彩的例子(這個例子是從同學的一次實驗中直接受啟發,我只是按照自己的理解實現了一把,例子非原創)。在這個例子中,input是4個不同的數字,分別是
(0,0,0,1)可以看作1 (0,0,1,0)可以看作2 (0,1,0,0)可以看作3 (1,0,0,0)可以看作4因為所有的 input 只有這4種,因此其實用4個bit是不經濟的,存在壓縮表示的可能性,比如2個bit就可以表示這4個不同的數。
那麼我們設計了輸入層是 4+1 個神經元(4個神經元接受4bit編碼的input,1個神經元是常數項,這個用來做先驗的);隱藏層是 2+1 個神經元(因為我們實現已經知道2個bit就夠了,所以2個隱藏層,具有足夠的表達能力);輸出層是 4 個神經元(為了能讓輸出和輸入保持一致)。
通過數輪迭代,我們看到如下的情況:
(0,0,0,1)->(0.99,0.09)->(0.06,0.00,0.01,0.91) (0,0,1,0)->(0.85,0.99)->(0.00,0.07,0.90,0.07) (0,1,0,0)->(0.01,0.67)->(0.06,0.87,0.11,0.00) (1,0,0,0)->(0.12,0.00)->(0.89,0.10,0.00,0.02) input_layer hidden_layer output_layer
我們可以看出,hidden層的編碼恰好可以看作是
(0.99,0.09) 1,0 (0.85,0.99) 1,1 (0.01,0.67) 0,1 (0.12,0.00) 0,0也就是說輸入的(0,0,0,1)可以被壓縮表示成(1,0),最終4bit的信息,可以用2bit表示,當然還需要保持邊的權重,但這些邊權重只需要一份,在輸入足夠複雜的時候,壓縮表示是有價值的。
那壓縮表示有什麼價值呢?比如一組廣告,一條新聞,人看了挺好,壓縮表示後,人看起來就不爽了,恰恰是人看著不爽了,機器就好處理了,下回再說。
Tensorflow實現如下
#! /usr/local/bin/python# -*- coding:utf-8 -*-import tensorflow as tfimport numpy as npdef model(x,w1,w2,b1,b2): a = tf.matmul(x,w1) b = tf.add(a,b1) c = tf.sigmoid(b) hidden = tf.sigmoid(tf.add(tf.matmul(x,w1),b1)) out = tf.nn.softmax(tf.add(tf.matmul(hidden,w2),b2)) return outx = tf.placeholder("float",[4,4])w1 = tf.Variable(tf.random_normal([4,2]),name=w1)w2 = tf.Variable(tf.random_normal([2,4]),name = w2)b1 = tf.Variable(tf.random_normal([2]),name = b1)b2 = tf.Variable(tf.random_normal([4]),name = b2)pred = model(x,w1,w2,b1,b2)cost = tf.reduce_sum(tf.pow(pred-x,2))optimizer = tf.train.AdamOptimizer().minimize(cost)with tf.Session() as sess: init = tf.initialize_all_variables() sess.run(init) input_data = np.array([[0,0,0,1],[0,0,1,0],[0,1,0,0],[1,0,0,0]],float) for i in xrange(10000): sess.run(optimizer,feed_dict={x:input_data}) res = sess.run(pred,feed_dict={x:input_data}) print res index = np.argmax(res,1) print index for i in xrange(4): tmp = np.zeros((4,)) tmp[index[i]]=1. print res[i] print tmp
得到結果
[ 1.05191693e-02 5.68247749e-04 1.96698848e-02 9.69242752e-01][ 0. 0. 0. 1.][ 4.83380754e-05 1.71381701e-02 9.65192318e-01 1.76211540e-02][ 0. 0. 1. 0.][ 1.75913218e-02 9.64919627e-01 1.66024622e-02 8.86660710e-04][ 0. 1. 0. 0.][ 9.71356690e-01 1.01418616e-02 1.51623710e-04 1.83499288e-02][ 1. 0. 0. 0.]
其中第1、3、5、7行為經過了encode、decode之後再用softmax進行歸一化的結果,第2、4、6、8行為取概率最大得到的結果,顯然與預期相符合
推薦閱讀:
※使用py-faster-rcnn進行目標檢測(object detect)
※從下往上看--新皮層資料的讀後感 第十一部分 hopfield-記憶的兩面
※動手實踐神經網路3: 用Excel實現多層全連接神經網路
※僅使用NumPy完成卷積神經網路CNN的搭建(附Python代碼)
※機器學習研究人員需要了解的8個神經網路架構(上)
TAG:TensorFlow | 神經網路 |