配置信息:
ubuntu16.04
python3.6.5
tensorflow1.4.1
keras2.1.5
cuda8
cudnn6
利用jupyter
打开Terminal,输入如下命令来启动Anaconda-Navigator图形化界面:
anaconda-navigator
然后Launch“jupyter notebook”,然后打开samples文件夹下的demo.ipynb文件。点击Run,就可以逐块(cell)运行,每个cell上面都有文字说明
错误1
运行第一块,出现如下错误:提示没有“pycocotools”
解决方法:
在这里cocoapi下载cocoapi,解压,进入到cocoapi-master/PythonAPI目录下,打开Terminal,输入:
make
然后把cocoapi-master/PythonAPI目录下的pycocotools拷贝到maskrcnn根目录下。
然后会提示成功下载了权重文件mask_rcnn_coco.h5:
Downloading pretrained model to /home/xxxxx/python/Mask_RCNN-master/mask_rcnn_coco.h5 ...
... done downloading pretrained model!
然后就没有别的错误了,能输出随机一张图片的检测结果:
参考资料:
利用pycharm
在pycharm中,打开maskrcnn文件夹,然后在samples文件夹下新建一个demo.py的文件。
然后把demo.ipynb的代码拷贝过去,然后运行。
错误1
解决方法%matplotlib inline是内置在jupyter中的函数,在pycharm中不支持该语句。
解决办法是注释掉%matplotlib inline,然后在代码的最后加上:plt.show()。
参考资料:
错误2
解决方法
安装imgaug即可:
pip install imgaug
参考资料:
错误3
解决方法:
降级安装了keras,本来安装的默认版本为2.2.2,后来换成了2.1.5。
参考资料:
然后就能运行出结果了。
附权重文件下载地址:
代码理解
# Download COCO trained weights from Releases if needed
if not os.path.exists(COCO_MODEL_PATH):
utils.download_trained_weights(COCO_MODEL_PATH)
#COCO_MODEL_PATH为 '/home/xxxxx/python/Mask_RCNN-master-pycharm/mask_rcnn_coco.h5'
上段代码在目录内没有权重文件时进行下载权重文件,download_trained_weights函数(位于utils.py)如下:
def download_trained_weights(coco_model_path, verbose=1):
"""Download COCO trained weights from Releases.
coco_model_path: local path of COCO trained weights
"""
if verbose > 0:
print("Downloading pretrained model to " + coco_model_path + " ...")
with urllib.request.urlopen(COCO_MODEL_URL) as resp, open(coco_model_path, 'wb') as out:
#urllib.request.urlopen就是打开URL的网址,实现对网页的get请求抓取
shutil.copyfileobj(resp, out)
#shutil模块是高级的文件操作模块,shutil.copyfileobj作用是拷贝文件内容到另一个文件
if verbose > 0:
print("... done downloading pretrained model!")
参考资料:
MEAN_PIXEL = np.array([123.7, 116.8, 103.9])
#位于mrcnn文件夹下config.py文件,np.array就是创建一个数组
#类InferenceConfig继承于CocoConfig,CocoConfig继承于config,config是很多基础的设置,有些参数未设置,因此如果要用config类,要进行修改或继承
keras.layers.Input()#获得输入张量
keras.layers.Lambda() #将任意表达式封装为Layer对象
MaskRcnn部分代码(为简单表示,省略一些参数,或直接改成具体的数字):
#Bottom-up Layers
_, C2, C3, C4, C5 = resnet_graph()
# C2:Tensor("res2c_out/Relu:0", shape=(?, ?, ?, 256), dtype=float32)
# C3:Tensor("res3d_out/Relu:0", shape=(?, ?, ?, 512), dtype=float32)
# C4:Tensor("res4w_out/Relu:0", shape=(?, ?, ?, 1024), dtype=float32)
# C5:Tensor("res5c_out/Relu:0", shape=(?, ?, ?, 2048), dtype=float32)
#Top-down Layers
P5 = KL.Conv2D(256, (1, 1), name='fpn_c5p5')(C5)
P4 = KL.Add( )([KL.UpSampling2D(size=(2, 2))(P5),KL.Conv2D(256, (1, 1))(C4)])
P3 = KL.Add( )([KL.UpSampling2D(size=(2, 2))(P4),KL.Conv2D(256, (1, 1))(C3)])
P2 = KL.Add( )([KL.UpSampling2D(size=(2, 2))(P3),KL.Conv2D(256, (1, 1))(C2)])
# Attach 3x3 conv to all P layers to get the final feature maps.
P2 = KL.Conv2D(256, (3, 3), padding="SAME")(P2)
P3 = KL.Conv2D(256, (3, 3), padding="SAME")(P3)
P4 = KL.Conv2D(256, (3, 3), padding="SAME")(P4)
P5 = KL.Conv2D(256, (3, 3), padding="SAME")(P5)
# P6 is used for the 5th anchor scale in RPN. Generated by subsampling from P5 with stride of 2.
P6 = KL.MaxPooling2D(pool_size=(1, 1), strides=2)(P5)
# P2:Tensor("fpn_p2/BiasAdd:0", shape=(?, ?, ?, 256), dtype=float32)
# P3:Tensor("fpn_p3/BiasAdd:0", shape=(?, ?, ?, 256), dtype=float32)
# P4:Tensor("fpn_p4/BiasAdd:0", shape=(?, ?, ?, 256), dtype=float32)
# P5:Tensor("fpn_p5/BiasAdd:0", shape=(?, ?, ?, 256), dtype=float32)
# P6:Tensor("fpn_p6/MaxPool:0", shape=(?, ?, ?, 256), dtype=float32)
# Note that P6 is used in RPN, but not in the classifier heads.
rpn_feature_maps = [P2, P3, P4, P5, P6]
mrcnn_feature_maps = [P2, P3, P4, P5]
ix = tf.nn.top_k(scores, pre_nms_limit, sorted=True, name="top_anchors").indices
# tf.nn.top_k(input,k,name=None)的作用是返回input中每行最大的k个数,并返回它们所在位置的索引。
def rpn_graph手写太丑……
def resnet_graph结构
conv_block和identity_block结构:
疑问
coco.py文件中有这么一句代码, 为什么import ... as 后面有两个名称:
from mrcnn import model as modellib, utils
K.shape(input_image)[1:3]是什么意思?
gt_boxes = KL.Lambda(lambda x: norm_boxes_graph(x, K.shape(input_image)[1:3]))(input_gt_boxes)
下面这个ZeroPadding2D((3, 3))到底执行的是什么操作,是在上下左右分别填充3行么?可是这里卷积层 Convolutional - Keras 中文文档解释的为“如果为 2 个整数的元组:解释为高度和高度的 2 个不同的对称裁剪值:(symmetric_height_pad,symmetric_width_pad)。”
x = KL.ZeroPadding2D((3, 3))(input_image) # x: Tensor("zero_padding2d_1/Pad:0", shape=(?,?,?,3),dtype=float32)
在model.py中有个继承自KL.BatchNormalization的类Batchnorm,这个继承有什么作用呢?最后的返回值又是啥意思?
return super(self.__class__, self).call(inputs, training=training)
不太懂rpn这个模型,在build_rpn_model中通过keras.models.Model返回的,然后rpn([p])不知道又表示什么?
# RPN Model
rpn = build_rpn_model(1,3,256)
# Loop through pyramid layers
layer_outputs = [] # list of lists
for p in rpn_feature_maps:
layer_outputs.append(rpn([p]))
帮助学习代码的阅读资料:scikit-image是基于scipy的一款图像处理包,它将图片作为numpy数组进行处理,正好与matlab一样。
因为是刚开始接触,所以很多代码看起来很迷,还希望各位小可爱们能指点迷津,不要嫌弃嘤嘤嘤