http://www.jianshu.com/p/4195577585e6
基於tensorflow的MNIST手寫字識別(一)--白話卷積神經網絡模型
一、本文的意義
因為谷歌官方其實已經寫了MNIST入門和深入兩篇教程了,那我寫這些文章又是為什么呢,只是抄襲?那倒並不是,更准確的說應該是筆記吧,然后用更通俗的語言來解釋,並且補充更多,官方文章中沒有詳細展開的一些知識點,不過建議與官方文章結合着閱讀。
另外是代碼部分的改動,官方的demo只提供了驗證精確度,我將它改造成了能輸入並預測輸出結果的代碼也就是說是一個從准備待測圖片到最終是別的一個完整demo
中文版本:MNIST機器學習入門
http://wiki.jikexueyuan.com/project/tensorflow-zh/tutorials/mnist_beginners.html
demo截圖如下,會將放進去的圖片預測,然后輸出結果,代碼說明請看github的readme(最底下)

官網:http://yann.lecun.com/exdb/mnist/
這個MNIST數據庫是一個手寫數字的數據庫,它提供了六萬的訓練集和一萬的測試集。
它的圖片是被規范處理過的,是一張被放在中間部位的28px*28px的灰度圖
總共4個文件:
train-images-idx3-ubyte: training set images
train-labels-idx1-ubyte: training set labels
t10k-images-idx3-ubyte: test set images
t10k-labels-idx1-ubyte: test set labels
圖片都被轉成二進制放到了文件里面,
所以,每一個文件頭部幾個字節都記錄着這些圖片的信息,然后才是儲存的圖片信息
TRAINING SET LABEL FILE (train-labels-idx1-ubyte):
[offset] [type] [value] [description]
0000 32 bit integer 0x00000801(2049) magic number (MSB first)
0004 32 bit integer 60000 number of items
0008 unsigned byte ?? label
0009 unsigned byte ?? label
........
xxxx unsigned byte ?? label
The labels values are 0 to 9.
TRAINING SET IMAGE FILE (train-images-idx3-ubyte):
[offset] [type] [value] [description]
0000 32 bit integer 0x00000803(2051) magic number
0004 32 bit integer 60000 number of images
0008 32 bit integer 28 number of rows
0012 32 bit integer 28 number of columns
0016 unsigned byte ?? pixel
0017 unsigned byte ?? pixel
........
xxxx unsigned byte ?? pixel
每個像素被轉成了0-255,0代表着白色,255代表着黑色。
TEST SET LABEL FILE (t10k-labels-idx1-ubyte):
[offset] [type] [value] [description]
0000 32 bit integer 0x00000801(2049) magic number (MSB first)
0004 32 bit integer 10000 number of items
0008 unsigned byte ?? label
0009 unsigned byte ?? label
........
xxxx unsigned byte ?? label
The labels values are 0 to 9.
TEST SET IMAGE FILE (t10k-images-idx3-ubyte):
[offset] [type] [value] [description]
0000 32 bit integer 0x00000803(2051) magic number
0004 32 bit integer 10000 number of images
0008 32 bit integer 28 number of rows
0012 32 bit integer 28 number of columns
0016 unsigned byte ?? pixel
0017 unsigned byte ?? pixel
........
xxxx unsigned byte ?? pixel
每個像素被轉成了0-255,0代表着白色,255代表着黑色。
1、將要識別的圖片轉為灰度圖,並且轉化為28*28矩陣(單通道,每個像素范圍0-255,0為黑色,255為白色,這一點與MNIST中的正好相反)
2、將28*28的矩陣轉換成1維矩陣(也就是把第2,3,4,5....行矩陣紛紛接入到第一行的后面)
3、用一個1*10的向量代表標簽,也就是這個數字到底是幾,舉個例子e數字1對應的矩陣就是[0,1,0,0,0,0,0,0,0,0]
4、softmax回歸預測圖片是哪個數字的概率
5、用交叉熵和梯度下降法訓練參數
這個部分其實是比較重要的,因為如果處理不得當可能並不一定會有很好的結果,所以按照mnist的標准規范需要將待測圖片轉為28×28且文字居中的灰度圖(其實彩色的也可以,不過就是最后代碼需要改一下),目前介紹兩種獲得待測圖片的方法:
1、自己用ps或者真的手寫一些數字
2、將MNIST數據庫中的二進制轉化成圖片,然后用來做測試
如圖所示,根據黑色部分的濃淡將其轉化成微一個浮點數的數組,(白色0,黑色1)

