############## A. 配置环境 ##############
pip install ultralytics grad-cam
修改 /home/wkmgc/miniconda3/envs/SMP/lib/python3.9/site-packages/pytorch_grad_cam/base_cam.py
将
        if targets is None:
            target_categories = np.argmax(outputs.cpu().data.numpy(), axis=-1)
            targets = [ClassifierOutputTarget(category) for category in target_categories]
变为
        if targets is None:
            # 循环解包，直到找到第一个非元组的元素，这可以处理嵌套元组，例如 ((Tensor, ...), ...)
            processed_outputs = outputs
            print(f"DEBUG: 原始 outputs 类型: {type(processed_outputs)}")
            while isinstance(processed_outputs, tuple):
                if len(processed_outputs) == 0:
                    # 如果遇到一个空元组，我们就无法继续，打印错误并退出循环
                    print(f"ERROR: 在解包时遇到空元组。原始 outputs: {outputs}")
                    break
                print(f"DEBUG: 正在解包元组... 选择第 0 个元素。")
                processed_outputs = processed_outputs[0] # 逐次选择第一个元素
            print(f"DEBUG: 最终选定的 outputs 类型: {type(processed_outputs)}")

            # 现在，processed_outputs 应该是我们需要的张量 (Tensor)
            try:
                target_categories = np.argmax(processed_outputs.cpu().data.numpy(), axis=-1)
                targets = [ClassifierOutputTarget(category) for category in target_categories]
            except AttributeError as e:
                print(f"ERROR: 最终选定的元素 (类型: {type(processed_outputs)}) 无法处理。")
                print(f"       它没有 .cpu() 属性。原始错误: {e}")
                print(f"       请检查您的模型输出结构。原始 outputs: {outputs}")
                raise e # 重新抛出异常，以便程序停止

############## B. 数据集构建（可选） ##############
参考：./Yolo数据集构建

############## C. Train 训练程序 ##############
# A. 第一次训练开一个梯子【需要下载内容】
export https_proxy=http://127.0.0.1:1080 http_proxy=http://127.0.0.1:1080
CUDA_VISIBLE_DEVICES=0 python train.py --model {YOLOv8n-seg, YOLOv8s-seg, YOLOv8m-seg, YOLOv8l-seg, YOLOv8x-seg, YOLOv9e-seg, YOLOv9c-seg, YOLO11l-seg, YOLO11n-seg, YOLO11s-seg, YOLO11m-seg, YOLO11x-seg, YOLO12-seg, YOLO12-seg}

# B. 运行单个训练程序
1. 在 dataset.yaml 中修改 训练数据集；CUDA_VISIBLE_DEVICES修改使用显卡；--model 修改算法；
2. CUDA_VISIBLE_DEVICES=0 python yolo_train.py --model "YOLOv8n-seg"

# C. 批量运行训练程序
1. train.sh 修改想让它使用的显卡、算法；
2. bash yolo_train.sh
3. 会生成 ./yolo_logs_parallel_DATE 的终端记录文件；结果先存储在 ../DataSet_Public_outputs/DATASET-Yolo 后自动移动到 ../Hardisk/DATASET_outputs-SegModel 中

############## D. Predict 推理程序 ##############
# A. 预先步骤：将模型同步到 Nas_BackUp_Seg 或 ./Hardisk 文件夹中【cd .. && bash ./Back_Up.sh】
# B1. 将最优模型文件从 ./Nas_BackUp_Seg 移动到 ./BestMode_Predict_Results_DataSet_Public 指定文件夹中
bash ./Tool_Yolo_Copy_Best_Model.sh --pt_name "best.pt" # "epoch100.pt" # 修改里面的路径
# B2. 如果需要处理自定义数据集，请将模型文件夹手动复制为 ./BestMode_Predict_Results_DataSet_Public/DATASET-Yolo 中
可以先对原有 ./BestMode_Predict_Results_DataSet_Public/ORI_DATASET-Yolo 临时改名
运行 bash ./Tool_Yolo_Copy_Best_Model.sh --pt_name "best.pt" # "epoch100.pt" # 修改里面的路径
在将生成的 ./BestMode_Predict_Results_DataSet_Public/ORI_DATASET-Yolo 改为 ./BestMode_Predict_Results_DataSet_Public/DATASET-Yolo
# C. 运行单个推理程序
1. 在 dataset.yaml 中修改 预测数据集 及 val/test； yolo_config.py 中需修改模型保存路径 PREDICT_ALL_BEST_MODELS_DIR/PREDICT_BEST_MODEL_DIR；CUDA_VISIBLE_DEVICES修改使用显卡；--model 修改算法；
2. CUDA_VISIBLE_DEVICES=0 python yolo_predict_V1_NoColor.py --model "YOLOv8n-seg"
CUDA_VISIBLE_DEVICES=0 python yolo_predict_V2.py --model "YOLOv8n-seg" --conf 0.2 --pt_name "epoch100.pt" # "epoch100.pt" # "best.pt"
# D. 批量运行推理程序(分割图可视化 或 热图可视化)
1. yolo_predict.sh 修改想让它使用的显卡、算法；
2. bash yolo_predict.sh --conf 0.2 --pt_name "epoch100.pt" # "best.pt"（默认）# 分割图可视化
3. bash yolo_predict.sh --conf 0.2 --heatmap_method "All"  --pt_name "epoch100.pt" # "best.pt"（默认）# 热图可视化
4. 会生成 ./yolo_predict_logs_parallel_DATE 的终端记录文件；结果存储在 ../BestMode_Predict_Results_DataSet_Public/DATASET-Yolo 中
# E. 横向对比训练结果
1. 将模型结果进行横向对比(生成color_mask、Yolo_result的横向对比)
python yolo_predict_V2_compare_all.py --pt_name "all" # "epoch100.pt" # "best.pt" # "all"（默认）

