写点什么

【案例共创】基于华为开发者空间的 RestNet50 目标检测

  • 2025-12-18
    贵州
  • 本文字数:11471 字

    阅读完需:约 38 分钟

【案例共创】基于华为开发者空间的RestNet50目标检测

最新案例动态,请查阅【案例共创】基于华为开发者空间的RestNet50目标检测。小伙伴们快来领取华为开发者空间进行实操吧!


本案例由:梅科尔工作室提供

1 概述

1.1 案例介绍

ResNet50 模型是一种深度卷积神经网络,它使用残差模块和跳跃连接来缓解梯度消失问题。反向传播算法在 ResNet 模型中同样起着到头重要的作用,它可以计算 ResNet 模型中各个权重的梯度,并更新权重,从而优化模型性能。本案例使用到开发者空间----工作台/AI Notebook


本案例选择医院的病例数据作为示例,并借助开发者空间工作台提供的免费 AI Notebook 编辑器进行本地编辑函数、轻松部署上云,直观地展示 Notebook 支持 AI 训练模型的开发与调试能力和实际应用开发中为开发者带来的便利。


通过实际操作,让大家深入了解如何利用 Notebook 开发并部署一个梯度与反向传播算法。在这个过程中,大家将学习到从函数创建、模型训练到应用部署以及与 API 集成等一系列关键步骤,从而掌握 ResNet50 的基本使用方法,体验其在 Notebook 开发中的优势。

1.2 适用对象

  • 企业

  • 个人开发者

  • 高校学生

1.3 案例时间

本案例总时长预计 120 分钟。

1.4 案例流程


说明:


  1. 开发者空间进入 Notebook;

  2. 在 Notebook 中用 NPU 训练模型,跑结果;

1.5 资源总览

| 资源名称 | 规格 | 单价(元) | 时长(分钟) |


| 开发者空间----工作台/AI Notebook | NPU basic · 1 * NPU 910B · 8v CPU · 24GB | 免费 | 120 |

2 梯度与反向传播算法

2.1 代码分析

环境配置

详细资源配置请参考案例华为开发者空间AI Notebook使用指导:步骤二。


进入华为开发者空间界面,进入 AI Notebook 页面。




!pip install mindspore
复制代码



!pip install numpy
复制代码



说明 numpy 模块已经被安装了。


!pip install matplotlib
复制代码



!pip install opencv-python
复制代码



opencv 模块在 pip install 安装失败,用-i 指定其他下载源也安装失败,所以此处用 yum install 安装 opencv 模块。


!pip install pillow
复制代码



MindSpore:深度学习框架,用于构建和训练模型。


NumPy:用于数值计算,处理数据。


Matplotlib:用于数据可视化,绘制图表。


OpenCV:用于图像处理,可能在数据预处理中使用。


Pillow:用于图像处理,加载和处理图像数据。


注:如果存在软件包下载失败,可以添加参数-i 指定华为云的安装源。例如:


!pip install matplotlib -i https://repo.huaweicloud.com/repository/pypi/simple/
复制代码

数据获取和准备

!wget <https://dtse-mirrors.obs.cn-north-4.myhuaweicloud.com/case/0036/skin-cancer-detection.tar>
复制代码


!mkdir pifudata_Maker
复制代码


!tar -xvf skin-cancer-detection.tar -C pifudata_Maker/
复制代码



注释:使用 git 命令克隆数据集仓库,并解压数据集到指定文件夹。


分析:数据集是项目的基础,克隆和解压操作确保了数据的可用性。


import osdiseases = {0: "basal_cell_carcinoma",1: "melanoma",2: "nevus",3: "pigmented_benign_keratosis",}target_directory = "pifudata_Maker/images"for folder in ["train", "val"]:folder_path = os.path.join(target_directory, folder)for number, disease in diseases.items():old_folder_path = os.path.join(folder_path, disease)if not os.path.exists(old_folder_path):print(f"Folder not found: {old_folder_path}")continuenew_folder_name = f"{number}"new_folder_path = os.path.join(folder_path, new_folder_name)os.rename(old_folder_path, new_folder_path)print(f"Renamed {old_folder_path} to {new_folder_path}")
复制代码


