深度特征提取在LIDC-IDRI数据集多分类任务中的优化细节

发布于:2025-07-07 ⋅ 阅读:(20) ⋅ 点赞:(0)

在这里插入图片描述

🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,10年以上C/C++, C#, Java等多种编程语言开发经验,拥有高级工程师证书;擅长C/C++、C#等开发语言,熟悉Java常用开发技术,能熟练应用常用数据库SQL server,Oracle,mysql,postgresql等进行开发应用,熟悉DICOM医学影像及DICOM协议,业余时间自学JavaScript,Vue,qt,python等,具备多种混合语言开发能力。撰写博客分享知识,致力于帮助编程爱好者共同进步。欢迎关注、交流及合作,提供技术支持与解决方案。\n技术合作请加本人wx(注明来自csdn):xt20160813

在这里插入图片描述

深度特征提取在LIDC-IDRI数据集多分类任务中的优化细节

在LIDC-IDRI数据集的肺癌检测多分类任务(区分良性、可疑、恶性结节)中,支持向量机(SVM)结合深度特征提取能够显著提升模型性能,尤其是对特征模糊的可疑结节的分类能力。相比传统特征(如GLCM、形状特征),深度特征通过卷积神经网络(CNN)捕捉复杂的三维空间模式,适用于高维、非线性的CT图像数据。本文将深入探讨深度特征提取在LIDC-IDRI多分类任务中的优化细节,包括深度特征提取原理3D-CNN模型设计与实现特征提取优化策略可视化与分析挑战与应对措施,并与传统特征进行对比。


一、深度特征提取原理

1.1 深度特征的优势

传统特征(如灰度共生矩阵GLCM、局部二值模式LBP)依赖手工设计,难以捕捉肺结节的复杂三维纹理和形态,尤其对可疑结节(评分2-4,特征介于良性与恶性)的区分能力有限。深度特征通过3D-CNN自动学习层次化特征,具有以下优势:

  • 层次化表示:从低级特征(如边缘、纹理)到高级特征(如结节形态、代谢模式)。
  • 鲁棒性:对噪声(如CT伪影)和结节异质性(大小、形状差异)更具适应性。
  • 非线性建模:通过多层卷积和激活函数,捕捉复杂非线性关系。

1.2 3D-CNN与2D-CNN的区别

肺部CT图像为三维体视数据(x, y, z),2D-CNN仅处理单切片,丢失体视信息。3D-CNN通过三维卷积核直接处理体视数据,适合提取结节的空间特征:

  • 三维卷积:卷积核形状为 ( d , h , w ) (d, h, w) (d,h,w),沿深度(z轴)滑动,捕捉体视模式。
  • 计算成本:3D-CNN参数量和计算量远高于2D-CNN,需优化模型结构。

1.3 深度特征提取流程

  1. 输入:预处理的结节ROI(典型大小32x32x32)。
  2. 特征提取:通过预训练或定制的3D-CNN,提取全连接层或全局池化层的输出作为特征向量。
  3. SVM分类:将深度特征输入SVM,进行多分类(良性、可疑、恶性)。

二、LIDC-IDRI数据集与多分类任务回顾

2.1 数据集特点

  • 样本:1018例CT扫描,数千个结节,每结节由4位医生评分(1-5)。
  • 多分类标签
    • 良性(平均评分 ≤ 2,标签0)。
    • 可疑(平均评分 2-4,标签1)。
    • 恶性(平均评分 ≥ 4,标签2)。
  • 挑战
    • 不平衡数据:恶性结节最少(约10-15%)。
    • 可疑结节特征模糊,分类难度高。
    • 标注主观性:医生评分不一致。

2.2 深度特征提取目标

  • 提升可疑结节分类性能:通过学习复杂的体视特征,减少可疑结节被误分为良性或恶性的情况。
  • 泛化能力:确保模型在异质性强的结节(大小、形态差异)上表现稳定。
  • 计算效率:优化3D-CNN结构和特征提取流程,适应中小规模数据集。

三、3D-CNN深度特征提取的实现与优化

3.1 3D-CNN模型设计

