我是一个深度学习的新手,在尝试构建一个Masked R-CNN模型来训练我的自定义数据集时,遇到了以下错误:
TypeError: 无法为 <KerasTensor: shape=(None, None, 4) dtype=float32 (由 'tf.math.truediv' 层创建)> 构建 TypeSpec,类型为 KerasTensor
以下是我尝试实现的用于构建Masked R-CNN 模型的PYTHON 代码:
Mask R-CNN配置和MS COCO数据加载代码。版权所有 © 2017 Matterport, Inc.根据MIT许可证授权使用(详情请参阅LICENSE文件)由Waleed Abdulla编写------------------------------------------------------------使用方法:导入模块(参见Jupyter笔记本中的示例),或在命令行中运行如下: # 从预训练的COCO权重开始训练一个新模型 python3 coco.py train --dataset=/path/to/coco/ --model=coco # 从ImageNet权重开始训练一个新模型。也自动下载COCO数据集 python3 coco.py train --dataset=/path/to/coco/ --model=imagenet --download=True # 继续训练之前训练过的模型 python3 coco.py train --dataset=/path/to/coco/ --model=/path/to/weights.h5 # 继续训练你最后训练的模型 python3 coco.py train --dataset=/path/to/coco/ --model=last # 在你最后训练的模型上运行COCO评估 python3 coco.py evaluate --dataset=/path/to/coco/ --model=last"""import osimport sysimport timeimport numpy as npimport imgaug # https://github.com/aleju/imgaug (pip3 install imgaug)# 从https://github.com/waleedka/coco下载并安装Python COCO工具# 这是一个原始版本https://github.com/pdollar/coco的分支,修复了Python 3的一个错误。# 我提交了一个拉取请求https://github.com/cocodataset/cocoapi/pull/50# 如果PR被合并,则使用原始仓库。# 注意:编辑PythonAPI/Makefile并将"python"替换为"python3"。from pycocotools.coco import COCOfrom pycocotools.cocoeval import COCOevalfrom pycocotools import mask as maskUtilsimport zipfileimport urllib.requestimport shutil# 项目的根目录ROOT_DIR = os.path.abspath("../../")# 导入Mask RCNNsys.path.append(ROOT_DIR) # 查找库的本地版本from mrcnn.config import Configfrom mrcnn import model as modellib, utils# 训练权重文件的路径COCO_MODEL_PATH = os.path.join(ROOT_DIR, "mask_rcnn_coco.h5")# 保存日志和模型检查点的目录,如果未通过命令行参数 --logs 提供# 使用默认目录DEFAULT_LOGS_DIR = os.path.join(ROOT_DIR, "Mask_RCNN\\logs")DEFAULT_DATASET_YEAR = "2014"############################################################# 配置############################################################class CocoConfig(Config): """配置用于在MS COCO上训练。 从基本Config类派生并覆盖特定于COCO数据集的值。 """ # 给配置一个可识别的名称 NAME = "coco" # 我们使用一个具有12GB内存的GPU,可以容纳两张图片。 # 如果使用更小的GPU,请相应调整。 IMAGES_PER_GPU = 2 # 取消注释以在8个GPU上训练(默认值为1) # GPU_COUNT = 8 # 类别数(包括背景) NUM_CLASSES = 1 + 80 # COCO有80个类别############################################################# 数据集############################################################class CocoDataset(utils.Dataset): def load_coco(self, dataset_dir, subset, year=DEFAULT_DATASET_YEAR, class_ids=None, class_map=None, return_coco=False, auto_download=False): """加载COCO数据集的一个子集。 dataset_dir: COCO数据集的根目录。 subset: 要加载的内容(train, val, minival, valminusminival) year: 要加载的数据集年份(2014, 2017)作为字符串,不是整数 class_ids: 如果提供,只加载包含给定类别的图像。 class_map: TODO: 尚未实现。支持从不同数据集映射类别到相同的类别ID。 return_coco: 如果为True,返回COCO对象。 auto_download: 自动下载和解压MS-COCO图像和注释 """ if auto_download is True: self.auto_download(dataset_dir, subset, year) coco = COCO("{}/annotations/instances_{}{}.json".format(dataset_dir, subset, year)) if subset == "minival" or subset == "valminusminival": subset = "val" image_dir = "{}/{}{}".format(dataset_dir, subset, year) # 加载所有类别还是子集? if not class_ids: # 所有类别 class_ids = sorted(coco.getCatIds()) # 所有图像还是子集? if class_ids: image_ids = [] for id in class_ids: image_ids.extend(list(coco.getImgIds(catIds=[id]))) # 移除重复项 image_ids = list(set(image_ids)) else: # 所有图像 image_ids = list(coco.imgs.keys()) # 添加类别 for i in class_ids: self.add_class("coco", i, coco.loadCats(i)[0]["name"]) # 添加图像 for i in image_ids: self.add_image( "coco", image_id=i, path=os.path.join(image_dir, coco.imgs[i]['file_name']), width=coco.imgs[i]["width"], height=coco.imgs[i]["height"], annotations=coco.loadAnns(coco.getAnnIds( imgIds=[i], catIds=class_ids, iscrowd=None))) if return_coco: return coco def auto_download(self, dataDir, dataType, dataYear): """如果请求,下载COCO数据集/注释。 dataDir: COCO数据集的根目录。 dataType: 要加载的内容(train, val, minival, valminusminival) dataYear: 要加载的数据集年份(2014, 2017)作为字符串,不是整数 注意: 对于2014,使用"train", "val", "minival", 或 "valminusminival" 对于2017,只有"train" 和 "val" 注释可用 """ # 设置路径和文件名 if dataType == "minival" or dataType == "valminusminival": imgDir = "{}/{}{}".format(dataDir, "val", dataYear) imgZipFile = "{}/{}{}.zip".format(dataDir, "val", dataYear) imgURL = "http://images.cocodataset.org/zips/{}{}.zip".format("val", dataYear) else: imgDir = "{}/{}{}".format(dataDir, dataType, dataYear) imgZipFile = "{}/{}{}.zip".format(dataDir, dataType, dataYear) imgURL = "http://images.cocodataset.org/zips/{}{}.zip".format(dataType, dataYear) # print("图像路径:"); print(imgDir); print(imgZipFile); print(imgURL) # 如果主文件夹不存在,则创建 if not os.path.exists(dataDir): os.makedirs(dataDir) # 如果本地不可用,则下载图像 if not os.path.exists(imgDir): os.makedirs(imgDir) print("正在下载图像到 " + imgZipFile + " ...") with urllib.request.urlopen(imgURL) as resp, open(imgZipFile, 'wb') as out: shutil.copyfileobj(resp, out) print("... 下载完成。") print("正在解压 " + imgZipFile) with zipfile.ZipFile(imgZipFile, "r") as zip_ref: zip_ref.extractall(dataDir) print("... 解压完成") print("将使用 " + imgDir + " 中的图像") # 设置注释数据路径 annDir = "{}/annotations".format(dataDir) if dataType == "minival": annZipFile = "{}/instances_minival2014.json.zip".format(dataDir) annFile = "{}/instances_minival2014.json".format(annDir) annURL = "https://dl.dropboxusercontent.com/s/o43o90bna78omob/instances_minival2014.json.zip?dl=0" unZipDir = annDir elif dataType == "valminusminival": annZipFile = "{}/instances_valminusminival2014.json.zip".format(dataDir) annFile = "{}/instances_valminusminival2014.json".format(annDir) annURL = "https://dl.dropboxusercontent.com/s/s3tw5zcg7395368/instances_valminusminival2014.json.zip?dl=0" unZipDir = annDir else: annZipFile = "{}/annotations_trainval{}.zip".format(dataDir, dataYear) annFile = "{}/instances_{}{}.json".format(annDir, dataType, dataYear) annURL = "http://images.cocodataset.org/annotations/annotations_trainval{}.zip".format(dataYear) unZipDir = dataDir # print("注释路径:"); print(annDir); print(annFile); print(annZipFile); print(annURL) # 如果本地不可用,则下载注释 if not os.path.exists(annDir): os.makedirs(annDir) if not os.path.exists(annFile): if not os.path.exists(annZipFile): print("正在下载压缩的注释到 " + annZipFile + " ...") with urllib.request.urlopen(annURL) as resp, open(annZipFile, 'wb') as out: shutil.copyfileobj(resp, out) print("... 下载完成。") print("正在解压 " + annZipFile) with zipfile.ZipFile(annZipFile, "r") as zip_ref: zip_ref.extractall(unZipDir) print("... 解压完成") print("将使用 " + annFile + " 中的注释") def load_mask(self, image_id): """为给定图像加载实例掩码。 不同数据集使用不同方式存储掩码。此函数将不同格式的掩码转换为一种格式, 形式为位图 [height, width, instances]。 返回值: masks: 形状为 [height, width, instance count] 的布尔数组,每个实例一个掩码。 class_ids: 实例掩码的类别ID的一维数组。 """ # 如果不是COCO图像,则委托给父类。 image_info = self.image_info[image_id] if image_info["source"] != "coco": return super(CocoDataset, self).load_mask(image_id) instance_masks = [] class_ids = [] annotations = self.image_info[image_id]["annotations"] # 构建形状为 [height, width, instance_count] 的掩码,并列出 # 与掩码的每个通道对应的类别ID。 for annotation in annotations: class_id = self.map_source_class_id( "coco.{}".format(annotation['category_id'])) if class_id: m = self.annToMask(annotation, image_info["height"], image_info["width"]) # 有些对象非常小,以至于它们的面积小于1像素
将上述代码保存为.py文件后,我在终端执行了以下命令:
(base) C:\Users\HP>python C:\Users\HP\Mask_RCNN\samples\coco\coco.py train --dataset=C:\Users\HP\Test\Train --model=coco
我得到了以下结果:
2020-12-21 00:41:06.252236: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] 无法加载动态库 'cudart64_110.dll';dlerror: cudart64_110.dll 未找到2020-12-21 00:41:06.260248: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] 如果你的机器上没有设置GPU,请忽略上面的 cudart dlerror。(base) C:\Users\HP>python C:\Users\HP\Desktop\try.py train --dataset=C:\Users\HP\Test\Train --model=C:\Users\HP\mask_rcnn_coco.h52020-12-21 00:42:34.586446: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] 无法加载动态库 'cudart64_110.dll';dlerror: cudart64_110.dll 未找到2020-12-21 00:42:34.594568: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] 如果你的机器上没有设置GPU,请忽略上面的 cudart dlerror。(base) C:\Users\HP>python C:\Users\HP\Mask_RCNN\samples\coco\coco.py train --dataset=C:\Users\HP\Test\Train --model=coco2020-12-21 00:44:41.479421: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] 无法加载动态库 'cudart64_110.dll';dlerror: cudart64_110.dll 未找到2020-12-21 00:44:41.490317: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] 如果你的机器上没有设置GPU,请忽略上面的 cudart dlerror。命令: train模型: coco数据集: C:\Users\HP\Test\Train年份: 2014日志: C:\Mask_RCNN\logs自动下载: False配置:BACKBONE resnet101BACKBONE_STRIDES [4, 8, 16, 32, 64]BATCH_SIZE 2BBOX_STD_DEV [0.1 0.1 0.2 0.2]COMPUTE_BACKBONE_SHAPE NoneDETECTION_MAX_INSTANCES 100DETECTION_MIN_CONFIDENCE 0.7DETECTION_NMS_THRESHOLD 0.3FPN_CLASSIF_FC_LAYERS_SIZE 1024GPU_COUNT 1GRADIENT_CLIP_NORM 5.0IMAGES_PER_GPU 2IMAGE_MAX_DIM 1024IMAGE_META_SIZE 93IMAGE_MIN_DIM 800IMAGE_MIN_SCALE 0IMAGE_RESIZE_MODE squareIMAGE_SHAPE [1024 1024 3]LEARNING_MOMENTUM 0.9LEARNING_RATE 0.001LOSS_WEIGHTS {'rpn_class_loss': 1.0, 'rpn_bbox_loss': 1.0, 'mrcnn_class_loss': 1.0, 'mrcnn_bbox_loss': 1.0, 'mrcnn_mask_loss': 1.0}MASK_POOL_SIZE 14MASK_SHAPE [28, 28]MAX_GT_INSTANCES 100MEAN_PIXEL [123.7 116.8 103.9]MINI_MASK_SHAPE (56, 56)NAME cocoNUM_CLASSES 81POOL_SIZE 7POST_NMS_ROIS_INFERENCE 1000POST_NMS_ROIS_TRAINING 2000ROI_POSITIVE_RATIO 0.33RPN_ANCHOR_RATIOS [0.5, 1, 2]RPN_ANCHOR_SCALES (32, 64, 128, 256, 512)RPN_ANCHOR_STRIDE 1RPN_BBOX_STD_DEV [0.1 0.1 0.2 0.2]RPN_NMS_THRESHOLD 0.7RPN_TRAIN_ANCHORS_PER_IMAGE 256STEPS_PER_EPOCH 1000TOP_DOWN_PYRAMID_SIZE 256TRAIN_BN FalseTRAIN_ROIS_PER_IMAGE 200USE_MINI_MASK TrueUSE_RPN_ROIS TrueVALIDATION_STEPS 50WEIGHT_DECAY 0.0001Traceback (most recent call last): File "C:\Users\HP\Mask_RCNN\samples\coco\coco.py", line 456, in <module> model_dir=args.logs) File "C:\Users\HP\anaconda3\lib\site-packages\mrcnn\model.py", line 1832, in __init__ self.keras_model = self.build(mode=mode, config=config) File "C:\Users\HP\anaconda3\lib\site-packages\mrcnn\model.py", line 1871, in build x, K.shape(input_image)[1:3]))(input_gt_boxes) File "C:\Users\HP\anaconda3\lib\site-packages\tensorflow\python\keras\engine\base_layer.py", line 952, in __call__ input_list) File "C:\Users\HP\anaconda3\lib\site-packages\tensorflow\python\keras\engine\base_layer.py", line 1091, in _functional_construction_call inputs, input_masks, args, kwargs) File "C:\Users\HP\anaconda3\lib\site-packages\tensorflow\python\keras\engine\base_layer.py", line 822, in _keras_tensor_symbolic_call return self._infer_output_signature(inputs, args, kwargs, input_masks) File "C:\Users\HP\anaconda3\lib\site-packages\tensorflow\python\keras\engine\base_layer.py", line 869, in _infer_output_signature keras_tensor.keras_tensor_from_tensor, outputs) File "C:\Users\HP\anaconda3\lib\site-packages\tensorflow\python\util\nest.py", line 659, in map_structure structure[0], [func(*x) for x in entries], File "C:\Users\HP\anaconda3\lib\site-packages\tensorflow\python\util\nest.py", line 659, in <listcomp> structure[0], [func(*x) for x in entries], File "C:\Users\HP\anaconda3\lib\site-packages\tensorflow\python\keras\engine\keras_tensor.py", line 606, in keras_tensor_from_tensor out = keras_tensor_cls.from_tensor(tensor) File "C:\Users\HP\anaconda3\lib\site-packages\tensorflow\python\keras\engine\keras_tensor.py", line 205, in from_tensor type_spec = type_spec_module.type_spec_from_value(tensor) File "C:\Users\HP\anaconda3\lib\site-packages\tensorflow\python\framework\type_spec.py", line 554, in type_spec_from_value (value, type(value).__name__))TypeError: 无法为 <KerasTensor: shape=(None, None, 4) dtype=float32 (由 'tf.math.truediv' 层创建)> 构建 TypeSpec,类型为 KerasTensor
回答:
你应该使用Tensorflow 1.x版本。在Colab上使用 %tensorflow_version 1.x 更改TF版本。之后,我想你会遇到与Keras版本相关的问题,添加命令来安装Keras 2.1.5。!pip install keras==2.1.5