注释:定义疾病名称和编号的映射,并对训练和验证数据集的文件夹进行重命名,方便后续处理。


分析:数据组织结构的调整有助于模型训练时的数据加载和管理。


预训练模型准备

在工程文件下新建文件夹,命名为:pretrainmodel,然后在命令行中输入:


!mkdir pretrainmodel
复制代码


!wget -P pretrainmodel <https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/models/application/resnet50_224_new.ckpt>
复制代码



注意:如果系统中没有 wget 环境请先安装:


sudo apt-get install wget
复制代码

数据可视化

注意:下面 Python 代码中,data_path_train data_path_val 需要根据实际位置进行修改。


import osimport matplotlib.pyplot as pltdiseases = {0: "basal_cell_carcinoma",1: "melanoma",2: "nevus",3: "pigmented_benign_keratosis",}data_path_train = "pifudata_Maker/images/train"data_path_val = "pifudata_Maker/images/val"file_counts_train = {}file_counts_val = {}for folder_name in os.listdir(data_path_train):folder_path = os.path.join(data_path_train, folder_name)if os.path.isdir(folder_path):count = len(os.listdir(folder_path))file_counts_train[diseases.get(folder_name, folder_name)] = countfor folder_name in os.listdir(data_path_val):folder_path = os.path.join(data_path_val, folder_name)if os.path.isdir(folder_path):count = len(os.listdir(folder_path))file_counts_val[diseases.get(folder_name, folder_name)] = counttrain_categories = list(file_counts_train.keys())plt.figure(figsize=(12, 8))train_bars = plt.bar(train_categories, file_counts_train.values(), width=0.4, color='blue', label='Train')val_bars = plt.bar([train_categories.index(cat) + 0.4 for cat in train_categories], [file_counts_val.get(cat, 0) for cat in train_categories], width=0.4, color='green', label='Validation')plt.legend()plt.xlabel('labels')plt.ylabel('Number of Images')plt.title('Training and Validation Datasets')train_list = [diseases[int(i)] for i in train_categories]plt.xticks([train_categories.index(cat) + 0.2 for cat in train_categories], train_list, rotation=30, fontsize='small')for i, (train_bar, val_bar) in enumerate(zip(train_bars, val_bars)):train_height = train_bar.get_height()val_height = val_bar.get_height() if val_bar else 0plt.text(train_bar.get_x() + train_bar.get_width() / 2, train_height, '{}'.format(train_height), ha='center', va='bottom')plt.text(val_bar.get_x() + val_bar.get_width() / 2, val_height, '{}'.format(val_height), ha='center', va='bottom') if val_bar else Noneplt.show()
复制代码


注释:统计训练和验证数据集中各类别的样本数量,并生成条形图进行可视化。


分析:数据分布的可视化有助于了解数据的平衡性,为模型训练提供参考。


超参数定义

# 超参数定义batch_size = 30 # 批量大小image_size = 224 # 训练图像空间大小num_epochs = 5 # 训练周期数lr = 0.001 # 学习率momentum = 0.6 # 动量workers = 4 # 并行线程个数import mindsporemindspore.set_context(device_target="CPU")
复制代码


注释:定义模型训练的超参数,包括批量大小、图像大小、训练周期数、学习率、动量和并行线程个数。


分析:超参数的选择对模型的训练效果和效率有重要影响,需要根据具体任务进行调整。


数据加载和预处理