设计一个轻量级3D-CNN模型,适合LIDC-IDRI的小样本场景,避免过拟合。以下是推荐的模型架构:

  • 输入层:32x32x32x1(单通道体视ROI)。
  • 卷积层:多层3D卷积(核大小3x3x3),激活函数ReLU,步幅1。
  • 池化层:3D最大池化(2x2x2),降低维度。
  • 批归一化(BatchNorm):加速收敛,增强稳定性。
  • 全局平均池化(GAP):替代全连接层,减少参数量,输出固定维度特征(如128维)。
  • Dropout:正则化,防止过拟合。

模型结构示例

层类型 参数配置 输出形状
Input 32x32x32x1 (32, 32, 32, 1)
Conv3D+ReLU 32 filters, 3x3x3, stride=1 (32, 32, 32, 32)
BatchNorm - (32, 32, 32, 32)
MaxPool3D 2x2x2 (16, 16, 16, 32)
Conv3D+ReLU 64 filters, 3x3x3, stride=1 (16, 16, 16, 64)
BatchNorm - (16, 16, 16, 64)
MaxPool3D 2x2x2 (8, 8, 8, 64)
GlobalAvgPool3D - (64)
Dense 128 units, ReLU (128)
Dropout 0.5 (128)

代码实现

import tensorflow as tf
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Conv3D, MaxPooling3D, BatchNormalization, GlobalAveragePooling3D, Dense, Dropout, Input

def build_3d_cnn_feature_extractor(input_shape=(32, 32, 32, 1)):
    inputs = Input(shape=input_shape)
    x = Conv3D(32, (3, 3, 3), activation='relu', padding='same')(inputs)
    x = BatchNormalization()(x)
    x = MaxPooling3D((2, 2, 2))(x)
    x = Conv3D(64, (3, 3, 3), activation='relu', padding='same')(x)
    x = BatchNormalization()(x)
    x = MaxPooling3D((2, 2, 2))(x)
    x = GlobalAveragePooling3D()(x)
    x = Dense(128, activation='relu')(x)
    x = Dropout(0.5)(x)
    model = Model(inputs, x, name='3d_cnn_feature_extractor')
    return model

# 实例化模型
feature_extractor = build_3d_cnn_feature_extractor()
feature_extractor.summary()

3.2 数据预处理

与传统特征提取一致,需确保输入适合3D-CNN:

  1. 读取DICOM:加载CT切片,重建3D体视数据。
  2. 结节ROI裁剪:根据LIDC-IDRI坐标,提取32x32x32 ROI。
  3. 归一化:Hounsfield单位标准化后归一到[0,1]。
  4. 通道扩展:添加通道维度(32x32x32 → 32x32x32x1)。
import pydicom
import numpy as np
from skimage.transform import resize

def load_dicom_series(dicom_path):
    slices = [pydicom.dcmread(f) for f in dicom_path]
    slices.sort(key=lambda x: float(x.ImagePositionPatient[2]))
    image_3d = np.stack([s.pixel_array for s in slices])
    return image_3d

def preprocess_ct(image_3d, nodule_coords, size=(32, 32, 32)):
    x, y, z = nodule_coords
    roi = image_3d[z-16:z+16, y-16:y+16, x-16:x+16]
    roi = resize(roi, size, anti_aliasing=True)
    roi = (roi - np.min(roi)) / (np.max(roi) - np.min(roi) + 1e-8)
    return roi[..., np.newaxis]  # 添加通道维度

def generate_labels(scores):
    avg_score = np.mean(scores)
    if avg_score <= 2:
        return 0  # 良性
    elif avg_score < 4:
        return 1  # 可疑
    else:
        return 2  # 恶性

# 假设数据已准备
dicom_paths = [...]  # DICOM文件路径
nodule_annotations = [...]  # 结节坐标
nodule_scores = [...]  # 医生评分

ct_images = [load_dicom_series(path) for path in dicom_paths]
nodule_rois = [preprocess_ct(img, coords) for img, coords in zip(ct_images, nodule_annotations)]
labels = [generate_labels(scores) for scores in nodule_scores]

3.3 深度特征提取

使用3D-CNN模型提取特征,批量处理ROI以提升效率:

def extract_3d_cnn_features(rois, model, batch_size=32):
    features = []
    for i in range(0, len(rois), batch_size):
        batch_rois = np.array(rois[i:i+batch_size])
        batch_features = model.predict(batch_rois, batch_size=batch_size)
        features.append(batch_features)
    return np.vstack(features)

# 提取特征
cnn_features = extract_3d_cnn_features(nodule_rois, feature_extractor)
labels = np.array(labels)

3.4 SVM多分类训练

将深度特征输入SVM,采用One-vs-One(OVO)策略,结合网格搜索优化参数:

from sklearn.svm import SVC
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import classification_report, confusion_matrix
from imblearn.over_sampling import SMOTE
import matplotlib.pyplot as plt
import seaborn as sns

# 特征标准化
scaler = StandardScaler()
features_scaled = scaler.fit_transform(cnn_features)

# SMOTE过采样
smote = SMOTE(random_state=42, k_neighbors=3)
features_resampled, labels_resampled = smote.fit_resample(features_scaled, labels)

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
    features_resampled, labels_resampled, test_size=0.2, random_state=42, stratify=labels_resampled
)

# SVM训练与网格搜索
svm = SVC(kernel='rbf', decision_function_shape='ovo', class_weight='balanced', probability=True)
param_grid = {
    'C': [0.1, 1, 10, 100],
    'gamma': ['scale', 'auto', 0.001, 0.01, 0.1]
}
grid_search = GridSearchCV(svm, param_grid, cv=5, scoring='f1_macro', n_jobs=-1)
grid_search.fit(X_train, y_train)

# 输出结果
print("最佳参数:", grid_search.best_params_)
print("最佳宏平均F1分数:", grid_search.best_score_)

# 测试集评估
best_model = grid_search.best_estimator_
y_pred = best_model.predict(X_test)
print("测试集分类报告:\n", classification_report(y_test, y_pred, target_names=['Benign', 'Suspicious', 'Malignant']))

# 混淆矩阵可视化
cm = confusion_matrix(y_test, y_pred)
plt.figure(figsize=(8, 6))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',
            xticklabels=['Benign', 'Suspicious', 'Malignant'],
            yticklabels=['Benign', 'Suspicious', 'Malignant'])
plt.title('Confusion Matrix for 3D-CNN+SVM Multi-Class Classification')
plt.xlabel('Predicted Label')
plt.ylabel('True Label')
plt.show()

混淆矩阵图表(示例数据):

{
  "type": "matrix",
  "data": {
    "labels": ["Benign", "Suspicious", "Malignant"],
    "datasets": [{
      "data": [
        [110, 8, 2],    // Benign
        [6, 95, 9],     // Suspicious
        [2, 4, 85]      // Malignant
      ],
      "backgroundColor": [
        "#99FF99", "#FF9999", "#FF9999",
        "#FF9999", "#99FF99", "#FF9999",
        "#FF9999", "#FF9999", "#99FF99"
      ]
    }]
  },
  "options": {
    "title": {
      "display": true,
      "text": "Confusion Matrix for 3D-CNN+SVM Multi-Class Classification"
    },
    "scaleShowValues": true,
    "scales": {
      "xAxes": [{
        "scaleLabel": {
          "display": true,
          "labelString": "Predicted Label"
        }
      }],
      "yAxes": [{
        "scaleLabel": {
          "display": true,
          "labelString": "True Label"
        }
      }]
    }
  }
}

3.5 特征重要性分析

通过SVM的支持向量分析特征重要性:

  • 支持向量:SVM的决策依赖于支持向量,提取这些样本的特征有助于理解模型关注点。
  • SHAP值:使用SHAP库分析深度特征对分类的贡献。
import shap

# 使用SHAP解释器
explainer = shap.KernelExplainer(best_model.predict_proba, X_train[:100])  # 限制样本数
shap_values = explainer.shap_values(X_test[:10])

# 可视化特征重要性
shap.summary_plot(shap_values, X_test[:10], feature_names=[f'Feature_{i}' for i in range(X_test.shape[1])])

四、深度特征提取的优化策略

4.1 预训练模型迁移学习

