近年來,深度學習已經成爲機器學習的一大趨勢。它已成功地應用於解決視覺、語音識別和自然語言處理等領域以前無法解決的問題。有許多領域正在應用深度學習,並已顯示出其有用性。
Caffe(快速特徵嵌入的卷積結構)是在伯克利視覺和學習中心(BVLC)開發的一個深度學習框架。Caffe項目是楊慶佳在加州大學伯克利分校攻讀博士學位期間創建的。Caffe提供了一種簡單的方法來進行深入學習的實驗。它是用C++編寫的,提供了 python 和 Matlab < /b>的綁定。
它支持多種不同類型的深度學習體系結構,如卷積神經網絡、長短期記憶和完全連接。它支持GPU,因此非常適合於涉及深層神經網絡的生產環境。它還支持基於CPU的內核庫,如NVIDIA、CUDA深層神經網絡庫(cuDNN)和英特爾數學內核庫(英特爾MKL)。
2017年4月,美國社交網絡服務公司Facebook宣布了Caffe2,現在包括RNN(遞歸神經網絡),2018年3月,Caffe2併入Pythorch。Caffe2的創造者和社區成員已經創建了解決各種問題的模型。這些模型作爲預先訓練的模型提供給公衆。Caffe2幫助創建者使用這些模型並創建自己的網絡來對數據集進行預測。
在討論Caffe2的細節之前,讓我們先了解一下機器學習和深度學習之間的區別。這對於理解如何在Caffe2中創建和使用模型是必要的。
Machine Learning v/s Deep Learning
在任何一種機器學習算法中,無論是傳統算法還是深度學習算法,數據集中特徵的選擇對於獲得期望的預測精度都起著極其重要的作用。在傳統的機器學習技術中,特徵選擇主要是通過人的觀察、判斷和深入的領域知識來完成的。有時,您可以從一些經過測試的算法中尋求幫助以進行特徵選擇。
傳統的機器學習流程如下圖所示;
在深度學習中,特徵選擇是自動的,是深度學習算法本身的一部分。如下圖所示;
在深度學習算法中,特徵工程是自動完成的。一般來說,特徵工程是耗時的,並且需要在領域中很好的專業知識。爲了實現特徵的自動提取,深度學習算法通常需要大量的數據,因此如果你只有成千上萬的數據點,深度學習技術可能無法給你帶來令人滿意的結果。
在數據量較大的情況下,與傳統的ML算法相比,深度學習算法具有較少或不需要特徵工程的優點。
Caffe2 - Overview
現在,隨著您對深入學習的深入了解,讓我們來了解一下什麼是Caffe。
Training a CNN
讓我們學習訓練CNN對圖像進行分類的過程。這個過程包括以下步驟&負;
數據準備在這一步中,我們將圖像居中裁剪並調整大小,以便所有用於訓練和測試的圖像都具有相同的大小。這通常是通過在圖像數據上運行一個小的Python腳本來完成的。
模型定義在這個步驟中,我們定義一個CNN架構。配置存儲在.pb(protobuf)文件中。典型的CNN架構如下圖所示。
解算器定義−我們定義解算器配置文件。Solver進行模型優化。
模型培訓&負;我們使用內置的Caffe實用程序來培訓模型。培訓可能需要相當長的時間和CPU使用量。培訓完成後,Caffe將模型存儲在一個文件中,該文件稍後可用於測試數據和最終部署以進行預測。
What’s New in Caffe2
在Caffe2中,您會發現許多準備好使用的預先訓練的模型,並且還經常利用新模型和算法的社區貢獻。您創建的模型可以使用雲中的GPU功能輕鬆擴展,也可以使用移動平台上的mass及其跨平台庫。
Caffe2相對於Caffe的改進可概括如下&;
- Mobile deployment
- New hardware support
- Support for large-scale distributed training
- Quantized computation
- Stress tested on Facebook
Pretrained Model Demo
伯克利視覺和學習中心(BVLC)網站提供了他們預先訓練的網絡的演示。一個這樣的圖像分類網絡可以在這裡所述的連結上獲得,並在下面的螢幕截圖中描述。
在螢幕截圖中,狗的圖像被分類並用其預測精度標記。它還說,對圖像進行分類只需0.068秒。您可以通過指定圖像URL或在螢幕底部提供的選項中上載圖像本身來嘗試自己選擇的圖像。
Caffe2 - Installation
現在,你已經對Caffe2的功能有了足夠的了解,現在是時候自己來試驗Caffe2了。要使用預先訓練的模型或在自己的Python代碼中開發模型,必須首先在計算機上安裝Caffe2。
在Caffe2站點的安裝頁面上,連結https://caffe2.ai/docs/getting started.html您將看到以下內容來選擇您的平台和安裝類型。
正如您在上面的螢幕截圖中看到的,Caffe2支持幾種流行的平台,包括移動平台。
現在,我們將了解MacOS安裝的步驟,本教程中的所有項目都將在這些步驟上進行測試。
MacOS Installation
裝置可以有四種類型,如下所示;
- Pre-Built Binaries
- Build From Source
- Docker Images
- Cloud
根據您的偏好,選擇以上任意一種作爲安裝類型。這裡給出的說明是根據Caffe2安裝站點爲預構建二進位文件提供的。它使用水蟒來適應朱庇特環境。在控制台提示符下執行以下命令
pip install torch_nightly -f https://download.pytorch.org/whl/nightly/cpu/torch_nightly.html
除上述內容外,您還需要一些第三方庫,這些庫是使用以下命令安裝的−
conda install -c anaconda setuptools conda install -c conda-forge graphviz conda install -c conda-forge hypothesis conda install -c conda-forge ipython conda install -c conda-forge jupyter conda install -c conda-forge matplotlib conda install -c anaconda notebook conda install -c anaconda pydot conda install -c conda-forge python-nvd3 conda install -c anaconda pyyaml conda install -c anaconda requests conda install -c anaconda scikit-image conda install -c anaconda scipy
Caffe2網站中的一些教程還要求安裝zeromq,該程序使用以下命令−
conda install -c anaconda zeromq
Windows/Linux Installation
在控制台提示符下執行以下命令−
conda install -c pytorch pytorch-nightly-cpu
你一定注意到了,你需要水蟒來使用上面的裝置。您需要按照MacOS安裝中的說明安裝其他軟體包。
Testing Installation
爲了測試您的安裝,下面給出了一個小的Python腳本,您可以在Juypter項目中剪切粘貼並執行它。
from caffe2.python import workspace import numpy as np print ("Creating random data") data = np.random.rand(3, 2) print(data) print ("Adding data to workspace ...") workspace.FeedBlob("mydata", data) print ("Retrieving data from workspace") mydata = workspace.FetchBlob("mydata") print(mydata)
當您執行上述代碼時,您應該看到以下輸出−
Creating random data [[0.06152718 0.86448082] [0.36409966 0.52786113] [0.65780886 0.67101053]] Adding data to workspace ... Retrieving data from workspace [[0.06152718 0.86448082] [0.36409966 0.52786113] [0.65780886 0.67101053]]
此處顯示安裝測試頁的螢幕截圖,供您快速參考;
現在,您已經在計算機上安裝了Caffe2,請繼續安裝教程應用程式。
Tutorial Installation
使用控制台上的以下命令下載教程原始碼−
git clone --recursive https://github.com/caffe2/tutorials caffe2_tutorials
下載完成後,您將在安裝目錄中的caffe2_tutorials文件夾中找到幾個Python項目。此文件夾的螢幕截圖供您快速閱讀。
/Users/yourusername/caffe2_tutorials
您可以打開其中一些教程,查看Caffe2代碼的外觀。本教程中描述的下兩個項目主要基於上面顯示的示例。
現在是我們自己編寫Python代碼的時候了。讓我們了解一下,如何使用Caffe2的預先訓練模型。稍後,您將學習創建自己的小神經網絡,以便在自己的數據集上進行訓練。
Caffe2 - Verifying Access to Pre-Trained Models
在學習在Python應用程式中使用預先訓練的模型之前,讓我們首先驗證這些模型是否安裝在您的機器上,並且可以通過Python代碼訪問。
安裝Caffe2時,預培訓的模型將複製到安裝文件夾中。在安裝了Anaconda的機器上,以下文件夾中提供了這些型號。
anaconda3/lib/python3.7/site-packages/caffe2/python/models
查看計算機上的安裝文件夾以了解這些型號的存在。您可以嘗試使用以下簡短的Python腳本從安裝文件夾加載這些模型−
CAFFE_MODELS = os.path.expanduser("/anaconda3/lib/python3.7/site-packages/caffe2/python/models") INIT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'init_net.pb') PREDICT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'predict_net.pb') print(INIT_NET) print(PREDICT_NET)
當腳本成功運行時,您將看到以下輸出−
/anaconda3/lib/python3.7/site-packages/caffe2/python/models/squeezenet/init_net.pb /anaconda3/lib/python3.7/site-packages/caffe2/python/models/squeezenet/predict_net.pb
這確認擠壓網模塊已安裝在您的計算機上,並且您的代碼可以訪問它。
現在,您可以編寫自己的Python代碼,使用Caffe2squezenetpre-trained模塊進行圖像分類。
Image Classification Using Pre-Trained Model
在本課程中,您將學習使用預先訓練的模型來檢測給定圖像中的對象。您將使用擠壓網預先訓練的模塊,以極高的精度檢測和分類給定圖像中的對象。
打開一個新的Juypter筆記本,按照步驟開發這個圖像分類應用程式。
Importing Libraries
首先,我們使用以下代碼導入所需的包−
from caffe2.proto import caffe2_pb2 from caffe2.python import core, workspace, models import numpy as np import skimage.io import skimage.transform from matplotlib import pyplot import os import urllib.request as urllib2 import operator
接下來,我們設置幾個變量;
INPUT_IMAGE_SIZE = 227 mean = 128
用於訓練的圖像顯然大小不一。所有這些圖像必須轉換成一個固定的大小,以便進行準確的訓練。同樣,測試圖像和要在生產環境中預測的圖像也必須轉換爲大小,與培訓期間使用的大小相同。因此,我們在上面創建一個名爲INPUT_IMAGE_SIZE的變量,其值爲227。因此,在分類器中使用之前,我們會將所有圖像轉換爲大小227x227。
我們還聲明了一個名爲mean的變量,其值128,稍後將用於改進分類結果。
接下來,我們將開發兩個圖像處理功能。
Image Processing
圖像處理包括兩個步驟。第一個是調整圖像的大小,第二個是集中裁剪圖像。對於這兩個步驟,我們將編寫兩個用於調整大小和裁剪的函數。
Image Resizing
首先,我們將編寫一個調整圖像大小的函數。如前所述,我們將把圖像大小調整爲227x227。因此,讓我們定義函數resize如下−
def resize(img, input_height, input_width):
我們用寬度除以高度得到圖像的長寬比。
original_aspect = img.shape[1]/float(img.shape[0])
如果縱橫比大於1,則表示圖像很寬,即處於橫向模式。現在,我們調整圖像高度並使用以下代碼返回調整大小的圖像−
if(original_aspect>1): new_height = int(original_aspect * input_height) return skimage.transform.resize(img, (input_width, new_height), mode='constant', anti_aliasing=True, anti_aliasing_sigma=None)
如果縱橫比小於1,則表示縱向模式。我們現在使用下面的代碼調整寬度;
if(original_aspect<1): new_width = int(input_width/original_aspect) return skimage.transform.resize(img, (new_width, input_height), mode='constant', anti_aliasing=True, anti_aliasing_sigma=None)
如果縱橫比等於1,則不進行任何高度/寬度調整。
if(original_aspect == 1): return skimage.transform.resize(img, (input_width, input_height), mode='constant', anti_aliasing=True, anti_aliasing_sigma=None)
下面給出了完整的功能代碼,供您快速參考;
def resize(img, input_height, input_width): original_aspect = img.shape[1]/float(img.shape[0]) if(original_aspect>1): new_height = int(original_aspect * input_height) return skimage.transform.resize(img, (input_width, new_height), mode='constant', anti_aliasing=True, anti_aliasing_sigma=None) if(original_aspect<1): new_width = int(input_width/original_aspect) return skimage.transform.resize(img, (new_width, input_height), mode='constant', anti_aliasing=True, anti_aliasing_sigma=None) if(original_aspect == 1): return skimage.transform.resize(img, (input_width, input_height), mode='constant', anti_aliasing=True, anti_aliasing_sigma=None)
現在我們將編寫一個函數來裁剪圖像的中心。
Image Cropping
我們聲明crop_image函數如下−
def crop_image(img,cropx,cropy):
我們使用以下語句提取圖像的維度&負;
y,x,c = img.shape
我們使用以下兩行代碼爲圖像創建一個新的起點−
startx = x//2-(cropx//2) starty = y//2-(cropy//2)
最後,我們通過創建具有新維度的圖像對象來返回裁剪後的圖像;
return img[starty:starty+cropy,startx:startx+cropx]
下面給出了整個函數代碼,供您快速參考;
def crop_image(img,cropx,cropy): y,x,c = img.shape startx = x//2-(cropx//2) starty = y//2-(cropy//2) return img[starty:starty+cropy,startx:startx+cropx]
現在,我們將編寫代碼來測試這些函數。
Processing Image
首先,將圖像文件複製到項目目錄中的images子文件夾中。在項目中複製tree.jpg文件。下面的Python代碼加載圖像並將其顯示在控制台上−
img = skimage.img_as_float(skimage.io.imread("images/tree.jpg")).astype(np.float32) print("Original Image Shape: " , img.shape) pyplot.figure() pyplot.imshow(img) pyplot.title('Original image')
輸出如下所示;
請注意,原始圖像的大小爲600 x 960。我們需要將其調整到我們的規格227 x 227。調用前面定義的resize函數來完成這個任務。
img = resize(img, INPUT_IMAGE_SIZE, INPUT_IMAGE_SIZE) print("Image Shape after resizing: " , img.shape) pyplot.figure() pyplot.imshow(img) pyplot.title('Resized image')
輸出如下所示;
請注意,現在圖像大小爲227 x 363。我們需要將其裁剪爲227 x 227以作爲算法的最終提要。爲此,我們調用前面定義的crop函數。
img = crop_image(img, INPUT_IMAGE_SIZE, INPUT_IMAGE_SIZE) print("Image Shape after cropping: " , img.shape) pyplot.figure() pyplot.imshow(img) pyplot.title('Center Cropped')
下面提到的是代碼的輸出&;
此時,圖像的大小爲227 x 227,並準備好進行進一步處理。我們現在交換圖像軸,將三種顏色提取到三個不同的區域。
img = img.swapaxes(1, 2).swapaxes(0, 1) print("CHW Image Shape: " , img.shape)
下面給出的是輸出值;
CHW Image Shape: (3, 227, 227)
請注意,最後一個軸現在已成爲數組中的第一個維度。我們現在將使用以下代碼繪製三個通道−
pyplot.figure() for i in range(3): pyplot.subplot(1, 3, i+1) pyplot.imshow(img[i]) pyplot.axis('off') pyplot.title('RGB channel %d' % (i+1))
輸出如下所示;
最後,我們對圖像進行一些額外的處理,例如將紅綠藍轉換爲藍綠紅(RGB到BGR),去除平均值以獲得更好的結果,並使用以下三行代碼&減號添加批處理大小軸;
# convert RGB --> BGR img = img[(2, 1, 0), :, :] # remove mean img = img * 255 - mean # add batch size axis img = img[np.newaxis, :, :, :].astype(np.float32)
此時,您的圖像是NCHW格式的,可以輸入我們的網絡。接下來,我們將加載預先訓練好的模型文件,並將上面的圖像輸入其中進行預測。
Predicting Objects in Processed Image
我們首先爲Caffe的預先訓練模型中定義的init和predict網絡設置路徑。
Setting Model File Paths
請記住,在前面的討論中,所有經過預培訓的模型都安裝在models文件夾中。我們將此文件夾的路徑設置如下−
CAFFE_MODELS = os.path.expanduser("/anaconda3/lib/python3.7/site-packages/caffe2/python/models")
我們按照以下方式設置squezenet模型的init戔netprotobuf文件的路徑−
INIT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'init_net.pb')
同樣,我們設置了到predict_netprotobuf的路徑,如下所示−
PREDICT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'predict_net.pb')
我們列印這兩條路徑用於診斷目的&負;
print(INIT_NET) print(PREDICT_NET)
上面的代碼和輸出在這裡給出,供您快速參考;
CAFFE_MODELS = os.path.expanduser("/anaconda3/lib/python3.7/site-packages/caffe2/python/models") INIT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'init_net.pb') PREDICT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'predict_net.pb') print(INIT_NET) print(PREDICT_NET)
輸出如下所述;
/anaconda3/lib/python3.7/site-packages/caffe2/python/models/squeezenet/init_net.pb /anaconda3/lib/python3.7/site-packages/caffe2/python/models/squeezenet/predict_net.pb
接下來,我們將創建一個預測。
Creating Predictor
我們使用以下兩個語句來讀取模型文件−
with open(INIT_NET, "rb") as f: init_net = f.read() with open(PREDICT_NET, "rb") as f: predict_net = f.read()
通過將指針作爲參數傳遞給predictor函數來創建predictor。
p = workspace.Predictor(init_net, predict_net)
p對象是預測器,用於預測任何給定圖像中的對象。請注意,每個輸入圖像必須採用NCHW格式,就像我們之前對tree.jpg文件所做的那樣。
Predicting Objects
預測給定圖像中的對象很簡單——只需執行一行命令。對於給定圖像中的對象檢測,我們對predictor對象調用run方法。
results = p.run({'data': img})
預測結果現在可以在results對象中使用,我們將其轉換爲數組以提高可讀性。
results = np.asarray(results)
使用以下語句列印數組的維度以供您理解−
print("results shape: ", results.shape)
輸出如下所示;
results shape: (1, 1, 1000, 1, 1)
我們現在將刪除不必要的軸&負;
preds = np.squeeze(results)
現在可以通過獲取preds數組中的max值來檢索最上面的謂詞。
curr_pred, curr_conf = max(enumerate(preds), key=operator.itemgetter(1)) print("Prediction: ", curr_pred) print("Confidence: ", curr_conf)
輸出如下所示;
Prediction: 984 Confidence: 0.89235985
如您所見,該模型預測了一個索引值984且置信度89%的對象。984的指數對我們理解探測到什麼樣的物體沒有多大意義。我們需要使用對象的索引值獲取該對象的字符串化名稱。github存儲庫中提供了模型識別的對象類型及其相應的索引值。
現在,我們將看到如何檢索索引值爲984的對象的名稱。
Stringifying Result
我們創建一個指向github存儲庫的URL對象,如下所示−
codes = "https://gist.githubusercontent.com/aaronmarkham/cd3a6b6ac0 71eca6f7b4a6e40e6038aa/raw/9edb4038a37da6b5a44c3b5bc52e448ff09bfe5b/alexnet_codes"
我們閱讀了URL的內容;
response = urllib2.urlopen(codes)
響應將包含所有代碼及其說明的列表。下面的幾行響應可以幫助您理解它包含的內容;
5: 'electric ray, crampfish, numbfish, torpedo', 6: 'stingray', 7: 'cock', 8: 'hen', 9: 'ostrich, Struthio camelus', 10: 'brambling, Fringilla montifringilla',
現在,我們使用afor循環遍歷整個數組以定位所需的984代碼,如下所示−
for line in response: mystring = line.decode('ascii') code, result = mystring.partition(":")[::2] code = code.strip() result = result.replace("'", "") if (code == str(curr_pred)): name = result.split(",")[0][1:] print("Model predicts", name, "with", curr_conf, "confidence")
當您運行代碼時,您將看到以下輸出;
Model predicts rapeseed with 0.89235985 confidence
現在可以在另一個圖像上嘗試該模型。
Predicting a Different Image
要預測另一個圖像,只需將圖像文件複製到項目目錄的images文件夾中。這是以前的tree.jpg文件存儲的目錄。更改代碼中圖像文件的名稱。只需更改一次,如下所示
img = skimage.img_as_float(skimage.io.imread("images/pretzel.jpg")).astype(np.float32)
原始圖片和預測結果如下所示;
輸出如下所述;
Model predicts pretzel with 0.99999976 confidence
如您所見,預先訓練的模型能夠以非常高的精度檢測給定圖像中的對象。
Full Source
上述代碼的完整原始碼使用預先訓練的模型來檢測給定圖像中的對象,這裡將提到這些代碼,供您快速參考;
def crop_image(img,cropx,cropy): y,x,c = img.shape startx = x//2-(cropx//2) starty = y//2-(cropy//2) return img[starty:starty+cropy,startx:startx+cropx] img = skimage.img_as_float(skimage.io.imread("images/pretzel.jpg")).astype(np.float32) print("Original Image Shape: " , img.shape) pyplot.figure() pyplot.imshow(img) pyplot.title('Original image') img = resize(img, INPUT_IMAGE_SIZE, INPUT_IMAGE_SIZE) print("Image Shape after resizing: " , img.shape) pyplot.figure() pyplot.imshow(img) pyplot.title('Resized image') img = crop_image(img, INPUT_IMAGE_SIZE, INPUT_IMAGE_SIZE) print("Image Shape after cropping: " , img.shape) pyplot.figure() pyplot.imshow(img) pyplot.title('Center Cropped') img = img.swapaxes(1, 2).swapaxes(0, 1) print("CHW Image Shape: " , img.shape) pyplot.figure() for i in range(3): pyplot.subplot(1, 3, i+1) pyplot.imshow(img[i]) pyplot.axis('off') pyplot.title('RGB channel %d' % (i+1)) # convert RGB --> BGR img = img[(2, 1, 0), :, :] # remove mean img = img * 255 - mean # add batch size axis img = img[np.newaxis, :, :, :].astype(np.float32) CAFFE_MODELS = os.path.expanduser("/anaconda3/lib/python3.7/site-packages/caffe2/python/models") INIT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'init_net.pb') PREDICT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'predict_net.pb') print(INIT_NET) print(PREDICT_NET) with open(INIT_NET, "rb") as f: init_net = f.read() with open(PREDICT_NET, "rb") as f: predict_net = f.read() p = workspace.Predictor(init_net, predict_net) results = p.run({'data': img}) results = np.asarray(results) print("results shape: ", results.shape) preds = np.squeeze(results) curr_pred, curr_conf = max(enumerate(preds), key=operator.itemgetter(1)) print("Prediction: ", curr_pred) print("Confidence: ", curr_conf) codes = "https://gist.githubusercontent.com/aaronmarkham/cd3a6b6ac071eca6f7b4a6e40e6038aa/raw/9edb4038a37da6b5a44c3b5bc52e448ff09bfe5b/alexnet_codes" response = urllib2.urlopen(codes) for line in response: mystring = line.decode('ascii') code, result = mystring.partition(":")[::2] code = code.strip() result = result.replace("'", "") if (code == str(curr_pred)): name = result.split(",")[0][1:] print("Model predicts", name, "with", curr_conf, "confidence")
此時,您知道如何使用預先訓練的模型對數據集進行預測。
接下來是學習如何在Caffe2中定義神經網絡(NN)架構,並在數據集上訓練它們。我們現在將學習如何創建一個簡單的單層NN。
Caffe2 - Creating Your Own Network
在本課程中,您將學習在Caffe2中定義一個單層神經網絡(NN),並在隨機生成的數據集上運行它。我們將編寫代碼以圖形方式描述網絡架構、列印輸入、輸出、權重和偏差值。要理解這一課,您必須熟悉其中使用的神經網絡體系結構、其術語和數學。
Network Architecture
讓我們考慮構建一個單層NN,如下圖所示;
從數學上講,這個網絡由以下Python代碼表示−
Y = X * W^T + b
其中X,W,b是張量,Y是輸出。我們將用一些隨機數據填充所有三個張量,運行網絡並檢查Y輸出。爲了定義網絡和張量,Caffe2提供了幾個運算符函數。
Caffe2 Operators
在Caffe2中,運算符是基本的計算單位。Caffe2運算符表示如下。
Caffe2提供了一個詳盡的運算符列表。對於我們目前正在設計的網絡,我們將使用名爲FC的運算符,它計算將輸入向量X傳遞到具有二維權重矩陣W和一維偏移向量b的完全連接網絡的結果。換言之,它計算下列數學方程
Y = X * W^T + b
其中X具有尺寸(M X k),W具有尺寸(nxk),並且b是(1x n)。輸出Y將具有尺寸(M x n),其中M是批次大小。
對於向量X和W,我們將使用GaussianFill運算符創建一些隨機數據。爲了生成偏差值b,我們將使用ConstantFill運算符。
我們現在開始定義我們的網絡。
Creating Network
首先,導入所需的包&負;
from caffe2.python import core, workspace
接下來,通過調用core.Net來定義網絡,如下所示−
net = core.Net("SingleLayerFC")
網絡的名稱指定爲SingleLayerFC。此時,將創建名爲net的網絡對象。到目前爲止,它還沒有包含任何層。
Creating Tensors
我們現在將創建網絡所需的三個向量。首先,我們將通過調用GaussianFill操作符來創建X張量,如下所示−
X = net.GaussianFill([], ["X"], mean=0.0, std=1.0, shape=[2, 3], run_once=0)
X向量的維數爲2x 3,平均數據值爲0,0,標準偏差爲1.0。
同樣,我們創建W張量,如下所示−
W = net.GaussianFill([], ["W"], mean=0.0, std=1.0, shape=[5, 3], run_once=0)
W向量的大小爲5x 3。
最後,我們創建大小爲5的biasb矩陣。
b = net.ConstantFill([], ["b"], shape=[5,], value=1.0, run_once=0)
現在,代碼中最重要的部分就是定義網絡本身。
Defining Network
我們在下面的Python語句中定義網絡−
Y = X.FC([W, b], ["Y"])
我們對輸入數據調用FC運算符X。權重在W中指定,偏差在b中指定。輸出爲Y。或者,您可以使用下面的Python語句創建網絡,該語句更加詳細。
Y = net.FC([X, W, b], ["Y"])
在這一點上,網絡是簡單創建的。在我們至少運行一次網絡之前,它不會包含任何數據。在運行網絡之前,我們將檢查它的體系結構。
Printing Network Architecture
Caffe2在JSON文件中定義了網絡體系結構,可以通過對創建的net對象調用Proto方法來檢查該文件。
print (net.Proto())
這將產生以下輸出&負;
name: "SingleLayerFC" op { output: "X" name: "" type: "GaussianFill" arg { name: "mean" f: 0.0 } arg { name: "std" f: 1.0 } arg { name: "shape" ints: 2 ints: 3 } arg { name: "run_once" i: 0 } } op { output: "W" name: "" type: "GaussianFill" arg { name: "mean" f: 0.0 } arg { name: "std" f: 1.0 } arg { name: "shape" ints: 5 ints: 3 } arg { name: "run_once" i: 0 } } op { output: "b" name: "" type: "ConstantFill" arg { name: "shape" ints: 5 } arg { name: "value" f: 1.0 } arg { name: "run_once" i: 0 } } op { input: "X" input: "W" input: "b" output: "Y" name: "" type: "FC" }
正如您在上面的列表中看到的,它首先定義了操作符X,W和b。讓我們以W的定義爲例。W的類型指定爲GausianFill。平均值定義爲float0.0,標準偏差定義爲float1.0,形狀爲5x 3。
op { output: "W" name: "" type: "GaussianFill" arg { name: "mean" f: 0.0 } arg { name: "std" f: 1.0 } arg { name: "shape" ints: 5 ints: 3 } ... }
檢查X和b的定義,以便您自己理解。最後,讓我們看看單層網絡的定義
op { input: "X" input: "W" input: "b" output: "Y" name: "" type: "FC" }
這裡,網絡類型爲FC(完全連接),輸入爲X、W、b,輸出爲Y。這個網絡定義太過冗長,對於大型網絡,檢查其內容將變得乏味。幸運的是,Caffe2爲創建的網絡提供了圖形表示。
Network Graphical Representation
要獲得網絡的圖形表示,請運行以下代碼片段,這實際上只是兩行Python代碼。
from caffe2.python import net_drawer from IPython import display graph = net_drawer.GetPydotGraph(net, rankdir="LR") display.Image(graph.create_png(), width=800)
當您運行代碼時,您將看到以下輸出;
對於大型網絡,圖形表示在可視化和調試網絡定義錯誤時非常有用。
最後,現在是運行網絡的時候了。
Running Network
通過調用工作區中的RunNetOnce方法來運行網絡;
workspace.RunNetOnce(net)
在網絡運行一次之後,我們所有隨機生成的數據都將被創建,輸入網絡並生成輸出。在Caffe2中,運行網絡後產生的張量稱爲blobs。工作區由您創建並存儲在內存中的blob組成。這與Matlab非常相似。
運行網絡後,可以使用以下print命令檢查工作區中包含的blob
print("Blobs in the workspace: {}".format(workspace.Blobs()))
您將看到以下輸出&負;
Blobs in the workspace: ['W', 'X', 'Y', 'b']
注意,工作區由三個輸入blob−X、W和b組成。它還包含名爲Y的輸出blob。現在讓我們檢查一下這些斑點的內容。
for name in workspace.Blobs(): print("{}:\n{}".format(name, workspace.FetchBlob(name)))
您將看到以下輸出&負;
W: [[ 1.0426593 0.15479846 0.25635982] [-2.2461145 1.4581774 0.16827184] [-0.12009818 0.30771437 0.00791338] [ 1.2274994 -0.903331 -0.68799865] [ 0.30834186 -0.53060573 0.88776857]] X: [[ 1.6588869e+00 1.5279824e+00 1.1889904e+00] [ 6.7048723e-01 -9.7490678e-04 2.5114202e-01]] Y: [[ 3.2709925 -0.297907 1.2803618 0.837985 1.7562964] [ 1.7633215 -0.4651525 0.9211631 1.6511179 1.4302125]] b: [1. 1. 1. 1. 1.]
請注意,由於所有輸入都是隨機創建的,因此計算機上的數據或實際上網絡每次運行的數據都會有所不同。您現在已經成功地定義了一個網絡並在您的計算機上運行它。
Caffe2 - Defining Complex Networks
在上一課中,您學習了創建一個簡單的網絡,並學習了如何執行該網絡並檢查其輸出。創建複雜網絡的過程類似於上述過程。Caffe2爲創建複雜的體系結構提供了大量的操作符。我們鼓勵您查看Caffe2文檔以獲取操作員列表。在研究了各種運營商的目的之後,您將能夠創建複雜的網絡並對其進行培訓。爲了訓練網絡,Caffe2提供了幾個預定義的計算單元,即操作員。您需要選擇適當的運營商來培訓您的網絡,以解決您試圖解決的問題。
一旦網絡訓練到您滿意的程度,您就可以將其存儲在一個模型文件中,該模型文件與之前使用的預先訓練的模型文件類似。這些經過訓練的模型可以貢獻給Caffe2存儲庫,爲其他用戶帶來好處。或者你可以簡單地把訓練好的模型放在你自己的私人生產中使用。
Summary
Caffe2是一個深度學習框架,它允許你用幾種神經網絡來預測你的數據。Caffe2網站提供了許多預先培訓的模型。您學會了使用一個預先訓練的模型來對給定圖像中的對象進行分類。你還學會了定義自己選擇的神經網絡架構。這樣的自定義網絡可以在Caffe中使用許多預定義的操作符進行訓練。一個經過訓練的模型存儲在一個文件中,該文件可以被帶到生產環境中。