DataWhaleCV夏令营笔记 (1)

前言

cv小白一枚,难免有疏忽,如有大佬们给出建议或者指出错误,不胜感激,也欢迎大家一起和我讨论.

赛题介绍

脑PET图像分析和疾病预测挑战赛
简短的来说,就是要将三维的医学脑PET图像进行分类.
图像的维度为128x128x63.数据为nii格式数据.
分类的类别为NC正常,以及MCI轻度认知障碍.

对赛题的思考.

赛题为经典的图像分类问题,但是图像数据十分复杂,为三维数据,因此图像数据的处理为一个难点.同时进行分类的方法也需要进行思考。首先使用简单的机器学习方法如SVM,Logistc Regression,决策树,K最近邻等方法进行尝试。其次再使用CNN等神经网络进行处理,最后可尝试最新的视觉模型如Vit Transformer进行分类.

baseline 代码

夏令营提供了baseline代码,其中使用逻辑回归对数据进行分类,达到了50%的正确率.其中的亮点为对数据特征的处理,以及新手能够学习到数据处理的便捷方法。我会贴出我的一些学习体会.

代码如下

import glob                # 获取文件路径
import numpy as np
import pandas as pd
import nibabel as nib      # 处理医学图像数据
from nibabel.viewers import OrthoSlicer3D    # 图像可视化
from collections import Counter              # 计数统计

# 读取训练集文件路径
train_path = glob.glob('./脑PET图像分析和疾病预测挑战赛公开数据/Train/*/*')
test_path = glob.glob('./脑PET图像分析和疾病预测挑战赛公开数据/Test/*')

# 打乱训练集和测试集的顺序
np.random.shuffle(train_path)
np.random.shuffle(test_path)

# 对PET文件提取特征
def extract_feature(path):
    # 加载PET图像数据
    img = nib.load(path)
    # 获取第一个通道的数据
    img = img.dataobj[:, :, :, 0]
    
    # 随机筛选其中的10个通道提取特征
    random_img = img[:, :, np.random.choice(range(img.shape[2]), 10)]
    
    # 对图片计算统计值
    feat = [
        (random_img != 0).sum(),               # 非零像素的数量
        (random_img == 0).sum(),               # 零像素的数量
        random_img.mean(),                     # 平均值
        random_img.std(),                      # 标准差
        len(np.where(random_img.mean(0))[0]),  # 在列方向上平均值不为零的数量
        len(np.where(random_img.mean(1))[0]),  # 在行方向上平均值不为零的数量
        random_img.mean(0).max(),              # 列方向上的最大平均值
        random_img.mean(1).max()               # 行方向上的最大平均值
    ]
    
    # 根据路径判断样本类别('NC'表示正常,'MCI'表示异常)
    if 'NC' in path:
        return feat + ['NC']
    else:
        return feat + ['MCI']

# 对训练集进行30次特征提取,每次提取后的特征以及类别('NC'表示正常,'MCI'表示异常)被添加到train_feat列表中。
train_feat = []
for _ in range(30):
    for path in train_path:
        train_feat.append(extract_feature(path))
     
# 对测试集进行30次特征提取   
test_feat = []
for _ in range(30):
    for path in test_path:
        test_feat.append(extract_feature(path))
        
# 使用训练集的特征作为输入,训练集的类别作为输出,对逻辑回归模型进行训练。
from sklearn.linear_model import LogisticRegression
m = LogisticRegression(max_iter=1000)
m.fit(
    np.array(train_feat)[:, :-1].astype(np.float32),  # 特征
    np.array(train_feat)[:, -1]                       # 类别
)

# 对测试集进行预测并进行转置操作,使得每个样本有30次预测结果。
test_pred = m.predict(np.array(test_feat)[:, :-1].astype(np.float32))
test_pred = test_pred.reshape(30, -1).T

# 对每个样本的30次预测结果进行投票,选出最多的类别作为该样本的最终预测类别,存储在test_pred_label列表中。
test_pred_label = [Counter(x).most_common(1)[0][0] for x in test_pred]

# 生成提交结果的DataFrame,其中包括样本ID和预测类别。
submit = pd.DataFrame(
    {
        'uuid': [int(x.split('/')[-1][:-4]) for x in test_path],  # 提取测试集文件名中的ID
        'label': test_pred_label                                  # 预测的类别
    }
)

# 按照ID对结果排序并保存为CSV文件
submit = submit.sort_values(by='uuid')
submit.to_csv('submit1.csv', index=None)

学习心得

  1. 特征的提取,代码中提取了图像的统计特征,如同如非零像素数量、零像素数量、平均值、标准差等.进行了简单的特征提取.

传统的特征有:

图像特征统计(传统方法)
图像特征统计是指对图像中的像素或图像区域进行统计分析,以提取和描述图像的特征信息。

  • 占比特征:通过统计图像中不同像素值或颜色通道的像素数量,计算其在整个图像中的比例或占比。
  • 边缘特征:边缘是图像中像素值或颜色发生剧烈变化的区域,通常表示物体的边界或纹理的边界。
  • 纹理特征:描述了图像中的纹理信息,反映了图像的细节和结构。

代码中仅仅计算了一些统计量

    random_img = img[:, :, np.random.choice(range(img.shape[2]), 10)]
    
    # 对图片计算统计值
    feat = [
        (random_img != 0).sum(),               # 非零像素的数量
        (random_img == 0).sum(),               # 零像素的数量
        random_img.mean(),                     # 平均值
        random_img.std(),                      # 标准差
        len(np.where(random_img.mean(0))[0]),  # 在列方向上平均值不为零的数量
        len(np.where(random_img.mean(1))[0]),  # 在行方向上平均值不为零的数量
        random_img.mean(0).max(),              # 列方向上的最大平均值
        random_img.mean(1).max()               # 行方向上的最大平均值
    ]
    
    # 根据路径判断样本类别('NC'表示正常,'MCI'表示异常)
    if 'NC' in path:
        return feat + ['NC']
    else:
        return feat + ['MCI']

2. 模型的训练.
使用sklearn中的LogisticRegression进行训练.
同时使用glob函数进行大批量文件数据的读取.

3.后续的展望.

  • 使用CNN等模型进一步对数据进行分析
  • 使用其他的传统机器学习模型对于数据进行分析
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值