看到這里,如果你跟我一樣不熟悉python,是不是開始方了,沒事,其實python很厲害,自帶的PIL圖片庫一句話就可以搞定
img=array(Image.open(filename)) //打開然后就被numpy轉化了
如果是彩色的圖片,則需要先將它這樣子轉換一下(我當初並不知道可以轉化,傻不垃圾地自己寫了一個轉化,所以python還是好好學習啊)
im=Image.open("test_num3/8_3.png")
Lim = img=array(im.convert("L"))
轉化為一維的矩陣其實並不難,用python的reshape就能搞定,還是要講一下標簽的表示方法,這個曾經令隊友疑惑不久,直到我把這個數組打印出來
監督學習:利用一組已知類別的樣本調整分類器的參數,使其達到所要求性能的過程,也稱為監督訓練或有教師學習舉個例子,MNIST自帶了訓練圖片和訓練標簽,每張圖片都有一個對應的標簽,比如這張圖片是1,標簽也就是1,用他們訓練程序,之后程序也就能識別測試集中的圖片了,比如給定一張2的圖片,它能預測出他是2
無監督學習:其中很重要的一類叫聚類舉個例子,如果MNIST中只有訓練圖片,沒有標簽,我們的程序能夠根據圖片的不同特征,將他們分類,但是並不知道他們具體是幾,這個其實就是“聚類”
在這里標簽的表示方式有些特殊,它也是使用了一個一維數組,而不是單純的數字,上面也說了,他是一個一位數組,0表示方法[1,0,0,0,0,0,0,0,0,0],1表示[0,1,0,0,0,0,0,0,0,0],.........,
主要原因其實是這樣的,因為softmax回歸處理后會生成一個1*10的數組,數組[0,0]的數字表示預測的這張圖片是0的概率,[0,1]則表示這張圖片表示是1的概率......以此類推,這個數組表示的就是這張圖片是哪個數字的概率(已經歸一化),
因此,實際上,概率最大的那個數字就是我們所預測的值。兩者對應來看,標准的標簽就是表示圖片對應數字的概率為100%,而表示其它數字的概率為0,舉個例子,0表示[1,0,0,0,0,0,0,0,0,0],可以理解為它表示0的概率為100%,而表示別的數字的概率為0.
這是一個分類器,可以認為是Logistic回歸的擴展,Logistic大家應該都聽說過,就是生物學上的S型曲線,它只能分兩類,用0和1表示,這個用來表示答題對錯之類只有兩種狀態的問題時足夠了,但是像這里的MNIST要把它分成10類,就必須用softmax來進行分類了。
P(y=0)=p0,P(y=1)=p1,p(y=2)=p2......P(y=9)=p9.這些表示預測為數字i的概率,(跟上面標簽的格式正好對應起來了),它們的和為1,即 ∑(pi)=1。
tensorflow實現了這個函數,我們直接調用這個softmax函數即可,對於原理,可以參考下面的引文,這里只說一下我們這個MNIST demo要用softmax做什么。
(注:每一個神經元都可以接收來自網絡中其他神經元的一個或多個輸入信號,神經元與神經元之間都對應着連接權值,所有的輸入加權和決定該神經元是處於激活還是抑制狀態。感知器網絡的輸出只能取值0或1,不具備可導性。而基於敏感度的訓練算法要求其輸出函數必須處處可導,於是引入了常見的S型可導函數,即在每個神經元的輸出之前先經過S型激活函數的處理。)
通俗一點就是,方差大家都知道吧,用它可以衡量預測值和實際值的相差程度,交叉熵其實也是一樣的作用,那為什么不用方差呢,因為看sigmoid函數的圖像就會發現,它的兩側幾乎就是平的,導致它的方差在大部分情況下很小,這樣在訓練參數的時候收斂地就會很慢,交叉熵就是用來解決這個問題的,它的公式是
,其中,y是我們預測的概率分布,y'是實際的分布。

上面那步也說了,有個交叉熵,根據大伙對方差的理解,值越小,自然就越好,因此我們也要訓練使得交叉熵最小的參數,這里梯度下降法就派上用場了,這個解釋見上一篇系列文章吧,什么叫訓練參數呢,可以想象一下,我們先用實際的值在二位坐標上畫一條線,然后我們希望我們預測出來的那些值要盡可能地貼近這條線,我們假設生成我們這條線的公式ax+ax^2+bx^3+.....,我們需要生成這些系數,要求得這些系數,我們就需要各種點代入,然后才能求出,所以其實訓練參數跟求參數是個類似的過程。
4.7 預測
訓練結束以后我們就可以用這個模型去預測新的圖片了,就像我們已經求出來了方程,以后只要隨意輸入一個x,就能求出對應的y。
https://github.com/wlmnzf/tensorflow-train/tree/master/mnist
http://blog.csdn.net/acdreamers/article/details/44663305softmax回歸
http://wiki.jikexueyuan.com/project/tensorflow-zh/tutorials/mnist_beginners.html MNIST學習入門
http://blog.csdn.net/u012162613/article/details/44239919交叉熵代價函數
作者:會打代碼的掃地王大爺
鏈接:http://www.jianshu.com/p/4195577585e6
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。