kaggle比赛: RSNA Pneumonia Detection Challenge 【Mask-RCNN and COCO transfer learning思路以及优化】
第0部分 准备工作
引包
import os
import sys
import random
import math
import numpy as np
import cv2
import matplotlib.pyplot as plt
import json
import pydicom
from imgaug import augmenters as iaa
from tqdm import tqdm
import pandas as pd
import glob
from sklearn.model_selection import KFold
第1部分 导入数据
将数据导入,并设置存放日志和模型的目录
# 数据输入,因为是在线使用kaggle平台的算力,所以数据先传到kaggle平台,此处直接调用。实际离线使用时需要提前下载,下载链接如下
DATA_DIR = '/kaggle/input'
# 保存日志和训练模型的目录
ROOT_DIR = '/kaggle/working'
第2部分 导入Mask-RCNN 模型
从 github 安装 Matterport 的 Mask-RCNN 模型
更详细的资料,请参阅 Matterport 对 Mask-RCNN 的实现
!git clone https://www.github.com/matterport/Mask_RCNN.git
os.chdir('Mask_RCNN')
#!python setup.py -q install
运行后输出数据:
Cloning into ‘Mask_RCNN’…
remote: Enumerating objects: 956, done.
remote: Total 956 (delta 0), reused 0 (delta 0), pack-reused 956
Receiving objects: 100% (956/956), 119.41 MiB | 40.04 MiB/s, done.
Resolving deltas: 100% (569/569), done.
下载完毕后,将mask-RCNN的包引入
# Import Mask RCNN
sys.path.append(os.path.join(ROOT_DIR, 'Mask_RCNN')) # 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
运行后输出数据:
Using TensorFlow backend.
#进行路径拼接,指定文件路径
train_dicom_dir = os.path.join(DATA_DIR, 'stage_2_train_images')
test_dicom_dir = os.path.join(DATA_DIR, 'stage_2_test_images')
第3部分 导入COCO 预训练权重
下载 COCO 预训练权重
!wget --quiet https://github.com/matterport/Mask_RCNN/releases/download/v2.0/mask_rcnn_coco.h5
!ls -lh mask_rcnn_coco.h5
COCO_WEIGHTS_PATH = "mask_rcnn_coco.h5"
运行后输出数据:
-rw-r–r-- 1 root root 246M Nov 26 2017 mask_rcnn_coco.h5
Mask-RCNN 的一些设置函数和类
- dicom_fps 是 dicom 图像路径和文件名的列表
- image_annotions 是由文件名作为键值的注释字典
- 解析数据集返回图像文件名和注释字典的列表
def get_dicom_fps(dicom_dir):
dicom_fps = glob.glob(dicom_dir+'/'+'*.dcm')
return list(set(dicom_fps))
def parse_dataset(dicom_dir, anns):
image_fps = get_dicom_fps(dicom_dir)
image_annotations = {
fp: [] for fp in image_fps}
for index, row in anns.iterrows():
fp = os.path.join(dicom_dir, row['patientId']+'.dcm')
image_annotations[fp].append(row)
return image_fps, image_annotations
第4部分 设置训练参数
# 下列参数的设置,是为了演示时,节省时间而使用的,在实际训练时,需要重新设置
# 这些数据都不是最佳的
class DetectorConfig(Config):
"""
在 RSNA 肺炎数据集上训练肺炎检测的配置。覆盖基本 Config 类中的值。
"""
# 为配置指定一个可识别的名称
NAME = 'pneumonia'
# 在 1 个 GPU 和每个 GPU 8 个图像上训练。我们可以在每个 GPU 上放置多个图像,因为图像很小。批量大小为 8(GPUs * images/GPU).
GPU_COUNT = 1
IMAGES_PER_GPU = 8
BACKBONE = 'resnet50'
NUM_CLASSES = 2 # 其他类+患有肺炎的类(background + 1 pneumonia classes)
IMAGE_MIN_DIM = 256
IMAGE_MAX_DIM = 256
RPN_ANCHOR_SCALES = (16, 32, 64, 128)
TRAIN_ROIS_PER_IMAGE = 32
MAX_GT_INSTANCES = 4
DETECTION_MAX_INSTANCES = 3
DETECTION_MIN_CONFIDENCE = 0.78 ## 匹配目标分布(match target distribution)
DETECTION_NMS_THRESHOLD = 0.01
STEPS_PER_EPOCH = 200
config = DetectorConfig()
config.display()
运行后输出数据:
class DetectorDataset(utils.Dataset):
"""
匹配数据集的数据和数据集的各类
"""
def __init__(self, image_fps, image_annotations, orig_height, orig_width):
super().__init__(self)
# Add classes
self.add_class('pneumonia', 1, 'Lung Opacity')
# add images
for i, fp in enumerate(image_fps):
annotations = image_annotations[fp]
self.add_image('pneumonia', image_id=i, path=fp,
annotations=annotations, orig_height=orig_height, orig_width=orig_width)
def image_reference(self, image_id):
info = self.image_info[image_id]
return info['path']
def load_image(self, image_id):
info = self.image_info[image_id]
fp = info['path']
ds = pydicom.read_file(fp)
image = ds.pixel_array
# If grayscale. Convert to RGB for consistency.
if len(image.shape) != 3 or image.shape[2] != 3:
image = np.stack((image,) * 3, -1)
return image
def load_mask(self, image_id):
info = self.image_info[image_id]
annotations = info['annotations']
count = len(annotations)
if count == 0:
mask = np.zeros((info['orig_height'], info['orig_width'], 1), dtype=np.uint8)
class_ids = np.zeros((1,