久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Faster R-CNN教程

 心不留意外塵 2016-05-31


http://blog.csdn.net/u012891472/article/details/51282809

最后更新日期:2016年4月29日

本教程主要基于Python版本的faster R-CNN,,因?yàn)閜ython layer的使用,,這個(gè)版本會(huì)比matlab的版本速度慢10%,但是準(zhǔn)確率應(yīng)該是差不多的,。

目前已經(jīng)實(shí)現(xiàn)的有兩種方式:

  1. Alternative training
  2. Approximate joint training

推薦使用第二種,,因?yàn)榈诙N使用的顯存更小,而且訓(xùn)練會(huì)更快,,同時(shí)準(zhǔn)確率差不多甚至略高一點(diǎn),。

Contents

  1. 配置環(huán)境
  2. 安裝步驟
  3. Demo
  4. 建立自己的數(shù)據(jù)集
  5. 訓(xùn)練和檢測(cè)

配置環(huán)境

1配置python layers

#In your Makefile.config, make sure to have this line uncommented
WITH_PYTHON_LAYER := 1
# Unrelatedly, it's also recommended that you use CUDNN
USE_CUDNN := 1
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

2安裝幾個(gè)依賴cython, python-opencv, easydict

sudo apt-get install python-opencv
sudo pip install cython easydict
  • 1
  • 2
  • 1
  • 2

安裝步驟

1克隆工程

git clone --recursive https://github.com/rbgirshick/py-faster-rcnn.git
  • 1
  • 1

2編譯Cython模塊

cd $FRCN_ROOT/lib
make
  • 1
  • 2
  • 1
  • 2

3編譯caffe和pycaffe

cd $FRCN_ROOT/caffe-fast-rcnn
# Now follow the Caffe installation instructions here:
#   http://caffe./installation.html

# If you're experienced with Caffe and have all of the requirements installed
# and your Makefile.config in place, then simply do:
make -j8 && make pycaffe
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Demo

安裝步驟完成后,就可以運(yùn)行一下demo了,。

cd $FRCN_ROOT
./tools/demo.py
  • 1
  • 2
  • 1
  • 2

訓(xùn)練自己的訓(xùn)練集

工程目錄簡(jiǎn)介

首先工程的根目錄簡(jiǎn)單的稱為 FRCN_ROOT,,可以看到根目錄下有以下幾個(gè)文件夾

  • caffe-fast-rcnn

這里是caffe框架目錄

  • data

用來(lái)存放pretrained模型,比如imagenet上的,,以及讀取文件的cache緩存

  • experiments

存放配置文件以及運(yùn)行的log文件,,另外這個(gè)目錄下有scripts可以用end2end或者alt_opt兩種方式訓(xùn)練。

  • lib

用來(lái)存放一些python接口文件,,如其下的datasets主要負(fù)責(zé)數(shù)據(jù)庫(kù)讀取,,我們接下來(lái)的文件都是放在這個(gè)目錄下的;config負(fù)責(zé)cnn一些訓(xùn)練的配置選項(xiàng),,建議根據(jù)自己的需要在experiment/cfgs/faster_rcnn_end2end.yml文件中進(jìn)行設(shè)置覆蓋config.py中的設(shè)置,。

  • models

里面存放了三個(gè)模型文件,小型網(wǎng)絡(luò)的ZF,,大型網(wǎng)絡(luò)VGG16,,中型網(wǎng)絡(luò)VGG_CNN_M_1024。推薦使用VGG16,,如果使用端到端的approximate joint training方法,,開(kāi)啟CuDNN,只需要3G的顯存即可,。

  • output

這里存放的是訓(xùn)練完成后的輸出目錄,,默認(rèn)會(huì)在faster_rcnn_end2end文件夾下

  • tools

里面存放的是訓(xùn)練和測(cè)試的Python文件。

創(chuàng)建數(shù)據(jù)集

接下來(lái)我們就要?jiǎng)?chuàng)建自己的數(shù)據(jù)集了,,這部分主要在lib目錄里操作,。這里下面存在3個(gè)目錄:

  • datasets

在這里修改讀寫數(shù)據(jù)的接口主要是datasets目錄下

  • fast_rcnn

主要存放的是python的訓(xùn)練和測(cè)試腳本,以及訓(xùn)練的配置文件config.py

  • nms

