You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 11:52:44