wider face data 在 faster rcnn 上的實踐記錄(caffe)
按照githup上playerkk的工程進行實踐,地址為:https://github.com/playerkk/face-py-faster-rcnn/blob/master/README.md
1.搭建faster rcnn
這個沒什麼好說的,參考rbg大神的官網即可,附上地址:https://github.com/rbgirshick/py-faster-rcnn
需要注意的是對於顯示卡是1080的,因為faster rcnn是基於老版本的cudnn,所以編譯的時候會出現許多關於cudnn的報錯問題。解決方案推薦的是用caffe中相關的檔案替換掉faster rcnn中的相關檔案。可參考地址:http://blog.csdn.net/u010733679/article/details/52221404。
2.克隆工程及下載預訓練引數檔案
git clone --recursive https://github.com/playerkk/face-py-faster-rcnn.git在工程的根目錄下執行:
cd face-py-faster-rcnn
./data/scripts/fetch_faster_rcnn_models.sh
會在data下出現 faster rcnn models.tgz。
3.下載wider face data資料
網站下載地址為:http://mmlab.ie.cuhk.edu.hk/projects/WIDERFace/
下載三個資料檔案到一個目錄中,我選擇的是ubuntu的home目錄下:
如圖所示進行分佈。
圖中的最後一個文字檔案從該網址下載:https://people.cs.umass.edu/~hzjiang//files/wider_face_train_annot.txt 。按照的是FDDB的格式。
在如圖所示的data目錄下建立symlinks:
會在工程的data目錄下出現連結,如上圖所示。
4.下載預訓練的Imagenet模型
在工程目錄下執行上圖所示命令。
接下來就是開始執行訓練的過程:
在工程的根目錄下執行命令:
++++++++++++++++++++++++2017.0224++++++++++++++++++++更新+++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
更新工程後我的train_net.py檔案內容為:
#!/usr/bin/env python
# --------------------------------------------------------
# Fast R-CNN
# Copyright (c) 2015 Microsoft
# Licensed under The MIT License [see LICENSE for details]
# Written by Ross Girshick
# --------------------------------------------------------
"""Train a Fast R-CNN network on a region of interest database."""
# import matplotlib
# matplotlib.use('Agg')
import _init_paths
from fast_rcnn.train import get_training_roidb, train_net
from fast_rcnn.config import cfg, cfg_from_file, cfg_from_list, get_output_dir
from datasets.factory import get_imdb
import datasets.imdb
import caffe
import argparse
import pprint
import numpy as np
import sys
def parse_args():
"""
Parse input arguments
"""
parser = argparse.ArgumentParser(description='Train a Fast R-CNN network')
parser.add_argument('--gpu', dest='gpu_id',
help='GPU device id to use [0]',
default=0, type=int)
parser.add_argument('--solver', dest='solver',
help='solver prototxt',
default=None, type=str)
parser.add_argument('--iters', dest='max_iters',
help='number of iterations to train',
default=40000, type=int)
parser.add_argument('--weights', dest='pretrained_model',
help='initialize with pretrained model weights',
default=None, type=str)
parser.add_argument('--cfg', dest='cfg_file',
help='optional config file',
default=None, type=str)
parser.add_argument('--imdb', dest='imdb_name',
help='dataset to train on',
default='voc_2007_trainval', type=str)
parser.add_argument('--rand', dest='randomize',
help='randomize (do not use a fixed seed)',
action='store_true')
parser.add_argument('--set', dest='set_cfgs',
help='set config keys', default=None,
nargs=argparse.REMAINDER)
if len(sys.argv) == 1:
parser.print_help()
sys.exit(1)
args = parser.parse_args()
return args
def combined_roidb(imdb_names):
def get_roidb(imdb_name):
imdb = get_imdb(imdb_name)
print 'Loaded dataset `{:s}` for training'.format(imdb.name)
imdb.set_proposal_method(cfg.TRAIN.PROPOSAL_METHOD)
print 'Set proposal method: {:s}'.format(cfg.TRAIN.PROPOSAL_METHOD)
roidb = get_training_roidb(imdb)
return roidb
roidbs = [get_roidb(s) for s in imdb_names.split('+')]
roidb = roidbs[0]
if len(roidbs) > 1:
for r in roidbs[1:]:
roidb.extend(r)
imdb = datasets.imdb.imdb(imdb_names)
else:
imdb = get_imdb(imdb_names)
return imdb, roidb
if __name__ == '__main__':
args = parse_args()
print('Called with args:')
print(args)
if args.cfg_file is not None:
cfg_from_file(args.cfg_file)
if args.set_cfgs is not None:
cfg_from_list(args.set_cfgs)
cfg.GPU_ID = args.gpu_id
print('Using config:')
pprint.pprint(cfg)
if not args.randomize:
# fix the random seeds (numpy and caffe) for reproducibility
np.random.seed(cfg.RNG_SEED)
caffe.set_random_seed(cfg.RNG_SEED)
# set up caffe
caffe.set_mode_gpu()
caffe.set_device(args.gpu_id)
imdb, roidb = combined_roidb(args.imdb_name)
print '{:d} roidb entries'.format(len(roidb))
output_dir = get_output_dir(imdb)
print 'Output will be saved to `{:s}`'.format(output_dir)
train_net(args.solver, roidb, output_dir,
pretrained_model=args.pretrained_model,
max_iters=args.max_iters)
face.py:
# --------------------------------------------------------
# Fast R-CNN
# Copyright (c) 2015 Microsoft
# Licensed under The MIT License [see LICENSE for details]
# Written by Ross Girshick
# --------------------------------------------------------
# import datasets.face
# import os
# import datasets.imdb as imdb
# import xml.dom.minidom as minidom
# import numpy as np
# import scipy.sparse
# import scipy.io as sio
# import utils.cython_bbox
# import cPickle
# import subprocess
import os
from datasets.imdb import imdb
import datasets.ds_utils as ds_utils
import xml.etree.ElementTree as ET
import numpy as np
import scipy.sparse
import scipy.io as sio
import utils.cython_bbox
import cPickle
import subprocess
import uuid
from voc_eval import voc_eval
from fast_rcnn.config import cfg
import cv2
import PIL
class face(imdb):
def __init__(self, image_set, split, devkit_path):
imdb.__init__(self, 'wider')
self._image_set = image_set # {'train', 'test'}
self._split = split # {1, 2, ..., 10}
self._devkit_path = devkit_path # /data2/hzjiang/Data/CS2
# self._data_path = os.path.join(self._devkit_path, 'data')
self._data_path = self._devkit_path;
self._classes = ('__background__', # always index 0
'face')
self._class_to_ind = dict(zip(self.classes, xrange(self.num_classes)))
self._image_ext = ['.png']
self._image_index, self._gt_roidb = self._load_image_set_index()
# Default to roidb handler
self._roidb_handler = self.selective_search_roidb
# Specific config options
self.config = {'cleanup' : True,
'use_salt' : True,
'top_k' : 2000}
assert os.path.exists(self._devkit_path), \
'Devkit path does not exist: {}'.format(self._devkit_path)
assert os.path.exists(self._data_path), \
'Path does not exist: {}'.format(self._data_path)
def image_path_at(self, i):
"""
Return the absolute path to image i in the image sequence.
"""
return self.image_path_from_index(self._image_index[i])
def image_path_from_index(self, index):
"""
Construct an image path from the image's "index" identifier.
"""
for ext in self._image_ext:
image_path = os.path.join(self._data_path, index)
if os.path.exists(image_path):
break
assert os.path.exists(image_path), \
'Path does not exist: {}'.format(image_path)
return image_path
def _load_image_set_index(self):
"""
Load the indexes listed in this dataset's image set file.
"""
# # Example path to image set file:
# # self._data_path + /ImageSets/val.txt
# # read from file
# image_set_file = 'split%d/%s_%d_annot.txt' % (self._fold, self._image_set, self._fold)
# # image_set_file = os.path.join(self._devkit_path, image_set_file)
# image_set_file = os.path.join('/home/hzjiang/Code/py-faster-rcnn/CS3-splits', image_set_file)
image_set_file = self._name + '_face_' + self._image_set + '_annot.txt'
image_set_file = os.path.join(self._devkit_path, image_set_file)
# image_set_file = 'cs3_rand_train_annot.txt'
# image_set_file = 'wider_dets_annot_from_cs3_model.txt'
# image_set_file = 'wider_manual_annot.txt'
assert os.path.exists(image_set_file), \
'Path does not exist: {}'.format(image_set_file)
image_index = []
gt_roidb = []
with open(image_set_file) as f:
# print len(f.lines())
lines = f.readlines()
idx = 0
while idx < len(lines):
image_name = lines[idx].split('\n')[0]
image_name = os.path.join('WIDER_%s/images' % self._image_set, image_name)
# print image_name
image_ext = os.path.splitext(image_name)[1].lower()
# print image_ext
assert(image_ext == '.png' or image_ext == '.jpg' or image_ext == '.jpeg')
image = PIL.Image.open(os.path.join(self._data_path, image_name))
imw = image.size[0]
imh = image.size[1]
idx += 1
num_boxes = int(lines[idx])
# print num_boxes
boxes = np.zeros((num_boxes, 4), dtype=np.uint16)
gt_classes = np.zeros((num_boxes), dtype=np.int32)
overlaps = np.zeros((num_boxes, self.num_classes), dtype=np.float32)
for i in xrange(num_boxes):
idx += 1
coor = map(float, lines[idx].split())
x1 = min(max(coor[0], 0), imw - 1)
y1 = min(max(coor[1], 0), imh - 1)
x2 = min(max(x1 + coor[2] - 1, 0), imw - 1)
y2 = min(max(y1 + coor[3] - 1, 0), imh - 1)
if np.isnan(x1):
x1 = -1
if np.isnan(y1):
y1 = -1
if np.isnan(x2):
x2 = -1
if np.isnan(y2):
y2 = -1
cls = self._class_to_ind['face']
boxes[i, :] = [x1, y1, x2, y2]
gt_classes[i] = cls
overlaps[i, cls] = 1.0
widths = boxes[:, 2] - boxes[:, 0] + 1
heights = boxes[:, 3] - boxes[:, 1] + 1
keep_idx = np.where(np.bitwise_and(widths > 5, heights > 5))
if len(keep_idx[0]) <= 0:
idx += 1
continue
boxes = boxes[keep_idx]
gt_classes = gt_classes[keep_idx[0]]
overlaps = overlaps[keep_idx[0], :]
if not (boxes[:, 2] >= boxes[:, 0]).all():
print boxes
print image_name
# print boxes
assert (boxes[:, 2] >= boxes[:, 0]).all()
assert (boxes[:, 3] >= boxes[:, 1]).all()
overlaps = scipy.sparse.csr_matrix(overlaps)
gt_roidb.append({'boxes' : boxes,
'gt_classes': gt_classes,
'gt_overlaps' : overlaps,
'flipped' : False,
'image_name': image_name})
image_index.append(image_name)
idx += 1
assert(idx == len(lines))
return image_index, gt_roidb
def gt_roidb(self):
"""
Return the database of ground-truth regions of interest.
This function loads/saves from/to a cache file to speed up future calls.
"""
cache_file = os.path.join(self.cache_path, self.name + '_gt_roidb.pkl')
if os.path.exists(cache_file):
with open(cache_file, 'rb') as fid:
roidb = cPickle.load(fid)
print '{} gt roidb loaded from {}'.format(self.name, cache_file)
return roidb
with open(cache_file, 'wb') as fid:
cPickle.dump(self._gt_roidb, fid, cPickle.HIGHEST_PROTOCOL)
print 'wrote gt roidb to {}'.format(cache_file)
return self._gt_roidb
def selective_search_roidb(self):
"""
Return the database of selective search regions of interest.
Ground-truth ROIs are also included.
This function loads/saves from/to a cache file to speed up future calls.
"""
cache_file = os.path.join(self.cache_path,
self.name + '_selective_search_roidb.pkl')
if os.path.exists(cache_file):
with open(cache_file, 'rb') as fid:
roidb = cPickle.load(fid)
print '{} ss roidb loaded from {}'.format(self.name, cache_file)
return roidb
if self._image_set != 'test':
gt_roidb = self.gt_roidb()
ss_roidb = self._load_selective_search_roidb(gt_roidb)
roidb = datasets.imdb.merge_roidbs(gt_roidb, ss_roidb)
else:
roidb = self._load_selective_search_roidb(None)
print len(roidb)
with open(cache_file, 'wb') as fid:
cPickle.dump(roidb, fid, cPickle.HIGHEST_PROTOCOL)
print 'wrote ss roidb to {}'.format(cache_file)
return roidb
def _load_selective_search_roidb(self, gt_roidb):
filename = os.path.abspath(os.path.join(self._devkit_path,
self.name + '.mat'))
assert os.path.exists(filename), \
'Selective search data not found at: {}'.format(filename)
raw_data = sio.loadmat(filename)['all_boxes'].ravel()
box_list = []
for i in xrange(raw_data.shape[0]):
boxes = raw_data[i][:, (1, 0, 3, 2)] - 1
assert (boxes[:, 2] >= boxes[:, 0]).all()
box_list.append(boxes)
return self.create_roidb_from_box_list(box_list, gt_roidb)
def selective_search_IJCV_roidb(self):
"""
Return the database of selective search regions of interest.
Ground-truth ROIs are also included.
This function loads/saves from/to a cache file to speed up future calls.
"""
cache_file = os.path.join(self.cache_path,
'{:s}_selective_search_IJCV_top_{:d}_roidb.pkl'.
format(self.name, self.config['top_k']))
if os.path.exists(cache_file):
with open(cache_file, 'rb') as fid:
roidb = cPickle.load(fid)
print '{} ss roidb loaded from {}'.format(self.name, cache_file)
return roidb
gt_roidb = self.gt_roidb()
ss_roidb = self._load_selective_search_IJCV_roidb(gt_roidb)
roidb = datasets.imdb.merge_roidbs(gt_roidb, ss_roidb)
with open(cache_file, 'wb') as fid:
cPickle.dump(roidb, fid, cPickle.HIGHEST_PROTOCOL)
print 'wrote ss roidb to {}'.format(cache_file)
return roidb
def _load_selective_search_IJCV_roidb(self, gt_roidb):
IJCV_path = os.path.abspath(os.path.join(self.cache_path, '..',
'selective_search_IJCV_data',
self.name))
assert os.path.exists(IJCV_path), \
'Selective search IJCV data not found at: {}'.format(IJCV_path)
top_k = self.config['top_k']
box_list = []
for i in xrange(self.num_images):
filename = os.path.join(IJCV_path, self.image_index[i] + '.mat')
raw_data = sio.loadmat(filename)
box_list.append((raw_data['boxes'][:top_k, :]-1).astype(np.uint16))
return self.create_roidb_from_box_list(box_list, gt_roidb)
def _load_face_annotation(self, index):
"""
Load image and bounding boxes info from txt files of face.
"""
filename = os.path.join(self._data_path, 'Annotations', index + '.mat')
data = sio.loadmat(filename)
num_objs = data['gt'].shape[0]
boxes = np.zeros((num_objs, 4), dtype=np.uint16)
gt_classes = np.zeros((num_objs), dtype=np.int32)
overlaps = np.zeros((num_objs, self.num_classes), dtype=np.float32)
# Load object bounding boxes into a data frame.
for ix in xrange(num_objs):
# Make pixel indexes 0-based
coor = data['gt'][ix, :]
x1 = float(coor[0]) - 1
y1 = float(coor[1]) - 1
x2 = float(coor[2]) - 1
y2 = float(coor[3]) - 1
cls = self._class_to_ind['face']
boxes[ix, :] = [x1, y1, x2, y2]
gt_classes[ix] = cls
overlaps[ix, cls] = 1.0
overlaps = scipy.sparse.csr_matrix(overlaps)
if not (boxes[:, 2] >= boxes[:, 0]).all():
print boxes
print filename
assert (boxes[:, 2] >= boxes[:, 0]).all()
return {'boxes' : boxes,
'gt_classes': gt_classes,
'gt_overlaps' : overlaps,
'flipped' : False}
def _write_inria_results_file(self, all_boxes):
use_salt = self.config['use_salt']
comp_id = 'comp4'
if use_salt:
comp_id += '-{}'.format(os.getpid())
# VOCdevkit/results/comp4-44503_det_test_aeroplane.txt
path = os.path.join(self._devkit_path, 'results', self.name, comp_id + '_')
for cls_ind, cls in enumerate(self.classes):
if cls == '__background__':
continue
print 'Writing {} results file'.format(cls)
filename = path + 'det_' + self._image_set + '_' + cls + '.txt'
with open(filename, 'wt') as f:
for im_ind, index in enumerate(self.image_index):
dets = all_boxes[cls_ind][im_ind]
if dets == []:
continue
# the VOCdevkit expects 1-based indices
for k in xrange(dets.shape[0]):
f.write('{:s} {:.3f} {:.1f} {:.1f} {:.1f} {:.1f}\n'.
format(index, dets[k, -1],
dets[k, 0] + 1, dets[k, 1] + 1,
dets[k, 2] + 1, dets[k, 3] + 1))
return comp_id
def _do_matlab_eval(self, comp_id, output_dir='output'):
rm_results = self.config['cleanup']
path = os.path.join(os.path.dirname(__file__),
'VOCdevkit-matlab-wrapper')
cmd = 'cd {} && '.format(path)
cmd += '{:s} -nodisplay -nodesktop '.format(datasets.MATLAB)
cmd += '-r "dbstop if error; '
cmd += 'setenv(\'LC_ALL\',\'C\'); voc_eval(\'{:s}\',\'{:s}\',\'{:s}\',\'{:s}\',{:d}); quit;"' \
.format(self._devkit_path, comp_id,
self._image_set, output_dir, int(rm_results))
print('Running:\n{}'.format(cmd))
status = subprocess.call(cmd, shell=True)
def evaluate_detections(self, all_boxes, output_dir):
comp_id = self._write_inria_results_file(all_boxes)
self._do_matlab_eval(comp_id, output_dir)
def competition_mode(self, on):
if on:
self.config['use_salt'] = False
self.config['cleanup'] = False
else:
self.config['use_salt'] = True
self.config['cleanup'] = True
if __name__ == '__main__':
d = datasets.inria('train', '')
res = d.roidb
from IPython import embed; embed()
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
之後在命令列中輸入:[email protected]:~/face-py-faster-rcnn$ ./experiments/scripts/faster_rcnn_end2end.sh 0 VGG16 wider
輸出:
問題已經得到解決了:原因是因為我安裝的easydict的版本是1.4,即使我配置了faster_rcnn_end2end.yml,但是easydict並沒有將引數傳給train_net.py,所以才會出現上述問題,解決方案就是升級你的easydict。
相關推薦
wider face data 在 faster rcnn 上的實踐記錄(caffe)
按照githup上playerkk的工程進行實踐,地址為:https://github.com/playerkk/face-py-faster-rcnn/blob/master/README.md 1.搭建faster rcnn 這個沒什麼好說的,參考rbg大神的官網即可,
Faster-RCNN的一些記錄。
Faster-RCNN詳解 Ross B. Girshick的論文《Faster R-CNN: Towards Real-Time ObjectDetection with Region Proposal Networks》 主要解決兩個問題: 1、提出區域建議網路RPN,快速生成候
faster rcnn踩坑記錄
1.下載Faster-RCNN原始碼並且進行安裝 通過git工具直接下載,在linux命令列輸入 # Make sure to clone with --recursive git clone --recursive https://github.com/rbgirshick
記錄caffe下配置bottom up attention (py-faster-rcnn)環境配置遇到的坑
bottom up attention為py-faster-rcnn在 Visual Genome 資料集預訓練的模型,官方py-faster-rcnn在COCO資料集預訓練下僅識別80個class,bottom up attention可識別1600個object class以
Ubuntu 16.04下利用tf-faster-rcnn在VOC或其他資料集上訓練自己的模型
暑期的時候有朋友問我如何配置tf-faster-rcnn,那會簡單寫了個steps.pdf。正好最近閒了下來,就把它彙總一下。 Introduction 這是一篇介紹如何使用tf-faster-rcnn在VOC和其他資料集訓練自己模型的筆記. 筆記中所有檔案的地
tf-faster-rcnn執行自己到資料集記錄
我只從遇到問題到地方開始記錄,沒有問題到地方按照作者的read me做下去即可。 1、執行到第3步,準備測試demo 時候出現問題 解決辦法:自己下載三個訓練資料集,然後解壓到tf-faster-rcnn根目錄下,並改名為VOCdevkit2007,然後放置到da
tensorflow版本faster-rcnn-CPU, ubuntu, Python3.5配置記錄
寫在前面的話 在實驗室電腦上進行fasterrcnn_tensorflow版本的配置,看了很多blog也踩了很多的坑,現在在這裡把正確的整個步驟記錄下來 軟硬體配置 主要是軟體方面,硬體方面由於使用的GPU是amd的,所以沒法使用tensorflow-GPU版
深度學習之目標檢測常用演算法原理+實踐精講 YOLO / Faster RCNN / SSD / 文字檢測 / 多工網路
深度學習之目標檢測常用演算法原理+實踐精講 YOLO / Faster RCNN / SSD / 文字檢測 / 多工網路 資源獲取連結:點選這裡 第1章 課程介紹 本章節主要介紹課程的主要內容、核心知識點、課程涉及到的應用案例、深度學習演算法設計通用流程、適應人群、學習本門
深度學習之目標檢測常用算法原理+實踐精講 YOLO / Faster RCNN / SSD / 文本檢測 / 多任務網絡
資源 測試 -h 轉換 條件 評價 框架 檢測方法 結果 深度學習之目標檢測常用算法原理+實踐精講 YOLO / Faster RCNN / SSD / 文本檢測 / 多任務網絡 資源獲取鏈接:點擊這裏 第1章 課程介紹 本章節主要介紹課程的主要內容、核心知識點、課程
Faster-RCNN 訓練自己資料集的坑記錄
主要照這篇部落格進行訓練配置,因為沒有GPU所以好多坑,CPU訓練可以參見這篇部落格 正所謂,跑通了的都一樣,錯誤千萬樣。按照教程來也是坑多 訓練: python train_faster_rcnn_alt_opt.py --net_name ZF --weights
Faster RCNN訓練出現問題:Selective search data not found at: /home/py-faster-rcnn/data/selective_search_dat
~/py-faster-rcnn$ ./experiments/scripts/fast_rcnn.sh 0 VGG16 pascal_voc + set -e + export PYTHONUNBUFFERED=True + PYTHONUNBUFFERED=True +
Tensorflow框架下Faster-RCNN實踐(一)——Faster-RCNN所需資料集製作(附程式碼)
最近剛實現了在Ubuntu16.04、Tensorfllow1.0下 Faster R-CNN 從資料製作到訓練再到利用生成的模型檢測的測試圖片的全過程,現在將具體的過程記錄在部落格,方便遇到困惑或者需要的朋友檢視。 製作資料集 利用Fast
Ubuntu上編譯Caffe和拓展應用(faster-rcnn, pvanet)的錯誤及解決方案
Caffe 錯誤: 採用make方式編譯時遇到如下錯誤 In file included from /usr/include/boost/python/detail/prefix.hpp:13:0, fr
ubuntu14.04在cpu上配置caffe以及py-faster-rcnn環境(可在odroid上實現)
一、安裝依賴項 安裝blas $ sudo apt-get install libatlas-base-dev 安裝pip sudo apt-get install python-pip 安裝其他依賴庫 $ sudo apt-get in
Face Faster RCNN安裝步驟和遇到的問題
1.安裝 Build the Cython modules cd $FRCN_ROOT/lib make Build Caffe and pycaffe cd $FRCN_ROOT/caffe-fast-rcnn make -j8 && mak
在wider face驗證集上驗證自己檢測器的效能
1、首先訓練時用wider face的訓練集進行訓練(不要用驗證集)3、用wider face中的驗證集val進行測試,得到檢測結果格式為<image name i> score x1 y1 x2 y2,與wider face要求的格式< image nam
【Head First Servlets and JSP】實踐記錄01:從有腳本到無腳本
view 找不到 idt import == post 判斷 attr 查找 試圖章節式的閱讀《Head First Servlets and JSP》總感覺不對勁,這本書前後的聯系性很強,有點類似於“連續劇”,而不是通常的“知識清單&r
軟件工程實踐記錄p2(day4-6)
年齡 new array window 界面 back gin css map 前三天只要是搭建平臺,構建鏈接,而這三天的實踐內容則主要是實現數據的新增,刪除,查詢和修改。 com.crm.action.CustSaveAction.java新增信息代碼: pa
軟件工程實踐記錄p3(day7-9)
creates 內容 number 從零開始 軟件工程 工程 bean tty workbook 這三天的主要內容是模仿前6天的客戶關系管理系統創建庫存管理系統,大體框架和客戶系統類似,增加了時間記錄、根據數據生成excel文件,另對界面進行了美化。 增加時間相關
【轉載】 Faster-RCNN+ZF用自己的數據集訓練模型(Matlab版本)
cmp fin ont -m lac tails ram pos 識別 說明:本博文假設你已經做好了自己的數據集,該數據集格式和VOC2007相同。下面是訓練前的一些修改。 (做數據集的過程可以看http://blog.csdn.net/sinat_30071459/art