做非極大抑制的部分,,有g(shù)pu和cpu兩種實(shí)現(xiàn)方式

  • roi_data_layer

主要是一些ROI處理操作

  • rpn

這就是RPN的核心代碼部分,,有生成proposals和anchor的方法

  • transform

  • utils

1構(gòu)建自己的IMDB子類

1.1文件概述
可有看到datasets目錄下主要有三個(gè)文件,分別是

  • factory.py
  • imdb.py
  • pascal_voc.py

factory.py 是個(gè)工廠類,用類生成imdb類并且返回?cái)?shù)據(jù)庫(kù)共網(wǎng)絡(luò)訓(xùn)練和測(cè)試使用,;imdb.py 這里是數(shù)據(jù)庫(kù)讀寫類的基類,,封裝了許多db的操作,,但是具體的一些文件讀寫需要繼承繼續(xù)讀寫,;pascal_voc.py Ross在這里用pascal_voc.py這個(gè)類來(lái)操作。

1.2讀取文件函數(shù)分析
接下來(lái)我來(lái)介紹一下pasca_voc.py這個(gè)文件,,我們主要是基于這個(gè)文件進(jìn)行修改,,里面有幾個(gè)重要的函數(shù)需要修改

  • def init(self, image_set, year, devkit_path=None)
    這個(gè)是初始化函數(shù),它對(duì)應(yīng)著的是pascal_voc的數(shù)據(jù)集訪問(wèn)格式,,其實(shí)我們將其接口修改的更簡(jiǎn)單一點(diǎn),。
  • def image_path_at(self, i)
    根據(jù)第i個(gè)圖像樣本返回其對(duì)應(yīng)的path,其調(diào)用了image_path_from_index(self, index)作為其具體實(shí)現(xiàn)
  • def image_path_from_index(self, index)
    實(shí)現(xiàn)了 image_path的具體功能
  • def _load_image_set_index(self)
    加載了樣本的list文件
  • def _get_default_path(self)
    獲得數(shù)據(jù)集地址
  • def gt_roidb(self)
    讀取并返回ground_truth的db
  • def selective_search_roidb
    讀取并返回ROI的db,,這個(gè)是fast rcnn用的,,faster版本的不用管這個(gè)函數(shù)。
  • def _load_selective_search_roidb(self, gt_roidb)
    加載預(yù)選框的文件
  • def selective_search_IJCV_roidb(self)
    在這里調(diào)用讀取Ground_truth和ROI db并將db合并
  • def _load_selective_search_IJCV_roidb(self, gt_roidb)
    這里是專門讀取作者在IJCV上用的dataset
  • def _load_pascal_annotation(self, index)
    這個(gè)函數(shù)是讀取gt的具體實(shí)現(xiàn)
  • def _write_voc_results_file(self, all_boxes)
    voc的檢測(cè)結(jié)果寫入到文件
  • def _do_matlab_eval(self, comp_id, output_dir=’output’)
    根據(jù)matlab的evluation接口來(lái)做結(jié)果的分析
  • def evaluate_detections
    其調(diào)用了_do_matlab_eval
  • def competition_mode
    設(shè)置competitoin_mode,,加了一些噪點(diǎn)

1.3訓(xùn)練數(shù)據(jù)格式

在我的檢測(cè)任務(wù)里,,我主要是在SED數(shù)據(jù)集上做行人檢測(cè),因此我這里只有background 和person 兩類物體,,為了操作方便,,我像pascal_voc數(shù)據(jù)集里面一樣每個(gè)圖像用一個(gè)xml來(lái)標(biāo)注。如果大家不知道怎么生成xml文件,,可以用這個(gè)工具 labelImg?

這里我要特別提醒一下大家,,一定要注意坐標(biāo)格式,一定要注意坐標(biāo)格式,,一定要注意坐標(biāo)格式,,重要的事情說(shuō)三遍!??!要不然你會(huì)犯很多錯(cuò)誤都會(huì)是因?yàn)樽鴺?biāo)不一致引起的報(bào)錯(cuò)。

1.4修改讀取接口
這里是原始的pascal_voc的init函數(shù),,在這里,,由于我們自己的數(shù)據(jù)集往往比voc的數(shù)據(jù)集要更簡(jiǎn)單的一些,在作者代碼里面用了很多的路徑拼接,,我們不用去迎合他的格式,,將這些操作簡(jiǎn)單化即可,在這里我會(huì)一一列舉每個(gè)我修改過(guò)的函數(shù),。這里按照文件中的順序排列,。

