[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"similar-baidu-research--NCRF":3,"tool-baidu-research--NCRF":64},[4,17,27,35,43,56],{"id":5,"name":6,"github_repo":7,"description_zh":8,"stars":9,"difficulty_score":10,"last_commit_at":11,"category_tags":12,"status":16},3808,"stable-diffusion-webui","AUTOMATIC1111\u002Fstable-diffusion-webui","stable-diffusion-webui 是一个基于 Gradio 构建的网页版操作界面，旨在让用户能够轻松地在本地运行和使用强大的 Stable Diffusion 图像生成模型。它解决了原始模型依赖命令行、操作门槛高且功能分散的痛点，将复杂的 AI 绘图流程整合进一个直观易用的图形化平台。\n\n无论是希望快速上手的普通创作者、需要精细控制画面细节的设计师，还是想要深入探索模型潜力的开发者与研究人员，都能从中获益。其核心亮点在于极高的功能丰富度：不仅支持文生图、图生图、局部重绘（Inpainting）和外绘（Outpainting）等基础模式，还独创了注意力机制调整、提示词矩阵、负向提示词以及“高清修复”等高级功能。此外，它内置了 GFPGAN 和 CodeFormer 等人脸修复工具，支持多种神经网络放大算法，并允许用户通过插件系统无限扩展能力。即使是显存有限的设备，stable-diffusion-webui 也提供了相应的优化选项，让高质量的 AI 艺术创作变得触手可及。",162132,3,"2026-04-05T11:01:52",[13,14,15],"开发框架","图像","Agent","ready",{"id":18,"name":19,"github_repo":20,"description_zh":21,"stars":22,"difficulty_score":23,"last_commit_at":24,"category_tags":25,"status":16},1381,"everything-claude-code","affaan-m\u002Feverything-claude-code","everything-claude-code 是一套专为 AI 编程助手（如 Claude Code、Codex、Cursor 等）打造的高性能优化系统。它不仅仅是一组配置文件，而是一个经过长期实战打磨的完整框架，旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。\n\n通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能，everything-claude-code 能显著提升 AI 在复杂任务中的表现，帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略，使得模型响应更快、成本更低，同时有效防御潜在的攻击向量。\n\n这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库，还是需要 AI 协助进行安全审计与自动化测试，everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目，它融合了多语言支持与丰富的实战钩子（hooks），让 AI 真正成长为懂上",138956,2,"2026-04-05T11:33:21",[13,15,26],"语言模型",{"id":28,"name":29,"github_repo":30,"description_zh":31,"stars":32,"difficulty_score":23,"last_commit_at":33,"category_tags":34,"status":16},2271,"ComfyUI","Comfy-Org\u002FComfyUI","ComfyUI 是一款功能强大且高度模块化的视觉 AI 引擎，专为设计和执行复杂的 Stable Diffusion 图像生成流程而打造。它摒弃了传统的代码编写模式，采用直观的节点式流程图界面，让用户通过连接不同的功能模块即可构建个性化的生成管线。\n\n这一设计巧妙解决了高级 AI 绘图工作流配置复杂、灵活性不足的痛点。用户无需具备编程背景，也能自由组合模型、调整参数并实时预览效果，轻松实现从基础文生图到多步骤高清修复等各类复杂任务。ComfyUI 拥有极佳的兼容性，不仅支持 Windows、macOS 和 Linux 全平台，还广泛适配 NVIDIA、AMD、Intel 及苹果 Silicon 等多种硬件架构，并率先支持 SDXL、Flux、SD3 等前沿模型。\n\n无论是希望深入探索算法潜力的研究人员和开发者，还是追求极致创作自由度的设计师与资深 AI 绘画爱好者，ComfyUI 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能，使其成为当前最灵活、生态最丰富的开源扩散模型工具之一，帮助用户将创意高效转化为现实。",107662,"2026-04-03T11:11:01",[13,14,15],{"id":36,"name":37,"github_repo":38,"description_zh":39,"stars":40,"difficulty_score":23,"last_commit_at":41,"category_tags":42,"status":16},3704,"NextChat","ChatGPTNextWeb\u002FNextChat","NextChat 是一款轻量且极速的 AI 助手，旨在为用户提供流畅、跨平台的大模型交互体验。它完美解决了用户在多设备间切换时难以保持对话连续性，以及面对众多 AI 模型不知如何统一管理的痛点。无论是日常办公、学习辅助还是创意激发，NextChat 都能让用户随时随地通过网页、iOS、Android、Windows、MacOS 或 Linux 端无缝接入智能服务。\n\n这款工具非常适合普通用户、学生、职场人士以及需要私有化部署的企业团队使用。对于开发者而言，它也提供了便捷的自托管方案，支持一键部署到 Vercel 或 Zeabur 等平台。\n\nNextChat 的核心亮点在于其广泛的模型兼容性，原生支持 Claude、DeepSeek、GPT-4 及 Gemini Pro 等主流大模型，让用户在一个界面即可自由切换不同 AI 能力。此外，它还率先支持 MCP（Model Context Protocol）协议，增强了上下文处理能力。针对企业用户，NextChat 提供专业版解决方案，具备品牌定制、细粒度权限控制、内部知识库整合及安全审计等功能，满足公司对数据隐私和个性化管理的高标准要求。",87618,"2026-04-05T07:20:52",[13,26],{"id":44,"name":45,"github_repo":46,"description_zh":47,"stars":48,"difficulty_score":23,"last_commit_at":49,"category_tags":50,"status":16},2268,"ML-For-Beginners","microsoft\u002FML-For-Beginners","ML-For-Beginners 是由微软推出的一套系统化机器学习入门课程，旨在帮助零基础用户轻松掌握经典机器学习知识。这套课程将学习路径规划为 12 周，包含 26 节精炼课程和 52 道配套测验，内容涵盖从基础概念到实际应用的完整流程，有效解决了初学者面对庞大知识体系时无从下手、缺乏结构化指导的痛点。\n\n无论是希望转型的开发者、需要补充算法背景的研究人员，还是对人工智能充满好奇的普通爱好者，都能从中受益。课程不仅提供了清晰的理论讲解，还强调动手实践，让用户在循序渐进中建立扎实的技能基础。其独特的亮点在于强大的多语言支持，通过自动化机制提供了包括简体中文在内的 50 多种语言版本，极大地降低了全球不同背景用户的学习门槛。此外，项目采用开源协作模式，社区活跃且内容持续更新，确保学习者能获取前沿且准确的技术资讯。如果你正寻找一条清晰、友好且专业的机器学习入门之路，ML-For-Beginners 将是理想的起点。",84991,"2026-04-05T10:45:23",[14,51,52,53,15,54,26,13,55],"数据工具","视频","插件","其他","音频",{"id":57,"name":58,"github_repo":59,"description_zh":60,"stars":61,"difficulty_score":10,"last_commit_at":62,"category_tags":63,"status":16},3128,"ragflow","infiniflow\u002Fragflow","RAGFlow 是一款领先的开源检索增强生成（RAG）引擎，旨在为大语言模型构建更精准、可靠的上下文层。它巧妙地将前沿的 RAG 技术与智能体（Agent）能力相结合，不仅支持从各类文档中高效提取知识，还能让模型基于这些知识进行逻辑推理和任务执行。\n\n在大模型应用中，幻觉问题和知识滞后是常见痛点。RAGFlow 通过深度解析复杂文档结构（如表格、图表及混合排版），显著提升了信息检索的准确度，从而有效减少模型“胡编乱造”的现象，确保回答既有据可依又具备时效性。其内置的智能体机制更进一步，使系统不仅能回答问题，还能自主规划步骤解决复杂问题。\n\n这款工具特别适合开发者、企业技术团队以及 AI 研究人员使用。无论是希望快速搭建私有知识库问答系统，还是致力于探索大模型在垂直领域落地的创新者，都能从中受益。RAGFlow 提供了可视化的工作流编排界面和灵活的 API 接口，既降低了非算法背景用户的上手门槛，也满足了专业开发者对系统深度定制的需求。作为基于 Apache 2.0 协议开源的项目，它正成为连接通用大模型与行业专有知识之间的重要桥梁。",77062,"2026-04-04T04:44:48",[15,14,13,26,54],{"id":65,"github_repo":66,"name":67,"description_en":68,"description_zh":69,"ai_summary_zh":69,"readme_en":70,"readme_zh":71,"quickstart_zh":72,"use_case_zh":73,"hero_image_url":74,"owner_login":75,"owner_name":76,"owner_avatar_url":77,"owner_bio":76,"owner_company":78,"owner_location":78,"owner_email":78,"owner_twitter":78,"owner_website":79,"owner_url":80,"languages":81,"stars":86,"forks":87,"last_commit_at":88,"license":89,"difficulty_score":90,"env_os":91,"env_gpu":92,"env_ram":93,"env_deps":94,"category_tags":107,"github_topics":108,"view_count":23,"oss_zip_url":78,"oss_zip_packed_at":78,"status":16,"created_at":114,"updated_at":115,"faqs":116,"releases":151},2974,"baidu-research\u002FNCRF","NCRF","Cancer metastasis detection with neural conditional random field (NCRF)","NCRF 是一款基于深度学习的开源工具，专为癌症转移检测而设计。它源自百度研究院的研究成果，核心目标是解决病理全切片图像（WSI）中微小肿瘤病灶难以精准定位的难题。通过引入“神经条件随机场”（Neural Conditional Random Field）这一独特技术，NCRF 不仅能识别图像中的肿瘤区域，还能有效整合上下文空间信息，显著降低误报率，提升检测的准确性与鲁棒性。\n\n该工具主要面向医学影像领域的研究人员、AI 开发者以及生物信息学专家。用户需要具备一定的编程基础（特别是 Python 和 PyTorch），并拥有相应的病理数据集（如 Camelyon16 挑战赛数据）才能运行训练与测试流程。NCRF 提供了从数据预处理、模型训练到结果可视化（如生成概率图、肿瘤定位及 FROC 评估）的完整代码框架，复现了相关学术论文的核心实验结果。对于致力于探索深度学习在数字病理诊断中应用的专业人士而言，NCRF 是一个极具参考价值的研究基线与实践平台。","![Baidu Logo](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fbaidu-research_NCRF_readme_1f594f75ad6e.png)\n\n- [NCRF](#ncrf)\n- [Prerequisites](#prerequisites)\n- [Data](#data)\n    - [Whole slide images](#whole-slide-images)\n    - [Annotations](#annotations)\n    - [Patch images](#patch-images)\n- [Model](#model)\n- [Training](#training)\n- [Testing](#testing)\n    - [Tissue mask](#tissue-mask)\n    - [Probability map](#probability-map)\n    - [Tumor localization](#tumor-localization)\n    - [FROC evaluation](#froc-evaluation)\n\n\n# NCRF\nThis repository contains the code and data to reproduce the main results from the paper:\n\n[Yi Li and Wei Ping. Cancer Metastasis Detection With Neural Conditional Random Field. Medical Imaging with Deep Learning (MIDL), 2018.](https:\u002F\u002Fopenreview.net\u002Fforum?id=S1aY66iiM)\n\nIf you find the code\u002Fdata is useful, please cite the above paper:\n\n    @inproceedings{li2018cancer,\n        title={Cancer Metastasis Detection With Neural Conditional Random Field},\n        booktitle={Medical Imaging with Deep Learning},\n        author={Li, Yi and Ping, Wei},\n        year={2018}\n    }\n\nIf you have any quesions, please post it on github issues or email at yil8@uci.edu\n\n\n# Prerequisites\n* Python (3.6)\n\n* Numpy (1.14.3)\n\n* Scipy (1.0.1)\n\n* [PyTorch (0.3.1)\u002FCUDA 8.0](https:\u002F\u002Fpytorch.org\u002Fprevious-versions\u002F) The specific binary wheel file is [cu80\u002Ftorch-0.3.1-cp36-cp36m-linux_x86_64.whl](http:\u002F\u002Fdownload.pytorch.org\u002Fwhl\u002Fcu80\u002Ftorch-0.3.1-cp36-cp36m-linux_x86_64.whl). I havn't tested on other versions, especially 0.4+, wouldn't recommend using other versions.\n\n* torchvision (0.2.0)\n\n* PIL (5.1.0)\n\n* scikit-image (0.13.1)\n\n* [OpenSlide 3.4.1](https:\u002F\u002Fopenslide.org\u002F)(Please don't use 3.4.0 as some potential issues found on this version)\u002F[openslide-python (1.1.0)](https:\u002F\u002Fgithub.com\u002Fopenslide\u002Fopenslide-python)\n\n* matplotlib (2.2.2)\n\n* [tensorboardX](https:\u002F\u002Fgithub.com\u002Flanpa\u002Ftensorboard-pytorch) Standard along tensorboard that also works for PyTorch. This is mostly used in monitoring the training curves.\n\n* [QuPath](https:\u002F\u002Fqupath.github.io\u002F) Although not directly relevant to training\u002Ftesting models, I found it very useful to visualize the whole slide images.\n\nMost of the dependencies can be installed through pip install with version number, e.g. \n```\npip install 'numpy==1.14.3'\n```\nOr just simply\n```\npip install numpy\n```\nA [requirements.txt](requirements.txt) file is also provided, so that you can install most of the dependencies at once:\n```\npip install -r requirements.txt -i https:\u002F\u002Fpypi.python.org\u002Fsimple\u002F\n```\nFor PyTorch please consider downloading the specific wheel binary and use\n```\npip install torch-0.3.1-cp36-cp36m-linux_x86_64.whl\n```\n\n# Data\n## Whole slide images\nThe main data are the whole slide images (WSI) in `*.tif` format from the [Camelyon16](https:\u002F\u002Fcamelyon16.grand-challenge.org\u002F) challenge. You need to apply on [Camelyon16](https:\u002F\u002Fcamelyon16.grand-challenge.org\u002F) for data access, and once it's approved, you can download from either Google Drive, or Baidu Pan. Note that, one slide is usually ~100Kx100K pixels at level 0 and 1GB+ on disk. There are 400 slides in total, together about 700GB+. So make sure you have enough disk space. The tumor slides for training are named as `Tumor_XXX.tif`, where XXX ranges from 001 to 110. The normal slides for training are named as `Normal_XXX.tif`, where XXX ranges from 001 to 160. The slides for testing are named as `Test_XXX.tif` where XXX ranges from 001 to 130.\n\nOnce you download all the slides, please put all the tumor slides and normal slides for training under one same directory, e.g. named `\u002FWSI_TRAIN\u002F`.\n\n## Update\nIt seems the whole slide image `*tif` files are now application free to download at [GigaDB](http:\u002F\u002Fgigadb.org\u002Fdataset\u002F100439). But still please contact the Camelyon16 organizers for data usage.\n\n\n## Annotations\nThe Camelyon16 organizers also provides annotations of tumor regions for each tumor slide in xml format. I've converted them into some what simpler json format, located under [NCRF\u002Fjsons](\u002Fjsons\u002F). Each annotation is a list of polygons, where each polygon is represented by its vertices. Particularly, positive polygons mean tumor region and negative polygons mean normal regions. You can also use the following command to convert the xml format into the json format\n```\npython NCRF\u002Fwsi\u002Fbin\u002Fcamelyon16xml2json.py Tumor_001.xml Tumor_001.json\n```\n\n## Patch images\nAlthough the original 400 WSI files contain all the necessary information, they are not directly applicable to train a deep CNN. Therefore, we have to sample much smaller image patches, e.g. 256x256, that a typical deep CNN can handle. **Efficiently sampling informative and representative patches is one of the most critical parts to achieve good tumor detection performance.** To ease this process, I have included the coordinates of pre-sampled patches used in the paper for training within this repo. They are located at [NCRF\u002Fcoords](\u002Fcoords\u002F). Each one is a csv file, where each line within the file is in the format like `Tumor_024,25417,127565` that the last two numbers are (x, y) coordinates of the center of each patch at level 0. `tumor_train.txt` and `normal_train.txt` contains 200,000 coordinates respectively, and `tumor_valid.txt` and `normal_valid.txt` contains 20,000 coordinates respectively. Note that, coordinates of hard negative patches, typically around tissue boundary regions, are also included within `normal_train.txt` and `normal_valid.txt`. With the original WSI and pre-sampled coordinates, we can now generate image patches for training deep CNN models. Run the four commands below to generate the corresponding patches:\n```\npython NCRF\u002Fwsi\u002Fbin\u002Fpatch_gen.py \u002FWSI_TRAIN\u002F NCRF\u002Fcoords\u002Ftumor_train.txt \u002FPATCHES_TUMOR_TRAIN\u002F\npython NCRF\u002Fwsi\u002Fbin\u002Fpatch_gen.py \u002FWSI_TRAIN\u002F NCRF\u002Fcoords\u002Fnormal_train.txt \u002FPATCHES_NORMAL_TRAIN\u002F\npython NCRF\u002Fwsi\u002Fbin\u002Fpatch_gen.py \u002FWSI_TRAIN\u002F NCRF\u002Fcoords\u002Ftumor_valid.txt \u002FPATCHES_TUMOR_VALID\u002F\npython NCRF\u002Fwsi\u002Fbin\u002Fpatch_gen.py \u002FWSI_TRAIN\u002F NCRF\u002Fcoords\u002Fnormal_valid.txt \u002FPATCHES_NORMAL_VALID\u002F\n```\nwhere `\u002FWSI_TRAIN\u002F` is the path to the directory where you put all the WSI files for training as mentioned above, and `\u002FPATCHES_TUMOR_TRAIN\u002F` is the path to the directory to store generated tumor patches for training. Same naming applies to `\u002FPATCHES_NORMAL_TRAIN\u002F`, `\u002FPATCHES_TUMOR_VALID\u002F` and `\u002FPATCHES_NORMAL_VALID\u002F`. By default, each command is going to generate patches of size 768x768 at level 0 using 5 processes, where the center of each patch corresponds to the coordinates. Each 768x768 patch is going to be further split into a 3x3 grid of 256x256 patches, when the training algorithm that leverages CRF comes into play.\n\nNote that, generating 200,000 768x768 patches using 5 processes took me about 4.5 hours, and is about 202GB on disk. \n\n\n# Model\n![NCRF](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fbaidu-research_NCRF_readme_54acb28fa02c.png)\nThe core idea of NCRF is taking a grid of patches as input, e.g. 3x3, using CNN module to extract patch embeddings, and using CRF module to model their spatial correlations. The [CNN module](\u002Fwsi\u002Fmodel\u002Fresnet.py) is adopted from the standard ResNet released by torchvision (https:\u002F\u002Fgithub.com\u002Fpytorch\u002Fvision\u002Fblob\u002Fmaster\u002Ftorchvision\u002Fmodels\u002Fresnet.py). The major difference is during the forward pass that 1. the input tensor has one more dimension, 2. use the CRF module to smooth the logit of each patch using their embeddings.\n```python\ndef forward(self, x):\n    \"\"\"\n    Args:\n        x: 5D tensor with shape of\n        [batch_size, grid_size, 3, crop_size, crop_size],\n        where grid_size is the number of patches within a grid (e.g. 9 for\n        a 3x3 grid); crop_size is 224 by default for ResNet input;\n    Returns:\n        logits, 2D tensor with shape of [batch_size, grid_size], the logit\n        of each patch within the grid being tumor\n    \"\"\"\n    batch_size, grid_size, _, crop_size = x.shape[0:4]\n    # flatten grid_size dimension and combine it into batch dimension\n    x = x.view(-1, 3, crop_size, crop_size)\n\n    x = self.conv1(x)\n    x = self.bn1(x)\n    x = self.relu(x)\n    x = self.maxpool(x)\n\n    x = self.layer1(x)\n    x = self.layer2(x)\n    x = self.layer3(x)\n    x = self.layer4(x)\n\n    x = self.avgpool(x)\n    # feats means features, i.e. patch embeddings from ResNet\n    feats = x.view(x.size(0), -1)\n    logits = self.fc(feats)\n\n    # restore grid_size dimension for CRF\n    feats = feats.view((batch_size, grid_size, -1))\n    logits = logits.view((batch_size, grid_size, -1))\n\n    if self.crf:\n        logits = self.crf(feats, logits)\n\n    logits = torch.squeeze(logits)\n\n    return logits\n```\nThe [CRF module](\u002Fwsi\u002Fmodel\u002Flayers.py) only has one trainable parameter [W](\u002Fwsi\u002Fmodel\u002Flayers.py#L16) for pairwise potential between patches. You can plot the W from the ckpt file (see next section) of a trained CRF model by\n```\npython NCRF\u002Fwsi\u002Fbin\u002Fplot_W.py \u002FPATH_TO_MODEL\u002Fbest.ckpt\n```\nWhen the CRF model is well trained, W typically reflects the relative spatial positions between different patches within the input grid. For more details about the model, please refer to our paper.\n\u003Cp align=\"center\">\u003Cimg src=https:\u002F\u002Fgithub.com\u002Fbaidu-research\u002FNCRF\u002Fblob\u002Fmaster\u002Fdoc\u002FW.png width=\"50%\">\u003C\u002Fp>\n\n\n# Training\nWith the generated patch images, we can now train the model by the following command\n```\npython NCRF\u002Fwsi\u002Fbin\u002Ftrain.py \u002FCFG_PATH\u002Fcfg.json \u002FSAVE_PATH\u002F\n```\nwhere `\u002FCFG_PATH\u002F` is the path to the config file in json format, and `\u002FSAVE_PATH\u002F` is where you want to save your model in checkpoint(ckpt) format. Two config files are provided at [NCRF\u002Fconfigs](\u002Fconfigs\u002F), one is for ResNet-18 with CRF\n```json\n{\n \"model\": \"resnet18\",\n \"use_crf\": true,\n \"batch_size\": 10,\n \"image_size\": 768,\n \"patch_size\": 256,\n \"crop_size\": 224,\n \"lr\": 0.001,\n \"momentum\": 0.9,\n \"data_path_tumor_train\": \"\u002FPATCHES_TUMOR_TRAIN\u002F\",\n \"data_path_normal_train\": \"\u002FPATCHES_NORMAL_TRAIN\u002F\",\n \"data_path_tumor_valid\": \"\u002FPATCHES_TUMOR_VALID\u002F\",\n \"data_path_normal_valid\": \"\u002FPATCHES_NORMAL_VALID\u002F\",\n \"json_path_train\": \"NCRF\u002Fjsons\u002Ftrain\",\n \"json_path_valid\": \"NCRF\u002Fjsons\u002Fvalid\",\n \"epoch\": 20,\n \"log_every\": 100\n}\n```\nPlease modify `\u002FPATCHES_TUMOR_TRAIN\u002F`, `\u002FPATCHES_NORMAL_TRAIN\u002F`, `\u002FPATCHES_TUMOR_VALID\u002F`, `\u002FPATCHES_NORMAL_VALID\u002F` respectively to your own path of generated patch images. Please also modify `NCRF\u002Fjsons\u002Ftrain` and `NCRF\u002Fjsons\u002Fvalid` with respect to the full path to the NCRF repo on your machine. The other config file is for ResNet-18 without CRF (the baseline model). \n\nBy default, `train.py` use 1 GPU (GPU_0) to train model, 2 processes for load tumor patch images, and 2 processes to load normal patch images. On one GTX 1080Ti, it took about 5 hours to train 1 epoch, and 4 days to finish 20 epoches. You can also use tensorboard to monitor the training process\n```\ntensorboard --logdir \u002FSAVE_PATH\u002F\n```\n![training_acc](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fbaidu-research_NCRF_readme_70b0297bb3a4.png)\nTypically, you will observe the CRF model consistently achieves higher training accuracy than the baseline model.\n\n`train.py` will generate a `train.ckpt`, which is the most recently saved model, and a `best.ckpt`, which is the model with the best validation accuracy. We also provide the best.ckpt of pretained resnet18_base and resnet18_crf at [NCRF\u002Fckpt](\u002Fckpt\u002F). \n\n\n# Testing\n## Tissue mask\nThe main testing results from a trained model for WSI analysis is the probability map that represents where on the WSI the model thinks is tumor region. Naively, we can use a sliding window fashion that predicts the probability of all the patches being tumor or not across the whole slide image. But since most part of the WSI is actually white background region, lots of computation is wasted in this sliding window fashion. Instead, we first compute a binary tissue mask that represent each patch is tissue or background, and then tumor prediction is only performed on tissue region. A typical WSI and its tissue mask looks like this (Test_026)\n![tissue_mask](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fbaidu-research_NCRF_readme_0603800cee0e.png)\nTo obtain the tissue mask of a given input WSI, e.g. Test_026.tif, run the following command\n```\npython NCRF\u002Fwsi\u002Fbin\u002Ftissue_mask.py \u002FWSI_PATH\u002FTest_026.tif \u002FMASK_PATH\u002FTest_026.npy\n```\nwhere `\u002FWSI_PATH\u002F` is the path to the WSI you are interested, and `\u002FMASK_PATH\u002F` is the path where you want to save the generated tissue mask in numpy format. By default, the tissue mask is generated at level 6, corresponding to the inference stride of 64, i.e. making a prediction every 64 pixels at level 0.\n\nThe tissue mask of [Test_026_tissue_mask.npy](https:\u002F\u002Fdrive.google.com\u002Ffile\u002Fd\u002F1BdOJGeag7kq8_p1NqU_v-EQcV_OxHgcW\u002Fview) at level 6 is attached for comparison. Note that, when you plot it using matplotlib.pyplot.imshow, please transpose it.\n\n\n## Probability map\nWith the generated tissue mask, we can now obtain the probability map of a given WSI, e.g. Test_026.tif, using a trained model:\n```\npython NCRF\u002Fwsi\u002Fbin\u002Fprobs_map.py \u002FWSI_PATH\u002FTest_026.tif \u002FCKPT_PATH\u002Fbest.ckpt \u002FCFG_PATH\u002Fcfg.json \u002FMASK_PATH\u002FTest_026.npy \u002FPROBS_MAP_PATH\u002FTest_026.npy\n```\nwhere `\u002FWSI_PATH\u002F` is the path to the WSI you are interested. `\u002FCKPT_PATH\u002F` is where you saved your trained model and best.ckpt corresponds to the model with the best validation accuracy. `\u002FCFG_PATH\u002F` is the path to the config file of the trained model in json format, and is typically the same as `\u002FCKPT_PATH\u002F`. `\u002FMASK_PATH\u002F` is where you saved the generated tissue mask. `\u002FPROBS_MAP_PATH\u002F` is where you want to save the generated probability map in numpy format.\n\nBy defautl, `probs_map.py` use GPU_0 for interence, 5 processes for data loading. Note that, although we load a grid of patches, e.g. 3x3, only the predicted probability of the center patch is retained for easy implementation. And because of this heavy computational overhead, it takes 0.5-1 hour to obtain the probability map of one WSI. We are thinking about developing more efficient inference algorithm for obtaining probability maps.\n![probability_map](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fbaidu-research_NCRF_readme_9514b55f71bb.png)\nThis figure shows the probability maps of Test_026 with different settings: (a) original WSI, (b) ground truth annotation, (c) baseline method, (d) baseline method with hard negative mining, (e) NCRF with hard negative mining. We can see the probability map from the baseline method typically has lots of isolated false positives. Hard negative mining significantly reduces the number of false positives for the baseline method, but the probability density among the ground truth tumor regions is also decreased, which decreases model sensitivity. NCRF with hard negative mining not only achieves low false positives but also maintains high probability density among the ground truth tumor regions with sharp boundaries.\n\nThe probability map of [Test_026_probs_map.npy](https:\u002F\u002Fdrive.google.com\u002Ffile\u002Fd\u002F1RLhzfhfxBkspbZmt1SXl9DS_LVi1XcxU\u002Fview) at level 6 is attached for comparison. Note that, when you plot it using matplotlib.pyplot.imshow, please transpose it.\n\n## Tumor localization\nWe use non-maximal suppression (nms) algorithm to obtain the coordinates of each detectd tumor region at level 0 given a probability map.\n```\npython NCRF\u002Fwsi\u002Fbin\u002Fnms.py \u002FPROBS_MAP_PATH\u002FTest_026.npy \u002FCOORD_PATH\u002FTest_026.csv\n```\nwhere `\u002FPROBS_MAP_PATH\u002F` is where you saved the generated probability map, and `\u002FCOORD_PATH\u002F` is where you want to save the generated coordinates of each tumor regions at level 0 in csv format. There is an optional command `--level` with default value 6, and make sure it's consistent with the level used for the corresponding tissue mask and probability map.\n\n\n## FROC evaluation\nWith the coordinates of tumor regions for each test WSI, we can finally evaluate the average FROC score of tumor localization.\n```\npython NCRF\u002Fwsi\u002Fbin\u002FEvaluation_FROC.py \u002FTEST_MASK\u002F \u002FCOORD_PATH\u002F\n```\n`\u002FTEST_MASK\u002F` is where you put the ground truth tif mask files of the test set, and `\u002FCOORD_PATH\u002F` is where you saved the generated tumor coordinates. `Evaluation_FROC.py` is based on the evaluation code provided by the Camelyon16 organizers with minor modification. Note, Test_049 and Test_114 are excluded from the evaluation as noted by the Camelyon16 organizers.\n\n","![百度Logo](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fbaidu-research_NCRF_readme_1f594f75ad6e.png)\n\n- [NCRF](#ncrf)\n- [前提条件](#prerequisites)\n- [数据](#data)\n    - [全切片图像](#whole-slide-images)\n    - [标注](#annotations)\n    - [补丁图像](#patch-images)\n- [模型](#model)\n- [训练](#training)\n- [测试](#testing)\n    - [组织掩膜](#tissue-mask)\n    - [概率图](#probability-map)\n    - [肿瘤定位](#tumor-localization)\n    - [FROC评估](#froc-evaluation)\n\n\n# NCRF\n本仓库包含用于复现论文主要结果的代码和数据：\n\n[Yi Li 和 Wei Ping. 基于神经条件随机场的癌症转移检测。医学影像与深度学习（MIDL），2018年。](https:\u002F\u002Fopenreview.net\u002Fforum?id=S1aY66iiM)\n\n如果您觉得这些代码或数据有用，请引用上述论文：\n\n    @inproceedings{li2018cancer,\n        title={Cancer Metastasis Detection With Neural Conditional Random Field},\n        booktitle={Medical Imaging with Deep Learning},\n        author={Li, Yi and Ping, Wei},\n        year={2018}\n    }\n\n如有任何问题，请在 GitHub 问题页面留言，或发送邮件至 yil8@uci.edu\n\n\n# 前提条件\n* Python (3.6)\n\n* Numpy (1.14.3)\n\n* Scipy (1.0.1)\n\n* [PyTorch (0.3.1)\u002FCUDA 8.0](https:\u002F\u002Fpytorch.org\u002Fprevious-versions\u002F) 具体的二进制 wheel 文件为 [cu80\u002Ftorch-0.3.1-cp36-cp36m-linux_x86_64.whl](http:\u002F\u002Fdownload.pytorch.org\u002Fwhl\u002Fcu80\u002Ftorch-0.3.1-cp36-cp36m-linux_x86_64.whl)。我尚未在其他版本上进行测试，尤其是 0.4 及以上版本，因此不建议使用其他版本。\n\n* torchvision (0.2.0)\n\n* PIL (5.1.0)\n\n* scikit-image (0.13.1)\n\n* [OpenSlide 3.4.1](https:\u002F\u002Fopenslide.org\u002F)（请勿使用 3.4.0 版本，因为该版本存在一些潜在问题）\u002F[openslide-python (1.1.0)](https:\u002F\u002Fgithub.com\u002Fopenslide\u002Fopenslide-python)\n\n* matplotlib (2.2.2)\n\n* [tensorboardX](https:\u002F\u002Fgithub.com\u002Flanpa\u002Ftensorboard-pytorch) 这是一个与 TensorBoard 兼容且适用于 PyTorch 的工具，主要用于监控训练曲线。\n\n* [QuPath](https:\u002F\u002Fqupath.github.io\u002F) 虽然与模型的训练和测试没有直接关系，但我发现它非常有助于可视化全切片图像。\n\n大多数依赖项都可以通过 pip 安装指定版本，例如：\n```\npip install 'numpy==1.14.3'\n```\n或者简单地：\n```\npip install numpy\n```\n我们还提供了一个 [requirements.txt](requirements.txt) 文件，以便您可以一次性安装大部分依赖项：\n```\npip install -r requirements.txt -i https:\u002F\u002Fpypi.python.org\u002Fsimple\u002F\n```\n对于 PyTorch，请考虑下载特定的 wheel 二进制文件并使用以下命令：\n```\npip install torch-0.3.1-cp36-cp36m-linux_x86_64.whl\n```\n\n# 数据\n## 全切片图像\n主要数据是来自 [Camelyon16](https:\u002F\u002Fcamelyon16.grand-challenge.org\u002F) 挑战赛的 `*.tif` 格式全切片图像（WSI）。您需要向 [Camelyon16](https:\u002F\u002Fcamelyon16.grand-challenge.org\u002F) 申请数据访问权限，获批后可以从 Google Drive 或百度网盘下载。请注意，一张切片在第 0 层通常约为 10 万 x 10 万像素，占用磁盘空间超过 1GB。总共有 400 张切片，合计约 700GB 以上，因此请确保您有足够的磁盘空间。用于训练的肿瘤切片命名为 `Tumor_XXX.tif`，其中 XXX 从 001 到 110；用于训练的正常切片命名为 `Normal_XXX.tif`，其中 XXX 从 001 到 160。用于测试的切片命名为 `Test_XXX.tif`，其中 XXX 从 001 到 130。\n\n下载所有切片后，请将用于训练的所有肿瘤切片和正常切片放在同一个目录下，例如 `\u002FWSI_TRAIN\u002F`。\n\n## 更新\n目前，全切片图像 `*tif` 文件已可在 [GigaDB](http:\u002F\u002Fgigadb.org\u002Fdataset\u002F100439) 上免费下载。但为了规范数据使用，请仍与 Camelyon16 组织者联系。\n\n\n## 标注\nCamelyon16 组织者还提供了每张肿瘤切片的肿瘤区域标注，格式为 XML。我已将其转换为更为简单的 JSON 格式，位于 [NCRF\u002Fjsons](\u002Fjsons\u002F) 目录下。每个标注都是一个多边形列表，每个多边形由其顶点表示。其中，正多边形表示肿瘤区域，负多边形表示正常区域。您也可以使用以下命令将 XML 格式转换为 JSON 格式：\n```\npython NCRF\u002Fwsi\u002Fbin\u002Fcamelyon16xml2json.py Tumor_001.xml Tumor_001.json\n```\n\n## 补丁图像\n尽管原始的 400 张 WSI 文件包含了所有必要信息，但它们并不适合直接用于训练深度 CNN。因此，我们需要采样更小的图像补丁，例如 256x256，这是典型的深度 CNN 所能处理的尺寸。**高效地采样具有信息量且具有代表性的补丁，是实现良好肿瘤检测性能的关键环节之一。** 为了简化这一过程，我在本仓库中包含了论文中用于训练的预采样补丁坐标，位于 [NCRF\u002Fcoords](\u002Fcoords\u002F) 目录下。每个文件都是 CSV 格式，每行的格式类似于 `Tumor_024,25417,127565`，其中最后两个数字分别是补丁中心在第 0 层的 (x, y) 坐标。`tumor_train.txt` 和 `normal_train.txt` 分别包含 20 万个坐标，而 `tumor_valid.txt` 和 `normal_valid.txt` 分别包含 2 万个坐标。需要注意的是，硬负样本的坐标，通常位于组织边界区域，也包含在 `normal_train.txt` 和 `normal_valid.txt` 中。借助原始 WSI 和预采样的坐标，我们现在可以生成用于训练深度 CNN 模型的图像补丁。运行以下四条命令以生成相应的补丁：\n```\npython NCRF\u002Fwsi\u002Fbin\u002Fpatch_gen.py \u002FWSI_TRAIN\u002F NCRF\u002Fcoords\u002Ftumor_train.txt \u002FPATCHES_TUMOR_TRAIN\u002F\npython NCRF\u002Fwsi\u002Fbin\u002Fpatch_gen.py \u002FWSI_TRAIN\u002F NCRF\u002Fcoords\u002Fnormal_train.txt \u002FPATCHES_NORMAL_TRAIN\u002F\npython NCRF\u002Fwsi\u002Fbin\u002Fpatch_gen.py \u002FWSI_TRAIN\u002F NCRF\u002Fcoords\u002Ftumor_valid.txt \u002FPATCHES_TUMOR_VALID\u002F\npython NCRF\u002Fwsi\u002Fbin\u002Fpatch_gen.py \u002FWSI_TRAIN\u002F NCRF\u002Fcoords\u002Fnormal_valid.txt \u002FPATCHES_NORMAL_VALID\u002F\n```\n其中，`\u002FWSI_TRAIN\u002F` 是您存放所有用于训练的 WSI 文件的目录路径，如上所述；`\u002FPATCHES_TUMOR_TRAIN\u002F` 是用于存储生成的肿瘤训练补丁的目录路径。其他目录命名规则与此类似：`\u002FPATCHES_NORMAL_TRAIN\u002F`、`\u002FPATCHES_TUMOR_VALID\u002F` 和 `\u002FPATCHES_NORMAL_VALID\u002F`。默认情况下，每条命令会使用 5 个进程生成 768x768 大小的第 0 层补丁，补丁中心对应于提供的坐标。每个 768x768 的补丁将进一步分割成 3x3 的 256x256 小补丁，以便在利用 CRF 的训练算法时使用。\n\n需要注意的是，使用 5 个进程生成 20 万个 768x768 补丁大约耗时 4.5 小时，生成的文件大小约为 202GB。\n\n# 模型\n![NCRF](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fbaidu-research_NCRF_readme_54acb28fa02c.png)\nNCRF 的核心思想是将一个由补丁组成的网格作为输入，例如 3x3 网格，使用 CNN 模块提取补丁的嵌入表示，并利用 CRF 模块建模这些补丁之间的空间相关性。[CNN 模块](\u002Fwsi\u002Fmodel\u002Fresnet.py)源自 torchvision 发布的标准 ResNet（https:\u002F\u002Fgithub.com\u002Fpytorch\u002Fvision\u002Fblob\u002Fmaster\u002Ftorchvision\u002Fmodels\u002Fresnet.py）。主要区别在于前向传播过程中：1. 输入张量多了一个维度；2. 使用 CRF 模块通过补丁的嵌入表示对每个补丁的 logits 进行平滑处理。\n```python\ndef forward(self, x):\n    \"\"\"\n    Args:\n        x: 5D 张量，形状为\n        [batch_size, grid_size, 3, crop_size, crop_size],\n        其中 grid_size 是网格内补丁的数量（例如 3x3 网格为 9）；crop_size 默认为 ResNet 输入的 224；\n    Returns:\n        logits，2D 张量，形状为 [batch_size, grid_size]，表示网格内每个补丁属于肿瘤的 logits\n    \"\"\"\n    batch_size, grid_size, _, crop_size = x.shape[0:4]\n    # 将 grid_size 维度展平并合并到 batch 维度中\n    x = x.view(-1, 3, crop_size, crop_size)\n\n    x = self.conv1(x)\n    x = self.bn1(x)\n    x = self.relu(x)\n    x = self.maxpool(x)\n\n    x = self.layer1(x)\n    x = self.layer2(x)\n    x = self.layer3(x)\n    x = self.layer4(x)\n\n    x = self.avgpool(x)\n    # feats 表示特征，即来自 ResNet 的补丁嵌入\n    feats = x.view(x.size(0), -1)\n    logits = self.fc(feats)\n\n    # 恢复 grid_size 维度以便进行 CRF 处理\n    feats = feats.view((batch_size, grid_size, -1))\n    logits = logits.view((batch_size, grid_size, -1))\n\n    if self.crf:\n        logits = self.crf(feats, logits)\n\n    logits = torch.squeeze(logits)\n\n    return logits\n```\n[CRF 模块](\u002Fwsi\u002Fmodel\u002Flayers.py)仅有一个可训练参数 [W](\u002Fwsi\u002Fmodel\u002Flayers.py#L16)，用于补丁之间的成对势能。你可以通过以下命令从已训练 CRF 模型的 ckpt 文件中绘制 W（参见下一节）：\n```\npython NCRF\u002Fwsi\u002Fbin\u002Fplot_W.py \u002FPATH_TO_MODEL\u002Fbest.ckpt\n```\n当 CRF 模型训练良好时，W 通常反映了输入网格中不同补丁之间的相对空间位置。有关模型的更多详细信息，请参阅我们的论文。\n\u003Cp align=\"center\">\u003Cimg src=https:\u002F\u002Fgithub.com\u002Fbaidu-research\u002FNCRF\u002Fblob\u002Fmaster\u002Fdoc\u002FW.png width=\"50%\">\u003C\u002Fp>\n\n\n# 训练\n有了生成的补丁图像，我们现在可以使用以下命令训练模型：\n```\npython NCRF\u002Fwsi\u002Fbin\u002Ftrain.py \u002FCFG_PATH\u002Fcfg.json \u002FSAVE_PATH\u002F\n```\n其中 `\u002FCFG_PATH\u002F` 是 JSON 格式的配置文件路径，而 `\u002FSAVE_PATH\u002F` 是你希望以 checkpoint (ckpt) 格式保存模型的地方。在 [NCRF\u002Fconfigs](\u002Fconfigs\u002F) 中提供了两个配置文件，其中一个适用于带有 CRF 的 ResNet-18：\n```json\n{\n \"model\": \"resnet18\",\n \"use_crf\": true,\n \"batch_size\": 10,\n \"image_size\": 768,\n \"patch_size\": 256,\n \"crop_size\": 224,\n \"lr\": 0.001,\n \"momentum\": 0.9,\n \"data_path_tumor_train\": \"\u002FPATCHES_TUMOR_TRAIN\u002F\",\n \"data_path_normal_train\": \"\u002FPATCHES_NORMAL_TRAIN\u002F\",\n \"data_path_tumor_valid\": \"\u002FPATCHES_TUMOR_VALID\u002F\",\n \"data_path_normal_valid\": \"\u002FPATCHES_NORMAL_VALID\u002F\",\n \"json_path_train\": \"NCRF\u002Fjsons\u002Ftrain\",\n \"json_path_valid\": \"NCRF\u002Fjsons\u002Fvalid\",\n \"epoch\": 20,\n \"log_every\": 100\n}\n```\n请分别将 `\u002FPATCHES_TUMOR_TRAIN\u002F`、`\u002FPATCHES_NORMAL_TRAIN\u002F`、`\u002FPATCHES_TUMOR_VALID\u002F` 和 `\u002FPATCHES_NORMAL_VALID\u002F` 修改为你自己生成的补丁图像路径。同时，请根据你本地 NCRF 仓库的完整路径修改 `NCRF\u002Fjsons\u002Ftrain` 和 `NCRF\u002Fjsons\u002Fvalid`。另一个配置文件适用于不带 CRF 的 ResNet-18（基准模型）。\n\n默认情况下，`train.py` 使用 1 个 GPU (GPU_0) 来训练模型，2 个进程加载肿瘤补丁图像，2 个进程加载正常补丁图像。在一台 GTX 1080Ti 上，训练 1 个 epoch 大约需要 5 小时，完成 20 个 epoch 则需要 4 天。你还可以使用 tensorboard 监控训练过程：\n```\ntensorboard --logdir \u002FSAVE_PATH\u002F\n```\n![training_acc](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fbaidu-research_NCRF_readme_70b0297bb3a4.png)\n通常，你会观察到 CRF 模型的训练准确率始终高于基准模型。\n\n`train.py` 会生成一个 `train.ckpt`，即最近保存的模型，以及一个 `best.ckpt`，即验证准确率最高的模型。我们还在 [NCRF\u002Fckpt](\u002Fckpt\u002F) 中提供了预训练的 resnet18_base 和 resnet18_crf 的 best.ckpt。\n\n\n# 测试\n## 组织掩膜\n经过训练的模型用于 WSI 分析的主要测试结果是概率图，它表示模型认为 WSI 上哪些区域是肿瘤区域。最简单的方法是采用滑动窗口的方式，在整张切片上逐个预测所有补丁是否为肿瘤。但由于 WSI 的大部分区域实际上是白色背景，这种滑动窗口方式会浪费大量计算资源。因此，我们首先计算一个二值组织掩膜，用于标识每个补丁是组织还是背景，然后只在组织区域进行肿瘤预测。典型的 WSI 及其组织掩膜如下所示（Test_026）：\n![tissue_mask](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fbaidu-research_NCRF_readme_0603800cee0e.png)\n要获取给定输入 WSI 的组织掩膜，例如 Test_026.tif，运行以下命令：\n```\npython NCRF\u002Fwsi\u002Fbin\u002Ftissue_mask.py \u002FWSI_PATH\u002FTest_026.tif \u002FMASK_PATH\u002FTest_026.npy\n```\n其中 `\u002FWSI_PATH\u002F` 是你感兴趣的 WSI 路径，而 `\u002FMASK_PATH\u002F` 是你希望以 numpy 格式保存生成的组织掩膜的路径。默认情况下，组织掩膜是在第 6 层生成的，对应于 64 像素的推理步长，即在第 0 层每 64 像素进行一次预测。\n这里附上了 [Test_026_tissue_mask.npy](https:\u002F\u002Fdrive.google.com\u002Ffile\u002Fd\u002F1BdOJGeag7kq8_p1NqU_v-EQcV_OxHgcW\u002Fview) 在第 6 层的组织掩膜供参考。请注意，使用 matplotlib.pyplot.imshow 绘制时，需先对其进行转置。\n\n## 概率图\n借助生成的组织掩膜，我们现在可以使用训练好的模型为给定的WSI（例如Test_026.tif）获取概率图：\n```\npython NCRF\u002Fwsi\u002Fbin\u002Fprobs_map.py \u002FWSI_PATH\u002FTest_026.tif \u002FCKPT_PATH\u002Fbest.ckpt \u002FCFG_PATH\u002Fcfg.json \u002FMASK_PATH\u002FTest_026.npy \u002FPROBS_MAP_PATH\u002FTest_026.npy\n```\n其中，`\u002FWSI_PATH\u002F`是您感兴趣的WSI文件路径；`\u002FCKPT_PATH\u002F`是您保存训练模型的目录，而`best.ckpt`对应于验证准确率最高的模型；`\u002FCFG_PATH\u002F`是训练模型配置文件的路径，格式为JSON，通常与`\u002FCKPT_PATH\u002F`相同；`\u002FMASK_PATH\u002F`是您保存生成的组织掩膜的路径；`\u002FPROBS_MAP_PATH\u002F`则是您希望以NumPy格式保存生成的概率图的路径。\n\n默认情况下，`probs_map.py`会使用GPU_0进行推理，并启用5个进程加载数据。需要注意的是，尽管我们会加载一个补丁网格（例如3×3），但为了便于实现，仅保留中心补丁的预测概率。由于计算开销较大，生成一张WSI的概率图通常需要0.5至1小时。我们正在考虑开发更高效的推理算法来生成概率图。\n![probability_map](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fbaidu-research_NCRF_readme_9514b55f71bb.png)\n该图展示了Test_026在不同设置下的概率图：(a) 原始WSI，(b) 真实标注，(c) 基线方法，(d) 采用困难负样本挖掘的基线方法，(e) 结合困难负样本挖掘的NCRF。我们可以看到，基线方法生成的概率图通常存在大量孤立的假阳性区域。通过引入困难负样本挖掘，基线方法的假阳性数量显著减少，但同时真实肿瘤区域内的概率密度也随之降低，从而削弱了模型的敏感性。相比之下，结合困难负样本挖掘的NCRF不仅能够有效降低假阳性，还能在真实肿瘤区域内保持较高的概率密度，且边界更加清晰。\n\n附上[Test_026_probs_map.npy](https:\u002F\u002Fdrive.google.com\u002Ffile\u002Fd\u002F1RLhzfhfxBkspbZmt1SXl9DS_LVi1XcxU\u002Fview)在第6级下的概率图，供对比参考。请注意，使用matplotlib.pyplot.imshow绘制时，需先对其进行转置。\n\n## 肿瘤定位\n我们利用非极大值抑制（NMS）算法，根据概率图在第0级获取每个检测到的肿瘤区域的坐标。\n```\npython NCRF\u002Fwsi\u002Fbin\u002Fnms.py \u002FPROBS_MAP_PATH\u002FTest_026.npy \u002FCOORD_PATH\u002FTest_026.csv\n```\n其中，`\u002FPROBS_MAP_PATH\u002F`是您保存生成的概率图的路径，而`\u002FCOORD_PATH\u002F`则是您希望以CSV格式保存各肿瘤区域在第0级坐标的路径。该脚本提供了一个可选参数`--level`，其默认值为6，请确保它与用于生成相应组织掩膜和概率图的级别一致。\n\n## FROC评估\n有了每张测试WSI中肿瘤区域的坐标后，我们最终可以评估肿瘤定位的平均FROC分数。\n```\npython NCRF\u002Fwsi\u002Fbin\u002FEvaluation_FROC.py \u002FTEST_MASK\u002F \u002FCOORD_PATH\u002F\n```\n`\u002FTEST_MASK\u002F`是存放测试集真实标注TIFF掩膜文件的路径，而`\u002FCOORD_PATH\u002F`则是保存生成的肿瘤坐标文件的路径。`Evaluation_FROC.py`基于Camelyon16组织方提供的评估代码并进行了少量修改。需要注意的是，根据Camelyon16组织方的说明，Test_049和Test_114不参与本次评估。","# NCRF 快速上手指南\n\nNCRF (Neural Conditional Random Field) 是一个用于癌症转移检测的深度学习工具，基于全切片图像（WSI）进行肿瘤定位。本指南将帮助你快速搭建环境并运行模型。\n\n## 环境准备\n\n在开始之前，请确保你的系统满足以下要求：\n\n*   **操作系统**: Linux (推荐，官方测试环境为 Linux x86_64)\n*   **Python**: 3.6\n*   **GPU**: 支持 CUDA 8.0 的 NVIDIA 显卡\n*   **磁盘空间**: 建议预留 800GB+ 空间（原始 WSI 数据约 700GB+，生成的补丁数据约 200GB+）\n\n**核心依赖版本说明：**\n本项目对版本要求严格，特别是 PyTorch，**强烈建议使用指定版本**，其他版本（尤其是 0.4+）可能导致兼容性问题。\n\n*   PyTorch: 0.3.1 (CUDA 8.0)\n*   torchvision: 0.2.0\n*   Openslide: 3.4.1 (请勿使用 3.4.0)\n*   其他库：Numpy, Scipy, PIL, scikit-image, matplotlib, tensorboardX 等\n\n## 安装步骤\n\n### 1. 安装基础依赖\n你可以使用提供的 `requirements.txt` 一键安装大部分 Python 依赖。为了加速下载，推荐使用国内镜像源（如清华源或阿里源）。\n\n```bash\npip install -r requirements.txt -i https:\u002F\u002Fpypi.tuna.tsinghua.edu.cn\u002Fsimple\u002F\n```\n\n如果上述命令失败，也可以手动安装关键库：\n```bash\npip install 'numpy==1.14.3' 'scipy==1.0.1' 'Pillow==5.1.0' 'scikit-image==0.13.1' 'matplotlib==2.2.2' 'tensorboardX' -i https:\u002F\u002Fpypi.tuna.tsinghua.edu.cn\u002Fsimple\u002F\n```\n\n### 2. 安装 PyTorch (关键步骤)\n由于官方不再直接提供旧版 wheel 文件的便捷安装命令，你需要先下载特定的二进制文件，然后本地安装。\n\n**下载指定版本的 Wheel 文件：**\n```bash\nwget http:\u002F\u002Fdownload.pytorch.org\u002Fwhl\u002Fcu80\u002Ftorch-0.3.1-cp36-cp36m-linux_x86_64.whl\n```\n*(注：如果下载速度慢，可尝试寻找国内镜像站点的缓存，或手动下载后上传至服务器)*\n\n**安装 PyTorch 和 torchvision：**\n```bash\npip install torch-0.3.1-cp36-cp36m-linux_x86_64.whl\npip install 'torchvision==0.2.0' -i https:\u002F\u002Fpypi.tuna.tsinghua.edu.cn\u002Fsimple\u002F\n```\n\n### 3. 安装 OpenSlide\nOpenSlide 需要系统级安装，请根据你的 Linux 发行版执行相应命令（以 Ubuntu 为例）：\n\n```bash\nsudo apt-get update\nsudo apt-get install libopenslide0 openslide-tools\npip install 'openslide-python==1.1.0' -i https:\u002F\u002Fpypi.tuna.tsinghua.edu.cn\u002Fsimple\u002F\n```\n*注意：务必确保 libopenslide 版本为 3.4.1，避免使用 3.4.0。*\n\n## 基本使用\n\n本项目的核心流程包括：数据准备 -> 生成图像补丁 (Patches) -> 训练模型 -> 测试推理。以下是基于已有 Camelyon16 数据的极简操作流程。\n\n### 1. 数据准备\n你需要从 [Camelyon16](https:\u002F\u002Fcamelyon16.grand-challenge.org\u002F) 或 [GigaDB](http:\u002F\u002Fgigadb.org\u002Fdataset\u002F100439) 获取 `.tif` 格式的全切片图像 (WSI)。\n假设你将所有训练用的肿瘤切片 (`Tumor_XXX.tif`) 和正常切片 (`Normal_XXX.tif`) 放置在 `\u002FWSI_TRAIN\u002F` 目录下。\n\n### 2. 生成训练补丁 (Patch Generation)\nWSI 图像过大，无法直接输入 CNN。需利用仓库中预提供的坐标文件 (`NCRF\u002Fcoords\u002F`) 截取补丁。\n\n运行以下命令生成训练集和验证集的补丁（默认生成 768x768 的大图，后续会在模型中切割）：\n\n```bash\n# 生成肿瘤训练补丁\npython NCRF\u002Fwsi\u002Fbin\u002Fpatch_gen.py \u002FWSI_TRAIN\u002F NCRF\u002Fcoords\u002Ftumor_train.txt \u002FPATCHES_TUMOR_TRAIN\u002F\n\n# 生成正常训练补丁 (包含硬负样本)\npython NCRF\u002Fwsi\u002Fbin\u002Fpatch_gen.py \u002FWSI_TRAIN\u002F NCRF\u002Fcoords\u002Fnormal_train.txt \u002FPATCHES_NORMAL_TRAIN\u002F\n\n# 生成肿瘤验证补丁\npython NCRF\u002Fwsi\u002Fbin\u002Fpatch_gen.py \u002FWSI_TRAIN\u002F NCRF\u002Fcoords\u002Ftumor_valid.txt \u002FPATCHES_TUMOR_VALID\u002F\n\n# 生成正常验证补丁\npython NCRF\u002Fwsi\u002Fbin\u002Fpatch_gen.py \u002FWSI_TRAIN\u002F NCRF\u002Fcoords\u002Fnormal_valid.txt \u002FPATCHES_NORMAL_VALID\u002F\n```\n*提示：生成约 20 万张补丁在 5 进程下耗时约 4.5 小时，占用磁盘约 202GB。*\n\n### 3. 配置与训练\n修改配置文件 `NCRF\u002Fconfigs\u002Fresnet18_crf.json` (参考原文中的 JSON 结构)，将数据路径替换为你实际生成的补丁路径，例如：\n*   `data_path_tumor_train`: `\u002FPATCHES_TUMOR_TRAIN\u002F`\n*   `data_path_normal_train`: `\u002FPATCHES_NORMAL_TRAIN\u002F`\n*   ...以及其他验证集路径。\n\n启动训练（默认使用 GPU 0）：\n```bash\npython NCRF\u002Fwsi\u002Fbin\u002Ftrain.py NCRF\u002Fconfigs\u002Fresnet18_crf.json \u002FSAVE_PATH\u002F\n```\n*   `\u002FSAVE_PATH\u002F` 是模型检查点保存目录。\n*   可使用 `tensorboard --logdir \u002FSAVE_PATH\u002F` 监控训练曲线。\n*   训练完成后会生成 `best.ckpt` (验证集最佳模型)。\n\n### 4. 测试与推理\n测试阶段主要生成组织掩膜 (Tissue Mask) 和肿瘤概率图。\n\n**步骤 A: 生成组织掩膜**\n排除白色背景区域，仅对组织区域进行预测，以提高效率。\n```bash\npython NCRF\u002Fwsi\u002Fbin\u002Ftissue_mask.py \u002FWSI_PATH\u002FTest_026.tif \u002FMASK_PATH\u002FTest_026.npy\n```\n\n**步骤 B: 生成概率图与肿瘤定位**\n*(注：具体测试脚本命令在原文截断部分之前未完全展示，通常遵循类似 `test.py` 的模式，加载 `best.ckpt` 和生成的 mask 进行推理。请参考仓库中完整的 `testing` 章节或源码获取后续具体命令。)*\n\n---\n*更多细节（如 FROC 评估、可视化权重矩阵 W 等）请参阅项目原始 README 或相关论文。*","某三甲医院病理科正在处理数百张来自 Camelyon16 挑战赛的乳腺淋巴结全切片图像（WSI），急需精准定位其中的癌症转移灶以辅助医生确诊。\n\n### 没有 NCRF 时\n- **漏诊风险高**：面对每张高达 10 万像素级的巨幅切片，病理医生肉眼排查极易疲劳，导致微小转移灶被遗漏。\n- **上下文缺失**：传统深度学习模型仅基于独立图像块（Patch）判断，忽略了组织块之间的空间关联，导致大量假阳性误报。\n- **标注效率低**：缺乏自动化的概率热力图引导，医生需在整张切片上盲目搜索肿瘤区域，耗时数小时才能完成一张片的初筛。\n- **结果不一致**：不同医生或同一医生在不同时间段的判读标准存在波动，难以形成标准化的定量评估报告。\n\n### 使用 NCRF 后\n- **精度显著提升**：NCRF 引入神经条件随机场，有效建模了图像块间的空间依赖关系，大幅降低了孤立噪声点的干扰，提高了检测特异性。\n- **智能定位引导**：工具自动生成高精度的肿瘤概率热力图和定位掩膜，将医生注意力直接聚焦到可疑区域，筛查速度提升数倍。\n- **标准化输出**：基于 FROC 曲线评估的算法提供了客观、一致的检测结果，消除了人为主观因素带来的诊断差异。\n- **全流程自动化**：从组织掩膜提取到最终肿瘤定位，NCRF 实现了端到端的自动化处理，让医生只需专注于最终复核而非初步搜索。\n\nNCRF 通过融合深度学习特征与空间上下文信息，将癌症转移检测从“大海捞针”转变为“精准制导”，显著提升了病理诊断的效率与可靠性。","https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fbaidu-research_NCRF_a7300369.png","baidu-research","Baidu Research","https:\u002F\u002Foss.gittoolsai.com\u002Favatars\u002Fbaidu-research_faaa443a.png",null,"http:\u002F\u002Fusa.baidu.com\u002F","https:\u002F\u002Fgithub.com\u002Fbaidu-research",[82],{"name":83,"color":84,"percentage":85},"Python","#3572A5",100,760,183,"2026-02-23T14:28:20","Apache-2.0",4,"Linux","需要 NVIDIA GPU，提供 GTX 1080Ti 测试案例，需 CUDA 8.0","未说明（生成训练数据需约 202GB 磁盘空间）",{"notes":95,"python":96,"dependencies":97},"1. 严格依赖 PyTorch 0.3.1 和 CUDA 8.0，作者明确不建议使用 0.4+ 及其他版本。2. 需安装 OpenSlide 3.4.1（避免使用 3.4.0 版本）。3. 数据集来自 Camelyon16 挑战，原始全切片图像（WSI）共约 700GB+，生成的训练补丁数据约 202GB，需确保充足磁盘空间。4. 推荐使用 QuPath 软件可视化全切片图像。5. 在单张 GTX 1080Ti 上训练 20 个 epoch 约需 4 天。","3.6",[98,99,100,101,102,103,104,105,106],"torch==0.3.1","torchvision==0.2.0","numpy==1.14.3","scipy==1.0.1","PIL==5.1.0","scikit-image==0.13.1","openslide-python==1.1.0","matplotlib==2.2.2","tensorboardX",[13],[109,110,111,112,113],"deep-learning","conditional-random-fields","pathology","whole-slide-imaging","camelyon16","2026-03-27T02:49:30.150509","2026-04-06T07:13:05.040916",[117,122,127,132,137,142,147],{"id":118,"question_zh":119,"answer_zh":120,"source_url":121},13725,"运行测试时遇到 'Slide\u002FMask dimension does not match' (切片\u002F掩膜维度不匹配) 错误怎么办？","这通常是由 OpenSlide 版本不兼容引起的。请前往 https:\u002F\u002Fopenslide.org\u002Fdownload\u002F 下载并安装 OpenSlide 3.4.1 版本。如果您在 Ubuntu 上通过 apt-get 安装了旧版本（如 3.4.0），需要手动更新到 3.4.1 以解决维度计算不一致的问题。","https:\u002F\u002Fgithub.com\u002Fbaidu-research\u002FNCRF\u002Fissues\u002F6",{"id":123,"question_zh":124,"answer_zh":125,"source_url":126},13726,"生成的概率图 (probability map) .npy 文件中最大值远小于 1（例如 0.05），这是否代表模型检测失败？","这不是错误，而是正常的数值表现。概率图中的值代表每个像素检测到癌症的概率，在某些情况下整体概率值较低是正常的，并不代表模型失效。只要相对高低能区分肿瘤区域即可，无需强制最大值为 1。","https:\u002F\u002Fgithub.com\u002Fbaidu-research\u002FNCRF\u002Fissues\u002F7",{"id":128,"question_zh":129,"answer_zh":130,"source_url":131},13727,"如何复现论文中的高性能结果 (FROC > 0.79)？如果结果不理想有什么技巧吗？","作者确认是从头训练 ResNet18 并结合 CRF，没有使用预训练微调。如果结果差异巨大（如 FROC 仅 0.39），可能是测试集的地面真值 (Ground Truth) 掩膜生成有误。建议不要完全依赖自行转换的掩膜，可尝试使用作者提供的原始 test_026.tif ground truth mask 进行验证，或检查 XML 转 Tiff 掩膜的流程是否正确。","https:\u002F\u002Fgithub.com\u002Fbaidu-research\u002FNCRF\u002Fissues\u002F12",{"id":133,"question_zh":134,"answer_zh":135,"source_url":136},13728,"遇到 'openslide.lowlevel.OpenSlideError: TIFFRGBAImageGet failed' 或 'Not a JPEG file' 错误如何解决？","这通常是由于图像元数据损坏导致的。解决方法是调整读取区域的坐标范围 (coordinates)。可以通过试错法 (trial and error) 减小读取范围，或者修改 slide.read_region 的坐标参数，避开损坏的元数据区域即可正常运行。","https:\u002F\u002Fgithub.com\u002Fbaidu-research\u002FNCRF\u002Fissues\u002F9",{"id":138,"question_zh":139,"answer_zh":140,"source_url":141},13729,"训练时出现 'device-side assert triggered' (CUDA runtime error 59) 错误，是标签 (label) 格式有问题吗？","这通常与标签数据的格式或范围有关。对于肿瘤检测任务，只需标注肿瘤（阳性）区域，其余所有区域应视为背景\u002F正常（阴性）。请确保您的注释文件遵循此原则：如果一个注释文件同时包含阳性和阴性区域定义，可能需要预处理将其统一为二值掩膜（仅标记肿瘤为 1，其余为 0）。","https:\u002F\u002Fgithub.com\u002Fbaidu-research\u002FNCRF\u002Fissues\u002F16",{"id":143,"question_zh":144,"answer_zh":145,"source_url":146},13730,"使用 Camelyon16 提供的官方 XML 注释文件生成的掩膜在评估时无法正确计算 FROC（例如多个肿瘤被识别为一个），如何解决？","可以直接使用官方 XML 文件生成掩膜进行评估，但需要正确的转换代码。可以使用 MultiResolutionImageReader 读取 Tiff 和 XML，通过 AnnotationToMask 进行转换。关键在于确保 label_map 和 conversion_order 设置正确（例如将 metastases 映射为 1）。如果生成的掩膜连通域数量不对，需检查距离变换阈值 (Threshold) 设置，代码中推荐公式为：Threshold = 75 \u002F (resolution * pow(2, level) * 2)，其中 75µm 相当于 5 个肿瘤细胞的大小。","https:\u002F\u002Fgithub.com\u002Fbaidu-research\u002FNCRF\u002Fissues\u002F40",{"id":148,"question_zh":149,"answer_zh":150,"source_url":131},13731,"ResNet18 和 CRF 模型的训练顺序是怎样的？需要先单独训练 ResNet 再微调吗？","不需要分阶段微调。作者的做法是将 ResNet18 和 CRF 放在一起，从头开始 (from scratch) 联合训练，而不是先训练 ResNet18 再用 CRF 微调。",[152],{"id":153,"version":154,"summary_zh":78,"released_at":155},72649,"v1.0","2018-06-17T18:22:34"]