Blob是一個四維的數組。維度從高到低分別是:html
(num_,channels_,height_,width_)java
對於圖像數據來講就是:圖片個數,彩色通道個數,寬,高python
Blob中數據是row-major存儲的,W是變化最快的維度,例如在(n, k, h, w)處的數據,其物理偏移量計算方式爲:ios
Blob的經常使用方法:git
blob.data() // 返回數據github
blob.diff() // 返回梯度web
blob.shape() // 返回樣本的形狀算法
blob.num() // 返回樣本的個數(經常使用)數據庫
blob.channels() // 返回通道的個數(經常使用)express
blob.height() // 返回樣本維度一,對於圖像而言是高度(經常使用)
blob.width() // 返回樣本維度二,對於圖像而言是寬度(經常使用)
Data layer參數說明以下:
message ImageDataParameter {
// 指定圖片數據 txt 路徑.
optional string source = 1;
// batch size.
optional uint32 batch_size = 4 [default = 1];
// 隨機跳過部分數據樣本,以免全部同步 sgd 客戶端開始的樣本相同.
// 其中,跳過的點設置爲 rand_skip * rand(0,1).
// rand_skip 小於等於數據集樣本數.
optional uint32 rand_skip = 7 [default = 0];
// 每一個 epoch 後打亂數據順序
optional bool shuffle = 8 [default = false];
// resize 圖片到指定的 new_height 和 new_width 尺寸.
optional uint32 new_height = 9 [default = 0];
optional uint32 new_width = 10 [default = 0];
// 圖片是彩色仍是灰度圖 color or gray
optional bool is_color = 11 [default = true];
// DEPRECATED. See TransformationParameter.
// 數據預處理時,能夠進行簡單的縮放(scale) 和減均值處理
// 減均值是在縮放處理前進行.
optional float scale = 2 [default = 1];
optional string mean_file: "mean.proto";
// DEPRECATED. See TransformationParameter.
// 從圖片隨機裁剪.
// 剪裁一個 227*227的圖塊,在訓練階段隨機剪裁,在測試階段從中間裁剪
optional uint32 crop_size = 227 [default = 0];
// DEPRECATED. See TransformationParameter.
// 隨機水平翻轉.
optional bool mirror = 6 [default = false];
optional string root_folder = 12 [default = ""];
}
window_data_param {
source: "window_data_train.txt"
batch_size: 128
crop_size: 256 # 要把bounding box warp到的大小
fg_threshold: 0.5 # 與ground truth 大於 fg_threshold 的bbox才做爲正陽本
bg_threshold: 0.5 # 與ground truth 小於 bg_threshold 的bbox才做爲正陽本
fg_fraction: 0.25 # 一個batch中正陽本數量的比例
crop_mode: "warp"
}
負樣本的label是任意的, 可是overlap要小於threshold (絕對負樣本能夠將overlap 設置爲 0)
卷積層參數說明:
layer {
name: "conv"
type: "Convolution"
bottom: "data"
top: "conv"
param {
lr_mult: 1 #權重的學習率 該層lr=lr_mult*base_lr
decay_mult: 1 #權重的衰減值
}
param {
lr_mult: 2 #偏置項的學習率
decay_mult: 0 #偏置項的衰減值
}
convolution_param {
num_output: 96 #該層輸出的filter的個數。四維數組N*C*H*W中的N
kernel_size: 11 #卷積核大小11*11。可設定長kernel_h與寬kernel_w
stride: 4 #步長,也就是卷積核滑動的距離
weight_filler { #卷積核初始化方式
type: "gaussian" #高斯分佈
std: 0.01 #標準差爲0.01
}
bias_filler { #偏置項初始化方式
type: "constant" #連續分佈
value: 0
}
}
}
Data對應數據庫格式
WindowData對應存儲在硬盤上的圖片
DummyData用於開發與調試
學習率更新,如今step exp 和multistep用的比較多。
根據 caffe/src/caffe/proto/caffe.proto 裏的文件,能夠看到它有如下幾種學習率的衰減速機制:
(1). fixed: 在訓練過程當中,學習率不變;
(2). step: 它的學習率的變化就像臺價同樣;step by step 的; 其中的 gamma 與 stepsize須要設置的;
(3).exp :表示指數型的,其中參數 gamma 須要設置;
(4). inv : 其中參數 gamma 與 power 都須要設置;
(5).multistep: 能夠設置多個 stepvalue的值, 在prototxt裏面也沒有具體介紹, 它由參數 stepsize 與 stepvalue 決定; 它不是每時第刻都去計算 學習率,而是達到咱們設定的stepvalue的時候,纔去計算(根據方法2中的公式),而後更新學習率; stepvalue 能夠設置多個的,下面是 stepvalue的定義;
183 repeated int32 stepvalue = 34;
(6).poly :多項式衰減 ,當到達最大次數時, 學習率變爲了0;
(7).sigmoid形的:
solver.prototxt文件是用來告訴caffe如何訓練網絡的。solver.prototxt的各個參數的解釋以下:
base_lr
這個參數是用來表示網絡的初始學習率的。這個值是一個浮點型實數。
lr_policy
這個參數是用來表示學習率隨着時間是如何變化的。值是字符串,須要加""。學習率變化的可選參數有:
「step」——須要設置stepsize。根據gamma參數和stepsize參數來下降學習率,base_lr * gamma ^ (floor(iter / stepsize))。iter是當前迭代次數。學習率每迭代stepsize次變化一次。
「multistep」——與step相似,須要設置stepvalue,學習率根據stepvalue進行變化。
「fixed」——學習率base_lr保持不變。
「inv」——學習率變化公式爲base_lr * (1 + gamma * iter) ^ (- power)
「exp」——學習率變化公式爲base_lr * gamma ^ iter}
「poly」——學習率以多項式形式衰減,到最大迭代次數時降爲0。學習率變化公式爲base_lr * (1 - iter/max_iter) ^ (power)。
「sigmoid」——學習率以S型曲線形式衰減,學習率變化公式爲base_lr * (1 / (1 + exp(-gamma * (iter - stepsize))))。
gamma
這個參數表示學習率每次的變化程度,值爲實數。
stepsize
這個參數表示何時應該進行訓練的下一過程,值爲正整數。主要用在lr_policy爲step的狀況。
stepvalue
這個參數表示何時應該進行訓練的下一過程,值爲正整數。主要用在lr_policy爲multistep的狀況。
max_iter
這個參數表示訓練神經網絡迭代的最大次數,值爲正整數。
momentum
這個參數表示在新的計算中要保留的前面的權重數量,值爲真分數,一般設爲0.9。
weight_decay
這個參數表示對較大權重的懲罰(正則化)因子。值爲真分數。
This parameter indicates the factor of (regularization) penalization of large weights. This value is a often a real fraction.
solver_mode
這個參數用來表示求解神經網絡的模式——值爲CPU or GPU。
snapshot
這個參數用來表示每迭代多少次就應該保存snapshot的model和solverstate,值爲正整數。
snapshot_prefix:
這個參數用來表示保存snapshot時model和solverstate的前綴,值爲帶引號的字符串。
net:
這個參數表示訓練網絡所在的位置,值爲帶引號的字符串。
test_iter
這個參數表示
這個參數表示每一個test_interval進行多少次test迭代,值爲正整數。
test_interval
這個參數表示何時進行數據的測試,值爲正整數。
display
這個參數用來表示何時將輸出結果打印到屏幕上,值爲正整數,表示迭代次數。
type
這個參數表示訓練神經網絡採用的反向傳播算法,值爲帶引號的字符串。可選的值有:
Stochastic Gradient Descent 「SGD」——隨機梯度降低,默認值。
AdaDelta 「AdaDelta」——一種」魯棒的學習率方法「,是基於梯度的優化方法。
Adaptive Gradient 「AdaGrad」——自適應梯度方法。
Adam 「Adam」——一種基於梯度的優化方法。
Nesterov’s Accelerated Gradient 「Nesterov」——Nesterov的加速梯度法,做爲凸優化中最理想的方法,其收斂速度很是快。
RMSprop 「RMSProp」——一種基於梯度的優化方法。
2. Demo
lr_policy
# lr_policy爲multisetp
base_lr: 0.01
momentum: 0.9
lr_policy: "multistep"
gamma: 0.9
stepvalue: 1000
stepvalue: 2000
stepvalue: 3000
stepvalue: 4000
stepvalue: 5000
# lr_policy爲step
base_lr: 0.01
momentum: 0.9
lr_policy: "step"
gamma: 0.9
stepsize: 1000
solver.prototxt
net: "models/bvlc_alexnet/train_val.prototxt"
# 每次測試時進行1000次迭代
test_iter: 1000
# 每進行1000次訓練執行一次測試
test_interval: 1000
base_lr: 0.01
lr_policy: "step"
gamma: 0.1
stepsize: 100000
display: 20
max_iter: 450000
momentum: 0.9
weight_decay: 0.0005
snapshot: 10000
snapshot_prefix: "models/bvlc_alexnet/caffe_alexnet_train"
solver_mode: GPU
參考資料
http://www.cnblogs.com/denny402/p/5074049.html
https://github.com/BVLC/caffe/wiki/Solver-Prototxt
http://stackoverflow.com/questions/30033096/what-is-lr-policy-in-caffe
SSD 300在conv4_3生成prior box的conv4_3_norm_priorbox層prototxt定義以下:
儘可能一個實驗用一塊卡,caffe的多GPU並行作的很差。
不要-gpu 0,1,2. 用一個gpu便可
(Ctrl+B) + (Shift+5) 打開一個新窗口
(Ctrl+B) + right/left 在不一樣窗口之間切換
(Ctrl+B) + [ 或 ] 進入複製模式,查看歷史記錄
tmux ls 列出當前會話列表
tmux attach 進入會話窗口
Ctrl+B+X 結束會話
Github代碼地址以下:
https://github.com/weiliu89/caffe/tree/ssd
安裝步驟以下(github):
$CAFFE_ROOT
$CAFFE_ROOT/models/VGGNet/
$HOME/data/
git clone https://github.com/weiliu89/caffe.git
cd caffe
git checkout ssd
# Modify Makefile.config according to your Caffe installation.
cp Makefile.config.example Makefile.config
make -j8
# Make sure to include $CAFFE_ROOT/python to your PYTHONPATH.
make py
make test -j8
# (Optional)
make runtest -j8
# Download the data.
cd $HOME/data
wget http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012.tar
wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtrainval_06-Nov-2007.tar
wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtest_06-Nov-2007.tar
# Extract the data.
tar -xvf VOCtrainval_11-May-2012.tar
tar -xvf VOCtrainval_06-Nov-2007.tar
tar -xvf VOCtest_06-Nov-2007.tar
cd $CAFFE_ROOT
# Create the trainval.txt, test.txt, and test_name_size.txt in data/VOC0712/
./data/VOC0712/create_list.sh
# You can modify the parameters in create_data.sh if needed.
# It will create lmdb files for trainval and test with encoded original image:
# - $HOME/data/VOCdevkit/VOC0712/lmdb/VOC0712_trainval_lmdb
# - $HOME/data/VOCdevkit/VOC0712/lmdb/VOC0712_test_lmdb
# and make soft links at examples/VOC0712/
./data/VOC0712/create_data.sh
# It will create model definition files and save snapshot models in:
# - $CAFFE_ROOT/models/VGGNet/VOC0712/SSD_300x300/
# and job file, log file, and the python script in:
# - $CAFFE_ROOT/jobs/VGGNet/VOC0712/SSD_300x300/
# and save temporary evaluation results in:
# - $HOME/data/VOCdevkit/results/VOC2007/SSD_300x300/
# It should reach 77.* mAP at 120k iterations.
python examples/ssd/ssd_pascal.py
If you don't have time to train your model, you can download a pre-trained model at here.
# If you would like to test a model you trained, you can do:
python examples/ssd/score_ssd_pascal.py
# If you would like to attach a webcam to a model you trained, you can do:
python examples/ssd/ssd_pascal_webcam.py
Here is a demo video of running a SSD500 model trained on MSCOCO dataset.
examples/ssd_detect.ipynb
or examples/ssd/ssd_detect.cpp
on how to detect objects using a SSD model. Check out examples/ssd/plot_detections.py
on how to plot detection results output by ssd_detect.cpp.examples/ssd.ipynb
to check whether the new dataset is prepared correctly.We have provided the latest models that are trained from different datasets. To help reproduce the results in Table 6, most models contain a pretrained .caffemodel
file, many .prototxt
files, and python scripts.
[1]We use examples/convert_model.ipynb
to extract a VOC model from a pretrained COCO model.
sudo build/tools/compute_image_mean examples/mnist/mnist_train_lmdb examples/mnist/mean.binaryproto
帶兩個參數:
第一個參數:examples/mnist/mnist_train_lmdb, 表示須要計算均值的數據,格式爲lmdb的訓練數據。
第二個參數:examples/mnist/mean.binaryproto, 計算出來的結果保存文件。
def parse_args():
'''parse args'''
parser = argparse.ArgumentParser()
parser.add_argument('--gpu_id', type=int, default=0, help='gpu id')
parser.add_argument('--labelmap_file',
default='data/VOC0712/labelmap_voc.prototxt')
parser.add_argument('--model_def',
default='models/VGGNet/VOC0712/SSD_300x300/deploy.prototxt')
parser.add_argument('--image_resize', default=300, type=int)
parser.add_argument('--model_weights',
default='models/VGGNet/VOC0712/SSD_300x300/'
'VGG_VOC0712_SSD_300x300_iter_120000.caffemodel')
parser.add_argument('--image_file', default='examples/images/fish-bike.jpg')
return parser.parse_args()
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description = "Plot the detection results output by ssd_detect.")
parser.add_argument("resultfile",
help = "A file which contains all the detection results.")
parser.add_argument("imgdir",
help = "A directory which contains the images.")
parser.add_argument("--labelmap-file", default="",
help = "A file which contains the LabelMap.")
parser.add_argument("--visualize-threshold", default=0.01, type=float,
help = "Display detections with score higher than the threshold.")
parser.add_argument("--save-dir", default="",
help = "A directory which saves the image with detection results.")
parser.add_argument("--display-classes", default=None,
help = "If provided, only display specified class. Separate by ','")
Usage:
ssd_detect [FLAGS] model_file weights_file list_file
Flags from examples/ssd/ssd_detect.cpp:
-confidence_threshold (Only store detections with score higher than the
threshold.) type: double default: 0.01
-file_type (The file type in the list_file. Currently support image and
video.) type: string default: "image"
-mean_file (The mean file used to subtract from the input image.)
type: string default: ""
-mean_value (If specified, can be one value or can be same as image
channels - would subtract from the corresponding channel). Separated by
','.Either mean_file or mean_value should be provided, not both.)
type: string default: "104,117,123"
-out_file (If provided, store the detection results in the out_file.)
type: string default: ""
Step 1 使用訓練好的模型檢測圖片:
build/examples/ssd/ssd_detect.bin models/VGGNet/VOC0712/SSD_300x300/deploy.prototxt /home/daisida/ssd/models/VGGNet/VOC0712/SSD_300x300/VGG_VOC0712_SSD_300x300_iter_120000.caffemodel /home/daisida/ssd/list.txt --out_file tmp/output.txt
參數說明:
ssd_detect.bin:是ssd_detect.cpp的編譯文件,相似於caffe中的classifier.bin,主要用於ssd訓練模型的檢測,至關main函數。
deploy.prototxt:網絡結構參數
VGG_VOC0712_SSD_300×300_iter_120000.caffemodel:訓練模型
test.txt:測試數據,能夠是圖片,能夠是視頻,每一行爲圖片或視頻的路徑
--file_type:文件類型,圖片用image,視頻用video
--out_file:檢測結果輸出文件
--condidence_threshold:閾值參數,這裏設置爲0.5,參數範圍(0,1)
Step 2 結果可視化:
保存結果前須要將output.txt中的路徑進行修改,去掉每行前邊的路徑,避免重複。
python examples/ssd/plot_detections.py tmp/output.txt /home/daisida/data/testset --labelmap-file data/VOC0712/labelmap_voc.prototxt --save-dir tmp/
/home/daisida/data/testset///home/daisida/data/testset/3.jpg does not exist
/home/daisida/data/testset///home/daisida/data/testset/9.jpg does not exist
/home/daisida/data/testset///home/daisida/data/testset/7.jpg does not exist
/home/daisida/data/testset///home/daisida/data/testset/2.jpg does not exist
/home/daisida/data/testset///home/daisida/data/testset/8.jpg does not exist
解決方案:
修改output.txt文件,去掉每行前邊的路徑,避免重複。
假設你想定義一個「搜索請求」的消息格式,每個請求含有一個查詢字符串、你感興趣的查詢結果所在的頁數,以及每一頁多少條查詢結果。能夠採用以下的方式來定義消息類型的.proto文件了:
message SearchRequest {
required string query = 1;
optional int32 page_number = 2;
optional int32 result_per_page = 3;
}
SearchRequest消息格式有3個字段,在消息中承載的數據分別對應於每個字段。其中每一個字段都有一個名字和一種類型。
在上面的例子中,全部字段都是標量類型:兩個整型(page_number和result_per_page),一個string類型(query)。固然,你也能夠爲字段指定其餘的合成類型,包括枚舉(enumerations)或其餘消息類型。
正如上述文件格式,在消息定義中,每一個字段都有惟一的一個標識符。這些標識符是用來在消息的二進制格式中識別各個字段的,一旦開始使用就不可以再改變。注:[1,15]以內的標識號在編碼的時候會佔用一個字節。[16,2047]以內的標識號則佔用2個字節。因此應該爲那些頻繁出現的消息元素保留[1,15]以內的標識號。切記:要爲未來有可能添加的、頻繁出現的標識號預留一些標識號。
最小的標識號能夠從1開始,最大到229 - 1, or 536,870,911。不可使用其中的[19000-19999]的標識號, Protobuf協議實現中對這些進行了預留。若是非要在.proto文件中使用這些預留標識號,編譯時就會報警。
所指定的消息字段修飾符必須是以下之一:
required:一個格式良好的消息必定要含有1個這種字段。表示該值是必需要設置的;
optional:消息格式中該字段能夠有0個或1個值(不超過1個)。
repeated:在一個格式良好的消息中,這種字段能夠重複任意屢次(包括0次)。重複的值的順序會被保留。表示該值能夠重複,至關於java中的List。
因爲一些歷史緣由,基本數值類型的repeated的字段並無被儘量地高效編碼。在新的代碼中,用戶應該使用特殊選項[packed=true]來保證更高效的編碼。如:
repeated int32 samples = 4 [packed=true];
required是永久性的:在將一個字段標識爲required的時候,應該特別當心。若是在某些狀況下不想寫入或者發送一個required的字段,將原始該字段修飾符更改成optional可能會遇到問題——舊版本的使用者會認爲不含該字段的消息是不完整的,從而可能會無目的的拒絕解析。在這種狀況下,你應該考慮編寫特別針對於應用程序的、自定義的消息校驗函數。Google的一些工程師得出了一個結論:使用required弊多於利;他們更願意使用optional和repeated而不是required。固然,這個觀點並不具備廣泛性。
https://blog.csdn.net/jiongnima/article/details/80016683
python2 *.py #啓動Python2
python *.py #啓動Python3
sudo python #啓動系統Python,不加sudo,則啓動用戶bashrc中的Python
(1) 下載並解壓
(2) 配置環境變量:
D:\Program Files\opencv\build\x64\vc14\bin
(3) 新建控制檯應用程序——空項目
(4) 選擇編譯模式爲x64:項目右鍵——屬性——鏈接器——高級——目標計算機:Machine64——右上角配置管理器——平臺:新建——win32和x64
(5) 接下來有兩種方案,(64位系統要選擇debug模式爲x64)一是此項目上右鍵屬性,則只改變當前項目,二是視圖——其餘窗口——屬性管理器——修改全局配置
(6) 工程上右鍵屬性——包含目錄:
D:\Program Files\opencv\build\include\opencv2
D:\Program Files\opencv\build\include\opencv
D:\Program Files\opencv\build\include
(7) 庫目錄:
D:\Program Files\opencv\build\x64\vc14\lib
(8) 連接器——輸入——附加依賴項:
opencv_world345d.lib
opencv_world345.lib
(9) 測試代碼:
#include<iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
int main()
{
// 讀入一張圖片(遊戲原畫)
Mat img = imread("pic.jpg");
// 建立一個名爲 "遊戲原畫"窗口
namedWindow("遊戲原畫");
// 在窗口中顯示遊戲原畫
imshow("遊戲原畫", img);
// 等待6000 ms後窗口自動關閉
waitKey(6000);
}
1. 刪除全部服務器上的/home/public/local/cuda-7.5文件夾,只保留8.0文件夾,若是這臺服務器已經安裝過7.5的驅動,須要先卸載driver
卸載方法:
cd /home/public/local/cuda-7.5/bin
sudo ./uninstall_cuda_7.5.pl
(新安裝機器只裝了cuda8.0的直接刪了cuda-7.5文件夾就能夠)
2. 修改/home/bashrc文件裏面的cuda路徑
3. 修改本身的Makefile.config裏面的cuda路徑
4. 把10.90.41.188上/home/public/local/cuda-8.0.tar 和OpenCV-3.0-cuda8.0.tar 拷貝到每臺機器上的/home/public/local下,並解壓(沒有顯卡的機器也拷貝cuda8.0.tar,方便之後安裝)
5. 把10.90.41.188上/home/public/local/anaconda2/lib/python2.7/site-packages/cv2.so 拷貝到對應機器上對應路徑/home/public/local/anaconda2/lib/python2.7/site-packages/
從新make caffe和OpenCV
測試:
對於有顯卡的機器,測試在python中import cv2
Boost 的修改過程:
爲運行caffe,cd /usr/local/lib
將libboost_thread.so -> libboost_thread.so.1.68.0重命名爲libboost_thread.so_bak
新建libboost_thread.so -> libboost_thread.so.1.66.0
ps -aux | grep python | grep -v grep | awk '{print $2}' | xargs kill -9
解決方案:
pip install protobuf
Train階段:
(1) train.sh中的solver.prototxt路徑
(2) train.sh中的caffemodel路徑
(3) train.sh中的日誌名稱
(4) solver.prototxt中的net名稱(也就是train.prototxt路徑)
(5) solver.prototxt中的snapshot_prefix名稱(包括路徑+文件名)
(6) train.prototxt中的data層(有兩個,TRAIN和TEST)輸入文件的路徑,即list.txt或者lmdb的路徑
Test階段:
(1) test.py腳本中的caffemodel改爲訓練好的caffemodel
(2) test.py中的prototxt改爲deploy.prototxt
(3) test.py中的labelfile(即list.txt文件的路徑)
(1) 去掉輸入層(有兩個,phase=TRAIN或TEST),換成Input層:
layer {
name: "data_exp"
type: "ImageData"
top: "data_exp"
top: "label_exp"
include {
phase: TRAIN
}
transform_param {
mirror: true
mean_value: 104
mean_value: 117
mean_value: 123
}
image_data_param {
source: "list.txt"
batch_size: 32
shuffle: true
}
}
改爲:
layer {
name: "data"
type: "Input"
top: "data"
input_param { shape: { dim: 1 dim: 3 dim: 144 dim: 144 } }
}
(2) 第一個卷積層的bottom變量要和輸入層一致
(3) Loss層:從SoftmaxWithLoss改爲Softmax
layer {
name: "loss_expression"
type: "SoftmaxWithLoss"
bottom: "pool10_expression"
bottom: "label_exp"
top: "loss_exp"
loss_weight: 1
include {
phase: TRAIN
}
}
改爲:
layer {
name: "prob_expression"
type: "Softmax"
bottom: "pool10_expression"
top: "prob_expression"
}
(4) 去掉Accuracy層
(5) 對於多任務狀況,還要去掉concat層(deploy階段每次test只輸入一張圖片,同理也要去掉slice)
添加concat層以及slice層。
Concat用於拼接不一樣數據源的data,concat以後的數據通過網絡傳播,由slice層將feature分開,分別用於不一樣人物的訓練,生成不一樣的loss。Slice_point就是batchsize。
train.prototxt須要修改的位置:
(1) 有幾項任務,就要有幾份輸入數據(每項任務都要有各自的TRAIN和TEST數據輸入層);同時注意batchsized的大小;
(2) 修改Concat層以下(TRAIN和TEST各有一個)
layer {
name: "concat"
bottom: "data_blink"
bottom: "data_obstacle"
bottom: "data_blur"
top: "data"
type: "Concat"
include {
phase: TRAIN
}
concat_param {
axis: 0
}
}
其中bottom是三項任務各自的輸入數據層。
(3) 修改slice層(TRAIN和TEST各有一個):
layer {
name: "slice"
type: "Slice"
bottom: "fire9/concat"
top: "feature_blink"
top: "feature_obstacle"
top: "feature_blur"
include {
phase: TRAIN
}
slice_param {
axis: 0
slice_point: 128
slice_point: 256
}
}
(4) Slice層以後接不一樣任務的輸出層:
Eg. Conv、relu、pooling、SoftmaxWithLoss、accuracy_smile
(5) 修改deploy.prototxt: