基於深度學習的圖像目標識別預測 | 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 模塊,當構建完模型後即可對一幅圖識別概率預測。
微信群&交流合作
- 加入微信群:不定期分享資料,拓展行業人脈請在公眾號留言:「微信號+名字+研究領域/專業/學校/公司」,我們將很快與您聯繫。
- 投稿(無稿費)、交流合作事宜請留言聯繫。
http://weixin.qq.com/r/AC91bd-EloLprZsO93oS (二維碼自動識別)
推薦閱讀:
※TensorFlow的Debugger調試實例
※TensorFlow Estimator of Deep CTR --DeepFM/NFM/AFM/FNN/PNN
※安裝 TensorFlow 之 textsum 文章自動摘要
※YJango的前饋神經網路--代碼LV3
TAG:AI技術 | 圖像識別 | TensorFlow |