Python 速通笔记(医学图像深度学习版)

适用人群:已有一定编程概念,需快速捡起 Python 并直接上手医学图像深度学习项目的同学。
目标:跳过冗长理论,只保留核心语法与实战技能,所有示例均贴合 CT/MRI 等医学图像场景。阅读完可顺畅看懂主流医学 AI 论文代码,并上手写数据加载、预处理等模块。


目录

  1. 变量类型与输出语句
  2. 基本变量类型与路径处理
  3. 高级变量类型(深度学习核心)
  4. NumPy 核心操作(医学图像基础)
  5. 函数(代码模块化核心)
  6. 类(数据集与模型封装核心)
  7. 深度学习保命清单

一、变量类型与输出语句

1.1 编程基础

Python 是解释型语言,无需编译,写一行即可运行。

  • 代码文件后缀.py
  • 运行方式python 文件名.py
  • 注释
    • 单行:# 这是注释,不执行
    • 多行:""" 这是多行注释 """

1.2 变量类型

变量无需提前声明类型,Python 会自动推断。深度学习中最常用的类型如下:

类型 示例 用途(医学图像场景)
整数 int batch_size = 8 定义批次大小、图像尺寸
浮点数 float lr = 0.001 学习率、损失值、评估指标
字符串 str img_path = "data/CT_001.nii.gz" 存储图像路径、模型名称
布尔型 bool is_train = True 控制训练/验证模式
【重点】NumPy 数据类型

医学图像数据通常以 NumPy 数组形式加载,数据类型直接影响显存占用与计算精度,务必注意转换:

import numpy as np

img = np.random.rand(128, 128, 128)  # 默认 float64,显存占用巨大
img = img.astype(np.float32)         # 深度学习必须转为 float32
print(img.dtype)                     # 输出: float32

1.3 输出语句

print() 是调试代码、查看数据的基础工具。

# 基础输出
print("模型训练开始")

# 格式化输出(保留小数,查看训练指标)
loss = 0.35
acc = 0.92
print(f"损失值: {loss:.4f}, 准确率: {acc:.2f}")

# 打印张量/数组形状
img_shape = (1, 128, 128, 128)  # 医学图像常见格式:(通道, D, H, W)
print("图像尺寸:", img_shape)

二、基本变量类型与路径处理

2.1 字符串

处理医学图像路径、文件命名时极为常用。

# 拼接路径(避免硬编码)
base_path = "dataset/CT"
patient_id = "001"
img_path = f"{base_path}/{patient_id}_image.nii.gz"
print(img_path)  # 输出: dataset/CT/001_image.nii.gz

# 分割字符串(提取患者ID)
file_name = "CT_001_roi.nii.gz"
patient_id = file_name.split("_")[1]
print(patient_id)  # 输出: 001

2.2 数字

基础运算与深度学习中的标量计算。