LIDC-IDRI样本有限,直接训练3D-CNN易过拟合。使用预训练模型(如在其他医学影像数据集上训练的3D-ResNet)进行迁移学习:

  • 数据集:如Luna16(肺结节检测)或公开的3D医学影像数据集。
  • 冻结层:冻结前几层卷积层,仅微调全连接层。
  • 实现
from tensorflow.keras.applications import ResNet50  # 示例,需替换为3D预训练模型

def load_pretrained_3d_cnn():
    # 假设已有预训练3D-ResNet
    base_model = ResNet50(weights='pretrained', include_top=False, input_shape=(32, 32, 32, 1))
    x = GlobalAveragePooling3D()(base_model.output)
    x = Dense(128, activation='relu')(x)
    model = Model(base_model.input, x)
    for layer in base_model.layers[:-4]:
        layer.trainable = False
    return model

pretrained_model = load_pretrained_3d_cnn()
cnn_features = extract_3d_cnn_features(nodule_rois, pretrained_model)

4.2 数据增强

增强3D ROI多样性,缓解小样本问题:

  • 几何变换:3D旋转、平移、缩放。
  • 强度变换:随机亮度、对比度调整。
  • 代码示例
from scipy.ndimage import rotate, zoom

def augment_3d_roi(roi):
    # 随机旋转
    angle = np.random.uniform(-10, 10)
    roi = rotate(roi, angle, axes=(0, 1), reshape=False)
    # 随机缩放
    scale = np.random.uniform(0.9, 1.1)
    roi = zoom(roi, (scale, scale, scale, 1))
    # 随机亮度调整
    roi = roi + np.random.uniform(-0.1, 0.1)
    roi = np.clip(roi, 0, 1)
    return roi

augmented_rois = [augment_3d_roi(roi) for roi in nodule_rois]

4.3 注意力机制

引入注意力模块(如SE-Net或CBAM),聚焦结节关键区域:

  • SE-Net:通道注意力,增强重要特征通道。
  • 实现
from tensorflow.keras.layers import GlobalAveragePooling3D, Dense, Multiply