import mindspore as msimport mindspore.dataset as dsimport mindspore.dataset.vision as vision# 数据集目录路径data_path_train = "pifudata_Maker/images/train"data_path_val = "pifudata_Maker/images/val"# 创建训练数据集def create_dataset_canidae(dataset_path, usage):"""数据加载"""data_set = ds.ImageFolderDataset(dataset_path,num_parallel_workers=workers,shuffle=True,)# 数据增强操作mean = [0.485 * 255, 0.456 * 255, 0.406 * 255]std = [0.229 * 255, 0.224 * 255, 0.225 * 255]scale = 32if usage == "train":# Define map operations for training datasettrans = [vision.RandomCropDecodeResize(size=image_size, scale=(0.08, 1.0), ratio=(0.75, 1.333)),vision.RandomHorizontalFlip(prob=0.5),vision.Normalize(mean=mean, std=std),vision.HWC2CHW()]else:# Define map operations for inference datasettrans = [vision.Decode(),vision.Resize(image_size + scale),vision.CenterCrop(image_size),vision.Normalize(mean=mean, std=std),vision.HWC2CHW()]# 数据映射操作data_set = data_set.map(operations=trans,input_columns='image',num_parallel_workers=workers)# 批量操作data_set = data_set.batch(batch_size)return data_setdataset_train = create_dataset_canidae(data_path_train, "train")step_size_train = dataset_train.get_dataset_size()dataset_val = create_dataset_canidae(data_path_val, "val")step_size_val = dataset_val.get_dataset_size()print(step_size_train)print(step_size_val)data = next(dataset_val.create_dict_iterator())images = data["image"]labels = data["label"]# print(data["image"][0])print("Tensor of image", images.shape)print("Labels:", labels)
复制代码


注释:定义数据加载和预处理函数,对训练和验证数据集进行不同的数据增强操作,并批量加载数据。


分析:数据增强可以提高模型的泛化能力,预处理操作确保输入数据的格式和分布符合模型的要求。


数据集可视化

import matplotlib.pyplot as pltimport numpy as np# class_name对应label,按文件夹字符串从小到大的顺序标记labelclass_name = {0: "basal_cell_carcinoma",1: "melanoma",2: "nevus",3: "pigmented_benign_keratosis",}# print(images[0])plt.figure(figsize=(5, 5))for i in range(4):# 获取图像及其对应的label# print(images[i])data_image = images[i].asnumpy()data_label = labels[i]# 处理图像供展示使用data_image = np.transpose(data_image, (1, 2, 0))mean = np.array([0.485, 0.456, 0.406])std = np.array([0.229, 0.224, 0.225])data_image = std * data_image + meandata_image = np.clip(data_image, 0, 1)# 显示图像plt.subplot(2, 2, i+1)plt.imshow(data_image)plt.title(class_name[int(labels[i].asnumpy())])plt.axis("off")plt.show()
复制代码


注释:定义残差网络的基本模块、构建 ResNet 模型,并定义 ResNet50 的函数,支持加载预训练模型。


分析:ResNet 模型通过残差连接解决了深度网络中的梯度消失问题,预训练模型的加载可以加速训练并提高模型性能。


注意:该部分 Python 代码最好与第 5 部分代码合在一起运行,以免报 asnumpy()函数引用问题。


模型网络搭建

