1. 程式人生 > >【從傳統方法到深度學習】影象分類

【從傳統方法到深度學習】影象分類

1. 問題

Kaggle上有一個影象分類比賽Digit Recognizer,資料集是大名鼎鼎的MNIST——圖片是已分割 (image segmented)過的28*28的灰度圖,手寫數字部分對應的是0~255的灰度值,背景部分為0。

from keras.datasets import mnist

(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train[0] # .shape = 28*28
"""
[[  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 ...
 [  0   0   0   0   0   0   0   0   0   0   0   0   3  18  18  18 126 136
  175  26 166 255 247 127   0   0   0   0]
 [  0   0   0   0   0   0   0   0  30  36  94 154 170 253 253 253 253 253
  225 172 253 242 195  64   0   0   0   0]
 ...
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]]
"""

手寫數字圖片是長這樣的:

import matplotlib.pyplot as plt

plt.subplot(1, 3, 1)
plt.imshow(x_train[0], cmap='gray')
plt.subplot(1, 3, 2)
plt.imshow(x_train[1], cmap='gray')
plt.subplot(1, 3, 3)
plt.imshow(x_train[2], cmap='gray')
plt.show()

手寫數字識別可以看做是一個影象分類問題——對二維向量的灰度圖進行分類。

2. 識別

Rodrigo Benenson給出50種方法在MNIST的錯誤率。本文將從傳統方法過渡到深度學習,對比準確率來看。以下程式碼基於Python 3.6 + sklearn 0.18.1 + keras 2.0.4。

傳統方法

kNN

思路比較簡單:將二維向量拉直成一個一維向量,基於距離度量以判斷向量間的相似性。顯而易見,這種不帶特徵提取的樸素辦法,丟掉了二維向量中最重要的四周相鄰畫素的資訊。在比較乾淨的資料集MNIST還有不錯的表現,準確率為96.927%。此外,kNN模型訓練慢。

from sklearn import neighbors
from sklearn.metrics import precision_score

num_pixels = x_train[0].shape[0] * x_train[0].shape[1]
x_train = x_train.reshape((x_train.shape[0], num_pixels))
x_test = x_test.reshape((x_test.shape[0], num_pixels))

knn = neighbors.KNeighborsClassifier()
knn.fit(x_train, y_train)
pred = knn.predict(x_test)
precision_score(y_test, pred, average='macro') # 0.96927533865705706

MLP
多層感知器MLP (Multi Layer Perceptron)亦即三層的前饋神經網路,所採用的特徵與kNN方法類似——每一個畫素點的灰度值對應於輸入層的一個神經元,隱藏層的神經元數為700(一般介於輸入層與輸出層的數量之間)。sklearn的MLPClassifier實現MLP分類,下面給出基於keras的MLP實現。沒怎麼細緻地調參,準確率大概在98.530%左右。

from keras.layers import Dense
from keras.models import Sequential
from keras.utils import np_utils

# normalization
num_pixels = 28 * 28
x_train = x_train.reshape(x_train.shape[0], num_pixels).astype('float32') / 255
x_test = x_test.reshape(x_test.shape[0], num_pixels).astype('float32') / 255
# one-hot enconder for class
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)
num_classes = y_train.shape[1]

model = Sequential([
    Dense(700, input_dim=num_pixels, activation='relu', kernel_initializer='normal'),  # hidden layer
    Dense(num_classes, activation='softmax', kernel_initializer='normal')  # output layer
])
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.summary()

model.fit(x_train, y_train, validation_data=(x_test, y_test), epochs=600, batch_size=200, verbose=2)
model.evaluate(x_test, y_test, verbose=0)  # [0.10381294689745164, 0.98529999999999995]

深度學習

LeCun早在1989年發表的論文 [1]中提出了用CNN (Convolutional Neural Networks)來做手寫數字識別,後來 [2]又改進到Lenet-5,其網路結構如下圖所示:

卷積、池化、卷積、池化,然後套2個全連線層,最後接個Guassian連線層。眾所周知,CNN自帶特徵提取功能,不需要刻意地設計特徵提取器。基於keras,Lenet-5 非正式實現如下:

import keras
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Dense, Dropout, Flatten, Activation
from keras.models import Sequential
from keras.utils import np_utils

img_rows, img_cols = 28, 28
# TensorFlow backend: image_data_format() == 'channels_last'
x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1).astype('float32') / 255
x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1).astype('float32') / 255
# one-hot code for class
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)
num_classes = y_train.shape[1]

