基於深度學習的圖像目標識別預測 | CV | Tensorflow | Keras

點擊藍色字體,關註:九三智能控

在人工智慧研究的大潮中,如何模擬人類對於靜態或動態目標的有效識別預測一直是研究熱點,通過智能技術實現對於目標特徵的學習並對特定目標進行快速識別,預測得出目標識別概率,實現基於深度學習模型在複雜背景、不確定外部干擾下的高精度、實時識別目標,能夠保持或者優於有豐富經驗人員的識別效果。

基礎操作

首先,安裝Keras、TensorFlow,將TensorFlow作為後端,先去安裝TensorFlow。一旦,安裝完成了 TensorFlow,只需要使用 pip 很容易的安裝 Keras。

安裝 h5py,用於模型的保存和載入:

pip install h5py

pip install numpy scipy

pip install pillow

sudo pip install keras

使用以下命令來查看 Keras 版本。

>>> import kerasUsing TensorFlow backend.

>>> keras.__version__2.0.4

一旦,Keras 被安裝完成,需要去修改後端文件,也就是去確定,需要 TensorFlow 作為後端,還是 Theano 作為後端,修改的配置文件位於 ~/.keras/keras.json 。具體配置如下:

{

"floatx": "float32",

"epsilon": 1e-07,

"backend": "tensorflow",

"image_data_format": "channels_last"

}

請注意,參數 image_data_format 是 channels_last ,也就是說這個後端是 TensorFlow。因為,在TensorFlow中圖像的存儲方式是[height, width, channels],但是在Theano中是完全不同的,也就是 [channels, height, width]。因此,如果沒有正確的設置這個參數,那麼你模型的中間結果將是非常奇怪的。對於Theano來說,這個參數就是channels_first。

在Keras中主要的數據結構是 model ,該結構定義了一個完整的圖。可以向已經存在的圖中加入任何的網路結構。

import keras

Keras 有兩種不同的建模方式:

1. Sequential models:這種方法用於實現一些簡單的模型。你只需要向一些存在的模型中添加層就行了。

2. Functional API:Keras的API是非常強大的,你可以利用這些API來構造更加複雜的模型,比如多輸出模型,有向無環圖等等。

序列模型

將解決一個簡單的線性回歸問題進行建模示例,以下代碼是如何開始導入和構建序列模型。

from keras.models import Sequential

models = Sequential()

接下來可以向模型中添加 Dense(full connected layer),Activation,Conv2D,MaxPooling2D函數。

from keras.layers import Dense, Activation, Conv2D, MaxPooling2D, Flatten, Dropout

model.add(Conv2D(64, (3,3), activation=relu, input_shape = (100,100,32)))

# This ads a Convolutional layer with 64 filters of size 3 * 3 to the graph

以下是如何將一些最流行的圖層添加到網路中。

1. 卷積層

這裡使用一個卷積層,64個卷積核,維度是33的,之後採用 relu 激活函數進行激活,輸入數據的維度是 `100100*32`。注意,如果是第一個卷積層,那麼必須加上輸入數據的維度,後面幾個這個參數可以省略。

model.add(Conv2D(64, (3,3), activation=relu, input_shape = (100,100,32)))

2. MaxPooling 層

指定圖層的類型,並且指定赤的大小,然後自動完成赤化操作,酷斃了!

model.add(MaxPooling2D(pool_size=(2,2)))

3. 全連接層

這個層在 Keras 中稱為被稱之為 Dense 層,只需要設置輸出層的維度,然後Keras就會幫助自動完成了。

model.add(Dense(256, activation=relu))

4. Dropout

model.add(Dropout(0.5))

5. 扁平層

model.add(Flatten())

6. 數據輸入

網路的第一層需要讀入訓練數據。因此我們需要去制定輸入數據的維度。因此,input_shape 參數被用於制定輸入數據的維度大小。

model.add(Conv2D(32, (3,3), activation=relu, input_shape=(224, 224, 3)))

在這個例子中,數據輸入的第一層是一個卷積層,輸入數據的大小是 224*224*3 。

以上操作利用序列模型構建了一個模型。一旦指定了一個網路架構,還需要指定優化器和損失函數。在Keras中使用compile函數來達到這個功能。比如,在下面的代碼中,使用 rmsprop 來作為優化器,binary_crossentropy 來作為損失函數值。

model.compile(loss=binary_crossentropy, optimizer=rmsprop)

如果想要使用隨機梯度下降,那麼需要選擇合適的初始值和超參數:

from keras.optimizers import SGD

sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)

model.compile(loss=categorical_crossentropy, optimizer=sgd)

現在,已經構建完了模型。接下來,讓向模型中輸入數據,在Keras中是通過 fit 函數來實現的。也可以在該函數中指定 batch_size 和 epochs 來訓練。

model.fit(x_train, y_train, batch_size = 32, epochs = 10, validation_data(x_val, y_val))

最後,使用 evaluate 函數來測試模型的性能。

score = model.evaluate(x_test, y_test, batch_size = 32)

這些就是使用序列模型在Keras中構建神經網路的具體操作步驟。

線性回歸

在線性回歸問題中,可以得到很多的數據點,然後需要使用一條直線去擬合這些離散點。在這個例子中,創建了100個離散點,然後用一條直線去擬合它們。

a) 創建訓練數據