from typing import Type, Union, List, Optionalfrom mindspore import nn, trainfrom mindspore.common.initializer import Normalweight_init = Normal(mean=0, sigma=0.02)gamma_init = Normal(mean=1, sigma=0.02)class ResidualBlockBase(nn.Cell):expansion: int = 1 # 最后一个卷积核数量与第一个卷积核数量相等def __init__(self, in_channel: int, out_channel: int,stride: int = 1, norm: Optional[nn.Cell] = None,down_sample: Optional[nn.Cell] = None) -> None:super(ResidualBlockBase, self).__init__()if not norm:self.norm = nn.BatchNorm2d(out_channel)else:self.norm = normself.conv1 = nn.Conv2d(in_channel, out_channel,kernel_size=3, stride=stride,weight_init=weight_init)self.conv2 = nn.Conv2d(in_channel, out_channel,kernel_size=3, weight_init=weight_init)self.relu = nn.ReLU()self.down_sample = down_sampledef construct(self, x):"""ResidualBlockBase construct."""identity = x # shortcuts分支out = self.conv1(x) # 主分支第一层:3*3卷积层out = self.norm(out)out = self.relu(out)out = self.conv2(out) # 主分支第二层:3*3卷积层out = self.norm(out)if self.down_sample is not None:identity = self.down_sample(x)out += identity # 输出为主分支与shortcuts之和out = self.relu(out)return outclass ResidualBlock(nn.Cell):expansion = 4 # 最后一个卷积核的数量是第一个卷积核数量的4倍def __init__(self, in_channel: int, out_channel: int,stride: int = 1, down_sample: Optional[nn.Cell] = None) -> None:super(ResidualBlock, self).__init__()self.conv1 = nn.Conv2d(in_channel, out_channel,kernel_size=1, weight_init=weight_init)self.norm1 = nn.BatchNorm2d(out_channel)self.conv2 = nn.Conv2d(out_channel, out_channel,kernel_size=3, stride=stride,weight_init=weight_init)self.norm2 = nn.BatchNorm2d(out_channel)self.conv3 = nn.Conv2d(out_channel, out_channel * self.expansion,kernel_size=1, weight_init=weight_init)self.norm3 = nn.BatchNorm2d(out_channel * self.expansion)self.relu = nn.ReLU()self.down_sample = down_sampledef construct(self, x):identity = x # shortscuts分支out = self.conv1(x) # 主分支第一层:1*1卷积层out = self.norm1(out)out = self.relu(out)out = self.conv2(out) # 主分支第二层:3*3卷积层out = self.norm2(out)out = self.relu(out)out = self.conv3(out) # 主分支第三层:1*1卷积层out = self.norm3(out)if self.down_sample is not None:identity = self.down_sample(x)out += identity # 输出为主分支与shortcuts之和out = self.relu(out)return outdef make_layer(last_out_channel, block: Type[Union[ResidualBlockBase, ResidualBlock]],channel: int, block_nums: int, stride: int = 1):down_sample = None # shortcuts分支if stride != 1 or last_out_channel != channel * block.expansion:down_sample = nn.SequentialCell([nn.Conv2d(last_out_channel, channel * block.expansion,kernel_size=1, stride=stride, weight_init=weight_init),nn.BatchNorm2d(channel * block.expansion, gamma_init=gamma_init)])layers = []layers.append(block(last_out_channel, channel, stride=stride, down_sample=down_sample))in_channel = channel * block.expansion# 堆叠残差网络for _ in range(1, block_nums):layers.append(block(in_channel, channel))return nn.SequentialCell(layers)from mindspore import load_checkpoint, load_param_into_netclass ResNet(nn.Cell):def __init__(self, block: Type[Union[ResidualBlockBase, ResidualBlock]],layer_nums: List[int], num_classes: int, input_channel: int) -> None:super(ResNet, self).__init__()self.relu = nn.ReLU()# 第一个卷积层,输入channel为3(彩色图像),输出channel为64self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, weight_init=weight_init)self.norm = nn.BatchNorm2d(64)# 最大池化层,缩小图片的尺寸self.max_pool = nn.MaxPool2d(kernel_size=3, stride=2, pad_mode='same')# 各个残差网络结构块定义,self.layer1 = make_layer(64, block, 64, layer_nums[0])self.layer2 = make_layer(64 * block.expansion, block, 128, layer_nums[1], stride=2)self.layer3 = make_layer(128 * block.expansion, block, 256, layer_nums[2], stride=2)self.layer4 = make_layer(256 * block.expansion, block, 512, layer_nums[3], stride=2)# 平均池化层self.avg_pool = nn.AvgPool2d()# flattern层self.flatten = nn.Flatten()# 全连接层self.fc = nn.Dense(in_channels=input_channel, out_channels=num_classes)def construct(self, x):x = self.conv1(x)x = self.norm(x)x = self.relu(x)x = self.max_pool(x)x = self.layer1(x)x = self.layer2(x)x = self.layer3(x)x = self.layer4(x)x = self.avg_pool(x)x = self.flatten(x)x = self.fc(x)return xdef download_pretrained_model(url, save_path):# 创建目录os.makedirs(os.path.dirname(save_path), exist_ok=True)# 下载文件urllib.request.urlretrieve(url, save_path)print(f"预训练模型已下载到: {save_path}")def _resnet(model_url: str, block: Type[Union[ResidualBlockBase, ResidualBlock]],layers: List[int], num_classes: int, pretrained: bool, pretrianed_ckpt: str,input_channel: int):model = ResNet(block, layers, num_classes, input_channel)if pretrained:# 加载预训练模型# download(url=model_url, path=pretrianed_ckpt, replace=True)param_dict = load_checkpoint(pretrianed_ckpt)load_param_into_net(model, param_dict)return modeldef resnet50(num_classes: int = 1000, pretrained: bool = False):"ResNet50模型"resnet50_url = "https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/models/application/resnet50_224_new.ckpt"resnet50_ckpt = "./pretrainmodel/resnet50_224_new.ckpt"return _resnet(resnet50_url, ResidualBlock, [3, 4, 6, 3], num_classes,pretrained, resnet50_ckpt, 2048)
复制代码


