作者:chen_h
微信号 & QQ:862251340
微信公众号:coderpai
本博客是从梁斌博士的博客上面复制过来的,本人利用 Tensorflow 重新实现了博客中的代码
深度学习有一个重要的概念叫 autoencoder ,这是个什么东西呢,本文通过一个例子来普及这个术语。
简单来说 autoencoder 是一个压缩编码器,也就是对 input 的一坨东西通过变换,输出和 input 一样的东西。例如 input 是一个鸡, output 也是一个鸡, input 是一个鸭, output 也是一个鸭。学术一点说就是找到一个函数能够使得 Function(input) = input ,叫做 identity function 。如上图所示,即学习 Hw,b(x)=x 。
但这和深度学习有什么关系呢? 这就要说到压缩编码,我们都知道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表示,当然还需要保持边的权重,但这些边权重只需要一份,在输入足够复杂的时候,压缩表示是有价值的。
那压缩表示有什么价值呢?比如一组广告,一条新闻,人看了挺好,压缩表示后,人看起来就不爽了,恰恰是人看着不爽了,机器就好处理了,下回再说。
实验代码如下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
def 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 out
x = 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(tf.sub(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})
index = np.argmax(res, 1)
for i in xrange(4):
tmp = np.zeros((4,))
tmp[index[i]] = 1.
print res[i]
print tmp
Reference:
UFLDL
小白学Tensorflow之自编码Autoencoder