使用Anaconda安装,由于conda install出现一些问题,所以依赖项都是用pip安装
在安装imgaug时遇到了问题,解决办法是手动安装shapely,参考https://blog.csdn.net/w15797673137/article/details/90604062
其余部分均按照readme中教程执行,没有遇到问题
如果tensorflow安装成功但是在spyder中打不开,原因可能是spyder不是安装在该虚拟环境中,此时在虚拟环境conda install spyder之后再打开即可
使用jupyter notebook打开特定位置文件:
现在虚拟环境中cd到对应文件位置,然后打开jupyter notebook即可
我们为MS COCO提供预训练的权重,使它更加容易开始训练。你可以使用这些权重作为一个起始点,来训练你自己的网络。训练代码和评估代码在````samples/coco/coco.py```中,你可以在jupyter notebook中引用这个模块(参阅examples中提供是示例noebook)或者你也可以直接从命令行运行它。
# Train a new model starting from pre-trained COCO weights 使用coco预训练权重训练新的模型
python3 samples/coco/coco.py train --dataset=/path/to/coco/ --model=coco
# Train a new model starting from ImageNet weights 使用ImageNet权重训练新模型
python3 samples/coco/coco.py train --dataset=/path/to/coco/ --model=imagenet
# Continue training a model that you had trained earlier 继续训练之前训练过的模型
python3 samples/coco/coco.py train --dataset=/path/to/coco/ --model=/path/to/weights.h5
# Continue training the last model you trained. This will find 继续训练最新训练过的模型
# the last trained weights in the model directory. 从model文件夹中自动找到最新的模型
python3 samples/coco/coco.py train --dataset=/path/to/coco/ --model=last
你还可以使用以下命令运行COCO的评估代码:
# Run COCO evaluation on the last trained model 在最后训练的模型上运行COCO评估代码
python3 samples/coco/coco.py evaluate --dataset=/path/to/coco/ --model=last
训练计划,学习率,和其他参数应该samples/coco.coco.py
中设置。
首先要阅读关于气球颜色splash样本的博客。它涵盖了从标注训练图片到使用的过程.
总之,要在你的数据集上训练模型,你需要扩展两个类。
Config
该类包含默认配置。对其子类化并且根据你的需要修改属性
Dataset
该类提供了使用任何数据集的统一方法。它允许您使用新的数据集进行培训,而无需更改模型的代码。它还支持同时导入多个数据集,如果你想要检测的目标不全都在一个数据集中时,这就很有用。
在samples/shapes/train_shapes.ipynb
、samples/coco/coco.py
、samples/balloon/balloon.py
和samples/nucleus/nucleus.py
中查看示例。
这个实现大部分都遵循Mask RCNN文章,但是在一些情况下我们偏向于代码的简单性和泛化行。以下使我们意识到的一些不同,如果还有其他差异,请告诉我们
(1)图像大小的调整
为了支持每个batch训练多个图像,我们将所有图像调整为相同大小。例如,MS COCO上的1024*1024。我们保持了宽高比,因此如果图片不是正方形,我们用0填充,在论文中,调整大小是的最小边为800px,最大边为1000px。
(2)边界框
一些数据集提供了边界框BBox,一些只提供masks。为了支持对多个数据集的训练,我们选择忽略数据集附带的边界框,而是动态生成它们。我们选择了包含所有mask像素点的最小的边界框作为BBox。这简化了Mask的实现并还使得图像增强变得容易,否则图像增强将难以应用到BBOX中,例如例如图像旋转
为了验证这种方法,我们将我们计算出的BBOX和COCO数据集中提供的BBOX进行了比较。我们发现大约2%相差1pix以上,约0.05%相差5pix以上,只有0.01%相差10pix以上。
(3)学习率
本文使用的学习率是0.02,但是我们太高,并且经常导致梯度爆炸,特别是当使用小的batchsize时。这可能与caffe和tensorflow的梯度计算方法不同有关(通过batches和GPU求和及求均值的差异)。或者,光放模型使用了gradient clipping来避免这个问题。我们确实也使用了gradient clipping,但是不会设置的过于激进。我们发现更小的学习率无论如都会加速收敛所以我们减小了学习率。
使用该BilTeX来引用这个库
@misc{matterport_maskrcnn_2017,
title={Mask R-CNN for object detection and instance segmentation on Keras and TensorFlow},
author={Waleed Abdulla},
year={2017},
publisher={Github},
journal={GitHub repository},
howpublished={\url{https://github.com/matterport/Mask_RCNN}},
}
(用不上,先不翻译)
Python 3.4, TensorFlow 1.3, Keras 2.0.8 其他公共的包在requirements.txt
中
要在MS COCO上训练或者测试,你还需要:
(1)pycocotools(安装说明如下)
(2)MS COCO Dataset(http://cocodataset.org/#home)
(3)下载5K minival以及35K validationn-minus-minival子集。更多细节在最初的Faster R-CNN implementation中
如果你使用Docker,代码已经验证过可以再这个Docker container中运行(https://hub.docker.com/r/waleedka/modern-deep-learning/)
(1)下载这个库(此项目)
(2)安装依赖项
pip3 install -r requirements.txt
(3)从项目 的根目录运行setup.py
python3 setup.py install
(4)现在COCO预训练权重(mask_rcnn_coco.h5)(https://github.com/matterport/Mask_RCNN/releases)
(5)(可选项)想要在MS COCO上训练或者测试,需要从这些repos中的一个下载pycoctools
,他们是院士pycocotools的分支,具有python3和Windows的修复版本(官方repos似乎不再更新了)
Linux: https://github.com/waleedka/coco
Windows: https://github.com/philferriere/cocoapi. You must have the Visual C++ 2015 build tools on your path (see the repo for additional details)
(如果你使用这个模型或者拓展了模型,我们愿闻其详)
别人的代码详解可以参考https://blog.csdn.net/myGFZ/article/details/80217885
权重文件.h5如果中断下载会出现OS错误https://blog.csdn.net/qq_41185868/article/details/80831046
安装pycocotools模块(该demo中不需要下载coco数据集)
pip install git+https://github.com/philferriere/cocoapi.git#subdirectory=PythonAPI
# -*- coding: utf-8 -*-
"""
Created on Mon Sep 16 23:35:43 2019
@author: Lenovo
"""
#Mask R-CNN例子
#一个使用预训练模型检测和分割目标的简要介绍
import os
import sys
import random
import math
import numpy as np
import skimage.io
import matplotlib
import matplotlib.pyplot as plt
# Root directory of the project
#项目根目录(返回上级目录的绝对路径)
ROOT_DIR = os.path.abspath("../")
# Import Mask RCNN
#导入Mask RCNN
sys.path.append(ROOT_DIR) # To find local version of the library为了找到本地版本的库
from mrcnn import utils
import mrcnn.model as modellib
from mrcnn import visualize
# Import COCO config
#引用COCO设置模块
sys.path.append(os.path.join(ROOT_DIR, "samples/coco/")) # To find local version(即将coco模块的目录加入到系统环境中)
import coco
# Directory to save logs and trained model
#保存日志和训练模型的文件夹
MODEL_DIR = os.path.join(ROOT_DIR, "logs")
# Local path to trained weights file
#训练权重文件的本地路径
COCO_MODEL_PATH = os.path.join(ROOT_DIR, "mask_rcnn_coco.h5")
# Download COCO trained weights from Releases if needed
#如果需要的话,从Releases下载COCO训练权重
if not os.path.exists(COCO_MODEL_PATH):
utils.download_trained_weights(COCO_MODEL_PATH)
# Directory of images to run detection on
#要运行检测的图像目录
IMAGE_DIR = os.path.join(ROOT_DIR, "images")
#恭喜
#我们将使用在MS-COCO数据集上训练的模型。该模型的配置在coco.py的CocoConnfig类中
#对于推理来说,请稍微修改配置以适合任务。为此,请对CocoConfig类进行子类化并覆盖您需要更改的属性
class InferenceConfig(coco.CocoConfig):
# Set batch size to 1 since we'll be running inference on
# one image at a time. Batch size = GPU_COUNT * IMAGES_PER_GPU
#将batchsize设置成1因为我们将以此在一个图像上进行推断
#Batch=GPU个数*每个GPU处理的图像数
GPU_COUNT = 1
IMAGES_PER_GPU = 1
#保存配置信息
config = InferenceConfig()
#输出配置信息在面板
#config.display()
# Create model object in inference mode.
#创建模型Model,调用了model.py中的Mask RCNN类
#对应参数(模型类型,模型文件夹,配置信息)
model = modellib.MaskRCNN(mode="inference", model_dir=MODEL_DIR, config=config)
# Load weights trained on MS-COCO
#载入模型权重文件
model.load_weights(COCO_MODEL_PATH, by_name=True)
# COCO Class names
#将整数id与类型名字对应(如模型预测的id=1,对应的是person)
# Index of the class in the list is its ID. For example, to get ID of
# the teddy bear class, use: class_names.index('teddy bear')
class_names = ['BG', 'person', 'bicycle', 'car', 'motorcycle', 'airplane',
'bus', 'train', 'truck', 'boat', 'traffic light',
'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird',
'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear',
'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie',
'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball',
'kite', 'baseball bat', 'baseball glove', 'skateboard',
'surfboard', 'tennis racket', 'bottle', 'wine glass', 'cup',
'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple',
'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza',
'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed',
'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote',
'keyboard', 'cell phone', 'microwave', 'oven', 'toaster',
'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors',
'teddy bear', 'hair drier', 'toothbrush']
# Load a random image from the images folder
#返回文件夹中所有图片名字
file_names = next(os.walk(IMAGE_DIR))[2]
#随机选择一张图片(skimage模块用于图像的读取,显示,转换等)
image = skimage.io.imread(os.path.join(IMAGE_DIR, random.choice(file_names)))
# Run detection
#进行检测
results = model.detect([image], verbose=1)
# Visualize results
#结果可视化,result[0]是预测的标签信息
#display_instances也是mask_rcnn中的自定义函数
r = results[0]
visualize.display_instances(image, r['rois'], r['masks'], r['class_ids'],
class_names, r['scores'])
(1)ROOT_DIR为根目录,日志文件在根目录的“logs”文件夹,确保权重文件.h5存在
(2)创建一个Config子类,并进行相关配置(名称,类别数,图片大小限制,anchors大小设置,ROIs数量,epoch,val_step等),保存配置,打印配置信息
(3)可视化工作,创建自定义函数用来返回需要的Axes
(4)创建合成数据集
创建utils.Dataset的子类ShapeDataset,并且自定义一些函数(因为数据集是合成的,而非导入的),主要是前两个自定义函数,调用后几个进行图片的合成。
load_shapes 用于确定生成的图片的数量,尺寸,种类和对应类别名称标签,即数据集的shapes
load_image 用于生成具体image
imge_reference 用于返回图片的shapes数据
load_mask 用于生成对应图片的mask(可以理解成mask数据中手动标注的mask)
draw_shape 用于绘制图形(方形、圆形、三角形)
random_shape 在给定范围内生成特定图形
random_image 创建一个具有多个图形的图像,
(5)创建训练集training dataset,载入数据集(此处load_shapes实际上是生成),准备训练集
(6)创建验证集validation dateset
(7)查看生成的数据,显示image,mask,class_id,class_name等信息
(8)创建训练模型model=modellib.MaskRCN()
(9)载入权重model.load_weights()
(10)训练模型model.train()可以选择只训练头部,也可以训练所有层,或者特定的层。
代码中展示了如何只训练heads以及fine-tune所有层
(11)检测:重建一个InferenceConfig以及model用于检测,载入训练好的权重
(12)随机选择一张图片,先输出其真实信息(类别,mask,class等)
(13)进行检测,并输出检测结果
(14)检测10张图片并求mAP值
#此笔记本显示如何在您自己的数据集上训练Mask R-CNN。 为了简单起见,我们使用形状(正方形,三角形和圆形)的合成数据集来实现快速训练。
#但是,你仍然需要一个GPU,因为网络骨干网是一个Resnet101,它在CPU上训练的速度太慢了。
#在GPU上,您可以在几分钟内开始获得好结果,并在不到一个小时内获得良好结果。
#形状数据集的代码包含在下面。 它可以动态生成图像,因此不需要下载任何数据。
#它可以生成任何大小的图像,因此我们选择一个小图像尺寸来加快训练。
import os
import sys
import random
import math
import re
import time
import numpy as np
import cv2
import matplotlib
import matplotlib.pyplot as plt
# Root directory of the project
#项目根目录
ROOT_DIR = os.path.abspath("../../")
# Import Mask RCNN
#引入MaskRCNN模块
sys.path.append(ROOT_DIR) # To find local version of the library
from mrcnn.config import Config
from mrcnn import utils
import mrcnn.model as modellib
from mrcnn import visualize
from mrcnn.model import log
%matplotlib inline
# Directory to save logs and trained model
#保存日志和训练模型的文件夹
MODEL_DIR = os.path.join(ROOT_DIR, "logs")
# Local path to trained weights file
#训练权重文件的本地路径
COCO_MODEL_PATH = os.path.join(ROOT_DIR, "mask_rcnn_coco.h5")
# Download COCO trained weights from Releases if needed
#如果没有则下载
if not os.path.exists(COCO_MODEL_PATH):
utils.download_trained_weights(COCO_MODEL_PATH)
#####################################################
class ShapesConfig(Config):
"""Configuration for training on the toy shapes dataset.
Derives from the base Config class and overrides values specific
to the toy shapes dataset.
用于训练玩具形状数据集的配置,从Config基类中提取并覆盖特点的玩具数据集的值
"""
# Give the configuration a recognizable name
#给该配置一个可识别的名字
NAME = "shapes"
# Train on 1 GPU and 8 images per GPU. We can put multiple images on each
# GPU because the images are small. Batch size is 8 (GPUs * images/GPU).
#在1个GPU训练且每个GPU处理8张图片。我们可以给每个GPU分配多张图片因为图片很小。
#Batchsize=8
GPU_COUNT = 1
IMAGES_PER_GPU = 8
# Number of classes (including background)
#类别数(包括背景)
NUM_CLASSES = 1 + 3 # background + 3 shapes
# Use small images for faster training. Set the limits of the small side
# the large side, and that determines the image shape.
#使用小图片以更快的训练。设置短边和长边的限制,由此确定图片尺寸
IMAGE_MIN_DIM = 128
IMAGE_MAX_DIM = 128
# Use smaller anchors because our image and objects are small
#使用更小的anchors因为我们的图片和目标都很小
RPN_ANCHOR_SCALES = (8, 16, 32, 64, 128) # anchor side in pixels,anchor的边的像素数量
# Reduce training ROIs per image because the images are small and have
# few objects. Aim to allow ROI sampling to pick 33% positive ROIs.
#减少每张图片的训练ROI,因为是小图片并且目标很少。目的是使得ROI采样提取到33%的正确ROIs
TRAIN_ROIS_PER_IMAGE = 32
# Use a small epoch since the data is simple
#使用小epoch因为数据很简单
STEPS_PER_EPOCH = 100
# use small validation steps since the epoch is small
#使用小的val steps因为epoch很小
VALIDATION_STEPS = 5
#保存配置,打印配置信息
config = ShapesConfig()
config.display()
#####################################################
def get_ax(rows=1, cols=1, size=8):
"""Return a Matplotlib Axes array to be used in
all visualizations in the notebook. Provide a
central point to control graph sizes.
Change the default size attribute to control the size
of rendered images
返回一个Matplotlib Axes数组,用于notebook中的所有可视化。
提供控制图形大小的中心点。更改默认大小属性以控制渲染图像的大小
"""
_, ax = plt.subplots(rows, cols, figsize=(size*cols, size*rows))
return ax
#####################################################
#创建一个合成数据集
#扩展数据集种类并且添加一个方法来载入数据集,load_shapes(),并且重写以下方法
#load_image()、load_mask()、image_reference()
class ShapesDataset(utils.Dataset):
"""Generates the shapes synthetic dataset. The dataset consists of simple
shapes (triangles, squares, circles) placed randomly on a blank surface.
The images are generated on the fly. No file access required.
生成形状合成数据集。 数据集由在空白表面上随机放置的简单形状(三角形,正方形,圆形)组成。
图像是在运行中生成的。 无需文件访问权限。
"""
def load_shapes(self, count, height, width):
"""Generate the requested number of synthetic images.
count: number of images to generate.
height, width: the size of the generated images.
生成所需数量的合成图像。
count:要生成的图像数。
height,width:生成图像的大小。
"""
# Add classes,添加类别,方法定义在utils.py中(utils:辅助工具类模块)
#三个参数分别是(source,id,name)
self.add_class("shapes", 1, "square")
self.add_class("shapes", 2, "circle")
self.add_class("shapes", 3, "triangle")
# Add images,添加图像
# Generate random specifications of images (i.e. color and
# list of shapes sizes and locations). This is more compact than
# actual images. Images are generated on the fly in load_image().
#生成图像的随机规格(即颜色和形状大小和位置的列表)。
#这比实际图像更紧凑。 图像在load_image()中即时生成。
#自定义函数间utils.py
for i in range(count):
bg_color, shapes = self.random_image(height, width)
self.add_image("shapes", image_id=i, path=None,
width=width, height=height,
bg_color=bg_color, shapes=shapes)
def load_image(self, image_id):
"""Generate an image from the specs of the given image ID.
Typically this function loads the image from a file, but
in this case it generates the image on the fly from the
specs in image_info.
根据给定的图像ID生成图像。通常这个函数是从文件夹中载入图片的,
但是在这个案例中它会根据image_info中的规范(specs)在运行时(on the fly)生成图像
"""
info = self.image_info[image_id]
bg_color = np.array(info['bg_color']).reshape([1, 1, 3])
image = np.ones([info['height'], info['width'], 3], dtype=np.uint8)
image = image * bg_color.astype(np.uint8)
for shape, color, dims in info['shapes']:
image = self.draw_shape(image, shape, dims, color)
return image
def image_reference(self, image_id):
"""Return the shapes data of the image.
返回图片的形状数据"""
info = self.image_info[image_id]
if info["source"] == "shapes":
return info["shapes"]
else:
super(self.__class__).image_reference(self, image_id)
def load_mask(self, image_id):
"""Generate instance masks for shapes of the given image ID.
生成给定图片的id的形状的mask实例
"""
info = self.image_info[image_id]
shapes = info['shapes']
count = len(shapes)
mask = np.zeros([info['height'], info['width'], count], dtype=np.uint8)
for i, (shape, _, dims) in enumerate(info['shapes']):
mask[:, :, i:i+1] = self.draw_shape(mask[:, :, i:i+1].copy(),
shape, dims, 1)
# Handle occlusions
#处理遮挡
occlusion = np.logical_not(mask[:, :, -1]).astype(np.uint8)
for i in range(count-2, -1, -1):
mask[:, :, i] = mask[:, :, i] * occlusion
occlusion = np.logical_and(occlusion, np.logical_not(mask[:, :, i]))
# Map class names to class IDs.
#将类别名称与ID对应
class_ids = np.array([self.class_names.index(s[0]) for s in shapes])
return mask.astype(np.bool), class_ids.astype(np.int32)
def draw_shape(self, image, shape, dims, color):
"""Draws a shape from the given specs.
根据给定的规格绘制形状"""
# Get the center x, y and the size s
x, y, s = dims
if shape == 'square':
cv2.rectangle(image, (x-s, y-s), (x+s, y+s), color, -1)
elif shape == "circle":
cv2.circle(image, (x, y), s, color, -1)
elif shape == "triangle":
points = np.array([[(x, y-s),
(x-s/math.sin(math.radians(60)), y+s),
(x+s/math.sin(math.radians(60)), y+s),
]], dtype=np.int32)
cv2.fillPoly(image, points, color)
return image
def random_shape(self, height, width):
"""Generates specifications of a random shape that lies within
the given height and width boundaries.
在给定的宽高范围内生成特定的随机图形
Returns a tuple of three valus:返回一个三元组
* The shape name (square, circle, ...)图形名字
* Shape color: a tuple of 3 values, RGB.图形颜色(RGB三元组)
* Shape dimensions: A tuple of values that define the shape size 形状尺寸:定义形状大小和位置的值的元组,每个形状类型都不同
and location. Differs per shape type.
"""
# Shape形状
shape = random.choice(["square", "circle", "triangle"])
# Color颜色
color = tuple([random.randint(0, 255) for _ in range(3)])
# Center x, y中心坐标
buffer = 20
y = random.randint(buffer, height - buffer - 1)
x = random.randint(buffer, width - buffer - 1)
# Size尺寸
s = random.randint(buffer, height//4)
return shape, color, (x, y, s)
def random_image(self, height, width):
"""Creates random specifications of an image with multiple shapes.
Returns the background color of the image and a list of shape
specifications that can be used to draw the image.
创建一个具有多个图形的图像,返回图像的背景颜色和一个形状规格的列表,可以用来画图像
"""
# Pick random background color
#选择随机背景颜色
bg_color = np.array([random.randint(0, 255) for _ in range(3)])
# Generate a few random shapes and record their
# bounding boxes
#生成一些随机形状并且记录他们的边界框
shapes = []
boxes = []
N = random.randint(1, 4)
for _ in range(N):
shape, color, dims = self.random_shape(height, width)
shapes.append((shape, color, dims))
x, y, s = dims
boxes.append([y-s, x-s, y+s, x+s])
# Apply non-max suppression wit 0.3 threshold to avoid
# shapes covering each other
#使用0.3阈值的极大值抑制方法来避免图形彼此重叠
keep_ixs = utils.non_max_suppression(np.array(boxes), np.arange(N), 0.3)
shapes = [s for i, s in enumerate(shapes) if i in keep_ixs]
return bg_color, shapes
#####################################################
# Training dataset
#训练集
dataset_train = ShapesDataset()
dataset_train.load_shapes(500, config.IMAGE_SHAPE[0], config.IMAGE_SHAPE[1])
dataset_train.prepare()
# Validation dataset
#验证集
dataset_val = ShapesDataset()
dataset_val.load_shapes(50, config.IMAGE_SHAPE[0], config.IMAGE_SHAPE[1])
dataset_val.prepare()
#####################################################
# Load and display random samples
#载入并显示随机杨蓓
image_ids = np.random.choice(dataset_train.image_ids, 4)
for image_id in image_ids:
image = dataset_train.load_image(image_id)
mask, class_ids = dataset_train.load_mask(image_id)
visualize.display_top_masks(image, mask, class_ids, dataset_train.class_names)
#####################################################
# Create model in training mode
#创建训练模型
model = modellib.MaskRCNN(mode="training", config=config,
model_dir=MODEL_DIR)
#####################################################
# Which weights to start with?
#初始权重使用哪一个?
init_with = "coco" # imagenet, coco, or last
if init_with == "imagenet":
model.load_weights(model.get_imagenet_weights(), by_name=True)
elif init_with == "coco":
# Load weights trained on MS COCO, but skip layers that
# are different due to the different number of classes
# See README for instructions to download the COCO weights
#加载在MS coco上的训练权重,但是跳过一些层(由于类别数不同而引起不同的层)
#下载COCO权重的介绍见README
model.load_weights(COCO_MODEL_PATH, by_name=True,
exclude=["mrcnn_class_logits", "mrcnn_bbox_fc",
"mrcnn_bbox", "mrcnn_mask"])
elif init_with == "last":
# Load the last model you trained and continue training
#载入你训练或的最新模型,并继续训练
model.load_weights(model.find_last(), by_name=True)
#####################################################
"""
训练分两个阶段训练:
1.只训练头部。在这里,我们冻结所有主干层并仅训练随机初始化的层(即我们没有使用来自MS COCO的预训练权重的层)。
要仅训练头部层,将layer ='heads'传递给train()函数。
2.Fune-tune所有图层。对于这个简单的例子,没有必要,但我们将它包括在内以显示该过程。 只需传递layers =“all即可训练所有图层。
"""
# Train the head branches 训练head分支
# Passing layers="heads" freezes all layers except the head 冻结所有层除了head
# layers. You can also pass a regular expression to select 你也可以通过传递正则表达式来通过名称模式来选择一些层训练
# which layers to train by name pattern.
model.train(dataset_train, dataset_val,
learning_rate=config.LEARNING_RATE,
epochs=1,
layers='heads')
#####################################################
# Fine tune all layers Fine-tune所有层
# Passing layers="all" trains all layers. You can also 传入参数layers="all",也可以通过名字训练特定的层
# pass a regular expression to select which layers to
# train by name pattern.
model.train(dataset_train, dataset_val,
learning_rate=config.LEARNING_RATE / 10,
epochs=2,
layers="all")
#####################################################
# Save weights 保存权重
# Typically not needed because callbacks save after every epoch 通常是不需要的,因为callbacks函数在每个epoch之后的会自动保存
# Uncomment to save manually 取消注释可以手动保存
# model_path = os.path.join(MODEL_DIR, "mask_rcnn_shapes.h5") #模型路径
# model.keras_model.save_weights(model_path) #将权重信息保存在路径中
#####################################################
"""
检测
"""
class InferenceConfig(ShapesConfig):
GPU_COUNT = 1
IMAGES_PER_GPU = 1
inference_config = InferenceConfig()
# Recreate the model in inference mode
#以inference模式重建模型
model = modellib.MaskRCNN(mode="inference",
config=inference_config,
model_dir=MODEL_DIR)
# Get path to saved weights 获取权重路径
# Either set a specific path or find last trained weights 或者设置一个其他路径,找到最后训练的权重
# model_path = os.path.join(ROOT_DIR, ".h5 file name here") #取消注释,手动找权重文件
model_path = model.find_last()
# Load trained weights 载入权重
print("Loading weights from ", model_path)
model.load_weights(model_path, by_name=True)
#####################################################
# Test on a random image 随机检测一张图片
image_id = random.choice(dataset_val.image_ids)
original_image, image_meta, gt_class_id, gt_bbox, gt_mask =\
modellib.load_image_gt(dataset_val, inference_config,
image_id, use_mini_mask=False)
#记录信息
log("original_image", original_image)
log("image_meta", image_meta)
log("gt_class_id", gt_class_id)
log("gt_bbox", gt_bbox)
log("gt_mask", gt_mask)
#数据可视化(自定义函数来显示图片的信息)
visualize.display_instances(original_image, gt_bbox, gt_mask, gt_class_id,
dataset_train.class_names, figsize=(8, 8))
#####################################################
#result是检测得到的标签列表
results = model.detect([original_image], verbose=1)
#取第一个标签
r = results[0]
#可视化
visualize.display_instances(original_image, r['rois'], r['masks'], r['class_ids'],
dataset_val.class_names, r['scores'], ax=get_ax())
#####################################################
# Compute VOC-Style mAP @ IoU=0.5
#计算VOC模式下的mAP值,IoU=0.5
# Running on 10 images. Increase for better accuracy.
#在10张图片上运行,增加更好的准确度
image_ids = np.random.choice(dataset_val.image_ids, 10)
APs = []
for image_id in image_ids:
# Load image and ground truth data
#载入图片和背景的真实数据
image, image_meta, gt_class_id, gt_bbox, gt_mask =\
modellib.load_image_gt(dataset_val, inference_config,
image_id, use_mini_mask=False)
molded_images = np.expand_dims(modellib.mold_image(image, inference_config), 0)
# Run object detection
#运行检测
results = model.detect([image], verbose=0)
r = results[0]
# Compute AP
#计算AP
AP, precisions, recalls, overlaps =\
utils.compute_ap(gt_bbox, gt_class_id, gt_mask,
r["rois"], r["class_ids"], r["scores"], r['masks'])
APs.append(AP)
print("mAP: ", np.mean(APs))
为了帮助调试和理解模型,这里提供了三个可视化工具用于inspect,他们可以提供大量可视化并且允许逐步运行模型以检查每个点的输出,这里有一些例子:
第一阶段RPN网络每一步的可视化,以及显示有anchor box refinement的正负anchor
这是一个最终检测框(虚线)的实例以及在第二阶段中应用于它的细化(实线)
Mask的生成示例。然后将他们缩放并放置在图像的正确位置上
通常,检查不同层的激活函数以寻找故障迹象(全零或随机噪声)是有用的。
另一个有用的调试工具是检查权重直方图。 这些包含在inspect_weights.ipynb中。
TensorBoard是另一个很棒的调试和可视化工具。 该模型被配置为记录损失并在每个epoch结束时保存权重。
skimage模块:用于图像的读取,显示,转换灯等
os.path.abspath()
返回一个目录的绝对路径
next
每次调用返回迭代器的下一项,
也可以直接指定返回迭代器中的哪一项,如next(iterator)[n]
os.walk
os.walk(path)返回三个值:parent,dirnames,filenames,分别表示path的路径、path路径下的文件夹的名字和path路径下文件夹以外的其他文件;
对于模块和自己写的脚本不在同一个目录下,在脚本开头加sys.path.append(‘xxx’):
%matplotlib作用
是在使用jupyter notebook 或者 jupyter qtconsole的时候,才会经常用到%matplotlib,也就是说那一份代码可能就是别人使用jupyter notebook 或者 jupyter qtconsole进行编辑的。关于jupyter notebook是什么,可以参考这个链接:[Jupyter Notebook介绍、安装及使用教程][1]
而%matplotlib具体作用是当你调用matplotlib.pyplot的绘图函数plot()进行绘图的时候,或者生成一个figure画布的时候,可以直接在你的python console里面生成图像。