############## E. Predict_raw_img_Check 检测推理输出图片是否齐全 ##############
# 检测 dataset.yaml path/"labels"/test.name 和 yolo_config.PREDICT_BEST_MODEL_DIR/****/predicted_raw_masks 中图片是否匹配
1. 在 dataset.yaml 中修改 path、test；在yolo_config.PREDICT_ALL_BEST_MODELS_DIR；CUDA_VISIBLE_DEVICES修改使用显卡；
2. python yolo_predict_raw_masks_check.py --pt_name "best.pt" # "epoch100.pt" # "best.pt"（默认）

############## F. 神经网络热图可视化，目前只支持EigenCAM（无指定类别的方法） ##############
# A. 预先步骤：cd ./Yolo可视化测试；
python yolo_layer_tester.py --model "YOLO12-seg" --cam_method "GradCAM" --pt_name "best.pt" # 测试各个层是否能成功生成热图，选择合适的层
vim ../yolo_predict_visualize_nn.py # 修改 visualize_nn_comprehensive 中 model_key.lower().startswith("yoloXXX") 的部分，添加对应模型的默认层
# B. 运行单个热图可视化程序
# YOLOv8n-seg,YOLOv8s-seg,YOLOv8m-seg,YOLOv8l-seg,YOLOv8x-seg,YOLOv9c-seg,YOLOv9e-seg,YOLO11n-seg,YOLO11s-seg,YOLO11m-seg,YOLO11l-seg,YOLO11x-seg,YOLO12-seg
python yolo_predict_visualize_nn.py --model "YOLO11m-seg" --target_layers "default" --cam_method "All" --pt_name "best.pt" # "epoch100.pt" # "best.pt"

############## G.※ 快速进行分割实验 ※ ##############
# 1. 修改 dataset.yaml 中 训练数据集、修改 yolo_config.py 中 EPOCHS、PATIENCE
cd ~/Desktop/Seg/Seg_All_In_One_YoloModel
# 2. 批量化训练
bash yolo_train.sh 
# 3. 复制最优模型到预测文件夹
bash ./Tool_Yolo_Copy_Best_Model.sh --pt_name "best.pt" && bash ./Tool_Yolo_Copy_Best_Model.sh --pt_name "epoch100.pt"
# 4. 批量化预测+热度图可视化
bash yolo_predict.sh --conf 0.2 --pt_name "epoch100.pt" && bash yolo_predict.sh --conf 0.2 
bash ./yolo_predict.sh --heatmap_method "All" && bash ./yolo_predict.sh --pt_name "epoch100.pt"  --heatmap_method "All"
# 5. 横向对比结果
python yolo_predict_V2_compare_all.py 
# 6. 打包预测结果(不包含*.pt模型文件)
cd /home/wkmgc/Desktop/Seg/BestMode_Predict_Results_DataSet_Public/
zip -r /home/wkmgc/Desktop/5_My_Gastric_2025_10_29_938-Yolo.zip 5_My_Gastric_2025_10_29_938*-Yolo -x "*.pt"
# 7. 打包训练结果(只有.png、.jpg、.csv文件)
cd /home/wkmgc/Desktop/Seg/Hardisk/
zip -r /home/wkmgc/Desktop/5_My_Gastric_2025_10_29_938-Yolo_train.zip 5_My_Gastric_2025_10_29_938-Yolo -i \*.png \*.jpg \*.csv