Window Data Layer
window data layer 的数据是存在硬盘上的图片, 需要在一个txt里指定用于训练或测试的图片以及bounding box, bounding box 对应的标签, 以及bounding box和ground truth bounding box的overlap, 一个例子如下
# 0 /home/xxx/0001.jpg 3 641 677 7 1 1.0 353 356 393 396 1331 0.5 338 344 379 384 3964 0.7 339 336 379 376 4533 0 334 330 374 370 4689 1.0 330 324 370 364 4865 1.0 335 319 375 359 4927 1.0 341 313 381 353 # 1 /home/xxx/0002.jpg 3 600 400 3 1 1.0 353 356 393 396 1331 0.5 338 344 379 384 3964 0.7 339 336 379 376
其中第一行是图片的index, 从0开始, 接下来三行依此是图片的channel, height, width, 接下来一行表示 bounding box 数量. 再接下来的每一行都是一个bounding box, 第一个数字表示label, 第二个数字表示与真实goundtruth 的overlap, 接下来的四个数字表示x1, y1, x2, y2.
最后, 在prototxt里这样定义
layers { name: "data" type: WINDOW_DATA top: "data" top: "label" 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" } transform_param { mean_value: 128 mean_value: 128 mean_value: 128 mirror: false } include: { phase: TRAIN } }
负样本的label是任意的, 但是overlap要小于threshold (绝对负样本可以将overlap 设置为 0)
2. 如果 fg_fraction 小于 1, 并且如果一个dataset (TRAIN phase / TEST phase) 中没有负样本, 那么逻辑上就是矛盾的, caffe会报错 (但是错误内容是比较莫名其妙的) , 比如:
I0507 09:58:46.192163 21762 net.cpp:113] Setting up fc6 *** Aborted at 1430963926 (unix time) try "date -d @1430963926" if you are using GNU date *** PC: @ 0x7f5ad296f0db caffe::WindowDataLayer<>::InternalThreadEntry() *** SIGFPE (@0x7f5ad296f0db) received by PID 21762 (TID 0x7f5aacde6700) from PID 18446744072947691739; stack trace: *** @ 0x7f5ad1b19d40 (unknown) @ 0x7f5ad296f0db caffe::WindowDataLayer<>::InternalThreadEntry() @ 0x7f5aca2d6a4a (unknown) @ 0x7f5ac9839182 start_thread @ 0x7f5ad1bdd47d (unknown) @ 0x0 (unknown) ./train.sh: line 2: 21762 Floating point exception(core dumped) ./external/caffe/build/tools/caffe train -gpu 1 -solver external/my_models/lsp_window_data/lsp_solver.prototxt
3. 如果bbox坐标超过了image 的大小, 但是bbox有一部分在图像内部, 这种情况是允许的.
LMDB/LevelDB
需要在prototxt里面指定图像大小, 程序内部会check设定的大小是否和数据实际大小一致. 所以数据一旦存储后就不能再改变大小.