昇思学习打卡营第33天|基于MindSpore的恶性皮肤肿瘤识别

1. 实验介绍

        本次实验的目标是基于MindSpore框架,训练一个ResNet50模型,用于恶性皮肤肿瘤的分类识别。本实验将使用包含四类皮肤肿瘤图片的数据集,针对ResNet50模型进行微调,训练出一个能够精准分类皮肤病的模型。主要过程包括数据处理、模型搭建与训练、性能评估以及模型推理。

1.1 实验目标
  • 掌握使用MindSpore进行深度学习模型训练的基本流程;
  • 了解ResNet50模型的结构及其在图像分类中的应用;
  • 学习如何针对特定数据集(皮肤病图片)进行模型微调和参数优化。
1.2 使用工具
  • MindSpore框架:开源的AI计算框架,适用于多场景应用,支持端、边、云等多种部署环境。
  • ResNet50模型:一种经典的深度残差网络,能够有效解决深层网络的梯度消失问题。
  • 昇思大模型平台:基于昇思MindSpore的深度学习平台,提供丰富的模型库和强大的计算资源。
1.3 实验步骤
  1. 数据准备:收集并处理皮肤病数据集,确保数据质量;
  2. 模型选择:使用MindSpore提供的ResNet50预训练模型进行微调;
  3. 模型训练:配置训练参数,启动模型训练;
  4. 模型评估:通过验证集评估模型性能,进行超参数调整;
  5. 模型推理:部署训练好的模型进行恶性皮肤肿瘤识别。

2. 数据集处理

2.1 数据集介绍

        该实验数据集包含四类皮肤病图片,分别为:

  • 基底细胞癌(Basal Cell Carcinoma):最常见的皮肤癌,通常不扩散但有局部侵袭性;
  • 黑色素瘤(Melanoma):最严重的皮肤癌,易扩散至其他部位,需早期发现治疗;
  • 色素性良性角化病(Pigmented Benign Keratosis):良性皮肤病变,表现为皮肤上的色素斑块;
  • (Nevus):通常为良性的色素痣,但某些情况下可能发生恶变。
2.2 数据集获取和整理

        数据集的下载链接为:https://xihe.mindspore.cn/datasets/knoka/pifudata_Maker/tree。数据集包含4个分类,每类有若干图片,且已划分为训练集和验证集。

        接下来,我们将通过代码下载并解压数据集,同时将数据集文件夹按编号进行重命名,方便后续的加载和使用。

# 重命名数据集文件夹,方便后续处理
import os

# 定义疾病名称和编号的映射
diseases = {
    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)
        new_folder_path = os.path.join(folder_path, str(number))
        os.rename(old_folder_path, new_folder_path)
2.3 数据可视化

        

        数据集中的每个类别的图片数量如下:

  • 训练集:Nevus(357张)、Melanoma(438张)、Pigmented Benign Keratosis(462张)、Basal Cell Carcinoma(376张);
  • 验证集:每类均为16张。

        为了更直观地了解数据集分布,我们绘制了训练集和验证集的类别分布图。

import os
import matplotlib.pyplot as plt

# 数据集路径
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)
    count = len(os.listdir(folder_path))
    file_counts_train[folder_name] = count

for folder_name in os.listdir(data_path_val):
    folder_path = os.path.join(data_path_val, folder_name)
    count = len(os.listdir(folder_path))
    file_counts_val[folder_name] = count

# 绘制图像
categories = list(file_counts_train.keys())
plt.figure(figsize=(12, 8))

# 绘制训练集和验证集的条形图
plt.bar(categories, file_counts_train.values(), width=0.4, color='blue', label='Train')
plt.bar([x + 0.4 for x in range(len(categories))], file_counts_val.values(), width=0.4, color='green', label='Validation')

# 添加标签与图例
plt.xlabel('Category')
plt.ylabel('Number of Images')
plt.legend()
plt.show()
2.4 数据加载

        我们将通过MindSpore的ImageFolderDataset加载数据集,并定义数据增强操作来提高模型的泛化能力。训练集进行随机裁剪和翻转等增强操作,验证集只进行基本的归一化处理。

import mindspore.dataset as ds
import mindspore.dataset.vision as vision

# 定义数据集加载函数
def create_dataset(dataset_path, usage):
    data_set = ds.ImageFolderDataset(dataset_path, shuffle=True)
    mean = [0.485 * 255, 0.456 * 255, 0.406 * 255]
    std = [0.229 * 255, 0.224 * 255, 0.225 * 255]

    if usage == "train":
        trans = [
            vision.RandomCropDecodeResize(size=224, scale=(0.08, 1.0)),
            vision.RandomHorizontalFlip(prob=0.5),
            vision.Normalize(mean=mean, std=std),
            vision.HWC2CHW()
        ]
    else:
        trans = [
            vision.Decode(),
            vision.Resize(224),
            vision.Normalize(mean=mean, std=std),
            vision.HWC2CHW()
        ]
    
    data_set = data_set.map(operations=trans, input_columns="image")
    data_set = data_set.batch(64)
    return data_set

