[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"similar-deepgram--kur":3,"tool-deepgram--kur":61},[4,18,26,36,44,53],{"id":5,"name":6,"github_repo":7,"description_zh":8,"stars":9,"difficulty_score":10,"last_commit_at":11,"category_tags":12,"status":17},4358,"openclaw","openclaw\u002Fopenclaw","OpenClaw 是一款专为个人打造的本地化 AI 助手，旨在让你在自己的设备上拥有完全可控的智能伙伴。它打破了传统 AI 助手局限于特定网页或应用的束缚，能够直接接入你日常使用的各类通讯渠道，包括微信、WhatsApp、Telegram、Discord、iMessage 等数十种平台。无论你在哪个聊天软件中发送消息，OpenClaw 都能即时响应，甚至支持在 macOS、iOS 和 Android 设备上进行语音交互，并提供实时的画布渲染功能供你操控。\n\n这款工具主要解决了用户对数据隐私、响应速度以及“始终在线”体验的需求。通过将 AI 部署在本地，用户无需依赖云端服务即可享受快速、私密的智能辅助，真正实现了“你的数据，你做主”。其独特的技术亮点在于强大的网关架构，将控制平面与核心助手分离，确保跨平台通信的流畅性与扩展性。\n\nOpenClaw 非常适合希望构建个性化工作流的技术爱好者、开发者，以及注重隐私保护且不愿被单一生态绑定的普通用户。只要具备基础的终端操作能力（支持 macOS、Linux 及 Windows WSL2），即可通过简单的命令行引导完成部署。如果你渴望拥有一个懂你",349277,3,"2026-04-06T06:32:30",[13,14,15,16],"Agent","开发框架","图像","数据工具","ready",{"id":19,"name":20,"github_repo":21,"description_zh":22,"stars":23,"difficulty_score":10,"last_commit_at":24,"category_tags":25,"status":17},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,"2026-04-05T11:01:52",[14,15,13],{"id":27,"name":28,"github_repo":29,"description_zh":30,"stars":31,"difficulty_score":32,"last_commit_at":33,"category_tags":34,"status":17},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 真正成长为懂上",144730,2,"2026-04-07T23:26:32",[14,13,35],"语言模型",{"id":37,"name":38,"github_repo":39,"description_zh":40,"stars":41,"difficulty_score":32,"last_commit_at":42,"category_tags":43,"status":17},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 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能，使其成为当前最灵活、生态最丰富的开源扩散模型工具之一，帮助用户将创意高效转化为现实。",107888,"2026-04-06T11:32:50",[14,15,13],{"id":45,"name":46,"github_repo":47,"description_zh":48,"stars":49,"difficulty_score":32,"last_commit_at":50,"category_tags":51,"status":17},4721,"markitdown","microsoft\u002Fmarkitdown","MarkItDown 是一款由微软 AutoGen 团队打造的轻量级 Python 工具，专为将各类文件高效转换为 Markdown 格式而设计。它支持 PDF、Word、Excel、PPT、图片（含 OCR）、音频（含语音转录）、HTML 乃至 YouTube 链接等多种格式的解析，能够精准提取文档中的标题、列表、表格和链接等关键结构信息。\n\n在人工智能应用日益普及的今天，大语言模型（LLM）虽擅长处理文本，却难以直接读取复杂的二进制办公文档。MarkItDown 恰好解决了这一痛点，它将非结构化或半结构化的文件转化为模型“原生理解”且 Token 效率极高的 Markdown 格式，成为连接本地文件与 AI 分析 pipeline 的理想桥梁。此外，它还提供了 MCP（模型上下文协议）服务器，可无缝集成到 Claude Desktop 等 LLM 应用中。\n\n这款工具特别适合开发者、数据科学家及 AI 研究人员使用，尤其是那些需要构建文档检索增强生成（RAG）系统、进行批量文本分析或希望让 AI 助手直接“阅读”本地文件的用户。虽然生成的内容也具备一定可读性，但其核心优势在于为机器",93400,"2026-04-06T19:52:38",[52,14],"插件",{"id":54,"name":55,"github_repo":56,"description_zh":57,"stars":58,"difficulty_score":10,"last_commit_at":59,"category_tags":60,"status":17},4487,"LLMs-from-scratch","rasbt\u002FLLMs-from-scratch","LLMs-from-scratch 是一个基于 PyTorch 的开源教育项目，旨在引导用户从零开始一步步构建一个类似 ChatGPT 的大型语言模型（LLM）。它不仅是同名技术著作的官方代码库，更提供了一套完整的实践方案，涵盖模型开发、预训练及微调的全过程。\n\n该项目主要解决了大模型领域“黑盒化”的学习痛点。许多开发者虽能调用现成模型，却难以深入理解其内部架构与训练机制。通过亲手编写每一行核心代码，用户能够透彻掌握 Transformer 架构、注意力机制等关键原理，从而真正理解大模型是如何“思考”的。此外，项目还包含了加载大型预训练权重进行微调的代码，帮助用户将理论知识延伸至实际应用。\n\nLLMs-from-scratch 特别适合希望深入底层原理的 AI 开发者、研究人员以及计算机专业的学生。对于不满足于仅使用 API，而是渴望探究模型构建细节的技术人员而言，这是极佳的学习资源。其独特的技术亮点在于“循序渐进”的教学设计：将复杂的系统工程拆解为清晰的步骤，配合详细的图表与示例，让构建一个虽小但功能完备的大模型变得触手可及。无论你是想夯实理论基础，还是为未来研发更大规模的模型做准备",90106,"2026-04-06T11:19:32",[35,15,13,14],{"id":62,"github_repo":63,"name":64,"description_en":65,"description_zh":66,"ai_summary_zh":66,"readme_en":67,"readme_zh":68,"quickstart_zh":69,"use_case_zh":70,"hero_image_url":71,"owner_login":72,"owner_name":73,"owner_avatar_url":74,"owner_bio":75,"owner_company":76,"owner_location":76,"owner_email":76,"owner_twitter":76,"owner_website":77,"owner_url":78,"languages":79,"stars":84,"forks":85,"last_commit_at":86,"license":87,"difficulty_score":32,"env_os":88,"env_gpu":89,"env_ram":88,"env_deps":90,"category_tags":99,"github_topics":101,"view_count":32,"oss_zip_url":76,"oss_zip_packed_at":76,"status":17,"created_at":111,"updated_at":112,"faqs":113,"releases":144},5399,"deepgram\u002Fkur","kur","Descriptive Deep Learning","Kur 是一款致力于让深度学习变得“可描述”的开源框架，旨在帮助用户无需编写复杂代码即可设计、训练和评估先进的 AI 模型。它主要解决了传统深度学习开发门槛高、需大量编程工作以及多后端适配繁琐的痛点，让用户能将精力集中在模型逻辑本身而非底层实现细节上。\n\n无论是刚入门的机器学习新手，还是希望快速验证想法的资深研究人员，都能从 Kur 中受益。用户只需通过简洁易读的配置文件来描述模型结构，即可完成从构建到部署的全流程。对于需要更高灵活性的开发者，Kur 也提供了友好的扩展 API 以支持定制化需求。\n\n在技术亮点方面，Kur 原生支持 Theano、TensorFlow 和 PyTorch 三大主流后端，并开箱即用多 GPU 加速功能，显著提升了训练效率。此外，它巧妙集成了 Jinja2 模板引擎，允许用户通过参数化配置快速探索和优化模型版本。未来，Kur 还计划推出社区模型共享功能，进一步促进协作创新。如果你希望以更直观、高效的方式涉足深度学习领域，Kur 提供了一个极具价值的选择。",".. |LICENSE| image:: https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Flicense-Apache%202-blue.svg\n   :target: https:\u002F\u002Fgithub.com\u002Fdeepgram\u002Fkur\u002Fblob\u002Fmaster\u002FLICENSE\n.. |PYTHON| image:: https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fpython-3.4%2C3.5%2C3.6-lightgrey.svg\n   :target: https:\u002F\u002Fkur.deepgram.com\u002Finstalling.html\n.. |BUILD| image:: https:\u002F\u002Ftravis-ci.org\u002Fdeepgram\u002Fkur.svg?branch=master\n   :target: https:\u002F\u002Ftravis-ci.org\u002Fdeepgram\u002Fkur\n.. |GITTER| image:: https:\u002F\u002Fbadges.gitter.im\u002Fdeepgram-kur\u002FLobby.svg\n   :target: https:\u002F\u002Fgitter.im\u002Fdeepgram-kur\u002FLobby\n\n.. _Facebook: https:\u002F\u002Fwww.facebook.com\u002Fsharer\u002Fsharer.php?u=https%3A\u002F\u002Fkur.deepgram.com\n.. _Google+: https:\u002F\u002Fplus.google.com\u002Fshare?url=https%3A\u002F\u002Fkur.deepgram.com\n.. _LinkedIn: https:\u002F\u002Fwww.linkedin.com\u002FshareArticle?mini=true&url=https%3A\u002F\u002Fkur.deepgram.com&title=Kur%20-%20descriptive%20deep%20learning&summary=Kur%20is%20the%20future%20of%20deep%20learning%3A%20advanced%20AI%20without%20programming!&source=\n.. _Twitter: https:\u002F\u002Ftwitter.com\u002Fhome?status=%40DeepgramAI%20has%20released%20the%20future%20of%20deep%20learning.%20https%3A\u002F\u002Fkur.deepgram.com%20%23Kur\n\n.. image:: https:\u002F\u002Fkur.deepgram.com\u002Fimages\u002Flogo-small.png\n   :align: center\n   :target: https:\u002F\u002Fdeepgram.com\n\n.. package_readme_starts_here\n\n.. _Tutorial: https:\u002F\u002Fkur.deepgram.com\u002Ftutorial.html\n\n******************************\nKur: Descriptive Deep Learning\n******************************\n\n.. package_readme_ignore\n\n|BUILD| |LICENSE| |PYTHON| |GITTER|\n\nIntroduction\n============\n\nWelcome to Kur! You've found the future of deep learning!\n\n- Install Kur easily with ``pip install kur``.\n- Design, train, and evaluate models *without ever needing to code*.\n- Describe your model with easily understandable concepts.\n- Quickly explore better versions of your model with the power of the `Jinja2\n  \u003Chttp:\u002F\u002Fjinja.pocoo.org>`_ templating engine.\n- Supports Theano, TensorFlow, and PyTorch, and supports **multi-GPU**\n  out-of-the-box.\n- **COMING SOON**: Share your models with the community, making it incredibly\n  easy to collaborate on sophisticated models.\n\nGo ahead and give it a whirl: `Get the Code`_ and then jump into\nthe `Examples`_! Then build your own model in our Tutorial_. Remember to check\nout our `homepage \u003Chttps:\u002F\u002Fkur.deepgram.com>`_ for complete documentation and\nthe newest news.\n\n.. package_readme_ignore\n\nLike us? Share!\n\n.. package_readme_ignore\n\n- Facebook_\n- `Google+`_\n- LinkedIn_\n- Twitter_\n\nWhat is Kur?\n------------\n\nKur is a system for quickly building and applying state-of-the-art deep\nlearning models to new and exciting problems. Kur was designed to appeal to the\nentire machine learning community, from novices to veterans. It uses\nspecification files that are simple to read and author, meaning that you can\nget started building sophisticated models *without ever needing to code*. Even\nso, Kur exposes a friendly and extensible API to support advanced deep learning\narchitectures or workflows. Excited? Jump straight into the `Examples`_.\n\n.. _get_the_code:\n\nGet the Code\n============\n\nKur is really easy to install! You can pick either one of these two options for\ninstalling Kur.\n\n**NOTE**: Kur requires **Python 3.4** or greater. Take a look at our\n`installation guide \u003Chttps:\u002F\u002Fkur.deepgram.com\u002Finstall.html>`_ for\nstep-by-step instructions for installing Kur and setting up a `virtual\nenvironment \u003Chttps:\u002F\u002Fvirtualenv.pypa.io\u002F>`_.\n\nLatest Pip Release\n------------------\n\nIf you know what you are doing, then this is easy:\n\n.. code-block:: bash\n\n\tpip install kur\n\nLatest Development Release\n--------------------------\n\nJust check it out and run the setup script:\n\n.. code-block:: bash\n\n\tgit clone https:\u002F\u002Fgithub.com\u002Fdeepgram\u002Fkur\n\tcd kur\n\tpip install .\n\n**Quick Start**: Or, if you already have `Python 3 installed\n\u003Chttps:\u002F\u002Fkur.deepgram.com\u002Finstalling.html>`_, then here's a few quick-start\nlines to get you training your first model:\n\n**Quick Start For Using pip:**\n\n.. code-block:: bash\n\n\tpip install virtualenv                      # Make sure virtualenv is present\n\tvirtualenv -p $(which python3) ~\u002Fkur-env    # Create a Python 3 environment for Kur\n\t. ~\u002Fkur-env\u002Fbin\u002Factivate                    # Activate the Kur environment\n\tpip install kur                             # Install Kur\n\tkur --version                               # Check that everything works\n\tgit clone https:\u002F\u002Fgithub.com\u002Fdeepgram\u002Fkur   # Get the examples\n\tcd kur\u002Fexamples                             # Change directories\n\tkur train mnist.yml                         # Start training!\n\n**Quick Start For Using git:**\n\n.. code-block:: bash\n\n\tpip install virtualenv                      # Make sure virtualenv is present\n\tvirtualenv -p $(which python3) ~\u002Fkur-env    # Create a Python 3 environment for Kur\n\t. ~\u002Fkur-env\u002Fbin\u002Factivate                    # Activate the Kur environment\n\tgit clone https:\u002F\u002Fgithub.com\u002Fdeepgram\u002Fkur   # Check out the latest code\n\tcd kur                                      # Change directories\n\tpip install .                               # Install Kur\n\tkur --version                               # Check that everything works\n\tcd examples                                 # Change directories\n\tkur train mnist.yml                         # Start training!\n\nUsage\n-----\n\nIf everything has gone well, you shoud be able to use Kur:\n\n.. code-block:: bash\n\n\tkur --version\n\nYou'll typically be using Kur in commands like ``kur train model.yml`` or ``kur\ntest model.yml``. You'll see these in the `Examples`_, which is\nwhere you should head to next!\n\nTroubleshooting\n---------------\n\nIf you run into any problems installing or using Kur, please check out our\n`troubleshooting \u003Chttps:\u002F\u002Fkur.deepgram.com\u002Ftroubleshooting.html>`_ page for\nlots of useful help. And if you want more detailed installation instructions,\nwith help on setting up your environment, before sure to see our `installation\n\u003Chttps:\u002F\u002Fkur.deepgram.com\u002Finstalling.html>`_ page.\n\n.. package_readme_ends_here\n\n.. _the_examples:\n\nExamples\n********\n\nLet's look at some examples of how fun and easy Kur makes state-of-the-art deep\nlearning.\n\n.. _mnist_example:\n\nMNIST: Handwriting recognition\n==============================\n\nLet's jump right in and see how awesome Kur is! The first example we'll look at\nis Yann LeCun's `MNIST \u003Chttp:\u002F\u002Fyann.lecun.com\u002Fexdb\u002Fmnist\u002F>`_ dataset. This is a\ndataset of 28x28 pixel images of individual handwritten digits between 0 and 9.\nThe goal of our model will be to perform image recognition, tagging the image\nwith the most likely digit it represents.\n\n**NOTE**: As with most command line examples, lines preceded by ``$`` are lines\nthat you are supposed to type (followed by the ``ENTER`` key). Lines without an\ninitial ``$`` are lines which are printed to the screen (you don't type them).\n\nFirst, you need to `Get the Code`_! If you installed via\n``pip``, you'll need to checkout the ``examples`` directory from the\nrepository, like this:\n\n.. code-block:: bash\n\n\tgit clone https:\u002F\u002Fgithub.com\u002Fdeepgram\u002Fkur\n\tcd kur\u002Fexamples\n\nIf you installed via ``git``, then you alreay have the ``examples`` directory\nlocally, so just move into the example directory:\n\n.. code-block:: bash\n\n\t$ cd examples\n\nNow let's train the MNIST model. This will download the data directly from the\nweb, and then start training for 10 epochs.\n\n.. code-block:: bash\n\n\t$ kur train mnist.yml\n\tDownloading: 100%|█████████████████████████████████| 9.91M\u002F9.91M [03:44\u003C00:00, 44.2Kbytes\u002Fs]\n\tDownloading: 100%|█████████████████████████████████| 28.9K\u002F28.9K [00:00\u003C00:00, 66.1Kbytes\u002Fs]\n\tDownloading: 100%|█████████████████████████████████| 1.65M\u002F1.65M [00:31\u003C00:00, 52.6Kbytes\u002Fs]\n\tDownloading: 100%|█████████████████████████████████| 4.54K\u002F4.54K [00:00\u003C00:00, 19.8Kbytes\u002Fs]\n\n\tEpoch 1\u002F10, loss=1.524: 100%|███████████████████████| 480\u002F480 [00:02\u003C00:00, 254.97samples\u002Fs]\n\tValidating, loss=0.829: 100%|█████████████████████| 3200\u002F3200 [00:03\u003C00:00, 889.91samples\u002Fs]\n\n\tEpoch 2\u002F10, loss=0.628: 100%|███████████████████████| 480\u002F480 [00:02\u003C00:00, 228.25samples\u002Fs]\n\tValidating, loss=0.533: 100%|████████████████████| 3200\u002F3200 [00:03\u003C00:00, 1046.12samples\u002Fs]\n\n\tEpoch 3\u002F10, loss=0.547: 100%|███████████████████████| 480\u002F480 [00:02\u003C00:00, 185.77samples\u002Fs]\n\tValidating, loss=0.491: 100%|████████████████████| 3200\u002F3200 [00:03\u003C00:00, 1030.57samples\u002Fs]\n\n\tEpoch 4\u002F10, loss=0.488: 100%|███████████████████████| 480\u002F480 [00:02\u003C00:00, 225.42samples\u002Fs]\n\tValidating, loss=0.443: 100%|████████████████████| 3200\u002F3200 [00:03\u003C00:00, 1046.23samples\u002Fs]\n\n\tEpoch 5\u002F10, loss=0.464: 100%|███████████████████████| 480\u002F480 [00:03\u003C00:00, 115.17samples\u002Fs]\n\tValidating, loss=0.403: 100%|█████████████████████| 3200\u002F3200 [00:04\u003C00:00, 799.46samples\u002Fs]\n\n\tEpoch 6\u002F10, loss=0.486: 100%|███████████████████████| 480\u002F480 [00:03\u003C00:00, 183.11samples\u002Fs]\n\tValidating, loss=0.400: 100%|████████████████████| 3200\u002F3200 [00:02\u003C00:00, 1134.17samples\u002Fs]\n\n\tEpoch 7\u002F10, loss=0.369: 100%|███████████████████████| 480\u002F480 [00:02\u003C00:00, 214.10samples\u002Fs]\n\tValidating, loss=0.366: 100%|█████████████████████| 3200\u002F3200 [00:04\u003C00:00, 735.61samples\u002Fs]\n\n\tEpoch 8\u002F10, loss=0.353: 100%|███████████████████████| 480\u002F480 [00:03\u003C00:00, 204.33samples\u002Fs]\n\tValidating, loss=0.351: 100%|████████████████████| 3200\u002F3200 [00:02\u003C00:00, 1147.05samples\u002Fs]\n\n\tEpoch 9\u002F10, loss=0.399: 100%|███████████████████████| 480\u002F480 [00:02\u003C00:00, 219.17samples\u002Fs]\n\tValidating, loss=0.343: 100%|████████████████████| 3200\u002F3200 [00:02\u003C00:00, 1149.07samples\u002Fs]\n\n\tEpoch 10\u002F10, loss=0.307: 100%|██████████████████████| 480\u002F480 [00:02\u003C00:00, 220.97samples\u002Fs]\n\tValidating, loss=0.324: 100%|████████████████████| 3200\u002F3200 [00:02\u003C00:00, 1142.78samples\u002Fs]\n\nWhat just happened? Kur downloaded the MNIST dataset from LeCun's website, and\nthen trained a model for ten epochs. Awesome!\n\nNow let's see how well our model actually performs:\n\n.. code-block:: bash\n\n\t$ kur evaluate mnist.yml\n\tEvaluating: 100%|██████████████████████████████| 10000\u002F10000 [00:06\u003C00:00, 1537.74samples\u002Fs]\n\tLABEL     CORRECT   TOTAL     ACCURACY  \n\t0         969       980        98.9%\n\t1         1118      1135       98.5%\n\t2         910       1032       88.2%\n\t3         926       1010       91.7%\n\t4         923       982        94.0%\n\t5         735       892        82.4%\n\t6         871       958        90.9%\n\t7         884       1028       86.0%\n\t8         818       974        84.0%\n\t9         868       1009       86.0%\n\tALL       9022      10000      90.2%\n\nWow! Across the board, we already have 90% accuracy for recognizing\nhandwritten digits, and we only used 0.8% of the training set! That's how\nawesome Kur is.\n\nExcited yet? Read on!\n\n**NOTE**: Clever readers will notice that each training epoch only used 480\ntraining samples. But MNIST provides 60,000 training samples total, so what\ngives?  Simple: lots of us are running this code on consumer hardware; in fact,\nI'm running this example on my tiny ultrabook on an Intel Core m7 CPU. As\nyou'll see in `Under the Hood`_, I truncate the training process to only train\non 10 batches of 32 samples each, just to make the training loop finish in a\nreasonable amount of time. It's not cheating: you still get 90% accuracy! But\nif you have awesome hardware, or just want to see how good your accuracy can\nget, then by all means read on and we'll show you how to modify that.\n\nUnder the Hood\n--------------\n\nSo what exactly is going on here? Let's take a look at the MNIST example\nspecification file:\n\n.. code-block:: yaml\n\n\ttrain:\n\t  data:\n\t    - mnist:\n\t        images:\n\t          url: \"http:\u002F\u002Fyann.lecun.com\u002Fexdb\u002Fmnist\u002Ftrain-images-idx3-ubyte.gz\"\n\t        labels:\n\t          url: \"http:\u002F\u002Fyann.lecun.com\u002Fexdb\u002Fmnist\u002Ftrain-labels-idx1-ubyte.gz\"\n\n\tmodel:\n\t  - input: images\n\t  - convolution:\n\t      kernels: 64\n\t      size: [3, 3]\n\t  - activation: relu\n\t  - flatten:\n\t  - dense: 10\n\t  - activation: softmax\n\t    name: labels\n\n\tinclude: mnist-defaults.yml\n\nThis is just plain, old `YAML \u003Chttp:\u002F\u002Fyaml.org>`_, a markup language meant to\nbe easy for humans to interpret (for a good overview of YAML language features,\nlook at the `Ansible overview\n\u003Chttps:\u002F\u002Fdocs.ansible.com\u002Fansible\u002FYAMLSyntax.html>`_).\n\nThere's a section to put the data. That's this:\n\n.. code-block:: yaml\n\n\ttrain:\n\t  data:\n\t    - mnist:\n\t        images:\n\t          url: \"http:\u002F\u002Fyann.lecun.com\u002Fexdb\u002Fmnist\u002Ftrain-images-idx3-ubyte.gz\"\n\t        labels:\n\t          url: \"http:\u002F\u002Fyann.lecun.com\u002Fexdb\u002Fmnist\u002Ftrain-labels-idx1-ubyte.gz\"\n\nAnd then there's a spot to define your model:\n\n.. code-block:: yaml\n\n\tmodel:\n\t  - input: images\n\t  - convolution:\n\t      kernels: 64\n\t      size: [3, 3]\n\t  - activation: relu\n\t  - flatten:\n\t  - dense: 10\n\t  - activation: softmax\n\t    name: labels\n\nAnd there is an \"include\" part that just contains some default settings\n(advanced users might want to tweak these---don't worry, it's still simple):\n\n.. code-block:: yaml\n\n\tinclude: mnist-defaults.yml\n\nVery simple! Kur downloaded our data directly from LeCun's website for us,\nthat's easy. But what goes into in a Kur model? Just a nice, gentle list of\nthings you want your deep learning model to do. Let's break it down:\n\n- We have an ``input`` called ``images`` (yep, it's the same ``images`` from our\n  ``train`` section).\n- We pass the input to a ``convolution`` layer.\n- We add a regularized linear unit (\"ReLU\") activation.\n- We collapse (``flatten``) the high-dimensional output of a convolution into a\n  nice, flat, 1-dimensional shape appropriate for sending into the\n  fully-connected layers.\n- We add a fully-connected (``dense``) layer with 10 outputs.\n- We add a softmax activation (appropriate for classification tasks like MNIST),\n  and mark it as producing labels (``name: labels``).\n\nAnd that's it! It's pretty naïve: one convolution + activation +\nfully-connected + activation.  But it works: we got 90% accuracy after only\nshowing it a small subset of the training set.\n\nBut let's think about make it more complicated. What if we want two\nconvolutional layers instead? Easy! Just add another ``convolution`` section to\nthe model.  We'll also add in another non-linearity (ReLU activation) between\nthe two convolutions.\n\n.. code-block:: yaml\n\n\tmodel:\n\t  - input: images\n\t  - convolution:\n\t      kernels: 64\n\t      size: [3, 3]\n\t  - activation: relu\n\t  - convolution:\n\t      kernels: 64\n\t      size: [3, 3]\n\t  - activation: relu\n\t  - flatten:\n\t  - dense: 10\n\t  - activation: softmax\n\t    name: labels\n\nWe can also add more dense (fully-connected) layers. You probably want them\nseparated by activation layers, too. So if we add a 32-node fully-connected\nlayer to our model, it now looks like this:\n\n.. code-block:: yaml\n\n\tmodel:\n\t  - input: images\n\t  - convolution:\n\t      kernels: 64\n\t      size: [3, 3]\n\t  - activation: relu\n\t  - convolution:\n\t      kernels: 64\n\t      size: [3, 3]\n\t  - activation: relu\n\t  - flatten:\n\t  - dense: 32\n\t  - activation: relu\n\t  - dense: 10\n\t  - activation: softmax\n\t    name: labels\n\nLet's give it a try! Save your changes, a just run the same ``kur train\nmnist.yml`` and ``kur evaluate mnist.yml`` commands from before.\n\n**NOTE**: A more complex model will likely need more data. So be sure to look\nat the tip in `More Advanced Things`_ to train on more of the data set.\n\nIf you want to know more, the YAML specification that Kur uses is described in\ngreater detail in our `Using Kur\n\u003Chttps:\u002F\u002Fkur.deepgram.com\u002Fgetting_started.html>`_ page.\n\n.. _more_advanced_things:\n\nMore Advanced Things\n--------------------\n\nThe one line in the ``mnist.yml`` specification that we didn't cover is the\n``include: mnist-defaults.yml`` line. This is just a convenient way for us to\nseparate out the default behavior of the MNIST example.\n\nIf you tweak this file, probably the big thing you want to remove is the\n``num_batches: 10`` line, which is what limits training to just the first 10\nbatches every epoch. Just delete the line or comment it out, and Kur will train\non the whole dataset.\n\nA Better MNIST\n--------------\n\n90% is pretty good! But can we do better? Absolutely! Let's see how.\n\nWe need to build a more expressive, deeper model. We will use more\nconvolutional layers, with occassional pooling layers. \n\n.. code-block:: yaml\n\n\tmodel:\n\t  - input: images\n\n\t  - convolution:\n\t      kernels: 64\n\t      size: [3, 3]\n\t  - activation: relu\n\n\t  - convolution:\n\t      kernels: 96\n\t      size: [3, 3]\n\t  - activation: relu\n\n\t  - pool: [3, 3]\n\n\t  - convolution:\n\t      kernels: 96\n\t      size: [3, 3]\n\t  - activation: relu\n\n\t  - flatten:\n\t  - dense: [64, 10]\n\n\t  - activation: softmax\n\t    name: labels\n\nSo we have three convolutions with a 3-by-3 pooling layer in the middle, and\ntwo fully-connected layers.  Try training this model: ``kur train mnist.yml``.\nThen evaluate it to see how it does: ``kur eval mnist.yml``. We got better than\n95% *by training on only 0.8% of the training set*.\n\nWhat happens if we give it more data? Like we `mentioned above`__, we can\nadjust the amount of data we give Kur by twiddling the ``num_batches`` entry in\nthe ``train`` section of ``mnist-defaults.yml``. Let's try using 5% of the\ndataset.  To do this, we'll set ``num_batches: 94`` (because 5% of 60,000 is\n3000, and for the default batch size of 32, this comes out to about 94\nbatches). Now try training and evaluating again. We got almost 98%!\n\n__ more_advanced_things_\n\nDon't stop now, let's train on the whole thing (just remove the ``num_batches``\nline altogether, or set ``num_batches: null``). Still training only 10 epochs,\nwe got 98.6%. Wow. Let's compare this to state of the art, which Yann LeCun\ntracks on the `MNIST website \u003Chttp:\u002F\u002Fyann.lecun.com\u002Fexdb\u002Fmnist\u002F>`_. It looks\nlike the best error rate also uses convolutions and achieved a 0.23% error rate\n(so 99.77% accuracy). With just a couple tweaks, we are already only a percent\naway from the world's best. Kur rocks.\n\n.. _cifar_10:\n\nCIFAR-10: Image Classification\n==============================\n\nOkay, MNIST was pretty cool, but Kur can do much, much more. Imagine if you\nwanted to have an arbitrary number of convolution layers. Imagine if each\nconvolution should have a different number of kernels. Imagine if you truly\nwant *flexibility*. You've come to the right place.\n\nFlexibility: Variables\n----------------------\n\nKur uses an *engine* to determine how do variable substitution. `Jinja2\n\u003Chttp:\u002F\u002Fjinja.pocoo.org>`_ is the default templating engine, and it is very\npowerful and extensible. Let's see how to use it!\n\nLet's look at the `CIFAR-10 \u003Chttps:\u002F\u002Fwww.cs.toronto.edu\u002F~kriz\u002Fcifar.html>`_\ndataset. This is a image classification dataset of small 32 by 32 pixel color\n(RGB) images, each with one of ten classes (airplane, automobile, bird, cat,\ndeer, dog, frog, horse, ship, truck). You might decide to start with a very\nsimilar model to the MNIST example:\n\n.. code-block:: yaml\n\n\tmodel:\n\t  - input: images\n\t  - convolution:\n\t      kernels: 64\n\t      size: [3, 3]\n\t  - activation: relu\n\t  - flatten:\n\t  - dense: 10\n\t  - activation: softmax\n\t    name: labels\n\nWe will start with a simple modification: let's make the convolution `size` a\nvariable, so we can easily change it later. We can do it like this:\n\n.. code-block:: yaml\n\n\tsettings:\n\t  cnn:\n\t    size: [3, 3]\n\n\tmodel:\n\t  - input: images\n\t  - convolution:\n\t      kernels: 64\n\t      size: \"{{ cnn.size }}\"\n\t  - activation: relu\n\t  - flatten:\n\t  - dense: 10\n\t  - activation: softmax\n\t    name: labels\n\nOkay, what just happened? First, we added a ``settings:`` section. This section\nis the appropriate place to declare variables, settings, and hyperparameters\nthat will be used by the model (or for training, evaluation, etc.). We declared\na variable named ``cnn`` with a nested ``size`` variable. In Python, this would\nbe equivalent to a dictionary: ``{\"cnn\": {\"size\": [3, 3]}}``.\n\nThen we used the variable in the model's convolution layer: ``size: \"{{\ncnn.size }}\"``.  This is standard Jinja2 grammar. The double-brackets indicate\nthat variable substitution should take place (without the brackets, we would\naccidently assign ``size`` to the literal string \"cnn.size\", which doesn't make\nsense). The variable we grab is ``cnn.size``, corresponding to the variables we\nadded in the ``settings`` section.\n\nCool! So we can use variables now. But how does that help us? It seems like we\njust made it more complicated. Well, let's imagine if we added another\nconvolution layer. We already know how to add extra convolutions by just adding\nanother `convolution` block (and usually you want another `activation: relu`\nlayer, too). So this would look like:\n\n.. code-block:: yaml\n\n\tsettings:\n\t  cnn:\n\t    size: [3, 3]\n\n\tmodel:\n\t  - input: images\n\t  - convolution:\n\t      kernels: 64\n\t      size: \"{{ cnn.size }}\"\n\t  - activation: relu\n\t  - convolution:\n\t      kernels: 64\n\t      size: \"{{ cnn.size }}\"\n\t  - activation: relu\n\t  - flatten:\n\t  - dense: 10\n\t  - activation: softmax\n\t    name: labels\n\nAh! So now we can see why variablizing the convolution size was nice: if we\nwant to play with a model that uses different size kernels, we only need to\nedit one line instead of two.\n\nBut there are still two problems we might encounter:\n\n- What if we wanted to try out lots of models with different numbers of\n  convolutions?\n- What if we wanted to use *different* ``size`` or ``kernel`` values in each\n  convolution?\n\nKur can do it!\n\nFlexibility: Loops\n------------------\n\nLet's address the first problem: what if we want to make the number of\nconvolutions? Kur supports many \"meta-layers\" that it calls \"operators.\" A\nvery simple operator is the classic `\"for\" loop\n\u003Chttps:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FFor_loop>`_. This allows us to add many\nconvolution + activation layers at once. It looks like this:\n\n.. code-block:: yaml\n\n\tsettings:\n\t  cnn:\n\t    size: [3, 3]\n\n\tmodel:\n\t  - input: images\n\t  - for:\n\t      range: 2\n\t      iterate:\n\t        - convolution:\n\t            kernels: 64\n\t            size: \"{{ cnn.size }}\"\n\t        - activation: relu\n\t  - flatten:\n\t  - dense: 10\n\t  - activation: softmax\n\t    name: labels\n\nThis is equivalent to the version without the \"for\" loop. The ``for:`` loop\ntells us to do everything in the ``iterate:`` section twice. (Why twice?\nBecause ``range: 2``.) And of course, we can variabilize the number of\niterations like this:\n\n.. code-block:: yaml\n\n\tsettings:\n\t  cnn:\n\t    size: [3, 3]\n\t    layers: 2\n\n\tmodel:\n\t  - input: images\n\t  - for:\n\t      range: \"{{ cnn.layers }}\"\n\t      iterate:\n\t        - convolution:\n\t            kernels: 64\n\t            size: \"{{ cnn.size }}\"\n\t        - activation: relu\n\t  - flatten:\n\t  - dense: 10\n\t  - activation: softmax\n\t    name: labels\n\nThink about this for a minute. Does it make sense? It should. The model looks\nlike this:\n\n- An ``input`` layer of images.\n- A number of ``convolution`` and ``activation`` layers. How many?\n  ``cnn.layers``, so 2.\n- The rest of the model is as expected: a dense operation followed by an\n  activation.\n\nFlexibility: Variable-length Loops\n----------------------------------\n\nSo we solved the problem of allowing for a variable number of convolutions. But\nwhat if each convolution should use a different number of kernels (or sizes,\netc.)?  Well, Kur can happily handle this, too. In fact, the ``for:`` loop\nalready does most of the work. Every ``for:`` loop creates its own \"local\"\nvariable to let you know which iteration it is on. The default name for this\nvariable is ``index``. So if we want to use a different number of kernels for\neach convolution, we can do this:\n\n.. code-block:: yaml\n\n\tsettings:\n\t  cnn:\n\t    size: [3, 3]\n\t    kernels: [64, 32]\n\t    layers: 2\n\n\tmodel:\n\t  - input: images\n\t  - for:\n\t      range: \"{{ cnn.layers }}\"\n\t      iterate:\n\t        - convolution:\n\t            kernels: \"{{ cnn.kernels[index] }}\"\n\t            size: \"{{ cnn.size }}\"\n\t        - activation: relu\n\t  - flatten:\n\t  - dense: 10\n\t  - activation: softmax\n\t    name: labels\n\nAgain, this is just Jinja2 substitution: we are asking for the ``index``-th\nelement of the ``cnn.kernels`` list. Each iteration of the ``for:`` loop\ntherefore grabs a different value for ``kernels:``. Cool, huh?\n\nBut we can do one better.\n\nFlexibility: Filters\n--------------------\n\nThe annoying thing about our current model is that nothing forces the ``layers``\nvalue to be the same as the length of the ``kernels`` variable. If you make\nreally long (like, length seventeen) but leave ``layers`` at two, you probably\nmade a mistake. (Why did you put in seventeen layers but then only use the first\ntwo in the loop?) What you really want is to make sure that ``layers`` is set to\nthe length of the ``kernels`` list. Or put another way, you want add as many\nconvolutions as you have kernels in the list.\n\nJinja2 supports a concept called \"filters,\" which are basically functions that\nyou can apply to objects. You can even define your own filters. But what we\nwant right now is a way to get the length of a list. It's easy and it looks\nlike this:\n\n.. code-block:: yaml\n\n\tsettings:\n\t  cnn:\n\t    size: [3, 3]\n\t    kernels: [64, 32]\n\n\tmodel:\n\t  - input: images\n\t  - for:\n\t      range: \"{{ cnn.kernels|length }}\"\n\t      iterate:\n\t        - convolution:\n\t            kernels: \"{{ cnn.kernels[index] }}\"\n\t            size: \"{{ cnn.size }}\"\n\t        - activation: relu\n\t  - flatten:\n\t  - dense: 10\n\t  - activation: softmax\n\t    name: labels\n\nYou'll notice that the ``layers`` variable is gone, and we have this funky\n``|length`` thing in the \"for\" loop's ``range``. This is standard Jinja2: the\n``length`` filter returns the length of a list. So now we are asking the \"for\"\nloop to iterate as many times as we have another kernel size.\n\nThis is really cool if you think about it. You want to add another convolution\nto the network? *All you do is add it's size to the* ``kernels`` *list*. And\nlook!  You're model is now more general, more reuseable. You could have used\nthe same model for MNIST! Or CIFAR! Or many different applications.\n\nThis is the heart of the **Kur philosophy: you should describe your model once\nand simply.** The specification *describes** your model: a bunch of\nconvolutions and then a fully-connected layer. You can specify the details (how\nmany convolutions, their parameters, etc.) elsewhere. The model should stay\nelegant.\n\n**NOTE**: Of course, it isn't always easy to write reusable models. And the\nlearning curve can get in the way. When we say that models should be \"simple,\"\nwe don't mean that you don't need to think about it. We mean that it should be\nsimple to use, simple to modify, and simple to share. A more general model is\nelegant: making changes to it is easy (you only modify the settings). And this\nmakes it easier to reuse in new contexts or to share with the community.\nSimplicity is power.\n\nActually Training a CIFAR-10 Model\n----------------------------------\n\nGreat, we now have a simple, but powerful and general model. Let's train it. As\nbefore, you'll need to ``cd examples`` first.\n\n.. code-block:: bash\n\n\tkur train cifar.yml\n\nAgain, evaluation is just as simple:\n\n.. code-block:: bash\n\n\tkur evaluate cifar.yml\n\nAdvanced Features\n-----------------\n\nThe ``cifar.yml`` specification file is more complicated than the MNIST one,\nmostly to expose you to some more knobs you can tweak. For example, you'll see\nthese lines in the ``train`` section:\n\n.. code-block:: yaml\n\n\tprovider:\n\t  batch_size: 32\n\t  num_batches: 2\n\nAs in the MNIST case, ``num_batches`` tells Kur to only train on that many\nbatches of data each epoch (mostly so that if you don't have a nice GPU, the\nexample still finishes in a reasonable amount of time). The ``batch_size`` value\nindicates the number of training samples that should be used in each batch.\n\n.. _using_binary_logger:\n\nThe ``train`` section also has a ``log: cifar-log`` line. This tells Kur to\nsave a log file to ``cifar-log`` (in the current working directory). This log\ncontains lots of interesting information about current training loss, batch\nloss, and the number of epochs. By default, they are binary-encoded files, but\nyou can load them using the Kur API (in Python 3):\n\n.. code-block:: python\n\n\tfrom kur.loggers import BinaryLogger\n\tdata = BinaryLogger.load_column(LOG_PATH, STATISTIC)\n\nwhere ``LOG_PATH`` is the path to the log file (e.g., ``cifar-log``) and\n``STATISTIC`` is one of the logged statistics. ``data`` will be a `Numpy\n\u003Chttp:\u002F\u002Fwww.numpy.org\u002F>`_ array. To find available statistics, just list the\navailable files in the ``LOG_PATH``, like this:\n\n.. code-block:: bash\n\n\t$ ls cifar-log\n\ttraining_loss_labels\n\ttraining_loss_total\n\tvalidation_loss_labels\n\tvalidation_loss_total\n\nFor an example of using this log data, see our Tutorial_.\n\nAnother difference from the MNIST examples is that there are more files\nreferring to weights in the CIFAR specification. For example, in the\n``validate`` section there is:\n\n.. code-block:: yaml\n\n\tweights: cifar.best.valid.w\n\nThis tells Kur to save the best models weights (corresponding to the lowest\nloss on the *validation* set) to ``cifar.best.valid.w``. Similarly, in the\n``train`` section there is this:\n\n.. code-block:: yaml\n\n\tweights:\n\t  initial: cifar.best.valid.w\n\t  save_best: cifar.best.train.w\n\t  last: cifar.last.w\n\nThe ``initial`` key tells Kur to try and load ``cifar.best.valid.w`` (the best\nweights with respect to the *validation* loss) at the beginning of training. If\nthis file doesn't exist, nothing happens. This means that if you run the\ntraining cycle many times (with many calls to ``kur train cifar.yml``), you\nalways \"restart\" from the best model weights.\n\nWe are also saving the best weights (with respect to the *training* loss) to\n``cifar.best.train.w``.  The most recent weights are saved to ``cifar.last.w``. \n\n**NOTE**: The weights depend on the model architecture. Say you you train CIFAR\nand produce ``cifar.best.valid.w``. Then you tweak the model in the\nspecification file. If you try to resume training (``kur train cifar.yml``),\nKur will try to load ``cifar.best.valid.w``. But the weights many not fit the\nnew architecture! So, to be safe, you should always delete (or backup) your\nweight files before trying to train a fresh, tweaked model. In a production\nenvironment, you probably want to have different sub-directories for each\nvariation\u002Ftweak to the model so that you never run into this problem.\n\nThe CIFAR-10 example also explicitly specifies an optimizer in the ``train``\nsection:\n\n.. code-block:: yaml\n\n\toptimizer:\n\t  name: adam\n\t  learning_rate: 0.001\n\nThe optimizer function is set in the ``name`` field and all other parameters\n(such as ``learning_rate``) are defined in the other fields. You can safely\nchange the optimizer without breaking backwards-compatibility with older weight\nfiles.\n",".. |LICENSE| image:: https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Flicense-Apache%202-blue.svg\n   :target: https:\u002F\u002Fgithub.com\u002Fdeepgram\u002Fkur\u002Fblob\u002Fmaster\u002FLICENSE\n.. |PYTHON| image:: https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fpython-3.4%2C3.5%2C3.6-lightgrey.svg\n   :target: https:\u002F\u002Fkur.deepgram.com\u002Finstalling.html\n.. |BUILD| image:: https:\u002F\u002Ftravis-ci.org\u002Fdeepgram\u002Fkur.svg?branch=master\n   :target: https:\u002F\u002Ftravis-ci.org\u002Fdeepgram\u002Fkur\n.. |GITTER| image:: https:\u002F\u002Fbadges.gitter.im\u002Fdeepgram-kur\u002FLobby.svg\n   :target: https:\u002F\u002Fgitter.im\u002Fdeepgram-kur\u002FLobby\n\n.. _Facebook: https:\u002F\u002Fwww.facebook.com\u002Fsharer\u002Fsharer.php?u=https%3A\u002F\u002Fkur.deepgram.com\n.. _Google+: https:\u002F\u002Fplus.google.com\u002Fshare?url=https%3A\u002F\u002Fkur.deepgram.com\n.. _LinkedIn: https:\u002F\u002Fwww.linkedin.com\u002FshareArticle?mini=true&url=https%3A\u002F\u002Fkur.deepgram.com&title=Kur%20-%20descriptive%20deep%20learning&summary=Kur%20is%20the%20future%20of%20deep%20learning%3A%20advanced%20AI%20without%20programming!&source=\n.. _Twitter: https:\u002F\u002Ftwitter.com\u002Fhome?status=%40DeepgramAI%20has%20released%20the%20future%20of%20deep%20learning.%20https%3A\u002F\u002Fkur.deepgram.com%20%23Kur\n\n.. image:: https:\u002F\u002Fkur.deepgram.com\u002Fimages\u002Flogo-small.png\n   :align: center\n   :target: https:\u002F\u002Fdeepgram.com\n\n.. package_readme_starts_here\n\n.. _Tutorial: https:\u002F\u002Fkur.deepgram.com\u002Ftutorial.html\n\n******************************\nKur：描述式深度学习\n******************************\n\n.. package_readme_ignore\n\n|BUILD| |LICENSE| |PYTHON| |GITTER|\n\n引言\n====\n\n欢迎使用 Kur！你已经找到了深度学习的未来！\n\n- 通过 ``pip install kur`` 轻松安装 Kur。\n- 在无需编写任何代码的情况下设计、训练和评估模型。\n- 使用易于理解的概念来描述你的模型。\n- 利用强大的 `Jinja2 \u003Chttp:\u002F\u002Fjinja.pocoo.org>`_ 模板引擎，快速探索模型的改进版本。\n- 支持 Theano、TensorFlow 和 PyTorch，并且开箱即用支持 **多 GPU**。\n- **即将推出**：与社区共享你的模型，使协作构建复杂模型变得极其容易。\n\n赶快试一试吧：`获取代码`_，然后进入 `示例`_！接着在我们的教程_中构建你自己的模型。别忘了访问我们的 `主页 \u003Chttps:\u002F\u002Fkur.deepgram.com>`_，以获取完整的文档和最新资讯。\n\n.. package_readme_ignore\n\n喜欢我们吗？分享一下吧！\n\n.. package_readme_ignore\n\n- Facebook_\n- `Google+`_\n- LinkedIn_\n- Twitter_\n\n什么是 Kur？\n------------\n\nKur 是一个用于快速构建和应用最先进深度学习模型的系统，能够解决各种新颖而令人兴奋的问题。Kur 的设计旨在吸引整个机器学习社区，无论是初学者还是资深从业者。它使用简单易读且易于编写的配置文件，这意味着你可以开始构建复杂的模型，*而无需编写任何代码*。尽管如此，Kur 还提供了一个友好且可扩展的 API，以支持高级深度学习架构或工作流。心动了吗？直接跳到 `示例`_ 吧。\n\n.. _get_the_code:\n\n获取代码\n========\n\nKur 的安装非常简单！你可以选择以下两种方式之一来安装 Kur。\n\n**注意**：Kur 需要 **Python 3.4** 或更高版本。请参阅我们的 `安装指南 \u003Chttps:\u002F\u002Fkur.deepgram.com\u002Finstall.html>`_，其中包含安装 Kur 和设置 `虚拟环境 \u003Chttps:\u002F\u002Fvirtualenv.pypa.io\u002F>`_ 的分步说明。\n\n最新 Pip 版本\n----------------\n\n如果你熟悉操作，那么这很简单：\n\n.. code-block:: bash\n\n\tpip install kur\n\n最新开发版本\n-------------\n\n只需克隆仓库并运行安装脚本：\n\n.. code-block:: bash\n\n\tgit clone https:\u002F\u002Fgithub.com\u002Fdeepgram\u002Fkur\n\tcd kur\n\tpip install .\n\n**快速入门**：或者，如果你已经安装了 `Python 3 \u003Chttps:\u002F\u002Fkur.deepgram.com\u002Finstalling.html>`_，那么只需几行命令即可开始训练你的第一个模型：\n\n**使用 pip 的快速入门：**\n\n.. code-block:: bash\n\n\tpip install virtualenv                      # 确保已安装 virtualenv\n\tvirtualenv -p $(which python3) ~\u002Fkur-env    # 创建一个用于 Kur 的 Python 3 环境\n\t. ~\u002Fkur-env\u002Fbin\u002Factivate                    # 激活 Kur 环境\n\tpip install kur                             # 安装 Kur\n\tkur --version                               # 检查是否正常工作\n\tgit clone https:\u002F\u002Fgithub.com\u002Fdeepgram\u002Fkur   # 获取示例\n\tcd kur\u002Fexamples                             # 进入示例目录\n\tkur train mnist.yml                         # 开始训练！\n\n**使用 git 的快速入门：**\n\n.. code-block:: bash\n\n\tpip install virtualenv                      # 确保已安装 virtualenv\n\tvirtualenv -p $(which python3) ~\u002Fkur-env    # 创建一个用于 Kur 的 Python 3 环境\n\t. ~\u002Fkur-env\u002Fbin\u002Factivate                    # 激活 Kur 环境\n\tgit clone https:\u002F\u002Fgithub.com\u002Fdeepgram\u002Fkur   # 克隆最新代码\n\tcd kur                                      # 进入库目录\n\tpip install .                               # 安装 Kur\n\tkur --version                               # 检查是否正常工作\n\tcd examples                                 # 进入示例目录\n\tkur train mnist.yml                         # 开始训练！\n\n使用方法\n--------\n\n如果一切顺利，你应该可以正常使用 Kur：\n\n.. code-block:: bash\n\n\tkur --version\n\n通常你会使用类似 ``kur train model.yml`` 或 ``kur test model.yml`` 的命令。这些命令可以在 `示例`_ 中找到，这也是你接下来应该去的地方！\n\n故障排除\n---------\n\n如果你在安装或使用 Kur 时遇到任何问题，请查看我们的 `故障排除页面 \u003Chttps:\u002F\u002Fkur.deepgram.com\u002Ftroubleshooting.html>`_，那里有许多有用的帮助信息。如果你想获得更详细的安装说明，包括如何设置环境，请务必参考我们的 `安装页面 \u003Chttps:\u002F\u002Fkur.deepgram.com\u002Finstalling.html>`_。\n\n.. package_readme_ends_here\n\n.. _the_examples:\n\n示例\n********\n\n让我们来看几个例子，了解 Kur 如何让最先进的深度学习变得既有趣又简单。\n\n.. _mnist_example:\n\nMNIST：手写数字识别\n===================\n\n让我们直接上手，看看 Kur 有多强大！第一个例子是 Yann LeCun 的 `MNIST \u003Chttp:\u002F\u002Fyann.lecun.com\u002Fexdb\u002Fmnist\u002F>`_ 数据集。这是一个包含 28x28 像素图像的数据集，每张图像代表 0 到 9 之间的单个手写数字。我们的目标是构建一个图像识别模型，为每张图像打上最可能的数字标签。\n\n**注意**：与大多数命令行示例一样，以 ``$`` 开头的行是你需要输入的命令（后接 ``ENTER`` 键）。没有 ``$`` 的行则是屏幕上显示的内容，你不需要输入。\n\n首先，你需要 `获取代码`_！如果你是通过 ``pip`` 安装的，那么你需要从仓库中检出 ``examples`` 目录，如下所示：\n\n.. code-block:: bash\n\n\tgit clone https:\u002F\u002Fgithub.com\u002Fdeepgram\u002Fkur\n\tcd kur\u002Fexamples\n\n如果你通过 ``git`` 安装了 Kur，那么你本地就已经有了 ``examples`` 目录，可以直接进入该目录：\n\n.. code-block:: bash\n\n\t$ cd examples\n\n现在让我们来训练 MNIST 模型。这会直接从网上下载数据，然后开始训练 10 个 epoch。\n\n.. code-block:: bash\n\n\t$ kur train mnist.yml\n\tDownloading: 100%|█████████████████████████████████| 9.91M\u002F9.91M [03:44\u003C00:00, 44.2Kbytes\u002Fs]\n\tDownloading: 100%|█████████████████████████████████| 28.9K\u002F28.9K [00:00\u003C00:00, 66.1Kbytes\u002Fs]\n\tDownloading: 100%|█████████████████████████████████| 1.65M\u002F1.65M [00:31\u003C00:00, 52.6Kbytes\u002Fs]\n\tDownloading: 100%|█████████████████████████████████| 4.54K\u002F4.54K [00:00\u003C00:00, 19.8Kbytes\u002Fs]\n\n\tEpoch 1\u002F10, loss=1.524: 100%|███████████████████████| 480\u002F480 [00:02\u003C00:00, 254.97samples\u002Fs]\n\tValidating, loss=0.829: 100%|█████████████████████| 3200\u002F3200 [00:03\u003C00:00, 889.91samples\u002Fs]\n\n\tEpoch 2\u002F10, loss=0.628: 100%|███████████████████████| 480\u002F480 [00:02\u003C00:00, 228.25samples\u002Fs]\n\tValidating, loss=0.533: 100%|████████████████████| 3200\u002F3200 [00:03\u003C00:00, 1046.12samples\u002Fs]\n\n\tEpoch 3\u002F10, loss=0.547: 100%|███████████████████████| 480\u002F480 [00:02\u003C00:00, 185.77samples\u002Fs]\n\tValidating, loss=0.491: 100%|████████████████████| 3200\u002F3200 [00:03\u003C00:00, 1030.57samples\u002Fs]\n\n\tEpoch 4\u002F10, loss=0.488: 100%|███████████████████████| 480\u002F480 [00:02\u003C00:00, 225.42samples\u002Fs]\n\tValidating, loss=0.443: 100%|████████████████████| 3200\u002F3200 [00:03\u003C00:00, 1046.23samples\u002Fs]\n\n\tEpoch 5\u002F10, loss=0.464: 100%|███████████████████████| 480\u002F480 [00:03\u003C00:00, 115.17samples\u002Fs]\n\tValidating, loss=0.403: 100%|█████████████████████| 3200\u002F3200 [00:04\u003C00:00, 799.46samples\u002Fs]\n\n\tEpoch 6\u002F10, loss=0.486: 100%|███████████████████████| 480\u002F480 [00:03\u003C00:00, 183.11samples\u002Fs]\n\tValidating, loss=0.400: 100%|████████████████████| 3200\u002F3200 [00:02\u003C00:00, 1134.17samples\u002Fs]\n\n\tEpoch 7\u002F10, loss=0.369: 100%|███████████████████████| 480\u002F480 [00:02\u003C00:00, 214.10samples\u002Fs]\n\tValidating, loss=0.366: 100%|█████████████████████| 3200\u002F3200 [00:04\u003C00:00, 735.61samples\u002Fs]\n\n\tEpoch 8\u002F10, loss=0.353: 100%|███████████████████████| 480\u002F480 [00:03\u003C00:00, 204.33samples\u002Fs]\n\tValidating, loss=0.351: 100%|████████████████████| 3200\u002F3200 [00:02\u003C00:00, 1147.05samples\u002Fs]\n\n\tEpoch 9\u002F10, loss=0.399: 100%|███████████████████████| 480\u002F480 [00:02\u003C00:00, 219.17samples\u002Fs]\n\tValidating, loss=0.343: 100%|████████████████████| 3200\u002F3200 [00:02\u003C00:00, 1149.07samples\u002Fs]\n\n\tEpoch 10\u002F10, loss=0.307: 100%|██████████████████████| 480\u002F480 [00:02\u003C00:00, 220.97samples\u002Fs]\n\tValidating, loss=0.324: 100%|████████████████████| 3200\u002F3200 [00:02\u003C00:00, 1142.78samples\u002Fs]\n\n刚才发生了什么？Kur 从 LeCun 的网站下载了 MNIST 数据集，然后训练了一个模型，共进行了十轮迭代。太棒了！\n\n接下来我们来看看模型的实际表现如何：\n\n.. code-block:: bash\n\n\t$ kur evaluate mnist.yml\n\tEvaluating: 100%|██████████████████████████████| 10000\u002F10000 [00:06\u003C00:00, 1537.74samples\u002Fs]\n\tLABEL     CORRECT   TOTAL     ACCURACY  \n\t0         969       980        98.9%\n\t1         1118      1135       98.5%\n\t2         910       1032       88.2%\n\t3         926       1010       91.7%\n\t4         923       982        94.0%\n\t5         735       892        82.4%\n\t6         871       958        90.9%\n\t7         884       1028       86.0%\n\t8         818       974        84.0%\n\t9         868       1009       86.0%\n\tALL       9022      10000      90.2%\n\n哇！我们的模型在识别手写数字方面已经达到了 90% 的准确率，而且只使用了 0.8% 的训练集！这就是 Kur 的强大之处。\n\n是不是很兴奋？继续往下读吧！\n\n**注意**：细心的读者会发现，每一轮训练只使用了 480 个样本。但 MNIST 总共有 60,000 个训练样本，这是怎么回事呢？很简单：我们中的许多人都是在消费级硬件上运行这段代码；事实上，我就是在一台搭载 Intel Core m7 CPU 的小型超极本上运行这个示例。正如你在 `Under the Hood`_ 中所看到的，我将训练过程截断为仅训练 10 个批次，每个批次 32 个样本，这样可以让训练循环在合理的时间内完成。这并不是作弊：你仍然可以获得 90% 的准确率！不过，如果你拥有强大的硬件，或者只是想看看你的模型能达到多高的准确率，那就请继续阅读，我们会教你如何进行调整。\n\nUnder the Hood\n--------------\n\n那么这里到底发生了什么呢？让我们来看看 MNIST 示例的配置文件：\n\n.. code-block:: yaml\n\n\ttrain:\n\t  data:\n\t    - mnist:\n\t        images:\n\t          url: \"http:\u002F\u002Fyann.lecun.com\u002Fexdb\u002Fmnist\u002Ftrain-images-idx3-ubyte.gz\"\n\t        labels:\n\t          url: \"http:\u002F\u002Fyann.lecun.com\u002Fexdb\u002Fmnist\u002Ftrain-labels-idx1-ubyte.gz\"\n\n\tmodel:\n\t  - input: images\n\t  - convolution:\n\t      kernels: 64\n\t      size: [3, 3]\n\t  - activation: relu\n\t  - flatten:\n\t  - dense: 10\n\t  - activation: softmax\n\t    name: labels\n\n\tinclude: mnist-defaults.yml\n\n这只是一个普通的 `YAML \u003Chttp:\u002F\u002Fyaml.org>`_ 文件，这是一种旨在便于人类理解的标记语言（有关 YAML 语言特性的详细介绍，请参阅 `Ansible 概述 \u003Chttps:\u002F\u002Fdocs.ansible.com\u002Fansible\u002FYAMLSyntax.html>`_）。\n\n其中有一部分用于定义数据：\n\n.. code-block:: yaml\n\n\ttrain:\n\t  data:\n\t    - mnist:\n\t        images:\n\t          url: \"http:\u002F\u002Fyann.lecun.com\u002Fexdb\u002Fmnist\u002Ftrain-images-idx3-ubyte.gz\"\n\t        labels:\n\t          url: \"http:\u002F\u002Fyann.lecun.com\u002Fexdb\u002Fmnist\u002Ftrain-labels-idx1-ubyte.gz\"\n\n然后还有一部分用于定义模型：\n\n.. code-block:: yaml\n\n\tmodel:\n\t  - input: images\n\t  - convolution:\n\t      kernels: 64\n\t      size: [3, 3]\n\t  - activation: relu\n\t  - flatten:\n\t  - dense: 10\n\t  - activation: softmax\n\t    name: labels\n\n此外还有一个 ``include`` 部分，包含了默认设置（高级用户可能会想要调整这些设置——不用担心，操作依然很简单）：\n\n.. code-block:: yaml\n\n\tinclude: mnist-defaults.yml\n\n非常简单！Kur 已经帮我们从 LeCun 的网站直接下载了数据，这一点很容易理解。那么一个 Kur 模型究竟包含哪些内容呢？其实就是一个清晰、简洁的列表，列出了你希望深度学习模型执行的操作。我们来逐条解析：\n\n- 我们有一个名为 ``images`` 的输入（没错，它与 ``train`` 部分中的 ``images`` 是同一个）。\n- 将输入传递给一个卷积层。\n- 添加一个修正线性单元（ReLU）激活函数。\n- 将卷积层输出的高维特征图展平成一维向量，以便送入全连接层。\n- 添加一个有 10 个输出的全连接层。\n- 添加一个适合分类任务（如 MNIST）的 Softmax 激活函数，并将其标记为生成标签（``name: labels``）。\n\n就这么简单！虽然结构相当朴素——一次卷积 + 激活 + 全连接 + 激活——但它确实有效：我们只用了训练集的一小部分，就达到了 90% 的准确率。\n\n但是，让我们试着让它变得更复杂一些。如果我们想要两个卷积层呢？很简单！只需在模型中再添加一个“卷积”部分即可。我们还将在两个卷积层之间加入另一个非线性激活函数（ReLU）。\n\n.. code-block:: yaml\n\n\tmodel:\n\t  - input: images\n\t  - convolution:\n\t      kernels: 64\n\t      size: [3, 3]\n\t  - activation: relu\n\t  - convolution:\n\t      kernels: 64\n\t      size: [3, 3]\n\t  - activation: relu\n\t  - flatten:\n\t  - dense: 10\n\t  - activation: softmax\n\t    name: labels\n\n我们还可以添加更多的全连接层。你可能也希望这些层之间用激活层隔开。因此，如果我们在模型中加入一个包含32个节点的全连接层，那么现在的模型看起来就会是这样：\n\n.. code-block:: yaml\n\n\tmodel:\n\t  - input: images\n\t  - convolution:\n\t      kernels: 64\n\t      size: [3, 3]\n\t  - activation: relu\n\t  - convolution:\n\t      kernels: 64\n\t      size: [3, 3]\n\t  - activation: relu\n\t  - flatten:\n\t  - dense: 32\n\t  - activation: relu\n\t  - dense: 10\n\t  - activation: softmax\n\t    name: labels\n\n让我们试一试吧！保存你的更改，然后运行之前相同的 ``kur train mnist.yml`` 和 ``kur evaluate mnist.yml`` 命令。\n\n**注意**：更复杂的模型通常需要更多的数据。因此，请务必查看 `更高级的内容`_ 中的提示，以使用更多数据集进行训练。\n\n如果你想了解更多，Kur 所使用的 YAML 规范在我们的 `使用 Kur \u003Chttps:\u002F\u002Fkur.deepgram.com\u002Fgetting_started.html>`_ 页面中有更详细的说明。\n\n.. _more_advanced_things:\n\n更高级的内容\n--------------------\n\n在 ``mnist.yml`` 规范中，我们没有提到的一行是 ``include: mnist-defaults.yml``。这只是我们用来将 MNIST 示例的默认行为分离出来的一种便捷方式。\n\n如果你调整这个文件，可能最需要删除的是 ``num_batches: 10`` 这一行，它限制了每个 epoch 只训练前 10 个批次。只需删除这一行或将其注释掉，Kur 就会使用整个数据集进行训练。\n\n更好的 MNIST\n--------------\n\n90% 已经相当不错了！但我们还能做得更好吗？当然可以！让我们来看看如何实现。\n\n我们需要构建一个更具表现力、更深的模型。我们将使用更多的卷积层，并偶尔加入池化层。\n\n.. code-block:: yaml\n\n\tmodel:\n\t  - input: images\n\n\t  - convolution:\n\t      kernels: 64\n\t      size: [3, 3]\n\t  - activation: relu\n\n\t  - convolution:\n\t      kernels: 96\n\t      size: [3, 3]\n\t  - activation: relu\n\n\t  - pool: [3, 3]\n\n\t  - convolution:\n\t      kernels: 96\n\t      size: [3, 3]\n\t  - activation: relu\n\n\t  - flatten:\n\t  - dense: [64, 10]\n\n\t  - activation: softmax\n\t    name: labels\n\n所以我们有三个卷积层，中间有一个 3x3 的池化层，以及两个全连接层。尝试训练这个模型：``kur train mnist.yml``。然后评估它的表现：``kur eval mnist.yml``。我们仅用训练集的 0.8% 就达到了超过 95% 的准确率。\n\n如果我们给它更多的数据会怎样呢？正如我们 `上面提到的`__ 一样，可以通过调整 ``mnist-defaults.yml`` 文件中 ``train`` 部分的 ``num_batches`` 来改变 KUR 使用的数据量。让我们试试使用 5% 的数据集。为此，我们将设置 ``num_batches: 94``（因为 60,000 的 5% 是 3,000，而默认的批次大小为 32，大约相当于 94 个批次）。现在再次尝试训练和评估。我们几乎达到了 98%！\n\n__ more_advanced_things_\n\n不要停下，让我们用全部数据进行训练（只需完全删除 ``num_batches`` 行，或将 ``num_batches`` 设置为 ``null``）。仍然只训练 10 个 epoch，我们就达到了 98.6% 的准确率。太棒了！让我们与当前最先进的水平进行比较，Yann LeCun 在 `MNIST 网站 \u003Chttp:\u002F\u002Fyann.lecun.com\u002Fexdb\u002Fmnist\u002F>`_ 上记录了最新的结果。看起来最佳的错误率同样使用了卷积网络，达到了 0.23% 的错误率（即 99.77% 的准确率）。仅仅通过几次调整，我们就已经比世界顶尖水平只差了一个百分点。Kur 真是太棒了！\n\n.. _cifar_10:\n\nCIFAR-10：图像分类\n==================\n\n好吧，MNIST 确实很酷，但 Kur 能做的远不止这些。想象一下，你希望拥有任意数量的卷积层；或者每个卷积层都有不同数量的卷积核；又或者你真正需要 *灵活性*。那么你来对地方了。\n\n灵活性：变量\n----------------------\n\nKur 使用一个 *引擎* 来处理变量替换。`Jinja2 \u003Chttp:\u002F\u002Fjinja.pocoo.org>`_ 是默认的模板引擎，功能非常强大且可扩展。让我们来看看如何使用它！\n\n让我们来看一下 `CIFAR-10 \u003Chttps:\u002F\u002Fwww.cs.toronto.edu\u002F~kriz\u002Fcifar.html>`_ 数据集。这是一个小型 32x32 像素彩色（RGB）图像的分类数据集，每张图片属于十个类别之一（飞机、汽车、鸟、猫、鹿、狗、青蛙、马、船、卡车）。你可能会决定从一个与 MNIST 示例非常相似的模型开始：\n\n.. code-block:: yaml\n\n\tmodel:\n\t  - input: images\n\t  - convolution:\n\t      kernels: 64\n\t      size: [3, 3]\n\t  - activation: relu\n\t  - flatten:\n\t  - dense: 10\n\t  - activation: softmax\n\t    name: labels\n\n我们将从一个简单的修改开始：让卷积的 `size` 成为一个变量，这样我们以后就可以轻松地更改它。我们可以这样做：\n\n.. code-block:: yaml\n\n\tsettings:\n\t  cnn:\n\t    size: [3, 3]\n\n\tmodel:\n\t  - input: images\n\t  - convolution:\n\t      kernels: 64\n\t      size: \"{{ cnn.size }}\"\n\t  - activation: relu\n\t  - flatten:\n\t  - dense: 10\n\t  - activation: softmax\n\t    name: labels\n\n那么刚才发生了什么？首先，我们添加了一个 ``settings:`` 部分。这部分是声明变量、设置和超参数的合适位置，这些内容将在模型中（或用于训练、评估等）被使用。我们声明了一个名为 ``cnn`` 的变量，其中嵌套了一个 ``size`` 变量。在 Python 中，这相当于一个字典：``{\"cnn\": {\"size\": [3, 3]}}``。\n\n然后，我们在模型的卷积层中使用了这个变量：``size: \"{{ cnn.size }}\"``。这是标准的 Jinja2 语法。双括号表示需要进行变量替换（如果没有括号，我们就会错误地将 ``size`` 赋值为字符串 ``cnn.size``，这显然没有意义）。我们获取的变量是 ``cnn.size``，对应于我们在 ``settings`` 部分中添加的变量。\n\n太棒了！现在我们可以使用变量了。但这对我们有什么帮助呢？似乎只是让事情变得更复杂了。不过，让我们想象一下，如果我们再添加一个卷积层会怎样。我们已经知道，只需再添加一个“卷积”块即可增加额外的卷积层（通常你还希望再加一个“activation: relu”层）。那么代码就会变成这样：\n\n.. code-block:: yaml\n\n\tsettings:\n\t  cnn:\n\t    size: [3, 3]\n\n\tmodel:\n\t  - input: images\n\t  - convolution:\n\t      kernels: 64\n\t      size: \"{{ cnn.size }}\"\n\t  - activation: relu\n\t  - convolution:\n\t      kernels: 64\n\t      size: \"{{ cnn.size }}\"\n\t  - activation: relu\n\t  - flatten:\n\t  - dense: 10\n\t  - activation: softmax\n\t    name: labels\n\n啊！现在我们就能明白为什么将卷积核大小参数化是件好事了：如果我们\n想要尝试使用不同大小卷积核的模型，只需要修改一行代码，而不是两行。\n\n不过，我们仍然可能会遇到两个问题：\n\n- 如果我们想尝试许多具有不同数量卷积层的模型呢？\n- 如果我们希望在每个卷积层中使用 *不同* 的 ``size`` 或 ``kernel``\n  值呢？\n\nKur 可以做到！\n\n灵活性：循环\n--------------\n\n让我们先解决第一个问题：如果我们想让卷积层数量可变怎么办？Kur 支持\n许多被称为“算子”的“元层”。一个非常简单的算子就是经典的 `\"for\"\n循环 \u003Chttps:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FFor_loop>`_。这使我们可以一次性添加\n多个卷积层和激活层。代码如下所示：\n\n.. code-block:: yaml\n\n\tsettings:\n\t  cnn:\n\t    size: [3, 3]\n\n\tmodel:\n\t  - input: images\n\t  - for:\n\t      range: 2\n\t      iterate:\n\t        - convolution:\n\t            kernels: 64\n\t            size: \"{{ cnn.size }}\"\n\t        - activation: relu\n\t  - flatten:\n\t  - dense: 10\n\t  - activation: softmax\n\t    name: labels\n\n这与没有 `\"for\"` 循环的版本是等价的。``for:`` 循环告诉我们需要在\n``iterate:`` 部分重复执行两次。（为什么是两次？因为 ``range: 2``。）\n当然，我们也可以这样对迭代次数进行参数化：\n\n.. code-block:: yaml\n\n\tsettings:\n\t  cnn:\n\t    size: [3, 3]\n\t    kernels: [64, 32]\n\t    layers: 2\n\n\tmodel:\n\t  - input: images\n\t  - for:\n\t      range: \"{{ cnn.layers }}\"\n\t      iterate:\n\t        - convolution:\n\t            kernels: 64\n\t            size: \"{{ cnn.size }}\"\n\t        - activation: relu\n\t  - flatten:\n\t  - dense: 10\n\t  - activation: softmax\n\t    name: labels\n\n请仔细思考一下。这是否合理？应该是合理的。该模型看起来如下：\n\n- 一个输入图像的层。\n- 若干个卷积层和激活层。有多少个呢？由 ``cnn.layers`` 决定，这里是\n  2 个。\n- 模型的其余部分按预期进行：先是一个全连接层，然后是一个激活层。\n\n灵活性：可变长度的循环\n------------------------\n\n现在我们已经解决了允许卷积层数量可变的问题。但如果每个卷积层应该\n使用不同数量的卷积核（或不同的尺寸等）呢？嗯，Kur 同样可以轻松处理\n这一点。事实上，``for:`` 循环已经完成了大部分工作。每个 ``for:`` 循\n环都会创建一个自己的“局部”变量，用来告诉你当前处于第几次迭代。这个\n变量的默认名称是 ``index``。因此，如果我们要为每个卷积层使用不同数\n量的卷积核，可以这样做：\n\n.. code-block:: yaml\n\n\tsettings:\n\t  cnn:\n\t    size: [3, 3]\n\t    kernels: [64, 32]\n\t    layers: 2\n\n\tmodel:\n\t  - input: images\n\t  - for:\n\t      range: \"{{ cnn.layers }}\"\n\t      iterate:\n\t        - convolution:\n\t            kernels: \"{{ cnn.kernels[index] }}\"\n\t            size: \"{{ cnn.size }}\"\n\t        - activation: relu\n\t  - flatten:\n\t  - dense: 10\n\t  - activation: softmax\n\t    name: labels\n\n再次强调，这只是 Jinja2 替换：我们请求的是 ``cnn.kernels`` 列表中的\n第 ``index`` 个元素。因此，``for:`` 循环的每次迭代都会获取不同的\n``kernels:`` 值。很酷，不是吗？\n\n但我们可以做得更好。\n\n灵活性：过滤器\n---------------\n\n我们当前模型的一个麻烦之处在于，没有任何机制强制要求 ``layers``\n的值必须等于 ``kernels`` 变量的长度。如果你把 ``kernels`` 设置得非常\n长（比如长度为十七），却把 ``layers`` 保持为二，那很可能就是你犯了\n错误。（你为什么要设置十七个卷积层，却只在循环中使用前两个呢？）你\n真正想要的是确保 ``layers`` 的值等于 ``kernels`` 列表的长度。换句话说，\n你希望添加的卷积层数量正好等于列表中卷积核的数量。\n\nJinja2 支持一种称为“过滤器”的概念，它本质上是可以应用于对象的函数。\n你甚至可以定义自己的过滤器。但我们现在需要的是获取列表长度的方法。\n这很简单，代码如下：\n\n.. code-block:: yaml\n\n\tsettings:\n\t  cnn:\n\t    size: [3, 3]\n\t    kernels: [64, 32]\n\n\tmodel:\n\t  - input: images\n\t  - for:\n\t      range: \"{{ cnn.kernels|length }}\"\n\t      iterate:\n\t        - convolution:\n\t            kernels: \"{{ cnn.kernels[index] }}\"\n\t            size: \"{{ cnn.size }}\"\n\t        - activation: relu\n\t  - flatten:\n\t  - dense: 10\n\t  - activation: softmax\n\t    name: labels\n\n你会注意到，``layers`` 变量已经消失了，取而代之的是在 ``for`` 循环的\n``range`` 中出现了这个奇怪的 ``|length``。这是标准的 Jinja2 语法：\n``length`` 过滤器会返回列表的长度。因此，我们现在要求 ``for`` 循环\n迭代的次数正好等于卷积核列表的长度。\n\n仔细想想，这真的很酷。你想在网络中添加另一个卷积层吗？*你只需要将其\n尺寸添加到* ``kernels`` *列表中即可。* 看吧！你的模型现在变得更加通用、\n更加可重用。你本来可以用同样的模型来处理 MNIST 数据集！或者 CIFAR！\n又或者许多其他应用。\n\n这就是 **Kur 理念的核心：你应该用一次且简单的方式描述你的模型。** 规范\n*描述* 你的模型：一堆卷积层，然后是一个全连接层。你可以将细节（例如\n卷积层数量、参数等）放在别处指定。模型本身应保持简洁优雅。\n\n**注意**：当然，编写可重用的模型并不总是容易的。学习曲线也可能成为\n障碍。当我们说模型应该“简单”时，我们并不是指不需要动脑筋。而是说它\n应该易于使用、易于修改以及易于共享。更通用的模型往往更加优雅：对其\n进行更改很容易（只需修改设置即可）。这也使得它更容易在新的场景中复\n用，或者与社区分享。简单就是力量。\n\n训练 CIFAR-10 模型的实际操作\n-----------------------------\n\n太好了，我们现在有了一个简单但功能强大且通用的模型。让我们来训练它。\n和之前一样，你需要先切换到 `examples` 目录。\n\n.. code-block:: bash\n\n\tkur train cifar.yml\n\n同样地，评估也非常简单：\n\n.. code-block:: bash\n\n\tkur evaluate cifar.yml\n\n高级特性\n---------\n\n``cifar.yml`` 规范文件比 MNIST 的要复杂一些，主要是为了让你接触到更多\n可以调整的参数。例如，在 ``train`` 部分你会看到以下几行：\n\n.. code-block:: yaml\n\n\tprovider:\n\t  batch_size: 32\n\t  num_batches: 2\n\n与 MNIST 情况类似，``num_batches`` 告诉 Kur 每个 epoch 只训练这么多批\n数据（主要是为了避免在没有高性能 GPU 的情况下，示例运行时间过长）。\n而 ``batch_size`` 则表示每批次用于训练的样本数量。\n\n.. _using_binary_logger:\n\n``train`` 部分还包含一行 ``log: cifar-log``。这会指示 Kur 将日志文件保存到当前工作目录下的 `cifar-log`。该日志包含了关于当前训练损失、批次损失以及轮次数等大量有用信息。默认情况下，这些日志文件是二进制编码的，但你可以使用 Kur 的 API（在 Python 3 中）来加载它们：\n\n.. code-block:: python\n\n\tfrom kur.loggers import BinaryLogger\n\tdata = BinaryLogger.load_column(LOG_PATH, STATISTIC)\n\n其中 `LOG_PATH` 是日志文件的路径（例如 `cifar-log`），而 `STATISTIC` 是所记录的统计量之一。`data` 将是一个 `Numpy \u003Chttp:\u002F\u002Fwww.numpy.org\u002F>`_ 数组。要查看可用的统计量，只需列出 `LOG_PATH` 目录下的文件，如下所示：\n\n.. code-block:: bash\n\n\t$ ls cifar-log\n\ttraining_loss_labels\n\ttraining_loss_total\n\tvalidation_loss_labels\n\tvalidation_loss_total\n\n有关如何使用这些日志数据的示例，请参阅我们的教程_。\n\n与 MNIST 示例相比，CIFAR 规范中引用权重的文件更多。例如，在 `validate` 部分有：\n\n.. code-block:: yaml\n\n\tweights: cifar.best.valid.w\n\n这会指示 Kur 将最佳模型权重（对应于 *验证集* 上最低损失的权重）保存到 `cifar.best.valid.w`。类似地，在 `train` 部分也有以下内容：\n\n.. code-block:: yaml\n\n\tweights:\n\t  initial: cifar.best.valid.w\n\t  save_best: cifar.best.train.w\n\t  last: cifar.last.w\n\n`initial` 键指示 Kur 在训练开始时尝试加载 `cifar.best.valid.w`（即以 *验证集* 损失为准的最佳权重）。如果该文件不存在，则不会执行任何操作。这意味着如果你多次运行训练循环（多次调用 `kur train cifar.yml`），你始终会从最佳模型权重处“重启”。\n\n我们还将以 *训练集* 损失为准的最佳权重保存到 `cifar.best.train.w`，而最新的权重则保存到 `cifar.last.w`。\n\n**注意**：权重文件与模型架构密切相关。假设你训练了 CIFAR 并生成了 `cifar.best.valid.w`，随后你在配置文件中对模型进行了调整。如果你尝试继续训练（`kur train cifar.yml`），Kur 会尝试加载 `cifar.best.valid.w`，但这些权重可能并不适用于新的架构！因此，为安全起见，在训练全新的、经过调整的模型之前，务必删除（或备份）你的权重文件。在生产环境中，建议为每个不同的模型变体或调整创建单独的子目录，以避免此类问题。\n\nCIFAR-10 示例还在 `train` 部分显式指定了优化器：\n\n.. code-block:: yaml\n\n\toptimizer:\n\t  name: adam\n\t  learning_rate: 0.001\n\n优化器函数通过 `name` 字段指定，其他参数（如 `learning_rate`）则在其他字段中定义。你可以安全地更改优化器，而不会破坏与旧版权重文件的向后兼容性。","# Kur 快速上手指南\n\nKur 是一个描述式深度学习框架，旨在让用户无需编写代码即可设计、训练和评估先进的深度学习模型。它支持 Theano、TensorFlow 和 PyTorch 后端，并原生支持多 GPU 加速。\n\n## 环境准备\n\n在开始之前，请确保您的系统满足以下要求：\n\n*   **操作系统**：Linux, macOS 或 Windows (需配置相应环境)\n*   **Python 版本**：**Python 3.4** 或更高版本（推荐 Python 3.6+）\n*   **前置依赖**：\n    *   `pip` (Python 包管理工具)\n    *   `virtualenv` (用于创建独立的虚拟环境，强烈推荐)\n    *   Git (用于获取示例代码)\n\n> **注意**：虽然原文未明确提及国内镜像，但在中国大陆环境下，建议在安装 Python 包时使用清华或阿里镜像源以加速下载。例如：`pip install -i https:\u002F\u002Fpypi.tuna.tsinghua.edu.cn\u002Fsimple \u003Cpackage>`。\n\n## 安装步骤\n\n推荐使用虚拟环境进行安装，以避免依赖冲突。\n\n### 1. 创建并激活虚拟环境\n\n```bash\npip install virtualenv                      # 确保已安装 virtualenv\nvirtualenv -p $(which python3) ~\u002Fkur-env    # 创建名为 kur-env 的 Python 3 环境\nsource ~\u002Fkur-env\u002Fbin\u002Factivate               # 激活环境 (Windows 用户请使用: ~\u002Fkur-env\u002FScripts\u002Factivate)\n```\n\n### 2. 安装 Kur\n\n您可以选择通过 pip 安装稳定版，或通过 git 安装开发版。\n\n**方式一：通过 pip 安装（推荐）**\n\n```bash\npip install kur\n# 国内加速建议：pip install -i https:\u002F\u002Fpypi.tuna.tsinghua.edu.cn\u002Fsimple kur\n```\n\n**方式二：通过 git 安装（获取最新开发版）**\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002Fdeepgram\u002Fkur\ncd kur\npip install .\n```\n\n### 3. 验证安装\n\n```bash\nkur --version\n```\n如果输出了版本号，说明安装成功。\n\n## 基本使用\n\nKur 的核心工作流是通过 YAML 配置文件来定义模型，然后使用命令行工具进行训练和评估。\n\n### 1. 获取示例代码\n\n为了快速体验，我们需要克隆官方仓库以获取示例配置文件（如 MNIST 手写数字识别）：\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002Fdeepgram\u002Fkur\ncd kur\u002Fexamples\n```\n\n### 2. 训练模型\n\n使用 `kur train` 命令配合 YAML 配置文件即可开始训练。以下以经典的 MNIST 数据集为例：\n\n```bash\nkur train mnist.yml\n```\n\n**执行过程说明：**\n*   Kur 会自动从网络下载 MNIST 数据集。\n*   根据 `mnist.yml` 中定义的架构（卷积层、激活函数等）构建模型。\n*   开始训练迭代（默认示例为了演示速度，仅训练少量批次）。\n*   终端将实时显示下载进度、Epoch 进度及 Loss 变化。\n\n### 3. 评估模型\n\n训练完成后，使用 `kur evaluate` 命令测试模型性能：\n\n```bash\nkur evaluate mnist.yml\n```\n\n**输出示例：**\n系统将输出每个类别的预测准确率及总体准确率（例如：ALL 90.2%）。\n\n### 核心命令速查\n\n*   **训练模型**：`kur train \u003C配置文件.yml>`\n*   **评估模型**：`kur evaluate \u003C配置文件.yml>`\n*   **测试模型**：`kur test \u003C配置文件.yml>`\n\n您只需修改 YAML 文件中的参数（如层数、神经元数量、超参数等），即可轻松探索不同的模型架构，无需编写任何 Python 代码。","一家初创语音分析公司的算法团队，正急需为客服录音数据构建一个高精度的情感识别模型以快速验证商业价值。\n\n### 没有 kur 时\n- **开发门槛高**：团队成员若不熟悉 TensorFlow 或 PyTorch 的底层 API，需花费数周学习如何编写复杂的神经网络代码。\n- **迭代效率低**：每次调整网络结构（如增加卷积层或改变激活函数）都需要修改大量 Python 脚本，容易引入语法错误且难以回溯。\n- **多卡训练复杂**：想要利用公司服务器的多块 GPU 加速训练，必须手动编写繁琐的分布式训练配置和同步逻辑。\n- **协作困难**：资深工程师编写的模型代码对新手而言如同“黑盒”，非代码背景的领域专家无法直接参与模型设计的讨论与优化。\n\n### 使用 kur 后\n- **零代码建模**：团队仅需编写易读的 YAML 描述文件即可定义复杂的深度学习架构，完全无需触碰底层训练代码。\n- **敏捷实验**：借助 Jinja2 模板引擎，研究人员能快速生成并对比多种模型变体，将原本数天的结构调整工作缩短至几分钟。\n- **开箱即用的多 GPU 支持**：kur 原生支持多显卡并行训练，只需简单配置即可自动调度硬件资源，大幅缩短模型收敛时间。\n- **全员协同创新**：清晰的描述性配置文件让产品经理和领域专家也能理解模型结构，真正实现了跨角色的深度协作与模型共享。\n\nkur 通过“描述即模型”的理念，将深度学习从昂贵的编码工程转变为高效的配置实验，极大降低了先进 AI 技术的应用门槛。","https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fdeepgram_kur_9bbedc97.png","deepgram","Deepgram","https:\u002F\u002Foss.gittoolsai.com\u002Favatars\u002Fdeepgram_488014aa.png","",null,"https:\u002F\u002Fwww.deepgram.com","https:\u002F\u002Fgithub.com\u002Fdeepgram",[80],{"name":81,"color":82,"percentage":83},"Python","#3572A5",100,823,108,"2025-10-25T11:33:50","Apache-2.0","未说明","支持多 GPU（multi-GPU），但非必需。具体显卡型号、显存大小及 CUDA 版本未在文中明确指定，仅提及可在普通消费级硬件（如 Intel Core m7 CPU）上运行示例。",{"notes":91,"python":92,"dependencies":93},"该工具旨在无需编写代码即可通过 YAML 文件设计和训练模型。支持 Theano、TensorFlow 和 PyTorch 后端。官方示例默认仅使用少量数据批次以便在普通硬件上快速运行，若需完整训练可修改配置。建议使用 virtualenv 创建 Python 3 虚拟环境进行安装。","3.4, 3.5, 3.6",[94,95,96,97,98],"Theano","TensorFlow","PyTorch","Jinja2","virtualenv",[100,15,14],"音频",[102,103,104,105,106,107,108,109,110],"deep-learning","deep-neural-networks","speech-recognition","deep-learning-tutorial","machine-learning","neural-networks","neural-network","image-recognition","speech-to-text","2026-03-27T02:49:30.150509","2026-04-08T14:04:00.867387",[114,119,124,129,134,139],{"id":115,"question_zh":116,"answer_zh":117,"source_url":118},24484,"如何在自定义数据上训练语音识别模型？数据格式要求是什么？","Kurfile 中应包含如下配置：\n- speech_recognition:\n    path: PATH\n在指定的 PATH 文件夹下，需要包含一个 audio 目录和一个 dataset.jsonl 文件。\ndataset.jsonl 文件的每一行都是一个 JSON 对象，格式为：{ 'text' : '转录文本', 'duration_s' : 时长秒数, 'uuid' : '唯一标识符' }。\n对于 JSONL 中的每个条目，audio 目录中必须有一个对应的 UUID.wav 文件（支持 WAV, FLAC, MP3 格式）。","https:\u002F\u002Fgithub.com\u002Fdeepgram\u002Fkur\u002Fissues\u002F21",{"id":120,"question_zh":121,"answer_zh":122,"source_url":123},24485,"训练自定义数据时出现 'Saw a non-null label following a null label' 错误怎么办？","这通常是因为词汇表（vocab）与数据中的字符不匹配。Kur 使用字符级输出，默认词汇表可能只包含小写字母和空格。\n解决方法：删除现有的 vocab.json 文件，然后重新运行训练。Kur 会自动扫描你的数据集并生成包含所有出现字符（如大写字母、数字、标点符号等）的新词汇表。虽然包含更多字符可能会增加训练难度，但这能解决标签索引越界的问题。","https:\u002F\u002Fgithub.com\u002Fdeepgram\u002Fkur\u002Fissues\u002F99",{"id":125,"question_zh":126,"answer_zh":127,"source_url":128},24486,"如何将在 Kur 中训练好的模型用于新的音频文件进行推理或部署？","目前社区用户主要转向使用 Mozilla DeepSpeech 来进行生产环境部署（如 REST API 或 Android 应用），因为其支持和文档更完善。\n关于 Kur 本身的 'kur build' 命令，它主要用于构建模型定义，但官方文档中关于直接导出模型用于独立服务（如纯 Python 脚本或 TensorFlow 文件）的具体命令行示例较少。建议参考 DeepSpeech 的集成方案作为替代。","https:\u002F\u002Fgithub.com\u002Fdeepgram\u002Fkur\u002Fissues\u002F23",{"id":130,"question_zh":131,"answer_zh":132,"source_url":133},24487,"是否支持多 GPU 加速训练？","用户在 Issue 中询问是否可以通过添加更多 GPU 来加速如 DeepSpeech 示例的训练，但指出在文档中未找到相关描述。维护者回应称可以添加额外的日志记录以调试此问题，但当时并未直接确认多 GPU 的原生支持状态或提供具体的配置开关，建议用户关注后续的调试信息或新开 Issue 讨论。这表明该功能在当时可能尚不明确或需要特定配置。","https:\u002F\u002Fgithub.com\u002Fdeepgram\u002Fkur\u002Fissues\u002F24",{"id":135,"question_zh":136,"answer_zh":137,"source_url":138},24488,"字符级 RNN 示例运行时提示找不到 'train.jsonl' 文件怎么办？","该错误通常是因为示例所需的数据集尚未下载或生成。例如运行语言模型示例时，需要先执行数据准备脚本（如 make_data.py）来生成 train.jsonl 文件。\n此外，如果数据集过大，加载时间会非常长（曾有用例提到加载需 30 分钟）。可以通过减小数据集规模来显著减少数据生成时间和训练加载时间（从几小时降至几分钟）。","https:\u002F\u002Fgithub.com\u002Fdeepgram\u002Fkur\u002Fissues\u002F28",{"id":140,"question_zh":141,"answer_zh":142,"source_url":143},24489,"如何在 plot_weights hook 中绘制更多层的权重而不修改源代码？","可以通过利用 **kwargs 传递参数来避免每次修改源代码。\n具体工作流建议：\n1. 在 Executor.wrapped_train 中创建临时目录保存权重。\n2. 使用 kur.model.Model.save(weight_path) 保存权重。\n3. 遍历 weight_path 下的文件，利用正则匹配文件名提取权重。\n4. 将提取的权重数据传递给 plot_weights_hook.py 进行绘图。\n这样可以在不硬编码 weight_keywords 的情况下动态处理多层权重。","https:\u002F\u002Fgithub.com\u002Fdeepgram\u002Fkur\u002Fissues\u002F68",[]]