注释:定义残差网络的基本模块、构建 ResNet 模型,并定义 ResNet50 的函数,支持加载预训练模型。


分析:ResNet 模型通过残差连接解决了深度网络中的梯度消失问题,预训练模型的加载可以加速训练并提高模型性能。

模型训练(训练时长预计 40min)

先导入预训练模型文件:新建 pretrainmodel 文件夹,将以下文件导入:


resnet50_224_new.ckpt


命令如下


!mkdir pretrainmodel
!wget -P pretrainmodel <https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/models/application/resnet50_224_new.ckpt>
复制代码



# 代码中首先导入了必要的MindSpore模块和函数,并设置了运行环境。import mindsporefrom mindspore import nn, trainfrom mindspore.nn import Loss, Accuracy!pip install downloadimport mindspore as msfrom download import downloadnetwork = resnet50(pretrained=True)# 通过替换ResNet50的原始全连接层和平均池化层来适配新的任务# 全连接层输入层的大小in_channels = network.fc.in_channels# 输出通道数大小为皮肤肿瘤分类数4head = nn.Dense(in_channels, 4)# 重置全连接层network.fc = head# 平均池化层kernel size为7avg_pool = nn.AvgPool2d(kernel_size=7)# 重置平均池化层network.avg_pool = avg_poolimport mindspore as msimport mindspore# 定义优化器和损失函数opt = nn.Momentum(params=network.trainable_params(), learning_rate=lr, momentum=momentum)loss_fn = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean')# 实例化模型model = train.Model(network, loss_fn, opt, metrics={"Accuracy": Accuracy()})def forward_fn(inputs, targets):logits = network(inputs)loss = loss_fn(logits, targets)return lossgrad_fn = mindspore.ops.value_and_grad(forward_fn, None, opt.parameters)def train_step(inputs, targets):loss, grads = grad_fn(inputs, targets)opt(grads)return loss# 创建迭代器data_loader_train = dataset_train.create_tuple_iterator(num_epochs=num_epochs)# 最佳模型保存路径best_ckpt_dir = "./BestCheckpoint"best_ckpt_path = "./BestCheckpoint/resnet50-best.ckpt"import osimport time# 开始循环训练print("Start Training Loop ...")best_acc = 0# 训练循环中,数据通过迭代器被加载,模型在每个epoch中更新权重,并计算训练损失。# 在每个epoch结束时,模型在验证集上评估准确率,并保存具有最高准确率的模型检查点。for epoch in range(num_epochs):losses = []network.set_train()epoch_start = time.time()# 为每轮训练读入数据for i, (images, labels) in enumerate(data_loader_train):labels = labels.astype(ms.int32)loss = train_step(images, labels)losses.append(loss)# 每个epoch结束后,验证准确率acc = model.eval(dataset_val)['Accuracy']epoch_end = time.time()epoch_seconds = (epoch_end - epoch_start) * 1000step_seconds = epoch_seconds/step_size_trainprint("-" * 20)print("Epoch: [%3d/%3d], Average Train Loss: [%5.3f], Accuracy: [%5.3f]" % (epoch+1, num_epochs, sum(losses)/len(losses), acc))print("epoch time: %5.3f ms, per step time: %5.3f ms" % (epoch_seconds, step_seconds))if acc > best_acc:best_acc = accif not os.path.exists(best_ckpt_dir):os.mkdir(best_ckpt_dir)ms.save_checkpoint(network, best_ckpt_path)print("=" * 80)print(f"End of validation the best Accuracy is: {best_acc: 5.3f}, "f"save the best ckpt file in {best_ckpt_path}", flush=True)
复制代码


