基于Mask RCNN的脑肿瘤MRI分割项目复现报错求助
脑肿瘤Mask RCNN分割项目复现问题:
model.load_weights报错NoneType无lower属性 问题概述
复现GitHub上基于MRI扫描的脑肿瘤Mask RCNN分割项目时,运行到model.load_weights步骤出现报错:NoneType对象没有属性“lower”。使用MakeSense制作标注文件,适配代码如下,请求指出错误并提供复现建议。
适配代码
import os import sys import numpy as np import pandas as pd import skimage import matplotlib.pyplot as plt import matplotlib.patches from numpy import zeros, asarray # 语法错误:一行不能写两个import from PIL import Image, ImageDraw import json import datetime import cv2 import mrcnn from mrcnn.visualize import display_instances from mrcnn.utils import extract_bboxes from mrcnn.utils import Dataset from matplotlib import pyplot as plt from mrcnn.config import Config from mrcnn.model import MaskRCNN from mrcnn import model as modellib, utils df= r"C:\Users\Brain MRI\mask\image_data" train= os.path.join(df,'train') val=os.path.join(df,'val') pretrained_model=os.path.join(df,"mask_rcnn_coco.h5") log_dir=os.path.join(df,'logs') # 配置类定义错误 class Configuration(Config): NAME = "coco" GPU_COUNT=1 IMAGES_PER_GPU=1 num_classes=1+1 # 变量名应为NUM_CLASSES(大写) STEPS_PER_EPOCH=45 VALIDATION_STEPS=10 IMAGE_MAX_DIM=256 IMAGE_MIN_DIM=256 # 方法名错误:应为__init__,且未正确调用父类构造 def init(self, num_classes): self.NUM_CLASSES = num_classes super().init() model_path=pretrained_model class BrainScanDataset(utils.Dataset): def load_brain_scan(self, dataset_dir, subset): self.add_class("tumor", 1, "tumor") assert subset in ["train", "val"] dataset_dir = os.path.join(df, subset) annotations = json.load(open(os.path.join(df, subset, 'annotations_'+subset+'.json'))) annotations = list(annotations.values()) annotations = [a for a in annotations if a['regions']] for a in annotations: if type(a['regions']) is dict: polygons = [r['shape_attributes'] for r in a['regions'].values()] else: polygons = [r['shape_attributes'] for r in a['regions']] image_path = os.path.join(df,subset, a['filename']) image = skimage.io.imread(image_path) height, width = image.shape[:2] self.add_image("tumor", image_id=a['filename'], path=image_path, width=width, height=height, polygons=polygons ) def load_mask(self, image_id): image_info = self.image_info[image_id] if image_info["source"] != "tumor": return super(self.__class__, self).load_mask(image_id) info = self.image_info[image_id] mask = np.zeros([info["height"], info["width"], len(info["polygons"])], dtype=np.uint8) for i, p in enumerate(info["polygons"]): rr, cc = skimage.draw.polygon(p['all_points_y'], p['all_points_x']) mask[rr, cc, i] = 1 # 缺失返回值:必须返回mask和class_ids def image_reference(self, image_id): info = self.image_info[image_id] if info["source"] == "tumor": return info["path"] else: super(self.__class__, self).image_reference(image_id) dataset_train = BrainScanDataset() dataset_train.load_brain_scan(df, 'train') dataset_train.prepare() dataset_val = BrainScanDataset() dataset_val.load_brain_scan(df, 'val') dataset_val.prepare() # 核心错误:传入Config基类而非自定义配置实例 model = modellib.MaskRCNN( mode='training', config=Config, model_dir=log_dir ) model.load_weights( pretrained_model, by_name=True, exclude=["mrcnn_class_logits", "mrcnn_bbox_fc", "mrcnn_bbox", "mrcnn_mask"] )
错误修复与复现建议
1. 核心错误修复(解决load_weights报错)
报错根源是模型实例化时传入了Config基类而非自定义配置的实例,导致模型配置为无效状态。修复步骤:
- 修正自定义配置类的变量名与构造方法
- 实例化自定义配置后传入模型
class Configuration(Config): NAME = "brain_tumor" # 改为自定义名称,避免与COCO预训练模型混淆 GPU_COUNT = 1 IMAGES_PER_GPU = 1 NUM_CLASSES = 1 + 1 # 背景+肿瘤类,变量名必须大写 STEPS_PER_EPOCH = 45 VALIDATION_STEPS = 10 IMAGE_MAX_DIM = 256 IMAGE_MIN_DIM = 256 # 实例化自定义配置 config = Configuration() # 传入配置实例而非基类 model = modellib.MaskRCNN(mode='training', config=config, model_dir=log_dir)
2. 其他代码错误修复
- 导入语句拆分:将一行多import拆分为单独语句
from PIL import Image, ImageDraw import json import datetime import cv2 load_mask方法补全返回值:Mask RCNN要求该方法返回(mask, class_ids)def load_mask(self, image_id): image_info = self.image_info[image_id] if image_info["source"] != "tumor": return super(self.__class__, self).load_mask(image_id) info = self.image_info[image_id] mask = np.zeros([info["height"], info["width"], len(info["polygons"])], dtype=np.uint8) for i, p in enumerate(info["polygons"]): rr, cc = skimage.draw.polygon(p['all_points_y'], p['all_points_x']) mask[rr, cc, i] = 1 # 所有mask对应肿瘤类,id为1 class_ids = np.array([1 for _ in range(len(info["polygons"]))]) return mask.astype(np.bool), class_ids.astype(np.int32)
3. 复现建议
- 预训练模型校验:确认
mask_rcnn_coco.h5文件完整,路径无空格或特殊字符(建议将路径改为C:\Users\BrainMRI\mask\image_data这类无空格格式) - 标注文件验证:检查MakeSense导出的JSON,确保每个
regions的shape_attributes包含all_points_x和all_points_y字段 - MRI图像预处理:MRI多为单通道灰度图,需转为3通道(Mask RCNN默认输入为3通道),可通过
image = np.stack([image]*3, axis=-1)实现 - 训练前校验:先运行以下代码验证数据集加载是否正常
# 测试数据集加载 print(dataset_train.image_info[0]) mask, class_ids = dataset_train.load_mask(0) print(mask.shape, class_ids) - 环境适配:原版Mask RCNN基于TensorFlow 1.x开发,建议使用TF1.15版本;GPU显存需至少2GB(单GPU单张256x256图像)
内容的提问来源于stack exchange,提问作者kiwikiwi
相关产品推荐
相关产品推荐