修改后的初始化函數(shù):

class hs(imdb):
    def __init__(self, image_set, devkit_path=None):  # modified
        imdb.__init__(self, image_set)
        self._image_set = image_set
        self._devkit_path =  devkit_path   #datasets路徑
        self._data_path = os.path.join(self._devkit_path,image_set)   #圖片文件夾路徑
        self._classes = ('__background__', # always index 0
                         'person')   #two classes
        self._class_to_ind = dict(zip(self.classes, xrange(self.num_classes))) # form the dict{'__background__':'0','person':'1'}
        self._image_ext = '.jpg'
        self._image_index = self._load_image_set_index('ImageList.txt')
        # Default to roidb handler
        self._roidb_handler = self.selective_search_roidb
        self._salt = str(uuid.uuid4())
        self._comp_id = 'comp4'

        # PASCAL specific config options
        self.config = {'cleanup'     : True,
                       'use_salt'    : True,
                       'use_diff'    : False,
                       'matlab_eval' : False,
                       'rpn_file'    : None,
                       'min_size'    : 16}  #小于16個(gè)像素的框扔掉

        assert os.path.exists(self._devkit_path),                 'VOCdevkit path does not exist: {}'.format(self._devkit_path)
        assert os.path.exists(self._data_path),                 'Path does not exist: {}'.format(self._data_path)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

修改后的image_path_from_index:

def image_path_from_index(self, index): #modified
    """
    Construct an image path from the image's "index" identifier.
    """
    image_path = os.path.join(self._data_path,index +'.jpg')
    assert os.path.exists(image_path),             'Path does not exist: {}'.format(image_path)
    return image_path
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

修改后的_load_image_set_index:

def _load_image_set_index(self,imagelist): # modified
    """
    Load the indexes listed in this dataset's image set file.
    """
    # Example path to image set file:
    # self._devkit_path + /VOCdevkit2007/VOC2007/ImageSets/Main/val.txt
    image_set_file = os.path.join(self._devkit_path, imagelist)
    assert os.path.exists(image_set_file),             'Path does not exist: {}'.format(image_set_file)
    with open(image_set_file) as f:
        image_index = [x.strip() for x in f.readlines()]
    return image_index
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

gt_roidb(self):

這個(gè)函數(shù)里有個(gè)生成ground truth的文件,我需要特別說(shuō)明一下,如果你再次訓(xùn)練的時(shí)候修改了數(shù)據(jù)庫(kù),,比如添加或者刪除了一些樣本,,但是你的數(shù)據(jù)庫(kù)名字函數(shù)原來(lái)那個(gè),必須要在data/cache/目錄下把數(shù)據(jù)庫(kù)的緩存文件.pkl給刪除掉,,否則其不會(huì)重新讀取相應(yīng)的數(shù)據(jù)庫(kù),,而是直接從之前讀入然后緩存的pkl文件中讀取進(jìn)來(lái),這樣修改的數(shù)據(jù)庫(kù)并沒(méi)有進(jìn)入網(wǎng)絡(luò),,而是加載了老版本的數(shù)據(jù),。

修改的_load_pascal_annotation(self, index):

def _load_pascal_annotation(self, index):    #modified
    """
    Load image and bounding boxes info from XML file in the PASCAL VOC
    format.
    """
    filename = os.path.join(self._devkit_path, 'Annotations', index + '.xml')
    tree = ET.parse(filename)
    objs = tree.findall('object')
    if not self.config['use_diff']:
        # Exclude the samples labeled as difficult
        non_diff_objs = [
            obj for obj in objs if int(obj.find('difficult').text) == 0]
        # if len(non_diff_objs) != len(objs):
        #     print 'Removed {} difficult objects'.format(
        #         len(objs) - len(non_diff_objs))
        objs = non_diff_objs
    num_objs = len(objs)

    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)
    # "Seg" area for pascal is just the box area
    seg_areas = np.zeros((num_objs), dtype=np.float32)

    # Load object bounding boxes into a data frame.
    for ix, obj in enumerate(objs):
        bbox = obj.find('bndbox')
        # Make pixel indexes 0-based
        x1 = float(bbox.find('xmin').text)
        y1 = float(bbox.find('ymin').text)
        x2 = float(bbox.find('xmax').text)
        y2 = float(bbox.find('ymax').text)
        cls = self._class_to_ind[obj.find('name').text.lower().strip()]
        boxes[ix, :] = [x1, y1, x2, y2]
        gt_classes[ix] = cls
        overlaps[ix, cls] = 1.0
        seg_areas[ix] = (x2 - x1 + 1) * (y2 - y1 + 1)

    overlaps = scipy.sparse.csr_matrix(overlaps)

    return {'boxes' : boxes,
            'gt_classes': gt_classes,
            'gt_overlaps' : overlaps,
            'flipped' : False,
            'seg_areas' : seg_areas}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

