1. 程式人生 > >在Caffe中使用 DIGITS自定義Python層

在Caffe中使用 DIGITS自定義Python層

 注意:包含Python層的網路只支援單個GPU訓練!!!!!

  Caffe 使得我們有了使用Python自定義層的能力,而不是通常的C++/CUDA。這是一個非常有用的特性,但它的文件記錄不足,難以正確實現本演練將向您展示如何使用DIGHT來學習實現Python層。

注意:這個特性(自定義python層)在你是使用Cmake編譯Caffe或者使用Deb 包來安裝Caffe的時候自動被包含。如果你使用Make,你將需要將你的Makefile.config中的"WITH_PYTHON_LAYER := 1"解註釋來啟用它。

給MNIST新增遮擋

  對於這個例子,我們將在MNIST資料集上訓練LeNet,但是我們將建立一個python層,來實現在圖片喂進網路之前,擷取掉它的四分之一。這模擬遮擋的資料,這樣將會訓練出一個對遮擋更加魯棒的模型。

  比如變成

建立資料集

首先,仿照這個教程(https://github.com/NVIDIA/DIGITS/blob/master/docs/GettingStarted.md#creating-a-dataset)來使用DIGITS建立MNIST資料集(假設你還沒有建立)

建立Python檔案

接下來你將建立一個包含你的Pyhon層定義的Python檔案。開啟一個文字編輯器,然後建立一個包含如下內容的檔案。

import caffe
import random

class BlankSquareLayer(caffe.Layer):

    def setup(self, bottom, top):
        
assert len(bottom) == 1, 'requires a single layer.bottom' assert bottom[0].data.ndim >= 3, 'requires image data' assert len(top) == 1, 'requires a single layer.top' def reshape(self, bottom, top): # Copy shape from bottom top[0].reshape(*bottom[0].data.shape)
def forward(self, bottom, top): # Copy all of the data top[0].data[...] = bottom[0].data[...] # Then zero-out one fourth of the image height = top[0].data.shape[-2] width = top[0].data.shape[-1] h_offset = random.randrange(height/2) w_offset = random.randrange(width/2) top[0].data[..., h_offset:(h_offset + height/2), w_offset:(w_offset + width/2), ] = 0 def backward(self, top, propagate_down, bottom): pass
其中,top和bottom是包含一個或者多個blob的列表或者陣列,訪問其中的每一個blob使用下標index,如top[index],訪問其中的資料使用top[index].data,也就是一個四維向量[N,C,H,W]。

建立一個模型

注意:如果你以前沒有使用DIGITS建立一個模型,在建立之前,你可以參照教程(https://github.com/NVIDIA/DIGITS/blob/master/docs/GettingStarted.md#training-a-model)學習。
  • 點選主頁上的 New Model > Images > Classification
  • 從資料集列表中選擇MNIST資料集。
  • 單擊“Use client side file”,並選擇先前建立的Python檔案。
  • 點選LeNet under Standard Networks > Caffe
  • 點選右邊顯示的 Customize 連結。

這將把我們帶到一個視窗,我們可以自定義LeNet來新增自定義的Python層。我們將在scale層和conv層之間插入我們的層。找到這些層(從頂部的幾行),並插入這段prototxt程式碼的片段:

layer {
  name: "blank_square"
  type: "Python"
  bottom: "scaled"
  top: "scaled"
  python_param {
    module: "digits_python_layers"
    layer: "BlankSquareLayer"
  }
}

當你點選Visualize,你將看到如下圖:

 然後給模型一個名字,點選Create。你將會看到模型訓練會話開始。如果你注意,你你將會發現這個模型會比預設的LeNet網路精度低,這是為什麼呢?

 注意:當前的caffe版本不支援在有Python層的網路上使用多GPU。如果你向使用Python層,那麼你需要使用但GPU來訓練。詳見:https://github.com/BVLC/caffe/issues/2936

 測試模型

現在開始比較有趣的部分。在MNIST測試集中選擇一張圖片,然後將它上傳到 Test a single image(在頁面的底下)

 然後點選Show visualizationsstatistics! 原始的圖片將顯示在左上,然後是它的預測型別。在Visualization 列,你會看到減去均值的影象作為資料啟用的結果。

就在它下面,你會看到將影象從[0~255 ]縮小到[-1~1 ]的結果。你也會看到一個隨機的四分之一的影象已經被刪除-這是得益於我們的Python層!

 

注意:第二個啟用顯示為彩色熱圖,即使底層資料仍然是單通道的,並且可以顯示為灰度影象。“資料”啟用被視為一種特殊情況,所有其他啟用都被轉換為熱圖。