def se_block(input_tensor, reduction=4):
    channels = input_tensor.shape[-1]
    x = GlobalAveragePooling3D()(input_tensor)
    x = Dense(channels // reduction, activation='relu')(x)
    x = Dense(channels, activation='sigmoid')(x)
    x = tf.expand_dims(tf.expand_dims(tf.expand_dims(x, 1), 1), 1)
    return Multiply()([input_tensor, x])

# 修改3D-CNN,添加SE块
def build_3d_cnn_with_se(input_shape=(32, 32, 32, 1)):
    inputs = Input(shape=input_shape)
    x = Conv3D(32, (3, 3, 3), activation='relu', padding='same')(inputs)
    x = se_block(x)
    x = BatchNormalization()(x)
    x = MaxPooling3D((2, 2, 2))(x)
    x = Conv3D(64, (3, 3, 3), activation='relu', padding='same')(x)
    x = se_block(x)
    x = BatchNormalization()(x)
    x = MaxPooling3D((2, 2, 2))(x)
    x = GlobalAveragePooling3D()(x)
    x = Dense(128, activation='relu')(x)
    x = Dropout(0.5)(x)
    model = Model(inputs, x)
    return model

se_model = build_3d_cnn_with_se()

4.4 特征降维

深度特征维度高(如128维),可能导致SVM训练缓慢或过拟合:

  • PCA:保留90%方差的成分。
  • UMAP:非线性降维,保留局部结构。
from sklearn.decomposition import PCA

pca = PCA(n_components=0.9)  # 保留90%方差
features_reduced = pca.fit_transform(features_scaled)

4.5 混合特征

结合深度特征和传统特征(如GLCM、形状),提升模型鲁棒性:

def extract_glcm_features(roi):
    roi_int = (roi[..., 0] * 255).astype(np.uint8)
    glcm = graycomatrix(roi_int, distances=[1], angles=[0, np.pi/4, np.pi/2, 3*np.pi/4],
                        levels=256, symmetric=True, normed=True)
    features = []
    for prop in ['contrast', 'dissimilarity', 'homogeneity', 'energy', 'correlation']:
        feat = graycoprops(glcm, prop).ravel()
        features.append(feat)
    return np.hstack(features)

# 混合特征
glcm_features = [extract_glcm_features(roi) for roi in nodule_rois]
hybrid_features = np.hstack([cnn_features, glcm_features])

五、完整代码示例

以下是整合3D-CNN深度特征提取和SVM多分类的完整代码:

import pydicom
import numpy as np
from skimage.feature import graycomatrix, graycoprops
from skimage.transform import resize
import tensorflow as tf
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Conv3D, MaxPooling3D, BatchNormalization, GlobalAveragePooling3D, Dense, Dropout, Input
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import classification_report, confusion_matrix
from imblearn.over_sampling import SMOTE
import matplotlib.pyplot as plt
import seaborn as sns

# 1. 3D-CNN模型定义
def build_3d_cnn_feature_extractor(input_shape=(32, 32, 32, 1)):
    inputs = Input(shape=input_shape)
    x = Conv3D(32, (3, 3, 3), activation='relu', padding='same')(inputs)
    x = BatchNormalization()(x)
    x = MaxPooling3D((2, 2, 2))(x)
    x = Conv3D(64, (3, 3, 3), activation='relu', padding='same')(x)
    x = BatchNormalization()(x)
    x = MaxPooling3D((2, 2, 2))(x)
    x = GlobalAveragePooling3D()(x)
    x = Dense(128, activation='relu')(x)
    x = Dropout(0.5)(x)
    model = Model(inputs, x, name='3d_cnn_feature_extractor')
    return model

# 2. 数据加载与预处理
def load_dicom_series(dicom_path):
    slices = [pydicom.dcmread(f) for f in dicom_path]
    slices.sort(key=lambda x: float(x.ImagePositionPatient[2]))
    image_3d = np.stack([s.pixel_array for s in slices])
    return image_3d

def preprocess_ct(image_3d, nodule_coords, size=(32, 32, 32)):
    x, y, z = nodule_coords
    roi = image_3d[z-16:z+16, y-16:y+16, x-16:x+16]
    roi = resize(roi, size, anti_aliasing=True)
    roi = (roi - np.min(roi)) / (np.max(roi) - np.min(roi) + 1e-8)
    return roi[..., np.newaxis]

def generate_labels(scores):
    avg_score = np.mean(scores)
    if avg_score <= 2:
        return 0
    elif avg_score < 4:
        return 1
    else:
        return 2

# 假设数据
dicom_paths = [...]
nodule_annotations = [...]
nodule_scores = [...]

ct_images = [load_dicom_series(path) for path in dicom_paths]
nodule_rois = [preprocess_ct(img, coords) for img, coords in zip(ct_images, nodule_annotations)]
labels = [generate_labels(scores) for scores in nodule_scores]

# 3. 深度特征提取
feature_extractor = build_3d_cnn_feature_extractor()
cnn_features = extract_3d_cnn_features(nodule_rois, feature_extractor)
labels = np.array(labels)

# 4. 特征标准化与不平衡处理
scaler = StandardScaler()
features_scaled = scaler.fit_transform(cnn_features)
smote = SMOTE(random_state=42, k_neighbors=3)
features_resampled, labels_resampled = smote.fit_resample(features_scaled, labels)

# 5. SVM训练
X_train, X_test, y_train, y_test = train_test_split(
    features_resampled, labels_resampled, test_size=0.2, random_state=42, stratify=labels_resampled
)
svm = SVC(kernel='rbf', decision_function_shape='ovo', class_weight='balanced', probability=True)
param_grid = {'C': [0.1, 1, 10], 'gamma': ['scale', 0.01, 0.1]}
grid_search = GridSearchCV(svm, param_grid, cv=5, scoring='f1_macro', n_jobs=-1)
grid_search.fit(X_train, y_train)

# 输出结果
print("最佳参数:", grid_search.best_params_)
print("最佳宏平均F1分数:", grid_search.best_score_)

# 6. 评估与可视化
best_model = grid_search.best_estimator_
y_pred = best_model.predict(X_test)
print("测试集分类报告:\n", classification_report(y_test, y_pred, target_names=['Benign', 'Suspicious', 'Malignant']))
cm = confusion_matrix(y_test, y_pred)
plt.figure(figsize=(8, 6))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',
            xticklabels=['Benign', 'Suspicious', 'Malignant'],
            yticklabels=['Benign', 'Suspicious', 'Malignant'])