# 创建训练集和验证集
train_dataset = create_dataset("pifudata_Maker/images/train", "train")
val_dataset = create_dataset("pifudata_Maker/images/val", "val")

3. 模型训练

3.1 模型定义

        我们将使用MindSpore自带的ResNet50预训练模型,并对其最后一层进行修改,使其适应四类皮肤病的分类任务。

from mindspore import nn
from mindspore import load_checkpoint, load_param_into_net

# 定义ResNet50模型并加载预训练权重
def resnet50(num_classes=4, pretrained=True):
    net = nn.resnet50()
    in_channels = net.fc.in_channels
    net.fc = nn.Dense(in_channels, num_classes)
    return net

network = resnet50()
3.2 模型训练

        我们使用Momentum优化器和交叉熵损失函数进行模型训练。每个epoch结束后,会在验证集上进行评估,并保存最佳模型。

from mindspore import train

# 定义损失函数和优化器
loss_fn = nn.SoftmaxCrossEntropyWithLogits(sparse=True)
opt = nn.Momentum(params=network.trainable_params(), learning_rate=0.001, momentum=0.9)

# 实例化模型
model = train.Model(network, loss_fn, opt, metrics={'accuracy'})

# 训练模型
num_epochs = 25
best_acc = 0
for epoch in range(num_epochs):
    model.train(epoch, train_dataset)
    acc = model.eval(val_dataset)['accuracy']
    print(f'Epoch {epoch+1}/{num_epochs}, Accuracy: {acc}')
    if acc > best_acc:
        best_acc = acc
        model.save_checkpoint('best_model.ckpt')

4. 模型推理

        在模型推理部分,我们首先需要对输入的图像进行预处理,将其转换为适合模型输入的格式。预处理完成后,我们将调用训练好的模型进行预测,并展示最终的推理结果。

import matplotlib.pyplot as plt
import mindspore as ms

# 定义图片预处理函数
def preprocess_image(image_path):
    from PIL import Image
    image = Image.open(image_path)
    image = image.convert('RGB')  # 确保图像为RGB格式
    image = image.resize((224, 224))  # 调整大小
    image = np.array(image) / 255.0  # 归一化
    image = np.transpose(image, (2, 0, 1))  # 调整维度
    image = np.expand_dims(image, axis=0)  # 增加batch维度
    return image.astype(np.float32)

# 定义推理函数,加载模型并进行预测
def infer(image_path, checkpoint_path):
    # 加载预训练模型
    net = resnet50(num_classes=4)
    param_dict = ms.load_checkpoint(checkpoint_path)
    ms.load_param_into_net(net, param_dict)
    model = ms.Model(net)

    # 预处理输入图像
    image = preprocess_image(image_path)
    image_tensor = ms.Tensor(image)

    # 进行推理
    output = model.predict(image_tensor)
    predicted_class = np.argmax(output.asnumpy(), axis=1)[0]
    
    # 类别映射
    class_names = {
        0: "基底细胞癌",
        1: "黑色素瘤",
        2: "痣",
        3: "色素性良性角化病"
    }

    # 展示结果
    plt.imshow(np.transpose(image[0], (1, 2, 0)))
    plt.title(f"预测结果: {class_names[predicted_class]}")
    plt.axis('off')
    plt.show()

# 调用推理函数,展示结果
infer('path/to/your/image.jpg', 'best_model.ckpt')

        该推理函数会加载已经训练好的模型,并将输入图像转换为合适的格式,最后通过模型预测输出类别。我们将使用Matplotlib库展示预测结果,并标记图像的分类情况。

结语

        在本次实验中,我们一起学习了如何使用MindSpore框架进行皮肤肿瘤识别的任务。通过数据预处理、ResNet50模型的搭建与微调,以及模型训练与推理,逐步构建了一个能够对皮肤病进行分类的模型。虽然深度学习在医学图像识别领域具有广泛的应用前景,但在实际操作中,我们仍需要不断调整和优化模型的各项参数,以获得更好的性能。

        相信在实践的过程中,我们都能更加深入地理解这些技术背后的原理,并在今后的学习和项目中继续探索和应用。也希望我们在未来的研究中,能通过更多的尝试和合作,共同提升我们的技能和知识水平。学习是一个不断积累的过程,期待和大家一起继续进步!

如果你觉得这篇博文对你有帮助,请点赞、收藏、关注我,并且可以打赏支持我!

欢迎关注我的后续博文,我将分享更多关于人工智能、自然语言处理和计算机视觉的精彩内容。

谢谢大家的支持!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会飞的Anthony

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值