注释:定义模型训练的步骤,包括前向传播、反向传播、优化器和损失函数的设置,以及模型的训练和评估过程,保存最佳模型检查点。


分析:训练过程是模型学习数据特征的关键阶段,评估阶段用于监控模型的泛化能力,保存最佳模型可以用于后续的预测和部署。


模型评估

import matplotlib.pyplot as pltimport mindspore as msdef visualize_model(best_ckpt_path, val_ds):net = resnet50()# 全连接层输入层的大小in_channels = net.fc.in_channels# 输出通道数大小为分类数4head = nn.Dense(in_channels, 4)# 重置全连接层net.fc = head# 平均池化层kernel size为7avg_pool = nn.AvgPool2d(kernel_size=7)# 重置平均池化层net.avg_pool = avg_pool# 加载模型参数param_dict = ms.load_checkpoint(best_ckpt_path)ms.load_param_into_net(net, param_dict)model = train.Model(net)# 加载验证集的数据进行验证data = next(val_ds.create_dict_iterator())images = data["image"].asnumpy()labels = data["label"].asnumpy()#print(labels)class_name = {0: "basal_cell_carcinoma",1: "melanoma",2: "nevus",3: "pigmented_benign_keratosis"}# 预测图像类别data_pre=ms.Tensor(data["image"])output = model.predict(data_pre)# print(output)pred = np.argmax(output.asnumpy(), axis=1)# 显示图像及图像的预测值plt.figure(figsize=(10, 10))for i in range(16):plt.subplot(4, 4, i + 1)# 若预测正确,显示为蓝色;若预测错误,显示为红色color = 'blue' if pred[i] == labels[i] else 'red'plt.title('predict:{}'.format(class_name[pred[i]]), color=color,fontsize=7)picture_show = np.transpose(images[i], (1, 2, 0))mean = np.array([0.485, 0.456, 0.406])std = np.array([0.229, 0.224, 0.225])picture_show = std * picture_show + meanpicture_show = np.clip(picture_show, 0, 1)plt.imshow(picture_show)plt.axis('off')plt.show()visualize_model('BestCheckpoint/resnet50-best.ckpt', dataset_val)
复制代码


从验证数据集中提取了一批次的数据,使用模型进行预测,并根据预测结果将图像及其预测标签以蓝色(正确)或红色(错误)显示。


使用 matplotlib 库绘制了一个包含四个子图的图像,每个子图展示了一张图像及其预测结果。


推理使用

import numpy as npimport matplotlib.pyplot as pltimport mindspore as msfrom mindspore import nnfrom mindspore.train.serialization import load_checkpoint, load_param_into_netimport mindspore.numpy as mnpdef preprocess_image(image_path):# 使用PIL加载图像from PIL import Imageimage = Image.open(image_path)# 转换图像为RGB模式image = image.convert('RGB')# 调整图像大小以匹配模型输入image = image.resize((224, 224)) # 假设模型输入大小为224x224# 将图像转换为numpy数组image_array = np.array(image)# 归一化图像数组image_array = image_array / 255.0image_array = np.transpose(image_array, (2, 0, 1))# 扩展维度以匹配模型输入,例如 (1, 3, 224, 224)image_array = np.expand_dims(image_array, axis=0)return image_array.astype(np.float32) # 确保数据类型为float32def visualize_prediction(image_path, best_ckpt_path):net = resnet50()# 全连接层输入层的大小in_channels = net.fc.in_channels# 输出通道数大小为分类数4head = nn.Dense(in_channels, 4)# 重置全连接层net.fc = head# 平均池化层kernel size为7avg_pool = nn.AvgPool2d(kernel_size=7)# 重置平均池化层net.avg_pool = avg_pool# 加载模型参数param_dict = ms.load_checkpoint(best_ckpt_path)ms.load_param_into_net(net, param_dict)model = train.Model(net)# 预处理图像image = preprocess_image(image_path)data_pre = ms.Tensor(image)print(data_pre.shape)print(type(data_pre))class_name = {0: "basal_cell_carcinoma",1: "melanoma",2: "nevus",3: "pigmented_benign_keratosis"}output = model.predict(data_pre)print(output)pred = np.argmax(output.asnumpy(), axis=1)print(pred)plt.figure(figsize=(5, 5))plt.subplot(1, 1, 1)plt.title('predict:{}'.format(class_name[pred[0]]))picture_show = image[0] # 已经是归一化后的图像picture_show = np.transpose(picture_show, (1, 2, 0)) # 转换为(224, 224, 3)plt.imshow(picture_show)plt.axis('off')plt.show()# 调用函数,传入图片路径和模型检查点路径visualize_prediction('pifudata_Maker/images/val/2/ISIC_0000005.jpg','BestCheckpoint/resnet50-best.ckpt')
复制代码