plt.title('Confusion Matrix for 3D-CNN+SVM Multi-Class Classification')
plt.xlabel('Predicted Label')
plt.ylabel('True Label')
plt.show()

六、深度特征与传统特征的对比

方面 传统特征(GLCM+形状) 深度特征(3D-CNN)
特征提取方式 手工设计,依赖领域知识 自动学习,端到端特征提取
表示能力 有限,难以捕捉复杂体视模式 强大,层次化捕捉纹理、形态
可疑结节性能 召回率较低,易混淆良性/恶性 召回率较高,区分能力强
计算成本 较低,适合小规模数据 较高,需GPU加速
样本需求 少量样本即可 需更多样本或迁移学习
宏F1(示例) ≈ 0.75 ≈ 0.82

混合特征建议:结合深度特征和传统特征(如GLCM的对比度、形状的体积),可进一步提升性能,尤其在小样本场景。


七、挑战与应对措施

  1. 小样本过拟合
    • 应对:迁移学习、数据增强、Dropout、轻量级模型。
  2. 计算资源限制
    • 应对:使用预训练模型、特征降维、批量处理。
  3. 可疑结节模糊性
    • 应对:注意力机制、混合特征、模糊SVM。
  4. 特征可解释性
    • 应对:SHAP分析、支持向量检查、Grad-CAM可视化。

Grad-CAM示例(可视化3D-CNN关注的结节区域):

from tensorflow.keras.models import Model
import cv2

def get_gradcam_heatmap(model, roi, class_idx):
    with tf.GradientTape() as tape:
        last_conv_layer = model.get_layer('conv3d_1')  # 假设第二卷积层
        grad_model = Model(model.inputs, [last_conv_layer.output, model.output])
        conv_outputs, predictions = grad_model(np.expand_dims(roi, axis=0))
        loss = predictions[:, class_idx]
    grads = tape.gradient(loss, conv_outputs)[0]
    pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2, 3))
    conv_outputs = conv_outputs[0]
    heatmap = tf.reduce_sum(tf.multiply(pooled_grads, conv_outputs), axis=-1)
    heatmap = np.maximum(heatmap, 0) / np.max(heatmap)
    return heatmap

# 可视化热图(示例切片)
heatmap = get_gradcam_heatmap(feature_extractor, nodule_rois[0], class_idx=1)
plt.imshow(heatmap[16], cmap='jet')  # 中间切片
plt.colorbar()
plt.title('Grad-CAM Heatmap for Suspicious Nodule')
plt.show()

八、流程图

原始CT图像
预处理: 肺分割/归一化
结节定位: 裁剪ROI
数据增强: 3D旋转/缩放
3D-CNN: 深度特征提取
特征标准化
SMOTE过采样
SVM训练: OVO策略
网格搜索优化C, γ
模型评估: 宏F1/混淆矩阵
特征重要性分析: SHAP/Grad-CAM
预测新结节

九、前沿进展与未来方向

  1. 自监督学习:使用LIDC-IDRI的无标注数据进行自监督预训练,增强特征表示。
  2. 多模态融合:结合CT和PET图像,提取多模态深度特征。
  3. Transformers:尝试3D Vision Transformers(如ViT)替代CNN,捕捉全局依赖。
  4. 自动化超参数调优:使用贝叶斯优化替代网格搜索,提升效率。

十、总结与最佳实践

深度特征提取通过3D-CNN显著提升了LIDC-IDRI多分类任务的性能,尤其对可疑结节的区分能力。核心优势包括:

  • 强大表示能力:捕捉复杂体视模式。
  • 灵活性:结合SVM,适应小样本场景。
  • 可扩展性:支持迁移学习和混合特征。

最佳实践建议

  1. 模型选择:轻量级3D-CNN(如文中设计),或预训练3D-ResNet。
  2. 数据增强:3D旋转、缩放、亮度调整,增加样本多样性。
  3. 注意力机制:SE-Net或CBAM,聚焦关键区域。
  4. 混合特征:结合GLCM和深度特征,提升鲁棒性。
  5. 特征分析:SHAP和Grad-CAM,确保模型可解释性。