【CV夏令营】学习笔记01:跑通机器学习版本baseline

0 学习背景

有幸参与了DataWhale的AI视觉夏令营,沉浸式全流程体验AI比赛,比赛题目是:脑PET图像分析和疾病预测挑战赛,这里给出链接:https://challenge.xfyun.cn/topic/info?type=pet-2023&option=wdtd&ch=vWxQGFU

1 调通baseline

DataWhale官方baseline代码,逻辑回归版本

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)

官方提供的代码是Linux下的,需要做一些小修改。

修改1:修改数据集路径

由于代码中的路径是官方的相对路径,在自己电脑上路径并不相同。

在这里,保持良好习惯,把文件夹修改为了英文,即把 脑PET图像分析和疾病预测挑战赛公开数据 修改为了 datasets 。此外,由于数据集和python文件在平级路径下,所以 ./ 也可以去掉。因此,这两行代码就变为了:

# 读取训练集文件路径
train_path = glob.glob('datasets/Train/*/*')
test_path = glob.glob('datasets/Test/*')

修改2:修改测试时的文件名提取方法

由于官方代码是在Linux下运行的,所以对文件夹的读取有点不同。

这里需要把 / 修改为 \\ ,因此,第85行代码就变为了:

'uuid': [int(x.split('\\')[-1][:-4]) for x in test_path],  # 提取测试集文件名中的ID

这两个地方修改后,代码即可在本地pycharm完成运行。

修改3:强迫症修改

最后一行代码: submit.to_csv('submit1.csv', index=None) 会警告,说类型不对,查阅了to_csv()函数的用法才知道,index参数是个bool值,代表是否把索引也写进去,默认为True,这里为了契合官方的提交答案模板,不写索引,所以应该修改为False,而不是None。因此这段代码修改为:

submit.to_csv(path_or_buf='submit1.csv', index=False)

2 代码理解

代码流程如下:

【CV夏令营】学习笔记01:跑通机器学习版本baseline_第1张图片

你可能感兴趣的:(学习,笔记,机器学习)