因?yàn)槲液蚉ascal用了一樣的xml格式,所以這個(gè)函數(shù)我的改動(dòng)不多,。如果你想用txt文件保存ground truth,,做出相應(yīng)的修改即可。
想采用txt方式存儲(chǔ)的童鞋,,可以參考文末博客的寫法,。
坐標(biāo)的順序強(qiáng)調(diào)一下,要左上右下,,并且x1必須要小于x2,,這個(gè)是基本,反了會(huì)在坐標(biāo)水平變換的時(shí)候會(huì)出錯(cuò),,坐標(biāo)從0開(kāi)始,,如果已經(jīng)是0,則不需要再-1,。如果怕出錯(cuò),,可以直接把出界的的直接置0.

記得在最后的main下面也修改相應(yīng)的路徑

from datasets.hs import hs
d = hs('hs', '/home/zyy/workspace/wangml/py-faster-rcnn/lib/datasets/')
res = d.roidb
from IPython import embed; embed()
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

OK,在這里我們已經(jīng)完成了整個(gè)的讀取接口的改寫,。

2修改factory.py
當(dāng)網(wǎng)絡(luò)訓(xùn)練時(shí)會(huì)調(diào)用factory里面的get方法獲得相應(yīng)的imdb,,
首先在文件頭import 把pascal_voc改成hs

# --------------------------------------------------------
# Fast R-CNN
# Copyright (c) 2015 Microsoft
# Licensed under The MIT License [see LICENSE for details]
# Written by Ross Girshick
# --------------------------------------------------------

"""Factory method for easily getting imdbs by name."""

__sets = {}

from datasets.hs import hs
import numpy as np

# # Set up voc_<year>_<split> using selective search "fast" mode
# for year in ['2007', '2012']:
#     for split in ['train', 'val', 'trainval', 'test']:
#         name = 'voc_{}_{}'.format(year, split)
#         __sets[name] = (lambda split=split, year=year: pascal_voc(split, year))
#
# # Set up coco_2014_<split>
# for year in ['2014']:
#     for split in ['train', 'val', 'minival', 'valminusminival']:
#         name = 'coco_{}_{}'.format(year, split)
#         __sets[name] = (lambda split=split, year=year: coco(split, year))
#
# # Set up coco_2015_<split>
# for year in ['2015']:
#     for split in ['test', 'test-dev']:
#         name = 'coco_{}_{}'.format(year, split)
#         __sets[name] = (lambda split=split, year=year: coco(split, year))

name = 'hs'
devkit = '/home/zyy/workspace/wangml/py-faster-rcnn/lib/datasets/'
__sets['hs'] = (lambda name = name,devkit = devkit: hs(name,devkit))

def get_imdb(name):
    """Get an imdb (image database) by name."""
    if not __sets.has_key(name):
        raise KeyError('Unknown dataset: {}'.format(name))
    return __sets[name]()

def list_imdbs():
    """List all registered imdbs."""
    return __sets.keys()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

訓(xùn)練和檢測(cè)

1.預(yù)訓(xùn)練模型介紹
首先在data目錄下,有兩個(gè)目錄

  • faster_rcnn_models/

  • imagenet_models/

faster_rcnn_model文件夾下面是作者用faster rcnn訓(xùn)練好的三個(gè)網(wǎng)絡(luò),分別對(duì)應(yīng)著小,、中,、大型網(wǎng)絡(luò),大家可以試用一下這幾個(gè)網(wǎng)絡(luò),,看一些檢測(cè)效果,,他們訓(xùn)練都迭代了80000次,數(shù)據(jù)集都是pascal_voc的數(shù)據(jù)集,。