TrainX 的數據範圍是 -1 到 1,TrainY 與 TrainX 的關係是3倍,並且加入了一些雜訊點。

import keras

from keras.models import Sequential

from keras.layers import Dense

import numpy as np

trX = np.linspace(-1, 1, 101)

trY = 3 * trX + np.random.randn(*trX.shape) * 0.33

b) 構建模型

首先需要構建一個序列模型。需要的只是一個簡單的鏈接,因此只需要使用一個 Dense 層就夠了,然後用線性函數進行激活。

model = Sequential()

model.add(Dense(input_dim=1, output_dim=1, init=uniform, activation=linear))

下面的代碼將設置輸入數據 x,權重 w 和偏置項 b。具體的初始化工作如下:

weights = model.layers[0].get_weights()

w_init = weights[0][0][0]

b_init = weights[1][0]

print(Linear regression model is initialized with weights w: %.2f, b: %.2f % (w_init, b_init))

## Linear regression model is initialized with weight w: -0.03, b: 0.00

現在,可以l利用自己構造的數據 trX 和 trY 來訓練這個線性模型,其中 trY 是 trX 的3倍。因此,權重 w 的值應該是 3。

使用簡單的梯度下降來作為優化器,均方誤差(MSE)作為損失值。如下:

model.compile(optimizer=sgd, loss=mse)

最後,使用 fit 函數來輸入數據。

model.fit(trX, trY, nb_epoch=200, verbose=1)

在經過訓練之後,再次列印權重:

weights = model.layers[0].get_weights()

w_final = weights[0][0][0]

b_final = weights[1][0]

print(Linear regression model is trained to have weight w: %.2f, b: %.2f % (w_final, b_final))

##Linear regression model is trained to have weight w: 2.94, b: 0.08

在運行 200 輪之後,現在權重非常接近於 3。可以將運行的輪數修改為區間 [100, 300] 之間,然後觀察輸出結構有什麼變化。

一旦利用Keras完成了訓練,就可以將的網路保存在HDF5裡面。當然,你需要先安裝 h5py。HDF5 格式非常適合存儲大量的數字,並從 numpy 處理這些數據。比如,可以輕鬆的將存儲在磁碟上的多TB數據集進行切片,就好像他們是真正的 numpy 數組一樣。還可以將多個數據集存儲在單個文件中,遍歷他們或者查看 .shape 和 .dtype 屬性。

如果要保存訓練好的權重,那麼可以直接使用 save_weights 函數。

model.save_weights("my_model.h5")

載入預訓練權重,如果想要載入以前訓練好的模型,那麼可以使用 load_weights 函數。

model.load_weights(my_model_weights.h5)

應用級複雜神經網路舉例

如果對於簡單的模型和問題,那麼序列模型是非常好的方式。但是如果要構建一個現實世界中複雜的網路,那麼就需要知道一些功能性的API,在很多流行的神經網路中都有一個最小的網路結構,完整的模型是根據這些最小的模型進行疊加完成的。這些基礎的API可以讓一層一層的構建模型。因此,只需要很少的代碼就可以來構建一個完整的複雜神經網路。

首先,需要導入一些包。

from keras.models import Model

現在,需要去指定輸入數據,而不是在順序模型中,在最後的 fit 函數中輸入數據。這是序列模型和這些功能性的API之間最顯著的區別之一。使用 input() 函數來申明一個 1*28*28 的張量。

from keras.layers import Input

## First, define the vision modules

digit_input = Input(shape=(1, 28, 28))

現在,讓來利用API設計一個卷積層,需要指定要在在哪個層使用卷積網路,具體代碼這樣操作:

x = Conv2D(64, (3, 3))(digit_input)

x = Conv2D(64, (3, 3))(x)

x = MaxPooling2D((2, 2))(x)

out = Flatten()(x)

最後,對於指定的輸入和輸出數據來構建一個模型。

vision_model = Model(digit_input, out)

當然,還需要指定損失函數,優化器等等。

在進行圖像目標識別時可以使用的模型有很多,但是通常圖像目標識別對於計算資源要求很高,而equeezeNet 是一個非常了不起的網路架構,它的顯著點不在於對正確性有多少的提高,而是減少了計算量。當SequeezeNet的正確性和AlexNet接近時,但是ImageNet上面的預訓練模型的存儲量小於5 MB,這對於在現實世界中使用CNN是非常有利的。SqueezeNet模型引入了一個 Fire模型,它由交替的 Squeeze 和 Expand 模塊組成。

SqueezeNet fire module

對 fire 模型進行多次複製,從而來構建完整的網路模型,具體如下:

為了去構建這個網路,將利用Keras API的功能來構建一個單獨的 fire 模塊,當構建完模型後即可對一幅圖識別概率預測。

微信群&交流合作

  • 加入微信群:不定期分享資料,拓展行業人脈請在公眾號留言:「微信號+名字+研究領域/專業/學校/公司」,我們將很快與您聯繫。
  • 投稿(無稿費)、交流合作事宜請留言聯繫。

weixin.qq.com/r/AC91bd- (二維碼自動識別)


推薦閱讀:

TensorFlow的Debugger調試實例
TensorFlow Estimator of Deep CTR --DeepFM/NFM/AFM/FNN/PNN
安裝 TensorFlow 之 textsum 文章自動摘要
YJango的前饋神經網路--代碼LV3

TAG:AI技術 | 圖像識別 | TensorFlow |