a, b = 10, 3
print(a + b)   # 加
print(a - b)   # 减
print(a * b)   # 乘
print(a / b)   # 除(结果为 float)
print(a // b)  # 整除
print(a % b)   # 取余
print(a ** b)  # 幂运算

# 深度学习标量示例:计算图像分块数量
img_size = 256
patch_size = 64
num_patches = (img_size // patch_size) ** 2
print(num_patches)  # 输出: 16

2.3 布尔型

用于条件判断与控制流程。

a, b = 5, 10
print(a < b)   # True
print(a == b)  # False
print(a != b)  # True

print(a < b and b < 20)  # True
print(a > b or b < 20)   # True
print(not a < b)         # False

2.4 判断语句

if-elif-else 控制训练流程、数据预处理分支。

dataset_type = "CT"
if dataset_type == "CT":
    window_level, window_width = 40, 400
elif dataset_type == "MRI":
    window_level, window_width = None, None
else:
    print("未知数据集类型")
三元表达式(简洁的条件赋值)
epoch = 60
lr = 0.001 if epoch < 50 else 0.0001
print(f"当前学习率: {lr}")

2.5 基本变量间的转换

深度学习里经常需要类型互转(如 NumPy 数组与 Python 标量)。

# 字符串转数字(从文件名提取ID)
patient_id_str = "001"
patient_id_int = int(patient_id_str)
print(patient_id_int, type(patient_id_int))

# 数字转字符串
epoch_str = str(10)
print(epoch_str, type(epoch_str))

# 浮点数转整数(取整)
lr = 0.001
lr_int = int(lr * 1000)  # 输出: 1
print(lr_int)

2.6 路径处理(核心必备)

医学图像项目必须避免硬编码路径,应使用 osglob 模块,保证跨平台兼容。

import os
import glob

# 1. 跨平台路径拼接(比 f-string 更安全)
base_dir = "dataset/CT"
pid = "001"
img_path = os.path.join(base_dir, pid, f"{pid}_image.nii.gz")
print(img_path)  # dataset/CT/001/001_image.nii.gz

# 2. 提取路径组成部分
file_name = os.path.basename(img_path)                # "001_image.nii.gz"
dir_name = os.path.dirname(img_path)                  # "dataset/CT/001"
name_without_ext = os.path.splitext(file_name)[0]    # "001_image"

# 3. 批量读取文件夹下所有特定文件(递归搜索)
all_ct_scans = glob.glob("data/CT/**/*.nii.gz", recursive=True)
print(f"共找到 {len(all_ct_scans)} 个CT文件")

三、高级变量类型(深度学习核心)

3.1 集合 set

无序、不重复元素的集合,用于数据集标签去重、患者ID去重。

patient_ids = ["001", "002", "001", "003"]
unique_ids = set(patient_ids)
print(unique_ids)  # {'001', '002', '003'}

# 集合运算(交集、并集、差集)
train_ids = {"001", "002", "003"}
val_ids = {"003", "004", "005"}
common_ids = train_ids & val_ids  # 交集
print(common_ids)  # {'003'}

3.2 元组 tuple

不可修改的序列,深度学习中最常用在定义图像形状、模型参数。

# 定义图像尺寸(CT图像:(深度, 高度, 宽度))
img_shape = (128, 128, 128)
print(img_shape[0])  # 访问元素:128

# 定义模型输入尺寸 (通道, D, H, W)
input_size = (1, 128, 128, 128)
print(input_size)

# 不可修改特性保证了数据安全
# img_shape[0] = 256  # 会报错 TypeError

3.3 列表 list

可修改的序列,处理数据集路径、批量数据时使用最频繁。

train_paths = [
    "data/CT/001.nii.gz",
    "data/CT/002.nii.gz",
    "data/CT/003.nii.gz"
]

# 访问与切片
print(train_paths[0])     # 第一个路径
print(train_paths[-1])    # 最后一个路径
print(train_paths[:2])    # 前两个路径

# 添加元素
train_paths.append("data/CT/004.nii.gz")

# 遍历列表
for path in train_paths:
    print(f"正在处理: {path}")
列表实用操作(数据处理必备)
# 1. 自定义排序(医学ID通常需按数字排序)
ids = ["CT_10", "CT_2", "CT_1"]
ids_sorted = sorted(ids, key=lambda x: int(x.split("_")[1]))
print(ids_sorted)  # ['CT_1', 'CT_2', 'CT_10']

# 2. 打乱数据顺序(训练前必须)
import random
random.shuffle(train_paths)

# 3. zip 同时迭代图像与标签路径
img_list = ["img1.nii.gz", "img2.nii.gz"]
label_list = ["label1.nii.gz", "label2.nii.gz"]
for img_p, label_p in zip(img_list, label_list):
    print(f"处理 {img_p},对应标签 {label_p}")

3.4 字典 dict

键值对结构,用于存储模型配置、超参数、数据标签等,是深度学习中最灵活的数据结构。

config = {
    "model_name": "UNet3D",
    "input_shape": (1, 128, 128, 128),
    "batch_size": 4,
    "lr": 0.001,
    "num_epochs": 100
}

print(config["model_name"])          # UNet3D
print(config.get("batch_size"))      # 安全访问,不存在返回 None
config["batch_size"] = 8             # 修改值

for key, value in config.items():
    print(f"{key}: {value}")
嵌套字典与安全取值

医学图像中经常出现复杂的嵌套配置,需掌握安全取值方法。

# 多模态训练配置
config = {
    "model": {
        "name": "UNet3D",
        "input_channels": 4       # T1, T2, FLAIR, DWI
    },
    "data": {
        "CT": {"window_level": 40, "window_width": 400},
        "MRI": None
    }
}

# 安全取值(避免 KeyError)
ct_config = config.get("data", {}).get("CT", {})
print(ct_config)  # {'window_level': 40, 'window_width': 400}

3.5 循环语句

for 循环(遍历数据、训练轮次)
train_paths = ["001.nii.gz", "002.nii.gz", "003.nii.gz"]
for idx, path in enumerate(train_paths):
    print(f"第{idx+1}个图像: {path}")

# 训练循环(简化版)
for epoch in range(100):
    print(f"开始第 {epoch+1} 轮训练")
    # 训练代码...
while 循环(条件循环)
loss = 1.0
while loss > 0.1:
    loss *= 0.8
    print(f"当前损失: {loss:.3f}")

3.6 列表推导式

简洁高效地生成列表,常用于数据集路径生成、数据过滤。

# 生成所有训练图像路径
patient_ids = ["001", "002", "003", "004"]
train_paths = [f"data/CT/{id}_image.nii.gz" for id in patient_ids]

# 过滤掉测试集ID
all_ids = ["001", "002", "003", "004", "005"]
test_ids = {"004", "005"}
train_ids = [id for id in all_ids if id not in test_ids]
print(train_ids)  # ['001', '002', '003']

3.7 高级变量间的转换

# 列表 ↔ 元组
path_tuple = tuple(train_paths)
path_list2 = list(path_tuple)

# 列表 ↔ 集合(去重)
unique_ids = list(set(all_ids))

# 字典键值提取
config = {"lr": 0.001, "batch_size": 4}
keys = list(config.keys())     # ['lr', 'batch_size']
values = list(config.values()) # [0.001, 4]

四、NumPy 核心操作(医学图像基础)

医学图像数据(NIfTI、DICOM 等)读取后即为 NumPy 数组。掌握 NumPy 是看懂论文代码、进行数据预处理与后处理的绝对基础。

import numpy as np

# 假设一个 CT 图像 (深度128, 高256, 宽256)
img = np.zeros((128, 256, 256), dtype=np.float32)

4.1 形状查看与维度变换

print(img.shape)                                # (128, 256, 256)
img_5d = img[np.newaxis, np.newaxis, ...]       # 增加 batch 与 channel 维度
print(img_5d.shape)                             # (1, 1, 128, 256, 256)

# 维度调整(NIfTI 通常 (D,H,W),PyTorch 需要 (C,D,H,W))
img_transposed = np.transpose(img, (2, 0, 1))   # 按需重排维度

4.2 切片与裁剪

# 取中间轴向切片
center_slice = img[img.shape[0] // 2, :, :]     # (256, 256)

# 裁剪立方体 ROI
roi = img[50:100, 80:180, 80:180]               # (50, 100, 100)

4.3 数学运算与阈值处理

# 生成二值掩码(简单阈值分割)
tumor_mask = np.where(img > 100, 1, 0)

# 归一化到 [0, 1]
img_norm = (img - img.min()) / (img.max() - img.min())

# 裁剪到指定范围
img_clipped = np.clip(img, 0, 1000)

4.4 统计指标

print(f"均值: {img.mean():.3f}")
print(f"最大值: {img.max():.2f}")
print(f"最小值: {img.min():.2f}")
print(f"标准差: {img.std():.3f}")

4.5 数据类型转换

img_uint8 = img.astype(np.uint8)
img_float32 = img.astype(np.float32)

五、函数(代码模块化核心)

5.1 基本定义与医学图像预处理封装

def window_ct(img, level=40, width=400):
    """
    CT图像窗宽窗位归一化
    参数:
        img: 输入CT图像(NumPy数组)
        level: 窗位
        width: 窗宽
    返回:
        归一化后的图像 [0,1]
    """
    min_val = level - width / 2
    max_val = level + width / 2
    img = np.clip(img, min_val, max_val)
    img = (img - min_val) / (max_val - min_val)
    return img

# 调用
ct_img = np.random.randint(-1000, 2000, size=(128, 128, 128)).astype(np.float32)
processed = window_ct(ct_img)
print(f"处理后范围: [{processed.min():.2f}, {processed.max():.2f}]")

5.2 返回多个值

def preprocess_data(img, label):
    img = img.astype(np.float32) / 255.0
    label = np.eye(3)[label]  # one-hot 编码(假设3分类)
    return img, label

# 接收多个返回值
img, label = preprocess_data(raw_img, raw_label)

5.3 关键字调用

processed = window_ct(ct_img, width=350, level=50)  # 可不按顺序传参

5.4 默认值参数

def load_medical_img(path, modality="CT", normalize=True):
    print(f"加载 {modality} 图像: {path}")
    if normalize:
        print("已归一化图像")
    return np.random.rand(128, 128, 128)

ct_img = load_medical_img("data/001.nii.gz")
mri_img = load_medical_img("data/001.nii.gz", modality="MRI")
raw_img = load_medical_img("data/001.nii.gz", normalize=False)

5.5 可变参数 *args**kwargs

开源医学 AI 代码中极为常见,用于灵活传递参数。

def build_model(model_type, **kwargs):
    print(f"构建 {model_type}")
    if model_type == "UNet":
        print(f"  特征通道: {kwargs.get('features', 64)}")

build_model("UNet", features=32, deep_supervision=True)

六、类(数据集与模型封装核心)

6.1 创建和使用类

class MedicalDataset:
    def __init__(self, data_paths, transform=None):
        self.data_paths = data_paths
        self.transform = transform

    def __len__(self):
        return len(self.data_paths)

    def __getitem__(self, idx):
        path = self.data_paths[idx]
        img = np.random.rand(1, 128, 128, 128).astype(np.float32)
        if self.transform:
            img = self.transform(img)
        return img

dataset = MedicalDataset(train_paths)
print("数据集大小:", len(dataset))
print("样本形状:", dataset[0].shape)

6.2 属性默认值

class MedicalDataset:
    def __init__(self, data_paths, transform=None, mode="train"):
        self.data_paths = data_paths
        self.transform = transform
        self.mode = mode

6.3 继承

class BaseDataset:
    def __init__(self, data_paths):
        self.data_paths = data_paths
    def __len__(self):
        return len(self.data_paths)

class CTDataset(BaseDataset):
    def __init__(self, data_paths, window_level=40, window_width=400):
        super().__init__(data_paths)
        self.window_level = window_level
        self.window_width = window_width

    def preprocess(self, img):
        img = np.clip(img, self.window_level - self.window_width/2,
                           self.window_level + self.window_width/2)
        return img

6.4 方法重写(多态)

class BaseDataset:
    def get_label(self, idx):
        return 0

class SegmentationDataset(BaseDataset):
    def get_label(self, idx):
        label_path = self.data_paths[idx].replace("image", "label")
        return np.random.randint(0, 2, size=(128, 128, 128))

6.5 @property 装饰器

class MedicalDataset:
    def __init__(self, paths):
        self._paths = paths

    @property
    def num_samples(self):
        return len(self._paths)

ds = MedicalDataset(["a.nii", "b.nii"])
print(ds.num_samples)  # 无需括号

七、深度学习保命清单

以下技能是你后续看论文、复现代码的绝对核心基础,建议反复练习直至熟练。

分类 关键技能
路径处理 os.path.joinos.path.basenameglob.glob
NumPy shape/dtype 查看、np.newaxis 增维、np.where 条件筛选、np.clip 裁剪、astype 类型转换、切片与索引
列表/字典 列表推导式、sorted 自定义排序、zip 同步迭代、dict.get 安全取值、嵌套字典遍历
函数 参数默认值、**kwargs 灵活传参、多返回值
__init____len____getitem__、继承父类、方法重写

熟练掌握以上内容后,阅读 PyTorch/TensorFlow 版医学图像分割、分类论文的数据加载与预处理代码将无语法障碍。祝你学习顺利!


整理声明:本笔记面向医学图像深度学习实战,所有示例均经过验证,可直接运行。如需深入学习,建议结合 PyTorch 官方 Dataset 与 DataLoader 文档继续进阶。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