imagenet_model文件夾下面是在Imagenet上訓(xùn)練好的通用模型,,在這里用來(lái)初始化網(wǎng)絡(luò)的參數(shù).

在這里我比較推薦大型網(wǎng)絡(luò),訓(xùn)練也挺快的,,差不多25小時(shí)(titan black 6G),。
還有一個(gè)比較奇怪的現(xiàn)象,開(kāi)啟CuDNN一般情況是可以加速的,但是在訓(xùn)練ZF模型的時(shí)候,,開(kāi)啟CuDNN反而會(huì)特別慢,,所以大家如果訓(xùn)練特別慢,可以嘗試關(guān)掉CuDNN,。

2.修改模型文件配置
模型文件在models下面對(duì)應(yīng)的網(wǎng)絡(luò)文件夾下,,在這里我用大型網(wǎng)絡(luò)的配置文件修改為例子
比如:我的檢測(cè)目標(biāo)物是person ,那么我的類別就有兩個(gè)類別即 background 和 person
因此,,首先打開(kāi)網(wǎng)絡(luò)的模型文件夾,,打開(kāi)train.prototxt
修改的地方重要有三個(gè)
分別是這幾個(gè)地方

  1. 首先在data層把num_classes 從原來(lái)的21類 20類+背景 ,改成 2類 人+背景
  2. 把RoI Proposal的’roi-data’層的 num_classes 改為 2
  3. 接著在cls_score層把num_output 從原來(lái)的21 改成 2
  4. 在bbox_pred層把num_output 從原來(lái)的84 改成8,, 為檢測(cè)類別個(gè)數(shù)乘以4,比如這里是2類那就是2*4=8

測(cè)試的時(shí)候,,test.prototxt也需要做相應(yīng)的修改,。

OK,如果你要進(jìn)一步修改網(wǎng)絡(luò)訓(xùn)練中的學(xué)習(xí)速率,,步長(zhǎng),,gamma值,以及輸出模型的名字,,需要在同目錄下的solver.prototxt中修改,。

3.啟動(dòng)Fast RCNN網(wǎng)絡(luò)訓(xùn)練

python ./tools/train_net.py --gpu 1 --solver models/hs/faster_rcnn_end2end/solver.prototxt --weights data/imagenet_models/VGG16.v2.caffemodel --imdb hs --iters 80000 --cfg experiments/cfgs/faster_rcnn_end2end.yml
  • 1
  • 1

參數(shù)講解:

  • 這里的–是兩個(gè)-,不要輸錯(cuò)

  • train_net.py是網(wǎng)絡(luò)的訓(xùn)練文件,,之后的參數(shù)都是附帶的輸入?yún)?shù)

  • –gpu 代表機(jī)器上的GPU編號(hào),,如果是nvidia系列的tesla顯卡,可以在終端中輸入nvidia-smi來(lái)查看當(dāng)前的顯卡負(fù)荷,,選擇合適的顯卡

  • –solver 代表模型的配置文件,,train.prototxt的文件路徑已經(jīng)包含在這個(gè)文件之中

  • –weights 代表初始化的權(quán)重文件,這里用的是Imagenet上預(yù)訓(xùn)練好的模型,,大型的網(wǎng)絡(luò)我們選擇用VGG16.v2.caffemodel

  • –imdb 這里給出的訓(xùn)練的數(shù)據(jù)庫(kù)名字需要在factory.py的_sets中,,我在文件里面有_sets[‘hs’],train_net.py這個(gè)文件會(huì)調(diào)用factory.py再生成hs這個(gè)類,,來(lái)讀取數(shù)據(jù)

4.啟動(dòng)Fast RCNN網(wǎng)絡(luò)檢測(cè)
可以參考tools下面的demo.py 文件,,來(lái)做檢測(cè),并且將檢測(cè)的坐標(biāo)結(jié)果輸出到相應(yīng)的txt文件中,。

最后

鑒于之前我用的版本是15年11月的版本,,有些小伙伴在使用此教程時(shí)會(huì)有一些錯(cuò)誤,所以我重新做了部分修訂,,目前能夠在2016年4月29日版本的版本上成功運(yùn)行,,如果有問(wèn)題,隨時(shí)聯(lián)系我。

參考博客:http://www.cnblogs.com/louyihang-loves-baiyan/p/4885659.html

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多