图像预处理与模型加载

  • 定义了 preprocess_image 函数,用于将输入图像进行归一化处理并调整维度顺序,以适配模型的输入格式。

  • 定义了 visualize_prediction 函数,加载预训练的 ResNet50 模型,并对模型的全连接层和平均池化层进行调整以适配皮肤肿瘤分类任务。

模型预测与结果可视化

  • 使用预处理后的图像作为输入,通过模型进行预测,并获取预测结果。

  • 将预测结果映射到对应的皮肤肿瘤类别名称,并通过 matplotlib 将图像及其预测类别进行可视化展示。

实际应用

  • 通过调用 visualize_prediction 函数,对指定路径的图像进行预测和可视化,展示了如何将训练好的模型应用于实际的皮肤肿瘤分类任务中。

2.2 项目结果

模型构建与训练

  • 成功构建了一个基于 ResNet50 的深度学习模型,用于皮肤肿瘤分类任务。


  • 模型在训练集上进行了有效的学习,并在验证集上进行了性能评估。

分类准确率

  • 模型在验证集上达到了一定的分类准确率,具体数值在训练过程中输出。

  • 通过多个训练周期的迭代,准确率逐渐提升,最终在验证集上取得了最佳性能。

模型保存

  • 训练过程中保存了最佳模型的检查点,便于后续的模型部署和预测。

可视化评估

  • 通过可视化验证集中的图像,直观展示了模型对各类皮肤肿瘤的预测效果。

  • 对比预测结果与真实标签,评估模型的分类准确性。

单张图像预测

  • 实现了对单张皮肤肿瘤图像的预测功能,能够输出预测的肿瘤类型。

  • 通过图像预处理和模型推理,展示了模型在实际应用中的效果。

2.3 项目意义

医学应用价值

  • 皮肤肿瘤分类模型能够辅助医生进行皮肤肿瘤的早期筛查和诊断,提高诊断的准确性和效率。

  • 对于医疗资源有限的地区,该模型可以作为一种初步的诊断工具,帮助患者及时发现潜在的皮肤肿瘤问题。

早期诊断与治疗

  • 皮肤肿瘤的早期诊断对于治疗效果至关重要,尤其是对于恶性肿瘤如黑色素瘤。

  • 该模型能够快速识别出疑似肿瘤区域,并提供分类建议,有助于患者尽早接受治疗。

医疗资源优化

  • 减轻医生的工作负担,提高诊断效率,使医生能够将更多精力集中在复杂病例的处理上。

  • 通过自动化诊断工具,可以在大规模人群中进行皮肤肿瘤的初步筛查,筛选出高风险患者进行进一步检查。

医学研究支持

  • 为皮肤病学研究提供数据支持和分析手段,促进对皮肤肿瘤发病机制、特征和演变的研究。

  • 帮助研究人员更系统地整理和分析大量皮肤肿瘤图像数据,推动相关领域的研究进展。

技术创新与推广

  • 展示了深度学习技术在医学图像分类中的应用潜力,为其他医学领域的类似研究提供了参考和借鉴。

  • 推动人工智能技术在医疗领域的应用和发展,提高医疗服务的质量和可及性。

2.4 运行结果


用户头像

提供全面深入的云计算技术干货 2020-07-14 加入

生于云,长于云,让开发者成为决定性力量

评论

发布
暂无评论
【案例共创】基于华为开发者空间的RestNet50目标检测_人工智能_华为云开发者联盟_InfoQ写作社区