model = Sequential()
model.add(Conv2D(filters=6, kernel_size=(5, 5), padding='valid', input_shape=(28, 28, 1)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Activation("sigmoid"))

model.add(Conv2D(16, kernel_size=(5, 5), padding='valid'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Activation("sigmoid"))
model.add(Dropout(0.25))
# full connection
model.add(Conv2D(120, kernel_size=(1, 1), padding='valid'))
model.add(Flatten())
# full connection
model.add(Dense(84, activation='sigmoid'))
model.add(Dense(num_classes, activation='softmax'))

model.compile(loss=keras.losses.categorical_crossentropy,
              optimizer=keras.optimizers.SGD(lr=0.08, momentum=0.9),
              metrics=['accuracy'])
model.summary()
model.fit(x_train, y_train, batch_size=32, epochs=8,
          verbose=1, validation_data=(x_test, y_test))
model.evaluate(x_test, y_test, verbose=0)

以上三種方法的準確率如下:

特徵 分類器 準確率
gray kNN 96.927%
gray 3-layer neural networks 98.530%
Lenet-5 98.640%

3. 參考資料

[1] LeCun, Yann, et al. "Backpropagation applied to handwritten zip code recognition." Neural computation 1.4 (1989): 541-551.
[2] LeCun, Yann, et al. "Gradient-based learning applied to document recognition." Proceedings of the IEEE 86.11 (1998): 2278-2324.
[3] Taylor B. Arnold, Computer vision: LeNet-5, AlexNet, VGG-19, GoogLeNet.

相關推薦

傳統方法深度學習影象分類

1. 問題 Kaggle上有一個影象分類比賽Digit Recognizer,資料集是大名鼎鼎的MNIST——圖片是已分割 (image segmented)過的28*28的灰度圖,手寫數字部分對應的是0~255的灰度值,背景部分為0。 from keras.datasets import mnist (x

傳統方法深度學習情感分析

為了記錄在競賽中入門深度學習的過程,我開了一個新系列【從傳統方法到深度學習】。 1. 問題 Kaggle競賽Bag of Words Meets Bags of Popcorn是電影評論(review)的情感分析,可以視作為短文字的二分類問題(正向、負向)。標註資料集長這樣: id sentiment

神經網路與深度學習neural-style、chainer-fast-neuralstyle影象風格轉換使用

1. 安裝  我的作業系統是win10,裝了Anaconda,TensorFlow包是通過pip安裝的,中間沒什麼可說的.具體看TensorFlow官網就可以了. 2. 使用 python neural_style.py --content <content fi

神經網絡和深度學習筆記 - 第二章 反向傳播算法

討論 固定 特征 array sed 並不會 思想 隨機梯度 相關 上一章中我們遺留了一個問題,就是在神經網絡的學習過程中,在更新參數的時候,如何去計算損失函數關於參數的梯度。這一章,我們將會學到一種快速的計算梯度的算法:反向傳播算法。 這一章相較於後面的章節涉及到的數學

神經網路和深度學習筆記

文章導讀: 1.交叉熵損失函式   1.1 交叉熵損失函式介紹   1.2 在MNIST數字分類上使用交叉熵損失函式   1.3 交叉熵的意義以及來歷   1.4 Softmax 2. 過擬合和正則化   2.1 過擬合   2.2 正則化   2.3 為什麼正則化可以減輕

深度學習影象分類vgg到inception,到resnet

最近工作在做一件事情,就是把遊戲影象進行場景分類,相比於自然影象來說,遊戲影象種類較少,因此分類任務比較簡單,但是由於追求工程上的高精度和高效率,所以閱讀了vgg,inception,resnet等相關論文,並且都試了一下效果,算是對深度學習影象分類有了一個系統

計算機視覺神經網路與深度學習YOLO v2 detection訓練自己的資料

轉自:http://blog.csdn.net/hysteric314/article/details/54097845 說明 這篇文章是訓練YOLO v2過程中的經驗總結,我使用YOLO v2訓練一組自己的資料,訓練後的model,在閾值為.25的情況下,Reca

神經網路與深度學習計算機視覺SSD

背景介紹: 基於“Proposal + Classification” 的 Object Detection 的方法,R-CNN 系列(R-CNN、SPPnet、Fast R-CNN 以及 Faster R-CNN),取得了非常好的結果,但是在速度方面離實時效果還比較遠在提高 mAP 的同時兼顧速度,逐

深度學習影象分類入門,VGG16卷積神經網路開始

剛開始接觸深度學習、卷積神經網路的時候非常懵逼,不知道從何入手,我覺得應該有一個進階的過程,也就是說,理應有一些基本概念作為奠基石,讓你有底氣去完全理解一個龐大的卷積神經網路: 本文思路: 一、我認為學習卷積神經網路必須知道的幾個概念: 1、卷積過程:   我們經常說卷積

神經網路與深度學習Google Protocol Buffer介紹

簡介 什麼是 Google Protocol Buffer? 假如您在網上搜索,應該會得到類似這樣的文字介紹: Google Protocol Buffer( 簡稱 Protobuf) 是 Google 公司內部的混合語言資料標準,目前已經正在使用的有超過 48,162 種報文格式定義和超過 12,1

神經網路與深度學習C/C++ZLIB學習

zlib(http://zlib.NET/)提供了簡潔高效的In-Memory資料壓縮和解壓縮系列API函式,很多應用都會用到這個庫,其中compress和uncompress函式是最基本也是最常用的。不過很奇怪的是,compress和uncompress函式儘管已經非常

神經網路與深度學習Win10+VS2015 caffe環境搭建(極其詳細)

caffe是好用,可是配置其環境實在是太痛苦了,依賴的庫很多不說,在VS上編譯還各種報錯,你能想象那種被一百多個紅色提示所籠罩的恐懼。  且網上很多教程是VS2013環境下編譯的,問人很多也說讓我把15解除安裝了裝13,我的答案是:偏不  記下這個艱難的過程,萬一還要再來

神經網路與深度學習Caffe原始碼中各種依賴庫的作用及簡單使用

1.      Boost庫:它是一個可移植、跨平臺,提供原始碼的C++庫,作為標準庫的後備。 在Caffe中用到的Boost標頭檔案包括: (1)、shared_ptr.hpp:智慧指標,使用它可以不需要考慮記憶體釋放的問題; (2)、date_time/posi

神經網路與深度學習C/C++使用blas做矩陣乘法

#define min(x,y) (((x) < (y)) ? (x) : (y)) #include <stdio.h> #include <stdlib.h> #include <cublas_v2.h> #include <iostream>

神經網路與深度學習計算機視覺Fast R-CNN

先回歸一下: R-CNN ,SPP-net R-CNN和SPP-net在訓練時pipeline是隔離的:提取proposal,CNN提取特徵,SVM分類,bbox regression。 Fast R-CNN 兩大主要貢獻點 : 1 實現大部分end-to-end訓練(提proposal階段除外):

乾貨丨深度學習影象分類入門,VGG16卷積神經網路開始

剛開始接觸深度學習、卷積神經網路的時候非常懵逼,不知道從何入手,我覺得應該有一個進階的過程,也就

深度學習影象分類,定位檢測,語義分割,例項分割方法

計算機視覺領域四大基本任務中的應用,包括分類(圖a)、定位、檢測(圖b)、語義分割(圖c)、和例項分割(圖d)。 一、影象分類(image classification) 給定一張輸入影象,影象分類任務旨在判斷該影象所屬類別。 (1) 影象分類常用資料集 以下

深度學習影象分類模型AlexNet解讀

版權宣告:本文為博主原創文章 https://blog.csdn.net/sunbaigui/article/details/39938097 在imagenet上的影象分類challenge上Alex提出的alexnet網路結構模型贏得了2012屆的冠軍。要研究CNN型別

深度學習影象分類中的發展

深度學習是一門比較年輕的研究方向,從機器視覺到語音識別,以及自然語言識別等領域都有它的身影。說實話,喵哥此前只是知道有這個學科,但是並不清楚它到底是什麼,怎麼使用它。其實現在也是一無所知,但是我越發覺得深度學習是我們今後特別需要的專業,今天寫下這篇綜述性的文章,希望可以對以後

PaddlePaddle | 深度學習 101- 影象分類

本人僅以 PaddlePaddle 深度學習 101 官網教程為指導,添加個人理解和筆記,僅作為學習練習使用,若有錯誤,還望批評指教。–ZJ 環境: - Python 2.7 - Ubuntu 16.04 影象分類 本教程原始碼目錄在bo