Windows10下的FPN_TensorFlow复现

1、模型准备工作

1-1 模型运行环境

python3.6
TensorFlow1.15-GPU
windows10
Ananonda
Pycharm
CUDA9 + cuDNN7.6
opence-python
tensorflow-plot
:由于模型其中的一些模块需要用到C++编译,所以还需要下载一个VS2019

1-2 模型地址

https://github.com/DetectionTeamUCAS/FPN_Tensorflow

1-3 数据集及resnet网络地址

VOC2007:https://uinedu-my.sharepoint.com/:f:/g/personal/19604_myoffice_site/EiLTzAbNirROrQQF20eupMQB-KpIfZOa7w2YS5MB2ARvSA
resnet50_v1:http://download.tensorflow.org/models/resnet_v1_50_2016_08_28.tar.gz
resnet101_v1:http://download.tensorflow.org/models/resnet_v1_101_2016_08_28.tar.gz

1-4 修改setup.py

由于源码模型是适用于ubuntu16.04的编译,我们修改的地方主要是帮助其找到win10下的nvcc.exe以及相应的lib文件。并且没有用到gcc,要注释掉。
(本次修改参考博文:配置FPN_tensorflow
setup.py文件路径:

PATH\FPN_Tensorflow-master\libs\box_utils\cython_utils
PATH是你自己保存模型的路径

修改后代码如下:

# --------------------------------------------------------
# Fast R-CNN
# Copyright (c) 2015 Microsoft
# Licensed under The MIT License [see LICENSE for details]
# Written by Ross Girshick
# --------------------------------------------------------
 
import os
from os.path import join as pjoin
import numpy as np
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
 
 
lib_dir = 'lib/x64'
 
def find_in_path(name, path):
    "Find a file in a search path"
    #adapted fom http://code.activestate.com/recipes/52224-find-a-file-given-a-search-path/
    for dir in path.split(os.pathsep):
        binpath = pjoin(dir, name)
        if os.path.exists(binpath):
            return os.path.abspath(binpath)
    return None
 
def locate_cuda():
    """Locate the CUDA environment on the system
    Returns a dict with keys 'home', 'nvcc', 'include', and 'lib64'
    and values giving the absolute path to each directory.
    Starts by looking for the CUDAHOME env variable. If not found, everything
    is based on finding 'nvcc' in the PATH.
    """
 
    # first check if the CUDAHOME env variable is in use
    if 'CUDA_PATH' in os.environ:
        home = os.environ['CUDA_PATH']
        print("home = %s\n" % home)
        nvcc = pjoin(home, 'bin', 'nvcc.exe')
    else:
        # otherwise, search the PATH for NVCC
        default_path = pjoin(os.sep, 'usr', 'local', 'cuda', 'bin')
        nvcc = find_in_path('nvcc', os.environ['PATH'] + os.pathsep + default_path)
        if nvcc is None:
            raise EnvironmentError('The nvcc binary could not be '
                'located in your $PATH. Either add it to your path, or set $CUDAHOME')
        home = os.path.dirname(os.path.dirname(nvcc))
 
    cudaconfig = {'home':home, 'nvcc':nvcc,
                  'include': pjoin(home, 'include'),
                  'lib64': pjoin(home, lib_dir)}
    for k, v in cudaconfig.items():
        if not os.path.exists(v):
            raise EnvironmentError('The CUDA %s path could not be located in %s' % (k, v))
 
    return cudaconfig
CUDA = locate_cuda()
 
# Obtain the numpy include directory.  This logic works across numpy versions.
try:
    numpy_include = np.get_include()
except AttributeError:
    numpy_include = np.get_numpy_include()
 
 
def customize_compiler_for_nvcc(self):
    """inject deep into distutils to customize how the dispatch
    to cl/nvcc works.
    If you subclass UnixCCompiler, it's not trivial to get your subclass
    injected in, and still have the right customizations (i.e.
    distutils.sysconfig.customize_compiler) run on it. So instead of going
    the OO route, I have this. Note, it's kindof like a wierd functional
    subclassing going on."""
 
    # tell the compiler it can processes .cu
    #self.src_extensions.append('.cu')
 
	
    # save references to the default compiler_so and _comple methods
    #default_compiler_so = self.spawn 
    #default_compiler_so = self.rc
    super = self.compile
 
    # now redefine the _compile method. This gets executed for each
    # object but distutils doesn't have the ability to change compilers
    # based on source extension: we add it.
    def compile(sources, output_dir=None, macros=None, include_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, depends=None):
        postfix=os.path.splitext(sources[0])[1]
        
        if postfix == '.cu':
            # use the cuda for .cu files
            #self.set_executable('compiler_so', CUDA['nvcc'])
            # use only a subset of the extra_postargs, which are 1-1 translated
            # from the extra_compile_args in the Extension class
            postargs = extra_postargs['nvcc']
        else:
            postargs = extra_postargs['cl']
 
 
        return super(sources, output_dir, macros, include_dirs, debug, extra_preargs, postargs, depends)
        # reset the default compiler_so, which we might have changed for cuda
        #self.rc = default_compiler_so
 
    # inject our redefined _compile method into the class
    self.compile = compile
 
 
# run the customize_compiler
class custom_build_ext(build_ext):
    def build_extensions(self):
        customize_compiler_for_nvcc(self.compiler)
        build_ext.build_extensions(self)
 
ext_modules = [
    Extension(
        "cython_bbox",
        ["bbox.pyx"],
        #extra_compile_args={'gcc': ["-Wno-cpp", "-Wno-unused-function"]},
        extra_compile_args={'cl': []},
        include_dirs = [numpy_include]
    ),
    Extension(
        "cython_nms",
        ["nms.pyx"],
        #extra_compile_args={'gcc': ["-Wno-cpp", "-Wno-unused-function"]},
        extra_compile_args={'cl': []},
        include_dirs = [numpy_include]
    )
    # Extension(
    #     "cpu_nms",
    #     ["cpu_nms.pyx"],
    #     extra_compile_args={'gcc': ["-Wno-cpp", "-Wno-unused-function"]},
    #     include_dirs = [numpy_include]
    # )
]
 
setup(
    name='tf_faster_rcnn',
    ext_modules=ext_modules,
    # inject our custom trigger
    cmdclass={'build_ext': custom_build_ext},
)

2、Demo测试模型

2-1 放置resnet网络及修改cfgs.py

在下载你所需的网络后,将网络解压到下面这个路径

D:\pyprojects\FPN_Tensorflow-master\data\pretrained_weights

接下来修改cfgs.py文件,路径如下

D:\pyprojects\FPN_Tensorflow-master\libs\configs

打开configs文件夹,我们可以发现有如下文件
在这里插入图片描述
本人使用的网络为resnet101,而默认的cfgs.py中使用的也是resnet101,所以这部分不需要修改,如果你使用resnet50,则用第三个py文件的内容替代cfgs.py中的内容即可。
另外,在cfgs.py中我们还需要修改其中的默认路径,将其改为我们存放模型的路径。
修改之处如下
在这里插入图片描述
这部分也需要修改
在这里插入图片描述

2-2 下载权重

在选定cfgs.py所用的resnet网络后,我们去下载对应的网络的权重文件,权重文件地址如下:

https://github.com/DetectionTeamUCAS/Models/tree/master/FPN_Tensorflow

将下载好的权重文件解压在文件夹(D:\pyprojects\FPN_Tensorflow-master\output\trained_weights)中。
在这里插入图片描述

2-3 数据集设置

格式如下

├── data
│ ├── train
│—— ├──——Annotation
│—— ├──—— JPEGImages
│ ├── test
│—— ├──—— Annotation
│—— ├──—— JPEGImages

2-4 编译setup.py

打开Anaconda的命令提示符窗口
激活模型虚拟环境
进入模型文件的路径

cd D:\pyprojects\FPN_Tensorflow-master

在这里插入图片描述
再进入setup.py文件所在的路径

cd D:\pyprojects\FPN_Tensorflow-master\libs\box_utils\cython_utils

进入后在其中输入如下命令并运行

python setup.py build_ext --inplace

在这里插入图片描述
运行成功后如上图所示
其中cython_utils文件夹下会多出以下三个文件
在这里插入图片描述

2-5 运行inference.py演示文件

首先进入tools文件夹

cd D:\pyprojects\FPN_Tensorflow-master\tools

在tools文件夹下新建一个名为results的文件夹,用来保存回归框架
输入命令

python inference.py --data_dir="D:/pyprojects/FPN_Tensorflow-master/tools/demos/"  --save_dir="D:/pyprojects/FPN_Tensorflow-master/tools/results/"  --GPU='0'

在这里插入图片描述

3、训练VOC数据集

3-1 划分数据集

将VOC数据集放在data文件夹下

D:\pyprojects\FPN_Tensorflow-master\data\VOC\VOC_test\VOC2007

然后用以下代码划分训练集和测试集

# -*- coding: utf-8 -*-
from __future__ import division, print_function, absolute_import
import sys

sys.path.append('../../')
import shutil
import os
import random
import math


def mkdir(path):
    if not os.path.exists(path):
        os.makedirs(path)

divide_rate = 0.8

#root_path = '/mnt/ExtraDisk/yangxue/data_ship_clean'
root_path="D:\pyprojects\FPN_Tensorflow-master"  ##注释 修改成我们自己的主路径

#image_path = root_path + '/VOCdevkit/JPEGImages'
image_path = root_path + "/data/VOC/VOC_test/VOC2007/JPEGImages/"  ##注释 修改成图像存放的主路径
xml_path = root_path + "/data/VOC/VOC_test/VOC2007/Annotations/"  ##注释 修改成图像标注的存放的主路径

image_list = os.listdir(image_path)

image_name = [n.split('.')[0] for n in image_list]

random.shuffle(image_name)

train_image = image_name[:int(math.ceil(len(image_name)) * divide_rate)]
test_image = image_name[int(math.ceil(len(image_name)) * divide_rate):]

image_output_train = os.path.join(root_path, 'data/train/JPEGImages') ##注释 输出的train影像的路径
mkdir(image_output_train)
image_output_test = os.path.join(root_path, 'data/test/JPEGImages')#注释 输出的test影像的路径
mkdir(image_output_test)

xml_train = os.path.join(root_path, 'data/train/Annotations')##注释 输出的train影像的标注路径
mkdir(xml_train)
xml_test = os.path.join(root_path, 'data/test/Annotations')##注释 输出的test影像的标注路径
mkdir(xml_test)


count = 0
for i in train_image:
    shutil.copy(os.path.join(image_path, i + '.jpg'), image_output_train) ##影像数据格式.jpg
    shutil.copy(os.path.join(xml_path, i + '.xml'), xml_train)
    if count % 1000 == 0:
        print("process step {}".format(count))
    count += 1

for i in test_image:
    shutil.copy(os.path.join(image_path, i + '.jpg'), image_output_test)
    shutil.copy(os.path.join(xml_path, i + '.xml'), xml_test)
    if count % 1000 == 0:
        print("process step {}".format(count))
    count += 1

3-2 修改参数

首先修改label_dict.py,位于:

D:\pyprojects\FPN_Tensorflow-master\libs\label_name_dict

class_names = [
        'back_ground', 'aeroplane', 'bicycle', 'bird', 'boat',
        'bottle', 'bus', 'car', 'cat', 'chair',
        'cow', 'dining table', 'dog', 'horse', 'motorbike',
        'person', 'potted plant', 'sheep', 'sofa', 'train', 'tvmonitor']

classes_originID = {
    'aeroplane': 1, 'bicycle': 2, 'bird': 3, 'boat': 4,
    'bottle': 5, 'bus': 6, 'car': 7, 'cat': 8, 'chair': 9,
    'cow': 10, 'dining table': 11, 'dog': 12, 'horse': 13,
    'motorbike': 14, 'person': 15, 'potted plant': 16, 'sheep': 17,
    'sofa': 18, 'train': 19, 'tvmonitor': 20}

要与这部分匹配

elif cfgs.DATASET_NAME == 'pascal':
    NAME_LABEL_MAP = {
        'back_ground': 0,
        'aeroplane': 1,
        'bicycle': 2,
        'bird': 3,
        'boat': 4,
        'bottle': 5,
        'bus': 6,
        'car': 7,
        'cat': 8,
        'chair': 9,
        'cow': 10,
        'diningtable': 11,
        'dog': 12,
        'horse': 13,
        'motorbike': 14,
        'person': 15,
        'pottedplant': 16,
        'sheep': 17,
        'sofa': 18,
        'train': 19,
        'tvmonitor': 20
    }

3-3 read_tfrecord.py的修改

在模型文件夹的

D:\pyprojects\FPN_Tensorflow-master\data\io

在这里需要修改数据集的名字,但是由于使用的就是PASCAL_VOC的数据集,并且代码中已经有了pascal的数据名称字典,因此这里不需要修改。

3-4 运行read_tfrecord.py

通过命令

cd D:\pyprojects\FPN_Tensorflow-master\data\io

进入read_tfrecord.py所在的文件夹
运行命令

python convert_data_to_tfrecord.py --VOC_dir="D:\pyprojects/FPN_Tensorflow-master/data\train/"  --save_name="train_TF"
python convert_data_to_tfrecord.py --VOC_dir="D:\pyprojects/FPN_Tensorflow-master/data\test/"  --save_name="test_TF"

在这里插入图片描述
路径

D:\pyprojects\FPN_Tensorflow-master\data\tfrecord

生成两个对应文件
在这里插入图片描述

3-5 train.py

运行以下路径中的train.py即可开始训练

D:\pyprojects\FPN_Tensorflow-master\tools

在这里插入图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值