[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"similar-infinitered--nsfwjs":3,"tool-infinitered--nsfwjs":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 真正成长为懂上",141543,2,"2026-04-06T11:32:54",[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":77,"owner_twitter":78,"owner_website":79,"owner_url":80,"languages":81,"stars":90,"forks":91,"last_commit_at":92,"license":93,"difficulty_score":32,"env_os":94,"env_gpu":95,"env_ram":94,"env_deps":96,"category_tags":105,"github_topics":106,"view_count":32,"oss_zip_url":76,"oss_zip_packed_at":76,"status":17,"created_at":115,"updated_at":116,"faqs":117,"releases":148},4611,"infinitered\u002Fnsfwjs","nsfwjs","NSFW detection on the client-side via TensorFlow.js","nsfwjs 是一款基于 TensorFlow.js 的开源 JavaScript 库，专为在浏览器端（客户端）快速识别图像内容是否适宜工作场景而设计。它无需将图片上传至服务器，直接在用户浏览器中即可完成分析，有效保护了用户隐私并降低了服务器负载。\n\n该工具主要解决了网络平台中自动过滤色情、性感或不雅图片的需求。通过深度学习模型，nsfwjs 能将图像概率分类为五种类型：安全绘图、 hentai（成人绘图）、中性安全图、色情图以及性感图。其准确率相当可观，小型模型约 90%，中型模型可达 93%，且随着迭代仍在不断提升。\n\nnsfwjs 非常适合前端开发者、全栈工程师以及需要构建内容审核功能的初创团队使用。无论是 Web 应用、React Native 项目还是 Node.js 环境，都能轻松集成。其独特的技术亮点在于完全的“客户端运行”模式，支持 WASM 和 WebGPU 后端加速，并允许开发者通过树摇（tree-shaking）技术按需加载模型，从而优化应用体积。对于希望在不依赖后端复杂架构的前提下，快速实现基础图像内容风控的项目来说，nsfwjs 是一个高效且友好的选择。","\u003Cp align=\"center\">\n  \u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_bedfebff63d2.jpg\" alt=\"NSFWJS Logo\" width=\"400\" \u002F>\n  \u003Ch2 align=\"center\">Client-side indecent content checking\u003C\u002Fh2>\n\u003C\u002Fp>\n\n[![All Contributors](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fall_contributors-15-green.svg?style=flat-square)](#contributors)\n[![CircleCI](https:\u002F\u002Fdl.circleci.com\u002Fstatus-badge\u002Fimg\u002Fgh\u002Finfinitered\u002Fnsfwjs\u002Ftree\u002Fmaster.svg?style=svg)](https:\u002F\u002Fdl.circleci.com\u002Fstatus-badge\u002Fredirect\u002Fgh\u002Finfinitered\u002Fnsfwjs\u002Ftree\u002Fmaster)\n[![Netlify Status](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_999412434a2f.png)](https:\u002F\u002Fapp.netlify.com\u002Fsites\u002Fnsfwjs\u002Fdeploys)\n\nA simple JavaScript library to help you quickly identify unseemly images; all in the client's browser. NSFWJS isn't perfect, but it's pretty accurate (~90% with small and ~93% with midsized model)... and it's getting more accurate all the time.\n\nWhy would this be useful? [Check out the announcement blog post](https:\u002F\u002Fshift.infinite.red\u002Favoid-nightmares-nsfw-js-ab7b176978b1).\n\n\u003Cp align=\"center\">\n\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_524b6e150e00.gif\" alt=\"demo example\" width=\"800\" align=\"center\" \u002F>\n\u003C\u002Fp>\n\n## NOTE\n\nIf you're trying to access the Cloudfront hosted model and are running into an error, it's likely due to the fact that the model has been moved to a new location. Please take a look at our [Host your own model](#host-your-own-model) section. We will be returning the model after some hotlinkers have been dealt with.\n\n## **Table of Contents**\n\n\u003C!-- START doctoc generated TOC please keep comment here to allow auto update -->\n\u003C!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n\n\n- [QUICK: How to use the module](#quick-how-to-use-the-module)\n  - [Selective model bundles (tree-shaking)](#selective-model-bundles-tree-shaking)\n- [Library API](#library-api)\n  - [`load` the model](#load-the-model)\n  - [Caching](#caching)\n  - [`classify` an image](#classify-an-image)\n  - [`dispose` a loaded model](#dispose-a-loaded-model)\n- [Production](#production)\n- [Backend selection](#backend-selection)\n  - [WASM backend (optional)](#wasm-backend-optional)\n  - [WebGPU backend (optional)](#webgpu-backend-optional)\n  - [Node.js backend](#nodejs-backend)\n- [Install](#install)\n  - [Host your own model](#host-your-own-model)\n- [Run the Examples](#run-the-examples)\n  - [Tensorflow.js in the browser](#tensorflowjs-in-the-browser)\n  - [Browserify](#browserify)\n  - [React Native](#react-native)\n  - [Node JS App](#node-js-app)\n  - [NSFW Filter](#nsfw-filter)\n- [Learn TensorFlow.js](#learn-tensorflowjs)\n- [More!](#more)\n  - [Open Source](#open-source)\n  - [Need the experts? Hire Infinite Red for your next project](#need-the-experts-hire-infinite-red-for-your-next-project)\n- [Contributors](#contributors)\n\n\u003C!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\nThe library categorizes image probabilities in the following 5 classes:\n\n- `Drawing` - safe for work drawings (including anime)\n- `Hentai` - hentai and pornographic drawings\n- `Neutral` - safe for work neutral images\n- `Porn` - pornographic images, sexual acts\n- `Sexy` - sexually explicit images, not pornography\n\n> _The demo is a continuous deployment source - Give it a go: http:\u002F\u002Fnsfwjs.com_\n\n## QUICK: How to use the module\n\n```js\nimport * as nsfwjs from \"nsfwjs\";\n\nconst img = document.getElementById(\"img\");\n\n\u002F\u002F If you want to host models on your own or use different model from the ones available, see the section \"Host your own model\".\nconst model = await nsfwjs.load();\n\n\u002F\u002F Classify the image\nconst predictions = await model.classify(img);\nconsole.log(\"Predictions: \", predictions);\n```\n\n### Selective model bundles (tree-shaking)\n\n`nsfwjs` keeps the default behavior and includes built-in model definitions. For selective bundling, import from `nsfwjs\u002Fcore` and pass only the models you want in `modelDefinitions`.\n\n```js\nimport { load } from \"nsfwjs\u002Fcore\";\nimport { MobileNetV2Model } from \"nsfwjs\u002Fmodels\u002Fmobilenet_v2\";\nimport { MobileNetV2MidModel } from \"nsfwjs\u002Fmodels\u002Fmobilenet_v2_mid\";\n\nconst model = await load(\"MobileNetV2\", {\n  modelDefinitions: [MobileNetV2Model, MobileNetV2MidModel],\n});\n```\n\nIf you pass an empty model registry, named bundled model loads will fail:\n\n```js\nawait load(\"MobileNetV2\", { modelDefinitions: [] }); \u002F\u002F throws\n```\n\n## Library API\n\n### `load` the model\n\nBefore you can classify any image, you'll need to load the model.\n\n```js\nconst model = nsfwjs.load(); \u002F\u002F Default: \"MobileNetV2\"\n```\n\nYou can use the optional first parameter to specify which model you want to use from the three built-in bundled models. Defaults to: `\"MobileNetV2\"`.\n\nFor tree-shaken selective model bundling, use `nsfwjs\u002Fcore` and pass `modelDefinitions` as shown above.\n\n```js\nconst model = nsfwjs.load(\"MobileNetV2Mid\"); \u002F\u002F \"MobileNetV2\" | \"MobileNetV2Mid\" | \"InceptionV3\"\n```\n\nYou can also use same parameter and load the model from your website\u002Fserver, as explained in the [Host your own model](#host-your-own-model) section. Doing so could reduce the bundle size for loading the model by approximately 1.33 times (33%) since you can directly use the binary files instead of the base64 that are bundled with the package. i.e. The `\"MobileNetV2\"` model bundled into the package is 3.5MB instead of 2.6MB for hosted binary files. This would only make a difference if you are loading the model every time (without [Caching](#caching)) on the client-side browser since on the server-side, you'd only be loading the model once at the server start.\n\nIf you are hosting your own model via URL and want the smallest app bundle, import `load` from `nsfwjs\u002Fcore` instead of `nsfwjs`. The core entrypoint does not include built-in model definitions by default, so bundlers do not pull those model assets into your app bundle.\n\n```js\nimport { load } from \"nsfwjs\u002Fcore\";\n\nconst model = await load(\"\u002Fpath\u002Fto\u002Fmobilenet_v2\u002Fmodel.json\");\n```\n\nModel MobileNetV2 - [224x224](https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fblob\u002Fmaster\u002Fmodels\u002Fmobilenet_v2\u002F)\n\n```js\nconst model = nsfwjs.load(\"\u002Fpath\u002Fto\u002Fmobilenet_v2\u002F\");\n```\n\nIf you're using a model that needs an image of dimension other than 224x224, you can pass the size in the options parameter.\n\nModel MobileNetV2Mid - [Graph](https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Ftree\u002Fmaster\u002Fmodels\u002Fmobilenet_v2_mid)\n\n```js\n\u002F* You may need to load this model with graph type *\u002F\nconst model = nsfwjs.load(\"\u002Fpath\u002Fto\u002Fmobilenet_v2_mid\u002F\", { type: 'graph' });\n```\n\nIf you're using a graph model, you cannot use the infer method, and you'll need to tell model load that you're dealing with a graph model in options.\n\nModel InceptionV3 - [299x299](https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Ftree\u002Fmaster\u002Fmodels\u002Finception_v3)\n\n```js\nconst model = nsfwjs.load(\"\u002Fpath\u002Fto\u002Finception_v3\u002F\", { size: 299 });\n```\n\n### Caching\n\nIf you're using in the browser and you'd like to subsequently load from indexed db or local storage (NOTE: model size may be too large for local storage!) you can save the underlying model using the appropriate scheme and load from there.\n\n```js\nconst initialLoad = await nsfwjs.load(\n  \"\u002Fpath\u002Fto\u002Fdifferent\u002Fmodel\u002F\" \u002F*, { ...options }*\u002F\n);\nawait initialLoad.model.save(\"indexeddb:\u002F\u002FexampleModel\");\nconst model = await nsfwjs.load(\"indexeddb:\u002F\u002FexampleModel\" \u002F*, { ...options }*\u002F);\n```\n\n**Parameters**\n\nInitial Load:\n1. URL or path to folder containing `model.json`.\n2. Optional object with size or type property that your model expects.\n\nSubsequent Load:\n1. IndexedDB path.\n2. Optional object with size or type property that your model expects.\n\n\n**Returns**\n\n- Ready to use NSFWJS model object\n  \n\n**Troubleshooting**\n\n- On the tab where the model is being loaded, inspect element and navigate to the the \"Application\" tab. On the left pane under the \"Storage\" section, there is a subsection named \"IndexedDB\". Here you can view if the model is being saved.\n\nFor a complete browser worker implementation (including backend initialization, IndexedDB-first load, and save-on-miss caching), see [`examples\u002Fnsfw_demo\u002Fsrc\u002Fnsfwjs.worker.ts`](.\u002Fexamples\u002Fnsfw_demo\u002Fsrc\u002Fnsfwjs.worker.ts).\n\n### `classify` an image\n\nThis function can take any browser-based image elements (`\u003Cimg>`, `\u003Cvideo>`, `\u003Ccanvas>`) and returns an array of most likely predictions and their confidence levels.\n\n```js\n\u002F\u002F Return top 3 guesses (instead of all 5)\nconst predictions = await model.classify(img, 3);\n```\n\n**Parameters**\n\n- Tensor, Image data, Image element, video element, or canvas element to check\n- Number of results to return (default all 5)\n\n**Returns**\n\n- Array of objects that contain `className` and `probability`. Array size is determined by the second parameter in the `classify` function.\n\n### `dispose` a loaded model\n\nIf you are done with a model instance, call `dispose()` to release held tensors and model resources.\n\n```js\nconst model = await nsfwjs.load();\n\u002F\u002F ... classify\u002Finfer\nmodel.dispose();\n```\n\n## Production\n\nTensorflow.js offers two flags, `enableProdMode` and `enableDebugMode`. If you're going to use NSFWJS in production, be sure to enable prod mode before loading the NSFWJS model.\n\n```js\nimport * as tf from \"@tensorflow\u002Ftfjs\";\nimport * as nsfwjs from \"nsfwjs\";\ntf.enableProdMode();\n\u002F\u002F...\nlet model = await nsfwjs.load(`${urlToNSFWJSModel}`);\n```\n\n**NOTE:** Consider downloading and hosting the model yourself before moving to production as explained in the [Host your own model](#host-your-own-model) section. This could potentially improve the initial load time of the model. Furthermore, consider [Caching](#caching) the model, if you are using it in the browser.\n\n## Backend selection\n\nNSFWJS uses whichever TensorFlow.js backend is active.\n\nSetting a backend explicitly is optional. If you import one or more backends and call `await tf.ready()`, TensorFlow.js will pick the best available backend.\n\nUse `tf.setBackend(...)` only when you want deterministic behavior across devices.\n\nAutomatic backend selection:\n\n```js\nimport * as tf from \"@tensorflow\u002Ftfjs\";\nimport \"@tensorflow\u002Ftfjs-backend-webgpu\";\nimport \"@tensorflow\u002Ftfjs-backend-wasm\";\nimport * as nsfwjs from \"nsfwjs\";\n\nawait tf.ready();\n\nconst model = await nsfwjs.load();\n```\n\nPinned backend selection:\n\n```js\nimport * as tf from \"@tensorflow\u002Ftfjs\";\nimport \"@tensorflow\u002Ftfjs-backend-webgpu\";\n\nawait tf.setBackend(\"webgpu\");\nawait tf.ready();\n```\n\n### WASM backend (optional)\n\n```bash\nyarn add @tensorflow\u002Ftfjs-backend-wasm\n```\n\n```js\nimport * as tf from \"@tensorflow\u002Ftfjs\";\nimport {\n  setWasmPaths,\n} from \"@tensorflow\u002Ftfjs-backend-wasm\";\nimport \"@tensorflow\u002Ftfjs-backend-wasm\";\n\n\u002F\u002F If you aren't using a standard bundler, set the path to the .wasm binaries.\nsetWasmPaths(\"https:\u002F\u002Fcdn.jsdelivr.net\u002Fnpm\u002F@tensorflow\u002Ftfjs-backend-wasm\u002Fdist\u002F\");\n\nawait tf.setBackend(\"wasm\");\nawait tf.ready();\n```\n\n### WebGPU backend (optional)\n\n```bash\nyarn add @tensorflow\u002Ftfjs-backend-webgpu\n```\n\n```js\nimport * as tf from \"@tensorflow\u002Ftfjs\";\nimport \"@tensorflow\u002Ftfjs-backend-webgpu\";\n\nawait tf.setBackend(\"webgpu\");\nawait tf.ready();\n```\n\nBackend guidance:\n\n- `webgpu`: often fastest on supported browsers\u002Fhardware.\n- `webgl`: strong default in modern desktop\u002Fmobile browsers.\n- `wasm`: useful fallback for environments where WebGL is unavailable\u002Frestricted.\n- `cpu`: broad compatibility but typically slower.\n\n### Node.js backend\n\nFor Node.js workloads, consider using `@tensorflow\u002Ftfjs-node` (or `@tensorflow\u002Ftfjs-node-gpu` where applicable) for better performance. See the [Node JS App](#node-js-app) section for examples.\n\nAlways benchmark in your target browser\u002Fdevice set.\n\n## Install\n\nNSFWJS is powered by TensorFlow.js as a peer dependency. If your project does not already have TFJS you'll may want to add it.\n\n```bash\n# peer dependency\n$ yarn add @tensorflow\u002Ftfjs\n# install NSFWJS\n$ yarn add nsfwjs\n```\n\nFor script tags include all the bundles as shown [here](#browserify). Then simply access the nsfwjs global variable. This requires that you've already imported TensorFlow.js as well.\n\n### Host your own model\n\nThe magic that powers NSFWJS is the [NSFW detection model](https:\u002F\u002Fgithub.com\u002Fgantman\u002Fnsfw_model). By default, the models are bundled into this package. But you may want to host the models on your own server to reduce bundle size by loading them as raw binary files or to host your own custom model. If you want to host your own version of [the model files](https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Ftree\u002Fmaster\u002Fmodels), you can do so by following the steps below. You can then pass the relative URL to your hosted files in the `load` function along with the `options` if necessary.\n\nIf you are loading a hosted model URL, prefer `nsfwjs\u002Fcore` so your app does not bundle built-in model definitions. See [Selective model bundles (tree-shaking)](#selective-model-bundles-tree-shaking).\n\nHere is how to install the default model on a website:\n\n1. Download the project by either downloading as zip or cloning `git clone https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs.git`.\n2. Extract the `models` folder from the root of the project and drop it in the `public` directory of your web application to serve them as static files along side your website. (You can host it anywhere such as on a s3 bucket as long as you can access it via URL).\n3. Retrieve the URL and put it into `nsfwjs.load()`. For example: `nsfwjs.load(https:\u002F\u002Fyourwebsite.com\u002Fmodels\u002Fmobilenet_v2\u002Fmodel.json)`.\n\n## Run the Examples\n\n### Tensorflow.js in the browser\n\nThe demo that powers https:\u002F\u002Fnsfwjs.com\u002F is available in the [`examples\u002Fnsfw_demo`](https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Ftree\u002Fmaster\u002Fexamples\u002Fnsfw_demo) folder.\n\nTo run the demo, run `yarn demo` which will copy the latest code into the demo and start the dev server.\n\n### Browserify\n\nA browserified version using nothing but promises and script tags is available in the [`minimal_demo`](https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Ftree\u002Fmaster\u002Fexamples\u002Fminimal_demo) folder.\n\n```js\n\u003Cscript src=\"\u002Fpath\u002Fto\u002Fmodel\u002Fdirectory\u002Fmodel.min.js\">\u003C\u002Fscript>\n\u003Cscript src=\"\u002Fpath\u002Fto\u002Fmodel\u002Fdirectory\u002Fgroup1-shard1of2.min.js\">\u003C\u002Fscript>\n\u003Cscript src=\"\u002Fpath\u002Fto\u002Fmodel\u002Fdirectory\u002Fgroup1-shard2of2.min.js\">\u003C\u002Fscript>\n\u003Cscript src=\"\u002Fpath\u002Fto\u002Fbundle\u002Fnsfwjs.min.js\">\u003C\u002Fscript>\n```\n\nYou should host the `nsfwjs.min.js` file and all the model bundles that you want to use alongside your project, and reference them using the `src` attribute in the script tags.\n\n### React Native\n\nThe [NSFWJS React Native app](https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs-mobile)\n\n![React Native Demo](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_bde24ad9fb90.jpg)\n\nLoads a local copy of the model to reduce network load and utilizes TFJS-React-Native. [Blog Post](https:\u002F\u002Fshift.infinite.red\u002Fnsfw-js-for-react-native-a37c9ba45fe9)\n\n### Node JS App\n\nUsing NPM, you can also use the model on the server side.\n\n```bash\n$ npm install nsfwjs\n$ npm install @tensorflow\u002Ftfjs-node\n```\n\n```javascript\nconst axios = require(\"axios\"); \u002F\u002Fyou can use any http client\nconst tf = require(\"@tensorflow\u002Ftfjs-node\");\nconst nsfw = require(\"nsfwjs\");\nasync function fn() {\n  const pic = await axios.get(`link-to-picture`, {\n    responseType: \"arraybuffer\",\n  });\n  const model = await nsfw.load(); \u002F\u002F To load a local model, nsfw.load('file:\u002F\u002F.\u002Fpath\u002Fto\u002Fmodel\u002F')\n  \u002F\u002F Image must be in tf.tensor3d format\n  \u002F\u002F you can convert image to tf.tensor3d with tf.node.decodeImage(Uint8Array,channels)\n  const image = await tf.node.decodeImage(pic.data, 3);\n  const predictions = await model.classify(image);\n  image.dispose(); \u002F\u002F Tensor memory must be managed explicitly (it is not sufficient to let a tf.Tensor go out of scope for its memory to be released).\n  console.log(predictions);\n}\nfn();\n```\n\nHere is another full example of a [multipart\u002Fform-data POST using Express](examples\u002Fnode_demo), supposing you are using JPG format.\n\n```javascript\nconst express = require(\"express\");\nconst multer = require(\"multer\");\nconst jpeg = require(\"jpeg-js\");\n\nconst tf = require(\"@tensorflow\u002Ftfjs-node\");\nconst nsfw = require(\"nsfwjs\");\n\nconst app = express();\nconst upload = multer();\n\nlet _model;\n\nconst convert = async (img) => {\n  \u002F\u002F Decoded image in UInt8 Byte array\n  const image = await jpeg.decode(img, { useTArray: true });\n\n  const numChannels = 3;\n  const numPixels = image.width * image.height;\n  const values = new Int32Array(numPixels * numChannels);\n\n  for (let i = 0; i \u003C numPixels; i++)\n    for (let c = 0; c \u003C numChannels; ++c)\n      values[i * numChannels + c] = image.data[i * 4 + c];\n\n  return tf.tensor3d(values, [image.height, image.width, numChannels], \"int32\");\n};\n\napp.post(\"\u002Fnsfw\", upload.single(\"image\"), async (req, res) => {\n  if (!req.file) res.status(400).send(\"Missing image multipart\u002Fform-data\");\n  else {\n    const image = await convert(req.file.buffer);\n    const predictions = await _model.classify(image);\n    image.dispose();\n    res.json(predictions);\n  }\n});\n\nconst load_model = async () => {\n  _model = await nsfw.load();\n};\n\n\u002F\u002F Keep the model in memory, make sure it's loaded only once\nload_model().then(() => app.listen(8080));\n\n\u002F\u002F curl --request POST localhost:8080\u002Fnsfw --header 'Content-Type: multipart\u002Fform-data' --data-binary 'image=@\u002Ffull\u002Fpath\u002Fto\u002Fpicture.jpg'\n```\n\nYou can also use [`lovell\u002Fsharp`](https:\u002F\u002Fgithub.com\u002Flovell\u002Fsharp) for preprocessing tasks and more file formats.\n\n### NSFW Filter\n\n[**NSFW Filter**](https:\u002F\u002Fgithub.com\u002Fnavendu-pottekkat\u002Fnsfw-filter) is an open source web extension for Google Chrome that uses NSFWJS for filtering out NSFW images.\n\nCheck out the project [here](https:\u002F\u002Fgithub.com\u002Fnavendu-pottekkat\u002Fnsfw-filter).\n\n## Learn TensorFlow.js\n\nLearn how to write your own library like NSFWJS with my O'Reilly book \"Learning TensorFlow.js\" available on [O'Reilly](https:\u002F\u002Flearning.oreilly.com\u002Flibrary\u002Fview\u002Flearning-tensorflowjs\u002F9781492090786\u002F) and [Amazon](https:\u002F\u002Famzn.to\u002F3dR3vpY).\n\n[![Learning TensorFlow.js JavaScript Book Red](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_18a117956626.jpg)](https:\u002F\u002Famzn.to\u002F3dR3vpY)\n\n## More!\n\nAn [FAQ](https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fwiki\u002FFAQ:-NSFW-JS) page is available.\n\nMore about NSFWJS and TensorFlow.js - https:\u002F\u002Fyoutu.be\u002FuzQwmZwy3yw\n\nThe [model was trained in Keras over several days](https:\u002F\u002Fmedium.freecodecamp.org\u002Fhow-to-set-up-nsfw-content-detection-with-machine-learning-229a9725829c) and 60+ Gigs of data. Be sure to [check out the model code](https:\u002F\u002Fgithub.com\u002FGantMan\u002Fnsfw_model) which was trained on data provided by [Alexander Kim's](https:\u002F\u002Fgithub.com\u002Falexkimxyz) [nsfw_data_scraper](https:\u002F\u002Fgithub.com\u002Falexkimxyz\u002Fnsfw_data_scraper).\n\n### Open Source\n\nNSFWJS, as open source, is free to use and always will be :heart:. It's MIT licensed, and we'll always do our best to help and quickly answer issues. If you'd like to get a hold of us, join our [community slack](http:\u002F\u002Fcommunity.infinite.red).\n\n### Need the experts? Hire Infinite Red for your next project\n\nIf your project's calling for the experts in all things React Native, Infinite Red’s here to help! Our experienced team of software engineers have worked with companies like Microsoft, Zoom, and Mercari to bring even some of the most complex projects to life.\n\nWhether it’s running a full project or training a team on React Native, we can help you solve your company’s toughest engineering challenges – and make it a great experience at the same time.\nReady to see how we can work together? [Send us a message](mailto:hello@infinite.red)\n\n## Contributors\n\nThanks goes to these wonderful people ([emoji key](https:\u002F\u002Fallcontributors.org\u002Fdocs\u002Fen\u002Femoji-key)):\n\n\u003C!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->\n\u003C!-- prettier-ignore-start -->\n\u003C!-- markdownlint-disable -->\n\u003Ctable>\n  \u003Ctbody>\n    \u003Ctr>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"http:\u002F\u002Fgantlaborde.com\u002F\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_bdc9af73a5ae.png\" width=\"100px;\" alt=\"Gant Laborde\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Gant Laborde\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"#question-GantMan\" title=\"Answering Questions\">💬\u003C\u002Fa> \u003Ca href=\"#blog-GantMan\" title=\"Blogposts\">📝\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=GantMan\" title=\"Code\">💻\u003C\u002Fa> \u003Ca href=\"#example-GantMan\" title=\"Examples\">💡\u003C\u002Fa> \u003Ca href=\"#ideas-GantMan\" title=\"Ideas, Planning, & Feedback\">🤔\u003C\u002Fa> \u003Ca href=\"#infra-GantMan\" title=\"Infrastructure (Hosting, Build-Tools, etc)\">🚇\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fpulls?q=is%3Apr+reviewed-by%3AGantMan\" title=\"Reviewed Pull Requests\">👀\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=GantMan\" title=\"Tests\">⚠️\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fjamonholmgren.com\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_e1ff89f438e7.png\" width=\"100px;\" alt=\"Jamon Holmgren\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Jamon Holmgren\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=jamonholmgren\" title=\"Documentation\">📖\u003C\u002Fa> \u003Ca href=\"#ideas-jamonholmgren\" title=\"Ideas, Planning, & Feedback\">🤔\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=jamonholmgren\" title=\"Code\">💻\u003C\u002Fa> \u003Ca href=\"#content-jamonholmgren\" title=\"Content\">🖋\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fmazenchami\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_ba6ee2cab763.png\" width=\"100px;\" alt=\"Mazen Chami\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Mazen Chami\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=mazenchami\" title=\"Documentation\">📖\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=mazenchami\" title=\"Code\">💻\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fpulls?q=is%3Apr+reviewed-by%3Amazenchami\" title=\"Reviewed Pull Requests\">👀\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=mazenchami\" title=\"Tests\">⚠️\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fjstudenski\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_62653ffe618e.png\" width=\"100px;\" alt=\"Jeff Studenski\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Jeff Studenski\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"#design-jstudenski\" title=\"Design\">🎨\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Ffvonhoven\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_9e83535c1e6a.png\" width=\"100px;\" alt=\"Frank von Hoven III\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Frank von Hoven III\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=fvonhoven\" title=\"Documentation\">📖\u003C\u002Fa> \u003Ca href=\"#ideas-fvonhoven\" title=\"Ideas, Planning, & Feedback\">🤔\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fsandeshsoni\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_b9c30b1f118a.png\" width=\"100px;\" alt=\"Sandesh Soni\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Sandesh Soni\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=sandeshsoni\" title=\"Code\">💻\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fseannam1218\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_a99e43f1fa6e.png\" width=\"100px;\" alt=\"Sean Nam\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Sean Nam\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=seannam1218\" title=\"Documentation\">📖\u003C\u002Fa>\u003C\u002Ftd>\n    \u003C\u002Ftr>\n    \u003Ctr>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Femer7\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_2dc0674dcddd.png\" width=\"100px;\" alt=\"Gilbert Emerson\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Gilbert Emerson\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=emer7\" title=\"Code\">💻\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fxilaraux\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_072c9564da23.png\" width=\"100px;\" alt=\"Oleksandr Kozlov\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Oleksandr Kozlov\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"#infra-xilaraux\" title=\"Infrastructure (Hosting, Build-Tools, etc)\">🚇\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=xilaraux\" title=\"Tests\">⚠️\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=xilaraux\" title=\"Code\">💻\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"http:\u002F\u002Fmorganlaco.com\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_0a843ee9d73c.png\" width=\"100px;\" alt=\"Morgan\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Morgan\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=mlaco\" title=\"Code\">💻\u003C\u002Fa> \u003Ca href=\"#ideas-mlaco\" title=\"Ideas, Planning, & Feedback\">🤔\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"http:\u002F\u002Fmycaule.github.io\u002F\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_c378d2561983.png\" width=\"100px;\" alt=\"Michel Hua\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Michel Hua\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=mycaule\" title=\"Code\">💻\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=mycaule\" title=\"Documentation\">📖\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fwww.infinite.red\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_e680663f037d.png\" width=\"100px;\" alt=\"Kevin VanGelder\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Kevin VanGelder\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=kevinvangelder\" title=\"Code\">💻\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=kevinvangelder\" title=\"Documentation\">📖\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"http:\u002F\u002Ftechnikempire.com\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_4f6e0e1ab5bb.png\" width=\"100px;\" alt=\"Jesse Nicholson\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Jesse Nicholson\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"#data-TechnikEmpire\" title=\"Data\">🔣\u003C\u002Fa> \u003Ca href=\"#ideas-TechnikEmpire\" title=\"Ideas, Planning, & Feedback\">🤔\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fcamhart\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_457335ea11ae.png\" width=\"100px;\" alt=\"camhart\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>camhart\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=camhart\" title=\"Documentation\">📖\u003C\u002Fa>\u003C\u002Ftd>\n    \u003C\u002Ftr>\n    \u003Ctr>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002FCameron-Burkholder\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_8f0977220cca.png\" width=\"100px;\" alt=\"Cameron Burkholder\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Cameron Burkholder\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"#design-Cameron-Burkholder\" title=\"Design\">🎨\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fqwertyforce.ru\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_fc9c33157097.png\" width=\"100px;\" alt=\"qwertyforce\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>qwertyforce\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=qwertyforce\" title=\"Documentation\">📖\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002FYegorZaremba\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_3a8707c5b7c4.png\" width=\"100px;\" alt=\"Yegor \u003C3\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Yegor \u003C3\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=YegorZaremba\" title=\"Code\">💻\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=YegorZaremba\" title=\"Tests\">⚠️\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"http:\u002F\u002Fnavendu.me\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_296cbe1050f8.png\" width=\"100px;\" alt=\"Navendu Pottekkat\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Navendu Pottekkat\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=navendu-pottekkat\" title=\"Documentation\">📖\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002FVladStepanov\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_5f7647fa0663.png\" width=\"100px;\" alt=\"Vladislav\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Vladislav\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=VladStepanov\" title=\"Code\">💻\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=VladStepanov\" title=\"Documentation\">📖\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fnacht42\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_a2075b0885e0.png\" width=\"100px;\" alt=\"Nacht\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Nacht\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=nacht42\" title=\"Code\">💻\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fkateinkim\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_983b3429fd80.png\" width=\"100px;\" alt=\"kateinkim\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>kateinkim\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=kateinkim\" title=\"Code\">💻\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=kateinkim\" title=\"Documentation\">📖\u003C\u002Fa>\u003C\u002Ftd>\n    \u003C\u002Ftr>\n    \u003Ctr>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fjanpoonthong.github.io\u002Fportfolio\u002F\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_a438fa2e2e40.png\" width=\"100px;\" alt=\"jan\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>jan\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=JanPoonthong\" title=\"Documentation\">📖\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Froerohan\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_a66c79d560ec.png\" width=\"100px;\" alt=\"Rohan Mukherjee\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Rohan Mukherjee\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"#question-roerohan\" title=\"Answering Questions\">💬\u003C\u002Fa> \u003Ca href=\"#infra-roerohan\" title=\"Infrastructure (Hosting, Build-Tools, etc)\">🚇\u003C\u002Fa> \u003Ca href=\"#maintenance-roerohan\" title=\"Maintenance\">🚧\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=roerohan\" title=\"Code\">💻\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fhazya.dev\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_498148ec6987.png\" width=\"100px;\" alt=\"Hasitha Wickramasinghe\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Hasitha Wickramasinghe\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=haZya\" title=\"Code\">💻\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=haZya\" title=\"Documentation\">📖\u003C\u002Fa> \u003Ca href=\"#example-haZya\" title=\"Examples\">💡\u003C\u002Fa> \u003Ca href=\"#ideas-haZya\" title=\"Ideas, Planning, & Feedback\">🤔\u003C\u002Fa> \u003Ca href=\"#infra-haZya\" title=\"Infrastructure (Hosting, Build-Tools, etc)\">🚇\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=haZya\" title=\"Tests\">⚠️\u003C\u002Fa>\u003C\u002Ftd>\n    \u003C\u002Ftr>\n  \u003C\u002Ftbody>\n\u003C\u002Ftable>\n\n\u003C!-- markdownlint-restore -->\n\u003C!-- prettier-ignore-end -->\n\n\u003C!-- ALL-CONTRIBUTORS-LIST:END -->\n\nThis project follows the [all-contributors](https:\u002F\u002Fgithub.com\u002Fall-contributors\u002Fall-contributors) specification. Contributions of any kind welcome!\n","\u003Cp align=\"center\">\n  \u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_bedfebff63d2.jpg\" alt=\"NSFWJS Logo\" width=\"400\" \u002F>\n  \u003Ch2 align=\"center\">客户端不雅内容检测\u003C\u002Fh2>\n\u003C\u002Fp>\n\n[![所有贡献者](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fall_contributors-15-green.svg?style=flat-square)](#contributors)\n[![CircleCI](https:\u002F\u002Fdl.circleci.com\u002Fstatus-badge\u002Fimg\u002Fgh\u002Finfinitered\u002Fnsfwjs\u002Ftree\u002Fmaster.svg?style=svg)](https:\u002F\u002Fdl.circleci.com\u002Fstatus-badge\u002Fredirect\u002Fgh\u002Finfinitered\u002Fnsfwjs\u002Ftree\u002Fmaster)\n[![Netlify 状态](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_999412434a2f.png)](https:\u002F\u002Fapp.netlify.com\u002Fsites\u002Fnsfwjs\u002Fdeploys)\n\n一个简单的 JavaScript 库，帮助你在客户端浏览器中快速识别不雅图像。NSFWJS 并不完美，但它的准确率相当高（小型模型约为 90%，中型模型约为 93%）……而且它还在不断改进。\n\n这有什么用呢？[请查看我们的公告博客文章](https:\u002F\u002Fshift.infinite.red\u002Favoid-nightmares-nsfw-js-ab7b176978b1)。\n\n\u003Cp align=\"center\">\n\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_524b6e150e00.gif\" alt=\"演示示例\" width=\"800\" align=\"center\" \u002F>\n\u003C\u002Fp>\n\n## 注意\n\n如果您尝试访问 CloudFront 托管的模型时遇到错误，很可能是由于该模型已被移至新位置。请参阅我们的[自托管模型](#host-your-own-model)部分。在处理完一些盗链行为后，我们会将模型恢复到原位置。\n\n## **目录**\n\n\u003C!-- START doctoc generated TOC please keep comment here to allow auto update -->\n\u003C!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n\n\n- [快速：如何使用该模块](#quick-how-to-use-the-module)\n  - [选择性模型包（Tree Shaking）](#selective-model-bundles-tree-shaking)\n- [库 API](#library-api)\n  - [`load` 加载模型](#load-the-model)\n  - [缓存](#caching)\n  - [`classify` 分类图像](#classify-an-image)\n  - [`dispose` 释放已加载的模型](#dispose-a-loaded-model)\n- [生产环境](#production)\n- [后端选择](#backend-selection)\n  - [WASM 后端（可选）](#wasm-backend-optional)\n  - [WebGPU 后端（可选）](#webgpu-backend-optional)\n  - [Node.js 后端](#nodejs-backend)\n- [安装](#install)\n  - [自托管模型](#host-your-own-model)\n- [运行示例](#run-the-examples)\n  - [TensorFlow.js 在浏览器中](#tensorflowjs-in-the-browser)\n  - [Browserify](#browserify)\n  - [React Native](#react-native)\n  - [Node.js 应用程序](#node-js-app)\n  - [NSFW 过滤器](#nsfw-filter)\n- [学习 TensorFlow.js](#learn-tensorflowjs)\n- [更多！](#more)\n  - [开源项目](#open-source)\n  - [需要专家？为您的下一个项目聘请 Infinite Red](#need-the-experts-hire-infinite-red-for-your-next-project)\n- [贡献者](#contributors)\n\n\u003C!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\n该库将图像概率分为以下 5 类：\n\n- `Drawing` - 适合工作场所的插画（包括动漫）\n- `Hentai` - 色情和成人向插画\n- `Neutral` - 适合工作场所的中性图像\n- `Porn` - 色情图片、性行为\n- `Sexy` - 性暗示图像，但不属于色情内容\n\n> _该演示是一个持续部署的源代码——快来试试吧：http:\u002F\u002Fnsfwjs.com_\n\n## 快速：如何使用该模块\n\n```js\nimport * as nsfwjs from \"nsfwjs\";\n\nconst img = document.getElementById(\"img\");\n\n\u002F\u002F 如果您想自行托管模型或使用其他可用模型，请参阅“自托管模型”部分。\nconst model = await nsfwjs.load();\n\n\u002F\u002F 对图像进行分类\nconst predictions = await model.classify(img);\nconsole.log(\"预测结果：\", predictions);\n```\n\n### 选择性模型包（Tree Shaking）\n\n`nsfwjs` 保持默认行为，并包含内置的模型定义。若需选择性打包，请从 `nsfwjs\u002Fcore` 导入，并仅传递您所需的模型到 `modelDefinitions` 中。\n\n```js\nimport { load } from \"nsfwjs\u002Fcore\";\nimport { MobileNetV2Model } from \"nsfwjs\u002Fmodels\u002Fmobilenet_v2\";\nimport { MobileNetV2MidModel } from \"nsfwjs\u002Fmodels\u002Fmobilenet_v2_mid\";\n\nconst model = await load(\"MobileNetV2\", {\n  modelDefinitions: [MobileNetV2Model, MobileNetV2MidModel],\n});\n```\n\n如果传递空的模型注册表，命名的捆绑模型加载将会失败：\n\n```js\nawait load(\"MobileNetV2\", { modelDefinitions: [] }); \u002F\u002F 抛出异常\n```\n\n## 库 API\n\n### `load` 加载模型\n\n在对任何图像进行分类之前，您需要先加载模型。\n\n```js\nconst model = nsfwjs.load(); \u002F\u002F 默认： \"MobileNetV2\"\n```\n\n您可以使用可选的第一个参数来指定要使用的内置模型（共有三种）。默认值为：“MobileNetV2”。\n\n对于 Tree Shaking 的选择性模型打包，请使用 `nsfwjs\u002Fcore`，并按上述方式传递 `modelDefinitions`。\n\n```js\nconst model = nsfwjs.load(\"MobileNetV2Mid\"); \u002F\u002F \"MobileNetV2\" | \"MobileNetV2Mid\" | \"InceptionV3\"\n```\n\n您还可以使用相同的参数，从自己的网站或服务器加载模型，具体说明请参阅[自托管模型](#host-your-own-model)部分。这样做可以将模型加载的包体积减少约 1.33 倍（33%），因为您可以直接使用二进制文件，而不是随软件包一起打包的 Base64 编码数据。例如，“MobileNetV2”模型在软件包中为 3.5MB，而托管的二进制文件仅为 2.6MB。不过，这种优化只有在客户端浏览器每次加载模型（未使用[缓存](#caching)）时才会体现出来；而在服务器端，您只需在服务器启动时加载一次即可。\n\n如果您通过 URL 自行托管模型，并希望获得最小的应用程序包体积，应从 `nsfwjs\u002Fcore` 而不是 `nsfwjs` 中导入 `load`。核心入口点默认不包含内置模型定义，因此打包工具不会将这些模型资源引入您的应用程序包中。\n\n```js\nimport { load } from \"nsfwjs\u002Fcore\";\n\nconst model = await load(\"\u002Fpath\u002Fto\u002Fmobilenet_v2\u002Fmodel.json\");\n```\n\nMobileNetV2 模型 - [224x224](https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fblob\u002Fmaster\u002Fmodels\u002Fmobilenet_v2\u002F)\n\n```js\nconst model = nsfwjs.load(\"\u002Fpath\u002Fto\u002Fmobilenet_v2\u002F\");\n```\n\n如果您使用的模型需要不同于 224x224 的图像尺寸，可以在选项参数中指定尺寸。\n\nMobileNetV2Mid 模型 - [图模型](https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Ftree\u002Fmaster\u002Fmodels\u002Fmobilenet_v2_mid)\n\n```js\n\u002F* 您可能需要以图模型格式加载此模型 *\u002F\nconst model = nsfwjs.load(\"\u002Fpath\u002Fto\u002Fmobilenet_v2_mid\u002F\", { type: 'graph' });\n```\n\n如果使用图模型，则无法使用推理方法，您需要在选项中告知模型加载程序您正在处理的是图模型。\n\nInceptionV3 模型 - [299x299](https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Ftree\u002Fmaster\u002Fmodels\u002Finception_v3)\n\n```js\nconst model = nsfwjs.load(\"\u002Fpath\u002Fto\u002Finception_v3\u002F\", { size: 299 });\n```\n\n### 缓存\n\n如果你在浏览器中使用，并希望后续从 IndexedDB 或本地存储加载（注意：模型大小可能超出本地存储的限制！），你可以使用相应的方案保存底层模型，然后从中加载。\n\n```js\nconst initialLoad = await nsfwjs.load(\n  \"\u002Fpath\u002Fto\u002Fdifferent\u002Fmodel\u002F\" \u002F*, { ...options }*\u002F\n);\nawait initialLoad.model.save(\"indexeddb:\u002F\u002FexampleModel\");\nconst model = await nsfwjs.load(\"indexeddb:\u002F\u002FexampleModel\" \u002F*, { ...options }*\u002F);\n```\n\n**参数**\n\n首次加载：\n1. 包含 `model.json` 文件的文件夹的 URL 或路径。\n2. 可选对象，包含你的模型期望的尺寸或类型属性。\n\n后续加载：\n1. IndexedDB 路径。\n2. 可选对象，包含你的模型期望的尺寸或类型属性。\n\n\n**返回值**\n\n- 即可使用的 NSFWJS 模型对象\n  \n\n**故障排除**\n\n- 在加载模型的标签页中，打开开发者工具并切换到“Application”选项卡。在左侧“Storage”部分下，有一个名为 “IndexedDB”的子部分。在这里你可以查看模型是否已成功保存。\n\n有关完整的浏览器 Worker 实现（包括后端初始化、优先从 IndexedDB 加载以及未命中时的缓存保存），请参阅 [`examples\u002Fnsfw_demo\u002Fsrc\u002Fnsfwjs.worker.ts`](.\u002Fexamples\u002Fnsfw_demo\u002Fsrc\u002Fnsfwjs.worker.ts)。\n\n### 对图像进行 `classify`\n\n此函数可以接受任何基于浏览器的图像元素（`\u003Cimg>`、`\u003Cvideo>`、`\u003Ccanvas>`），并返回最可能的预测结果及其置信度。\n\n```js\n\u002F\u002F 返回前 3 名猜测（而不是全部 5 名）\nconst predictions = await model.classify(img, 3);\n```\n\n**参数**\n\n- 要检查的张量、图像数据、图像元素、视频元素或画布元素。\n- 要返回的结果数量（默认为全部 5 个）。\n\n**返回值**\n\n- 包含 `className` 和 `probability` 的对象数组。数组的大小由 `classify` 函数中的第二个参数决定。\n\n### 释放已加载的模型\n\n如果你不再需要某个模型实例，可以调用 `dispose()` 来释放持有的张量和模型资源。\n\n```js\nconst model = await nsfwjs.load();\n\u002F\u002F ... 分类\u002F推理\nmodel.dispose();\n```\n\n## 生产环境\n\nTensorFlow.js 提供了两个标志：`enableProdMode` 和 `enableDebugMode`。如果你要在生产环境中使用 NSFWJS，请务必在加载 NSFWJS 模型之前启用生产模式。\n\n```js\nimport * as tf from \"@tensorflow\u002Ftfjs\";\nimport * as nsfwjs from \"nsfwjs\";\ntf.enableProdMode();\n\u002F\u002F...\nlet model = await nsfwjs.load(`${urlToNSFWJSModel}`);\n```\n\n**注意**：建议在进入生产环境之前，按照“托管你自己的模型”一节所述，自行下载并托管模型。这可能会改善模型的初始加载时间。此外，如果在浏览器中使用该模型，还可以考虑对其进行 [缓存](#caching)。\n\n## 后端选择\n\nNSFWJS 使用当前激活的 TensorFlow.js 后端。\n\n显式设置后端是可选的。如果你导入了一个或多个后端并调用 `await tf.ready()`，TensorFlow.js 会自动选择最佳可用后端。\n\n仅当你希望在不同设备上获得确定性行为时，才应使用 `tf.setBackend(...)`。\n\n自动后端选择：\n\n```js\nimport * as tf from \"@tensorflow\u002Ftfjs\";\nimport \"@tensorflow\u002Ftfjs-backend-webgpu\";\nimport \"@tensorflow\u002Ftfjs-backend-wasm\";\nimport * as nsfwjs from \"nsfwjs\";\n\nawait tf.ready();\n\nconst model = await nsfwjs.load();\n```\n\n固定后端选择：\n\n```js\nimport * as tf from \"@tensorflow\u002Ftfjs\";\nimport \"@tensorflow\u002Ftfjs-backend-webgpu\";\n\nawait tf.setBackend(\"webgpu\");\nawait tf.ready();\n```\n\n### WASM 后端（可选）\n\n```bash\nyarn add @tensorflow\u002Ftfjs-backend-wasm\n```\n\n```js\nimport * as tf from \"@tensorflow\u002Ftfjs\";\nimport {\n  setWasmPaths,\n} from \"@tensorflow\u002Ftfjs-backend-wasm\";\nimport \"@tensorflow\u002Ftfjs-backend-wasm\";\n\n\u002F\u002F 如果你没有使用标准打包工具，需设置 .wasm 二进制文件的路径。\nsetWasmPaths(\"https:\u002F\u002Fcdn.jsdelivr.net\u002Fnpm\u002F@tensorflow\u002Ftfjs-backend-wasm\u002Fdist\u002F\");\n\nawait tf.setBackend(\"wasm\");\nawait tf.ready();\n```\n\n### WebGPU 后端（可选）\n\n```bash\nyarn add @tensorflow\u002Ftfjs-backend-webgpu\n```\n\n```js\nimport * as tf from \"@tensorflow\u002Ftfjs\";\nimport \"@tensorflow\u002Ftfjs-backend-webgpu\";\n\nawait tf.setBackend(\"webgpu\");\nawait tf.ready();\n```\n\n后端建议：\n\n- `webgpu`：在支持的浏览器和硬件上通常速度最快。\n- `webgl`：现代桌面和移动浏览器中的强大默认选项。\n- `wasm`：适用于 WebGL 不可用或受限的环境的有用备选方案。\n- `cpu`：兼容性广，但通常速度较慢。\n\n### Node.js 后端\n\n对于 Node.js 工作负载，建议使用 `@tensorflow\u002Ftfjs-node`（或在适用时使用 `@tensorflow\u002Ftfjs-node-gpu`）以获得更好的性能。示例请参见“Node.js 应用”一节。\n\n务必在目标浏览器\u002F设备组合上进行基准测试。\n\n## 安装\n\nNSFWJS 依赖于 TensorFlow.js 作为其对等依赖项。如果你的项目尚未包含 TensorFlow.js，你可能需要将其添加进来。\n\n```bash\n# 对等依赖\n$ yarn add @tensorflow\u002Ftfjs\n# 安装 NSFWJS\n$ yarn add nsfwjs\n```\n\n对于 script 标签，需包含所有捆绑包，如 [这里](#browserify) 所示。然后可以直接访问 nsfwjs 全局变量。这要求你已经同时引入了 TensorFlow.js。\n\n### 托管你自己的模型\n\nNSFWJS 的核心是 [NSFW 检测模型](https:\u002F\u002Fgithub.com\u002Fgantman\u002Fnsfw_model)。默认情况下，这些模型被打包在这个软件包中。但你可能希望将模型托管在自己的服务器上，以便通过加载原始二进制文件来减小捆绑包大小，或者托管自定义模型。如果你想托管 [模型文件](https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Ftree\u002Fmaster\u002Fmodels) 的自定义版本，可以按照以下步骤操作。然后可以在 `load` 函数中传递你托管文件的相对 URL，并在必要时提供 `options`。\n\n如果加载的是托管模型 URL，建议使用 `nsfwjs\u002Fcore`，这样你的应用就不会打包内置的模型定义。请参阅“选择性模型捆绑包（Tree Shaking）”一节。\n\n以下是将默认模型安装到网站上的方法：\n\n1. 下载该项目，可以选择下载 ZIP 文件或使用 `git clone https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs.git` 进行克隆。\n2. 从项目根目录中提取 `models` 文件夹，并将其放入你的 Web 应用程序的 `public` 目录中，以便与你的网站一起作为静态文件提供。（你也可以将其托管在任何地方，例如 S3 存储桶中，只要可以通过 URL 访问即可）。\n3. 获取 URL 并将其放入 `nsfwjs.load()` 中。例如：`nsfwjs.load(https:\u002F\u002Fyourwebsite.com\u002Fmodels\u002Fmobilenet_v2\u002Fmodel.json)`。\n\n## 运行示例\n\n### 浏览器中的 TensorFlow.js\n\n驱动 https:\u002F\u002Fnsfwjs.com\u002F 的演示位于 [`examples\u002Fnsfw_demo`](https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Ftree\u002Fmaster\u002Fexamples\u002Fnsfw_demo) 文件夹中。\n\n要运行该演示，执行 `yarn demo`，它会将最新代码复制到演示中并启动开发服务器。\n\n### Browserify\n\n仅使用 Promise 和 `\u003Cscript>` 标签的浏览器化版本，可在 [`minimal_demo`](https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Ftree\u002Fmaster\u002Fexamples\u002Fminimal_demo) 文件夹中找到。\n\n```js\n\u003Cscript src=\"\u002Fpath\u002Fto\u002Fmodel\u002Fdirectory\u002Fmodel.min.js\">\u003C\u002Fscript>\n\u003Cscript src=\"\u002Fpath\u002Fto\u002Fmodel\u002Fdirectory\u002Fgroup1-shard1of2.min.js\">\u003C\u002Fscript>\n\u003Cscript src=\"\u002Fpath\u002Fto\u002Fmodel\u002Fdirectory\u002Fgroup1-shard2of2.min.js\">\u003C\u002Fscript>\n\u003Cscript src=\"\u002Fpath\u002Fto\u002Fbundle\u002Fnsfwjs.min.js\">\u003C\u002Fscript>\n```\n\n您应该将 `nsfwjs.min.js` 文件以及所有要使用的模型包托管在您的项目目录下，并通过 `\u003Cscript>` 标签中的 `src` 属性引用它们。\n\n### React Native\n\n[NSFWJS React Native 应用](https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs-mobile)\n\n![React Native Demo](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_bde24ad9fb90.jpg)\n\n加载本地模型以减少网络负载，并利用 TFJS-React-Native。[博客文章](https:\u002F\u002Fshift.infinite.red\u002Fnsfw-js-for-react-native-a37c9ba45fe9)\n\n### Node JS 应用程序\n\n通过 NPM，您也可以在服务器端使用该模型。\n\n```bash\n$ npm install nsfwjs\n$ npm install @tensorflow\u002Ftfjs-node\n```\n\n```javascript\nconst axios = require(\"axios\"); \u002F\u002F您可以使用任何 HTTP 客户端\nconst tf = require(\"@tensorflow\u002Ftfjs-node\");\nconst nsfw = require(\"nsfwjs\");\nasync function fn() {\n  const pic = await axios.get(`link-to-picture`, {\n    responseType: \"arraybuffer\",\n  });\n  const model = await nsfw.load(); \u002F\u002F 要加载本地模型，可以使用 nsfw.load('file:\u002F\u002F.\u002Fpath\u002Fto\u002Fmodel\u002F')\n  \u002F\u002F 图像必须是 tf.tensor3d 格式\n  \u002F\u002F 您可以通过 tf.node.decodeImage(Uint8Array,channels) 将图像转换为 tf.tensor3d\n  const image = await tf.node.decodeImage(pic.data, 3);\n  const predictions = await model.classify(image);\n  image.dispose(); \u002F\u002F 必须显式管理张量内存（仅仅让 tf.Tensor 超出作用域并不能释放其内存）。\n  console.log(predictions);\n}\nfn();\n```\n\n以下是另一个使用 Express 的 [multipart\u002Fform-data POST 示例](examples\u002Fnode_demo)，假设您使用的是 JPG 格式。\n\n```javascript\nconst express = require(\"express\");\nconst multer = require(\"multer\");\nconst jpeg = require(\"jpeg-js\");\n\nconst tf = require(\"@tensorflow\u002Ftfjs-node\");\nconst nsfw = require(\"nsfwjs\");\n\nconst app = express();\nconst upload = multer();\n\nlet _model;\n\nconst convert = async (img) => {\n  \u002F\u002F 解码后的图像以 UInt8 字节数组形式存储\n  const image = await jpeg.decode(img, { useTArray: true });\n\n  const numChannels = 3;\n  const numPixels = image.width * image.height;\n  const values = new Int32Array(numPixels * numChannels);\n\n  for (let i = 0; i \u003C numPixels; i++)\n    for (let c = 0; c \u003C numChannels; ++c)\n      values[i * numChannels + c] = image.data[i * 4 + c];\n\n  return tf.tensor3d(values, [image.height, image.width, numChannels], \"int32\");\n};\n\napp.post(\"\u002Fnsfw\", upload.single(\"image\"), async (req, res) => {\n  if (!req.file) res.status(400).send(\"缺少 multipart\u002Fform-data 图像\");\n  else {\n    const image = await convert(req.file.buffer);\n    const predictions = await _model.classify(image);\n    image.dispose();\n    res.json(predictions);\n  }\n});\n\nconst load_model = async () => {\n  _model = await nsfw.load();\n};\n\n\u002F\u002F 将模型保留在内存中，确保只加载一次\nload_model().then(() => app.listen(8080));\n\n\u002F\u002F curl --request POST localhost:8080\u002Fnsfw --header 'Content-Type: multipart\u002Fform-data' --data-binary 'image=@\u002Ffull\u002Fpath\u002Fto\u002Fpicture.jpg'\n```\n\n您还可以使用 [`lovell\u002Fsharp`](https:\u002F\u002Fgithub.com\u002Flovell\u002Fsharp) 进行预处理任务和更多文件格式的支持。\n\n### NSFW 过滤器\n\n[**NSFW Filter**](https:\u002F\u002Fgithub.com\u002Fnavendu-pottekkat\u002Fnsfw-filter) 是一个开源的 Google Chrome 浏览器扩展，它使用 NSFWJS 来过滤掉不适宜的内容图片。\n\n请在此处查看该项目：[GitHub](https:\u002F\u002Fgithub.com\u002Fnavendu-pottekkat\u002Fnsfw-filter)。\n\n## 学习 TensorFlow.js\n\n学习如何编写像 NSFWJS 这样的库，请参阅我的 O'Reilly 出版社书籍《Learning TensorFlow.js》，可在 [O'Reilly](https:\u002F\u002Flearning.oreilly.com\u002Flibrary\u002Fview\u002Flearning-tensorflowjs\u002F9781492090786\u002F) 和 [亚马逊](https:\u002F\u002Famzn.to\u002F3dR3vpY) 上购买。\n\n[![Learning TensorFlow.js JavaScript Book Red](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_18a117956626.jpg)](https:\u002F\u002Famzn.to\u002F3dR3vpY)\n\n## 更多！\n\n现已提供常见问题解答页面：[FAQ](https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fwiki\u002FFAQ:-NSFW-JS)。\n\n有关 NSFWJS 和 TensorFlow.js 的更多信息 - https:\u002F\u002Fyoutu.be\u002FuzQwmZwy3yw\n\n该模型是在 Keras 中经过数天训练的，使用了超过 60GB 的数据。请务必查看由 [Alexander Kim](https:\u002F\u002Fgithub.com\u002Falexkimxyz) 提供的数据训练而成的模型代码：[nsfw_model](https:\u002F\u002Fgithub.com\u002FGantMan\u002Fnsfw_model) 和他的 [nsfw_data_scraper](https:\u002F\u002Fgithub.com\u002Falexkimxyz\u002Fnsfw_data_scraper)。\n\n### 开源\n\n作为开源项目，NSFWJS 可免费使用，并且永远保持免费：heart:。它采用 MIT 许可证，我们将始终竭诚帮助并快速回复各类问题。如果您想与我们取得联系，请加入我们的 [社区 Slack](http:\u002F\u002Fcommunity.infinite.red)。\n\n### 需要专家？为您的下一个项目聘请 Infinite Red\n\n如果您的项目需要 React Native 方面的专家，Infinite Red 随时为您提供帮助！我们经验丰富的软件工程师团队曾与微软、Zoom 和 Mercari 等公司合作，成功完成了许多复杂项目。\n\n无论是完整项目的开发，还是对团队进行 React Native 培训，我们都能够帮助您解决公司最棘手的工程挑战——同时为您带来愉快的合作体验。\n准备好了解我们如何携手合作了吗？[发送邮件给我们](mailto:hello@infinite.red)\n\n## 贡献者\n\n感谢以下各位贡献者（表情符号说明见 [allcontributors.org](https:\u002F\u002Fallcontributors.org\u002Fdocs\u002Fen\u002Femoji-key)）：\n\n\u003C!-- ALL-CONTRIBUTORS-LIST:START - 请勿删除或修改此部分 -->\n\u003C!-- prettier-ignore-start -->\n\u003C!-- markdownlint-disable -->\n\u003Ctable>\n  \u003Ctbody>\n    \u003Ctr>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"http:\u002F\u002Fgantlaborde.com\u002F\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_bdc9af73a5ae.png\" width=\"100px;\" alt=\"Gant Laborde\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Gant Laborde\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"#question-GantMan\" title=\"回答问题\">💬\u003C\u002Fa> \u003Ca href=\"#blog-GantMan\" title=\"博客文章\">📝\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=GantMan\" title=\"代码\">💻\u003C\u002Fa> \u003Ca href=\"#example-GantMan\" title=\"示例\">💡\u003C\u002Fa> \u003Ca href=\"#ideas-GantMan\" title=\"想法、规划与反馈\">🤔\u003C\u002Fa> \u003Ca href=\"#infra-GantMan\" title=\"基础设施（托管、构建工具等）\">🚇\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fpulls?q=is%3Apr+reviewed-by%3AGantMan\" title=\"已审阅的拉取请求\">👀\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=GantMan\" title=\"测试\">⚠️\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fjamonholmgren.com\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_e1ff89f438e7.png\" width=\"100px;\" alt=\"Jamon Holmgren\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Jamon Holmgren\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=jamonholmgren\" title=\"文档\">📖\u003C\u002Fa> \u003Ca href=\"#ideas-jamonholmgren\" title=\"想法、规划与反馈\">🤔\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=jamonholmgren\" title=\"代码\">💻\u003C\u002Fa> \u003Ca href=\"#content-jamonholmgren\" title=\"内容\">🖋\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fmazenchami\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_ba6ee2cab763.png\" width=\"100px;\" alt=\"Mazen Chami\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Mazen Chami\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=mazenchami\" title=\"文档\">📖\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=mazenchami\" title=\"代码\">💻\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fpulls?q=is%3Apr+reviewed-by%3Amazenchami\" title=\"已审阅的拉取请求\">👀\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=mazenchami\" title=\"测试\">⚠️\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fjstudenski\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_62653ffe618e.png\" width=\"100px;\" alt=\"Jeff Studenski\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Jeff Studenski\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"#design-jstudenski\" title=\"设计\">🎨\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Ffvonhoven\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_9e83535c1e6a.png\" width=\"100px;\" alt=\"Frank von Hoven III\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Frank von Hoven III\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=fvonhoven\" title=\"文档\">📖\u003C\u002Fa> \u003Ca href=\"#ideas-fvonhoven\" title=\"想法、规划与反馈\">🤔\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fsandeshsoni\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_b9c30b1f118a.png\" width=\"100px;\" alt=\"Sandesh Soni\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Sandesh Soni\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=sandeshsoni\" title=\"代码\">💻\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fseannam1218\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_a99e43f1fa6e.png\" width=\"100px;\" alt=\"Sean Nam\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Sean Nam\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=seannam1218\" title=\"文档\">📖\u003C\u002Fa>\u003C\u002Ftd>\n    \u003C\u002Ftr>\n    \u003Ctr>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Femer7\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_2dc0674dcddd.png\" width=\"100px;\" alt=\"Gilbert Emerson\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Gilbert Emerson\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=emer7\" title=\"代码\">💻\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fxilaraux\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_072c9564da23.png\" width=\"100px;\" alt=\"Oleksandr Kozlov\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Oleksandr Kozlov\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"#infra-xilaraux\" title=\"基础设施（托管、构建工具等）\">🚇\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=xilaraux\" title=\"测试\">⚠️\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=xilaraux\" title=\"代码\">💻\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"http:\u002F\u002Fmorganlaco.com\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_0a843ee9d73c.png\" width=\"100px;\" alt=\"Morgan\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Morgan\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=mlaco\" title=\"代码\">💻\u003C\u002Fa> \u003Ca href=\"#ideas-mlaco\" title=\"想法、规划与反馈\">🤔\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"http:\u002F\u002Fmycaule.github.io\u002F\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_c378d2561983.png\" width=\"100px;\" alt=\"Michel Hua\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Michel Hua\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=mycaule\" title=\"代码\">💻\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=mycaule\" title=\"文档\">📖\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fwww.infinite.red\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_e680663f037d.png\" width=\"100px;\" alt=\"Kevin VanGelder\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Kevin VanGelder\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=kevinvangelder\" title=\"代码\">💻\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=kevinvangelder\" title=\"文档\">📖\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"http:\u002F\u002Ftechnikempire.com\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_4f6e0e1ab5bb.png\" width=\"100px;\" alt=\"Jesse Nicholson\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Jesse Nicholson\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"#data-TechnikEmpire\" title=\"数据\">🔣\u003C\u002Fa> \u003Ca href=\"#ideas-TechnikEmpire\" title=\"想法、规划与反馈\">🤔\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fcamhart\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_457335ea11ae.png\" width=\"100px;\" alt=\"camhart\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>camhart\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=camhart\" title=\"文档\">📖\u003C\u002Fa>\u003C\u002Ftd>\n    \u003C\u002Ftr>\n    \u003Ctr>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002FCameron-Burkholder\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_8f0977220cca.png\" width=\"100px;\" alt=\"Cameron Burkholder\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Cameron Burkholder\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"#design-Cameron-Burkholder\" title=\"设计\">🎨\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fqwertyforce.ru\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_fc9c33157097.png\" width=\"100px;\" alt=\"qwertyforce\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>qwertyforce\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa>\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=qwertyforce\" title=\"文档\">📖\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002FYegorZaremba\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_3a8707c5b7c4.png\" width=\"100px;\" alt=\"Yegor \u003C3\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Yegor \u003C3\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa)\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=YegorZaremba\" title=\"代码\">💻\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=YegorZaremba\" title=\"测试\">⚠️\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"http:\u002F\u002Fnavendu.me\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_296cbe1050f8.png\" width=\"100px;\" alt=\"Navendu Pottekkat\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Navendu Pottekkat\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa)\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=navendu-pottekkat\" title=\"文档\">📖\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002FVladStepanov\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_5f7647fa0663.png\" width=\"100px;\" alt=\"Vladislav\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Vladislav\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa)\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=VladStepanov\" title=\"代码\">💻\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=VladStepanov\" title=\"文档\">📖\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fnacht42\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_a2075b0885e0.png\" width=\"100px;\" alt=\"Nacht\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Nacht\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa)\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=nacht42\" title=\"代码\">💻\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fkateinkim\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_983b3429fd80.png\" width=\"100px;\" alt=\"kateinkim\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>kateinkim\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa)\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=kateinkim\" title=\"代码\">💻\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=kateinkim\" title=\"文档\">📖\u003C\u002Fa>\u003C\u002Ftd>\n    \u003C\u002Ftr>\n    \u003Ctr>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fjanpoonthong.github.io\u002Fportfolio\u002F\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_a438fa2e2e40.png\" width=\"100px;\" alt=\"jan\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>jan\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa)\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=JanPoonthong\" title=\"文档\">📖\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Froerohan\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_a66c79d560ec.png\" width=\"100px;\" alt=\"Rohan Mukherjee\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Rohan Mukherjee\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa)\u003Cbr \u002F>\u003Ca href=\"#question-roerohan\" title=\"回答问题\">💬\u003C\u002Fa> \u003Ca href=\"#infra-roerohan\" title=\"基础设施（托管、构建工具等）\">🚇\u003C\u002Fa> \u003Ca href=\"#maintenance-roerohan\" title=\"维护\">🚧\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=roerohan\" title=\"代码\">💻\u003C\u002Fa>\u003C\u002Ftd>\n      \u003Ctd align=\"center\" valign=\"top\" width=\"14.28%\">\u003Ca href=\"https:\u002F\u002Fhazya.dev\">\u003Cimg src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_readme_498148ec6987.png\" width=\"100px;\" alt=\"Hasitha Wickramasinghe\"\u002F>\u003Cbr \u002F>\u003Csub>\u003Cb>Hasitha Wickramasinghe\u003C\u002Fb>\u003C\u002Fsub>\u003C\u002Fa)\u003Cbr \u002F>\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=haZya\" title=\"代码\">💻\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=haZya\" title=\"文档\">📖\u003C\u002Fa> \u003Ca href=\"#example-haZya\" title=\"示例\">💡\u003C\u002Fa> \u003Ca href=\"#ideas-haZya\" title=\"想法、规划与反馈\">🤔\u003C\u002Fa> \u003Ca href=\"#infra-haZya\" title=\"基础设施（托管、构建工具等）\">🚇\u003C\u002Fa> \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcommits?author=haZya\" title=\"测试\">⚠️\u003C\u002Fa>\u003C\u002Ftd>\n    \u003C\u002Ftr>\n  \u003C\u002Ftbody>\n\u003C\u002Ftable>\n\n\u003C!-- markdownlint-restore -->\n\u003C!-- prettier-ignore-end -->\n\n\u003C!-- ALL-CONTRIBUTORS-LIST:END -->\n\nThis project follows the [all-contributors](https:\u002F\u002Fgithub.com\u002Fall-contributors\u002Fall-contributors) specification. Contributions of any kind welcome!","# nsfwjs 快速上手指南\n\nnsfwjs 是一个运行在客户端（浏览器或 Node.js）的 JavaScript 库，用于快速识别图像中是否包含不适宜内容（NSFW）。它基于 TensorFlow.js，无需后端服务器即可在本地完成分类。\n\n## 环境准备\n\n*   **系统要求**：支持现代浏览器（Chrome, Firefox, Safari, Edge）或 Node.js 环境。\n*   **前置依赖**：\n    *   项目需安装 `@tensorflow\u002Ftfjs` 作为对等依赖（Peer Dependency）。\n    *   若需更佳性能，可选装特定后端（如 `@tensorflow\u002Ftfjs-backend-wasm` 或 `@tensorflow\u002Ftfjs-backend-webgpu`）。\n\n## 安装步骤\n\n使用 npm 或 yarn 安装核心库及 TensorFlow.js：\n\n```bash\n# 安装对等依赖 TensorFlow.js\nyarn add @tensorflow\u002Ftfjs\n# 或\nnpm install @tensorflow\u002Ftfjs\n\n# 安装 nsfwjs\nyarn add nsfwjs\n# 或\nnpm install nsfwjs\n```\n\n> **提示**：国内开发者若遇到下载缓慢，可配置淘宝镜像源：\n> `yarn config set registry https:\u002F\u002Fregistry.npmmirror.com`\n\n## 基本使用\n\n以下是在浏览器环境中最简单的使用示例。\n\n### 1. 导入与加载模型\n\n首先导入库并加载默认模型（MobileNetV2）。\n\n```js\nimport * as nsfwjs from \"nsfwjs\";\n\n\u002F\u002F 获取图片元素\nconst img = document.getElementById(\"img\");\n\n\u002F\u002F 加载模型 (默认从 CDN 加载，生产环境建议托管自己的模型)\nconst model = await nsfwjs.load();\n```\n\n### 2. 分类图像\n\n调用 `classify` 方法对图像进行分析，返回预测结果数组。\n\n```js\n\u002F\u002F 对图像进行分类，返回概率最高的前 3 个结果\nconst predictions = await model.classify(img, 3);\n\nconsole.log(\"Predictions: \", predictions);\n```\n\n### 3. 结果解读\n\n返回的数组包含 `className`（类别）和 `probability`（置信度）。支持的类别如下：\n\n*   `Drawing`: 安全的工作绘图（包括动漫）。\n*   `Hentai`: 色情绘图。\n*   `Neutral`: 安全的普通图像。\n*   `Porn`: 色情图像、性行为。\n*   `Sexy`: 性暗示图像，非直接色情。\n\n### 4. 释放资源（可选）\n\n当不再需要模型实例时，调用 `dispose()` 释放内存。\n\n```js\nmodel.dispose();\n```\n\n---\n\n**生产环境建议**：\n默认情况下模型从远程 CDN 加载。为了稳定性和加载速度，建议将模型文件托管到自己的服务器，并使用 `nsfwjs.load(\"\u002Fpath\u002Fto\u002Fyour\u002Fmodel\u002F\")` 进行加载。","某初创社交平台的开发团队正在构建一个允许用户实时上传头像和动态图片的社区功能，急需在内容发布前自动拦截违规图像。\n\n### 没有 nsfwjs 时\n- **审核滞后严重**：所有图片必须先上传至服务器，再由后端队列异步处理，用户发布后需等待数秒甚至更久才能得知是否违规，体验极差。\n- **服务器成本高昂**：大量的图片分类计算占用了宝贵的 GPU\u002FCPU 资源，导致云服务商账单激增，且高并发时容易拖垮主业务接口。\n- **隐私合规风险**：用户敏感图片必须传输并暂存到公司服务器进行扫描，增加了数据泄露风险，难以满足严格的隐私保护法规（如 GDPR）。\n- **误杀人工复核难**：缺乏前端即时反馈，大量明显违规图片涌入后台，审核人员需花费大量时间处理本可在源头阻断的垃圾内容。\n\n### 使用 nsfwjs 后\n- **毫秒级即时拦截**：利用 TensorFlow.js 在用户浏览器端直接运行模型，图片在本地即可完成“色情”、“性感”等 5 类识别，违规图片在上传前即被阻断。\n- **零服务器计算负载**：将繁重的推理计算完全转移至客户端设备，服务器仅需接收安全图片，显著降低了带宽压力和算力成本。\n- **隐私安全原生保障**：敏感图片无需离开用户设备即可完成检测，从架构上杜绝了违规内容落盘存储的风险，完美契合隐私合规要求。\n- **精准分类辅助决策**：nsfwjs 能区分“动漫绘图”与“中性图片”，有效减少对二次元内容的误判，让后端审核团队只需聚焦于极少数边缘案例。\n\nnsfwjs 通过将智能审核能力下沉至浏览器端，以零服务器成本实现了实时、隐私安全的违规内容过滤，彻底重构了社区内容风控流程。","https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Finfinitered_nsfwjs_bde24ad9.jpg","infinitered","Infinite Red, Inc.","https:\u002F\u002Foss.gittoolsai.com\u002Favatars\u002Finfinitered_b0225f30.png","Development Studio",null,"hello@infinite.red","infinite_red","http:\u002F\u002Finfinite.red","https:\u002F\u002Fgithub.com\u002Finfinitered",[82,86],{"name":83,"color":84,"percentage":85},"TypeScript","#3178c6",79,{"name":87,"color":88,"percentage":89},"JavaScript","#f1e05a",21,8831,590,"2026-04-05T00:02:42","MIT","未说明","非必需。支持通过 TensorFlow.js 后端选择：WebGPU（最快，需硬件支持）、WebGL（现代浏览器默认）、WASM（无 WebGL 时的备选）、CPU（兼容性广但较慢）。Node.js 环境可使用 tfjs-node-gpu。",{"notes":97,"python":98,"dependencies":99},"这是一个纯 JavaScript\u002FTypeScript 库，运行于浏览器或 Node.js 环境，无需 Python。默认模型为 MobileNetV2。建议在正式环境中自行托管模型文件以减少加载体积并提高速度。若在浏览器中使用，可利用 IndexedDB 缓存模型。生产环境请开启 TensorFlow.js 的生产模式 (enableProdMode)。","不需要",[100,101,102,103,104],"@tensorflow\u002Ftfjs","@tensorflow\u002Ftfjs-backend-webgl","@tensorflow\u002Ftfjs-backend-webgpu","@tensorflow\u002Ftfjs-backend-wasm","@tensorflow\u002Ftfjs-node",[14],[107,108,109,110,111,112,113,114],"machine-learning","machinelearning","javascript","tensorflowjs","tensorflow-js","node-module","content-management","nsfw-recognition","2026-03-27T02:49:30.150509","2026-04-07T06:14:51.828767",[118,123,128,133,138,143],{"id":119,"question_zh":120,"answer_zh":121,"source_url":122},20967,"为什么模型会将非成人图片（如女性露肤或动漫绘图）误判为色情内容（假阳性）？","这是模型偏差问题。维护者已发布更新模型（准确率提升至 93%），通过增加更多样化的训练数据集来减少此类偏差。如果遇到特定类型的误判，建议向数据抓取仓库（nsfw_data_scrapper）贡献相关类别的数据以帮助改进未来模型。对于当前的误判，可以尝试切换不同的模型版本（如 DAG 93 模型），但需注意没有任何模型能完全避免偏差。","https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fissues\u002F16",{"id":124,"question_zh":125,"answer_zh":126,"source_url":127},20968,"安装时遇到 \"classname and config must be set\" 错误怎么办？","这通常是由于 TensorFlow.js 包的安装顺序错误导致的。请严格按照以下步骤操作：\n1. 卸载现有包：uninstall @tensorflow\u002Ftfjs-node 和 @tensorflow\u002Ftfjs\n2. 先安装 node 版本：npm install @tensorflow\u002Ftfjs-node\n3. 再安装核心库：npm install @tensorflow\u002Ftfjs@^1.7.4\n注意：必须严格遵守此顺序，如果先安装 @tensorflow\u002Ftfjs 会导致崩溃。","https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fissues\u002F397",{"id":129,"question_zh":130,"answer_zh":131,"source_url":132},20969,"在 HTTPS 网站上加载模型时出现 \"Mixed Content\" 错误或 CORS 错误如何解决？","默认模型链接可能未强制使用 HTTPS 或存在缓存问题。维护者已更新配置以支持 HTTPS。如果遇到 CORS 错误，可能是 CloudFront 缓存尚未刷新，请稍后重试。如果问题依旧，需检查 S3\u002FCloudFront 的 CORS 配置是否正确（参考 AWS 相关文档）。确保请求的 URL 是以 https:\u002F\u002F 开头的有效地址。","https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fissues\u002F524",{"id":134,"question_zh":135,"answer_zh":136,"source_url":137},20970,"哪个模型的准确率最高？README 中的模型与 \"DAG 93\" 模型有什么区别？","官方演示网站 (nsfwjs.com) 使用的是准确率为 93% 的模型（通常指经过大量重训练的新版本）。旧版模型可能存在较多假阳性。关于 \"DAG\" 模型，它是指使用新的 TensorFlow 2 API 和 tfhub 集成的架构，通常能提供更好的数值表现。为了获得最佳准确率，建议手动清理分类数据并使用集成了新 TF2 API 的最新模型，而不是仅依赖 README 中提供的旧链接。","https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fissues\u002F324",{"id":139,"question_zh":140,"answer_zh":141,"source_url":142},20971,"如何报告模型的误判（假阳性\u002F假阴性）以帮助改进模型？","维护者会收集误判案例用于未来的训练数据集。如果您发现特定的假阳性或假阴性案例（例如 TikTok 视频截图被误判，或绘图被误判），可以直接在 Issue 中提供图片链接。维护者会将这些样本加入数据集进行重新训练。此外，更有效的贡献方式是直接向数据抓取仓库 (nsfw_data_scrapper) 提交包含该类图像的优质数据源（如特定的 subreddit），因为模型是基于海量数据训练的，单个样本影响有限，而数据源的改善能从根本上解决问题。","https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fissues\u002F572",{"id":144,"question_zh":145,"answer_zh":146,"source_url":147},20972,"服务器启动时报错无法连接到 cloudfront.net 或 URL 未找到怎么办？","这通常是因为模型文件的远程链接失效、被移动或网络临时故障。首先检查代码中引用的模型 URL 是否仍然有效（查看仓库最新代码中的 index.ts 文件）。如果是缓存问题，尝试清除本地缓存或等待 CDN 刷新。如果链接确实已变更，需要更新代码中的模型加载路径指向最新的发布版本（releases）地址。","https:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fissues\u002F808",[149,154,159,164,169,174,179,184,189,194,199,204,209,214],{"id":150,"version":151,"summary_zh":152,"released_at":153},126980,"v4.2.1","- 在 index.ts 中的 Buffer 导入语句末尾添加了斜杠 (#898)  93667b0\n\nhttps:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcompare\u002Fv4.2.0...v4.2.1","2024-11-11T11:56:41",{"id":155,"version":156,"summary_zh":157,"released_at":158},126981,"v4.2.0","- ESM 相关修复 (#897，由 @haZya 提交)  2f60c4e\n- 构建（开发依赖）：将 @tensorflow\u002Ftfjs 从 4.20.0 升级到 4.21.0 (#884)  ba33553\n- 构建（开发依赖）：将 TypeScript 从 5.5.4 升级到 5.6.2 (#887)  6d4e47a\n- 构建（开发依赖）：将 Terser 从 5.31.3 升级到 5.33.0 (#889)  8914307\n- 构建（开发依赖）：将 Terser 从 5.31.1 升级到 5.31.3 (#871)  5ce2a08\n- 构建（开发依赖）：将 np 从 10.0.6 升级到 10.0.7 (#872)  991f1ce\n- 构建（开发依赖）：将 TypeScript 从 5.5.2 升级到 5.5.4 (#874)  1a35b66\n- 构建（开发依赖）：将 TypeScript 从 5.4.3 升级到 5.5.2 (#865)  4a81f6a\n- 构建（开发依赖）：将 np 从 10.0.2 升级到 10.0.6 (#864)  e3fe0dc\n- 构建（开发依赖）：将 Terser 从 5.30.2 升级到 5.31.1 (#862)  c0b0a5c\n- 构建（开发依赖）：将 @tensorflow\u002Ftfjs 从 4.17.0 升级到 4.20.0 (#861)  b07ac90\n- 更新 README 文本 (#851)  b9527bc\n- 构建（开发依赖）：将 Terser 从 5.30.0 升级到 5.30.2 (#846)  92828a9\n- 构建（开发依赖）：将 TypeScript 从 5.3.3 升级到 5.4.3 (#840)  bb3ce2a\n- 构建（开发依赖）：将 np 从 10.0.0 升级到 10.0.2 (#841)  9e7e6fa\n- 构建（开发依赖）：将 Terser 从 5.29.2 升级到 5.30.0 (#842)  914ce72\n- 改进了部分内容，添加了我在测试中发现的有用信息。(#844)  cecfca6\n- 构建（开发依赖）：将 Terser 从 5.29.1 升级到 5.29.2 (#839)  939b512\n\nhttps:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcompare\u002Fv4.1.0...v4.2.0","2024-10-11T16:18:34",{"id":160,"version":161,"summary_zh":162,"released_at":163},126982,"v4.1.0","- 更新 npmignore 文件 (#836)  301d790\n- 构建（开发依赖）：将 terser 从 5.28.1 升级到 5.29.1 (#834)  d1c7af5\n- 在 npmignore 中忽略 Netlify.toml 文件 (#835)  f41912c\n- 修复 README 中的链接 (#832)  7b64a6e\n\nhttps:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcompare\u002Fv4.0.0...v4.1.0","2024-03-06T15:26:30",{"id":165,"version":166,"summary_zh":167,"released_at":168},126983,"v4.0.0","- 构建(开发依赖): 将 np 从 9.2.0 升级到 10.0.0 (#830)  3382745\n- 构建(开发依赖): 将 terser 从 5.28.0 升级到 5.28.1 (#828)  331b315\n- [非破坏性] 将模型打包到包本身中。(#811)  39aa4cb\n- 构建(开发依赖): 将 terser 从 5.27.2 升级到 5.28.0 (#827)  e88bce5\n- 构建(开发依赖): 将 terser 从 5.27.1 升级到 5.27.2 (#826)  f257733\n- 构建(开发依赖): 将 terser 从 5.27.0 升级到 5.27.1 (#825)  501942d\n- 禁止 `RU` 地区访问站点 (#823)  287021b\n- 添加预检查步骤，确保在发布新版本之前运行 npm run shipit (#822)  28192db\n\nhttps:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcompare\u002Fv3.0.0...v4.0.0","2024-03-05T16:41:51",{"id":170,"version":171,"summary_zh":172,"released_at":173},126984,"v3.0.0","- 升级 CI 节点版本和 `np` (#821)  bb5be16\n- 清理工作 (#820)  82dec3c\n- 移除 classifygif 及其相关代码 (#819)  f0233db\n- 如果没有模型路径则抛出 `console.warn` (#817)  bbd68e8\n- 构建（开发依赖）：将 ts-node 从 10.9.1 升级到 10.9.2 (#803)  5afc987\n- 构建（开发依赖）：将 TypeScript 从 5.3.2 升级到 5.3.3 (#802)  57cbcfd\n- 构建（开发依赖）：将 terser 从 5.23.0 升级到 5.27.0 (#812)  f2c1e42\n- 构建（开发依赖）：将 @tensorflow\u002Ftfjs 从 4.10.0 升级到 4.17.0 (#814)  c28b3af\n- 更新页脚链接 (#813)  486abea\n- 更新 README.md (#809)  88850ae\n- 构建（开发依赖）：将 TypeScript 从 5.2.2 升级到 5.3.2 (#797)  531bae8\n- 构建（开发依赖）：将 terser 从 5.19.3 升级到 5.23.0 (#793)  756086d\n- 构建（开发依赖）：将 terser 从 5.19.2 升级到 5.19.3 (#781)  06eaec5\n- 构建（开发依赖）：将 TypeScript 从 5.1.6 升级到 5.2.2 (#780)  3d73f98\n- 构建（开发依赖）：将 @tensorflow\u002Ftfjs 从 4.9.0 升级到 4.10.0 (#776)  95f3398\n- 构建（开发依赖）：将 terser 从 5.18.2 升级到 5.19.2 (#774)  4d1154f\n- 构建（开发依赖）：将 @tensorflow\u002Ftfjs 从 4.8.0 升级到 4.9.0 (#773)  1da15da\n- 构建（开发依赖）：将 @tensorflow\u002Ftfjs 从 4.6.0 升级到 4.8.0 (#765)  415777e\n- 构建（开发依赖）：将 terser 从 5.18.1 升级到 5.18.2 (#767)  e7e166a\n- 构建（开发依赖）：将 TypeScript 从 5.1.3 升级到 5.1.6 (#769)  58ebb53\n- 构建（开发依赖）：将 all-contributors-cli 从 6.26.0 升级到 6.26.1 (#770)  6ecdef0\n- 构建（开发依赖）：将 terser 从 5.18.0 升级到 5.18.1 (#764)  0fe23f8\n- 构建（开发依赖）：将 terser 从 5.17.6 升级到 5.18.0 (#761)  e6e7221\n- 构建（开发依赖）：将 TypeScript 从 5.0.4 升级到 5.1.3 (#754)  f7a6925\n- 构建（开发依赖）：将 @tensorflow\u002Ftfjs 从 4.5.0 升级到 4.6.0 (#747)  6b4cac2\n- 构建（开发依赖）：将 terser 从 5.17.1 升级到 5.17.6 (#749)  9fddee2\n- 构建（开发依赖）：将 all-contributors-cli 从 6.24.0 升级到 6.26.0 (#751)  bd26867\n- 构建（开发依赖）：将 @tensorflow\u002Ftfjs 从 4.4.0 升级到 4.5.0 (#742)  0fa9114\n- 构建（开发依赖）：将 terser 从 5.16.8 升级到 5.17.1 (#736)  5b34f6c\n- 构建（开发依赖）：将 TypeScript 从 5.0.3 升级到 5.0.4 (#733)  1b16411\n- 构建（开发依赖）：将 @tensorflow\u002Ftfjs 从 4.1.0 升级到 4.4.0 (#732)  aad2682\n- 构建（开发依赖）：将 TypeScript 从 4.9.5 升级到 5.0.3 (#731)  ee80fc7\n- 构建（开发依赖）：将 terser 从 5.16.5 升级到 5.16.8 (#729)  dfb81a1\n- 更新 README.md (#722)  f482648\n- 构建（开发依赖）：将 terser 从 5.16.4 升级到 5.16.5 (#721)  7a1475b\n- 构建（开发依赖）：将 terser 从 5.16.3 升级到 5.16.4 (#720)  76cf395\n- 构建（开发依赖）：将 terser 从 5.16.2 升级到 5.16.3 (#719)  36ccbfb\n- 构建（开发依赖）：将 terser 从 5.16.1 升级到 5.16.2 (#717)  63b822f\n- 构建（开发依赖）：将 TypeScript 从 4.9.4 升级到 4.9.5 (#718)  a0b62fe\n- 修复：升级 react-scripts 并修复演示依赖中的 polyfill (#700)  bbbc4cc\n- 将 all-contributors-cli 从 6.23.1 升级到 6.24.0 (#681)  3ad43ff\n- 将 terser 从 5.15.0 升级到 5.16.1 (#698)  3a637c3\n- 将 TypeScript 从 4.8.3 升级到 4.9.4 (#699)  07d3998\n- 将 @tensorflow\u002Ftfjs 从 4.0.0 升级到 4.1.0 (#693)  50b95d6\n- 修复：使用 c","2024-02-09T19:26:28",{"id":175,"version":176,"summary_zh":177,"released_at":178},126985,"v2.4.1","- 合并 github.com:infinitered\u002Fnsfwjs 的 master 分支  8f98084\n- 将 @roerohan 添加为贡献者  7a6ec59\n- 修复：将 tfjs 模型通过 https 而不是 http 加载 (#526)  ddf9cfd\n- 合并 github.com:infinitered\u002Fnsfwjs 的 master 分支  05b597f\n- 将 @roerohan 添加为贡献者  9e7e4d5\n- 将 @tensorflow\u002Ftfjs 版本从 3.6.0 升级到 3.7.0 (#515)  1527b56\n- 将 doctoc 版本从 2.0.0 升级到 2.0.1 (#516)  38b724c\n- 允许在演示站点中使用 webp 格式  b29d209\n- 将 typescript 版本从 4.3.3 升级到 4.3.4 (#519)  5981af7\n- 将 typescript 版本从 4.3.2 升级到 4.3.3 (#518)  3feacee\n- 将 typescript 版本从 4.2.4 升级到 4.3.2 (#514)  163c594\n- 将 ts-jest 版本从 26.5.5 升级到 26.5.6 (#511)  8857393\n- 升级到 GitHub 原生 Dependabot (#509)  d44edb4\n- 将 @tensorflow\u002Ftfjs 版本从 3.5.0 升级到 3.6.0 (#508)  f85cd84\n- 将 ts-jest 版本从 25.5.1 升级到 26.5.5 (#500)  5f975a5\n- 将 terser 版本从 5.6.1 升级到 5.7.0 (#505)  4a47a97\n- 将 @types\u002Fjest 版本从 26.0.22 升级到 26.0.23 (#507)  0ece806\n- 将 @types\u002Fjest 版本从 26.0.22 升级到 26.0.23 (#506)  b3a5682\n- 将 typescript 版本从 3.9.9 升级到 4.2.4 (#501)  c5a329f\n- 将 jest 版本从 25.5.4 升级到 26.6.3 (#502)  c1cc746\n- 将 @tensorflow\u002Ftfjs 版本从 3.4.0 升级到 3.5.0 (#503)  8b621e8\n- 将 @tensorflow\u002Ftfjs 版本从 3.3.0 升级到 3.4.0 (#495)  465a76c\n- 添加书籍  0f08e51\n- 添加书籍图片  ac22993\n\nhttps:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcompare\u002Fv2.4.0...v2.4.1","2021-06-26T17:14:39",{"id":180,"version":181,"summary_zh":182,"released_at":183},126986,"v2.4.0","- 添加 @JanPoonthong 为贡献者 6c41b72\n- 添加 @kateinkim 为贡献者 dedfd0c\n- 支持从 indexeddb:\u002F\u002F 或 localstorage:\u002F\u002F 加载 (#494) 85b10b9\n- README.md 中缺少引号 (#492) e0d2188\n- [安全] 将 y18n 从 4.0.0 升级到 4.0.1 (#490) 1c46e56\n- 将 @types\u002Fjest 从 26.0.21 升级到 26.0.22 (#488) 074cde5\n- 将 terser 从 5.6.0 升级到 5.6.1 (#486) 333f0a1\n- 将 @types\u002Fjest 从 26.0.20 升级到 26.0.21 (#487) 6822dd5\n- 将 @tensorflow\u002Ftfjs 从 3.2.0 升级到 3.3.0 (#484) 7edd72e\n- [安全] 将 elliptic 从 6.5.3 升级到 6.5.4 (#483) b00bca5\n- 将 @tensorflow\u002Ftfjs 从 3.1.0 升级到 3.2.0 (#481) 4b58fe1\n- 将 @types\u002Fjest 从 26.0.19 升级到 26.0.20 (#458) 677a5df\n- 将 jpeg-js 从 0.4.2 升级到 0.4.3 (#462) 35f0a81\n- 将 @tensorflow\u002Ftfjs 从 2.8.5 升级到 3.1.0 (#479) d6f1df5\n- 将 all-contributors-cli 从 6.13.0 升级到 6.20.0 (#477) ce74217\n- 将 terser 从 5.5.1 升级到 5.6.0 (#475) c067610\n- 将 typescript 从 3.9.8 升级到 3.9.9 (#473) e40e0d7\n- 将 typescript 从 3.9.7 升级到 3.9.8 (#472) f5bc61b\n- 将 @tensorflow\u002Ftfjs 从 2.8.4 升级到 2.8.5 (#467) f990324\n- 添加 @nacht42 为贡献者 b4fbd00\n- 将 className 的类型更新为字面量类型，而非字符串类型 (#465) e96cb7f\n- 将 @tensorflow\u002Ftfjs 从 2.8.2 升级到 2.8.4 (#463) 5d998cb\n- 将 @tensorflow\u002Ftfjs 从 2.8.1 升级到 2.8.2 (#453) 2540374\n- 将 @tensorflow\u002Ftfjs 从 2.8.0 升级到 2.8.1 (#450) ab50e37\n- 将 @types\u002Fjest 从 26.0.18 升级到 26.0.19 (#448) 7771f4d\n- 将 @tensorflow\u002Ftfjs 从 2.7.0 升级到 2.8.0 (#449) 193aeb1\n- [安全] 将 ini 从 1.3.5 升级到 1.3.7 (#447) 4dceb6e\n- 将 @types\u002Fjest 从 26.0.17 升级到 26.0.18 (#446) 175f78c\n- 将 @types\u002Fjest 从 26.0.16 升级到 26.0.17 (#444) c6df478\n- 将 ts-node 从 9.1.0 升级到 9.1.1 (#445) bd73175\n- 将 doctoc 从 1.4.0 升级到 2.0.0 (#443) 19992f9\n- 将 ts-node 从 8.10.2 升级到 9.1.0 (#442) cae2366\n- 添加 @VladStepanov 为贡献者 6919919\n- 更新 README 示例 (#440) 6739997\n- 将 @types\u002Fjest 从 26.0.14 升级到 26.0.16 (#441) 1bd7e2c\n- 将 terser 从 5.5.0 升级到 5.5.1 (#439) 4ba3337\n- 将 terser 从 5.4.0 升级到 5.5.0 (#438) c06f2d9\n- 将 terser 从 5.3.8 升级到 5.4.0 (#437) cec8e30\n- 将 @tensorflow\u002Ftfjs 从 2.6.0 升级到 2.7.0 (#432) 794ff8f\n- 使用 CloudFront 加速模型 (#429) ebcd41c\n\nhttps:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcompare\u002Fv2.3.0...v2.4.0","2021-04-04T04:24:25",{"id":185,"version":186,"summary_zh":187,"released_at":188},126987,"v2.3.0","- 升级 tfjs (#427)  3c34194\n- 添加 @navendu-pottekkat 为贡献者  8bfd8ab\n- 添加 @YegorZaremba 为贡献者  b76db9f\n- 功能：改进 GIF 分类 (#401)  91b0fa3\n- 将 uglify-js 从 3.11.2 升级到 3.11.3 (#426)  6ca2cdf\n- 将 uglify-js 从 3.11.0 升级到 3.11.2 (#424)  e2b2826\n- 将 browserify 从 16.5.2 升级到 17.0.0 (#423)  c0be38f\n- 将 uglify-js 从 3.10.4 升级到 3.11.0 (#417)  749dc84\n- 将 @types\u002Fjest 从 26.0.13 升级到 26.0.14 (#414)  c8f8ce4\n- 将 jpeg-js 从 0.4.1 升级到 0.4.2 (#406)  c276d6e\n- 将 @types\u002Fjest 从 26.0.10 升级到 26.0.13 (#410)  8a6b366\n- 将 uglify-js 从 3.10.1 升级到 3.10.4 (#411)  bc1a2ca\n- 将 node-fetch 从 2.6.0 升级到 2.6.1 (#412)  2b5ac15\n- 测试：为 DOM 添加手动测试用例 (#402)  bfdfe37\n- 将 @types\u002Fjest 从 26.0.9 升级到 26.0.10 (#400)  34bc164\n- [安全] 将 dot-prop 从 4.2.0 升级到 4.2.1 (#398)  48c430a\n- 将 @types\u002Fjest 从 26.0.8 升级到 26.0.9 (#390)  d151c35\n- 将 browserify 从 16.5.1 升级到 16.5.2 (#386)  644a2a1\n- 将 uglify-js 从 3.10.0 升级到 3.10.1 (#387)  73d9fb3\n- 将 @types\u002Fjest 从 26.0.7 升级到 26.0.8 (#384)  13bcb63\n- 将 tslint 从 6.1.2 升级到 6.1.3 (#385)  bf4f3dd\n- [安全] 将 elliptic 从 6.4.1 升级到 6.5.3 (#382)  4835fa0\n- 将 @types\u002Fjest 从 26.0.5 升级到 26.0.7 (#380)  d50f802\n- 将 @types\u002Fjest 从 26.0.4 升级到 26.0.5 (#377)  1f5d274\n- 将 typescript 从 3.9.6 升级到 3.9.7 (#374)  13630b8\n- [安全] 将 lodash 从 4.17.14 升级到 4.17.19 (#373)  4a0a3e6\n- 将 @types\u002Fjest 从 26.0.0 升级到 26.0.4 (#368)  0b1e252\n- 更新 README.md (#372)  e4de7ad\n- 将 typescript 从 3.9.5 升级到 3.9.6 (#366)  3bb29b1\n- 将 jpeg-js 从 0.4.0 升级到 0.4.1 (#365)  c5ae5a0\n- 将 uglify-js 从 3.9.4 升级到 3.10.0 (#359)  3c4e1c8\n- 修复依赖  5faec8f\n- 将 @types\u002Fjest 从 25.2.3 升级到 26.0.0 (#354)  a720642\n- 将 typescript 从 3.9.3 升级到 3.9.5 (#351)  cc0a19c\n- 将 ts-node 从 8.10.1 升级到 8.10.2 (#349)  3fdb084\n- 将 @tensorflow\u002Ftfjs 从 1.7.4 升级到 2.0.0 (#347)  8392717\n- 将 uglify-js 从 3.9.3 升级到 3.9.4 (#348)  35d35f1\n- 将 typescript 从 3.9.2 升级到 3.9.3 (#345)  47e7524\n- 将 @types\u002Fjest 从 25.2.2 升级到 25.2.3 (#344)  1b65f02\n- 添加 Netlify 徽章  4fd3ce9\n- 更新中间模型  602ae69\n- 将 @types\u002Fjest 从 25.1.4 升级到 25.2.2 (#341)  1c48c5a\n- 将 uglify-js 从 3.9.2 升级到 3.9.3 (#339)  bf6a40e\n- 将 typescript 从 3.8.3 升级到 3.9.2 (#340)  9561fd2\n- 将 ts-jest 从 25.2.1 升级到 25.5.1 (#337)  a1ca57a\n- 将 jest 从 25.5.3 升级到 25.5.4 (#333)  b6ec0ca\n- 在 README 中添加移动应用图片  29ac78c\n- 添加移动设备截图  116905f\n- 将 uglify-js 从 3.9.1 升级到 3.9.2 (#328)  09863dd\n- 将 ts-node 从 8.9.1 升级到 8.10.1 (#330)  9a9e8d3\n- 在示例中添加垃圾回收功能 (#327)  735a71d\n- 在 README.md 中为 tf.node.decodeImage 添加 channels 参数 (#326)  041faed","2020-10-23T04:16:42",{"id":190,"version":191,"summary_zh":192,"released_at":193},126988,"v2.1.0","- 合并拉取请求 #160，来自 infinitered\u002Fuse_uglify  fb56ed9\n- 忽略 bundle 并添加注释  30b0189\n- 新的脚本 bundle 方法  390c377\n- 合并拉取请求 #159，来自 infinitered\u002Fdependabot\u002Fnpm_and_yarn\u002Fall-contributors-cli-6.8.2  2424a38\n- 将 all-contributors-cli 从 6.8.1 升级到 6.8.2  4c0b9c1\n- 合并拉取请求 #158，来自 infinitered\u002Fdependabot\u002Fnpm_and_yarn\u002Ftypescript-3.6.2  efaa1f5\n- 将 typescript 从 3.5.3 升级到 3.6.2  e59af3d\n- 合并拉取请求 #157，来自 infinitered\u002Fdependabot\u002Fnpm_and_yarn\u002Fexample\u002Fnsfw_demo\u002Fmixin-deep-1.3.2  3c5e544\n- 在 \u002Fexample\u002Fnsfw_demo 中将 mixin-deep 从 1.3.1 升级到 1.3.2  b9cd6ae\n- 合并拉取请求 #156，来自 infinitered\u002Fdependabot\u002Fnpm_and_yarn\u002Fmixin-deep-1.3.2  081ffe8\n- [安全] 将 mixin-deep 从 1.3.1 升级到 1.3.2  de71874\n- 合并拉取请求 #155，来自 infinitered\u002Fdependabot\u002Fnpm_and_yarn\u002Fexample\u002Fnsfw_demo\u002Feslint-utils-1.4.2  db3d8f6\n- 在 \u002Fexample\u002Fnsfw_demo 中将 eslint-utils 从 1.3.1 升级到 1.4.2  0f9877e\n- 合并拉取请求 #154，来自 infinitered\u002Fdependabot\u002Fnpm_and_yarn\u002Ftensorflow\u002Ftfjs-1.2.8  3e5fe7c\n- 将 @tensorflow\u002Ftfjs 从 1.2.7 升级到 1.2.8  b67e699\n- 合并拉取请求 #153，来自 infinitered\u002Fdependabot\u002Fnpm_and_yarn\u002Ftslint-5.19.0  14664a4\n- 将 tslint 从 5.16.0 升级到 5.19.0  184d7e3\n- 合并拉取请求 #152，来自 infinitered\u002Fdependabot\u002Fnpm_and_yarn\u002Ftypes\u002Fjest-24.0.18  bd09353\n- 将 @types\u002Fjest 从 24.0.17 升级到 24.0.18  4a91ae9\n- 合并拉取请求 #151，来自 infinitered\u002Fdependabot\u002Fnpm_and_yarn\u002Fjest-24.9.0  adcf088\n- 将 jest 从 24.8.0 升级到 24.9.0  e44f2c1\n- 合并拉取请求 #149，来自 infinitered\u002Fdependabot\u002Fnpm_and_yarn\u002Fseedrandom-3.0.3  78568c3\n- 合并拉取请求 #150，来自 infinitered\u002Fdependabot\u002Fnpm_and_yarn\u002Fbrowserify-16.5.0  2506819\n- 将 browserify 从 16.4.0 升级到 16.5.0  948b1d8\n- 将 seedrandom 从 2.4.4 升级到 3.0.3  4375a5c\n- 合并拉取请求 #148，来自 infinitered\u002Fdependabot\u002Fnpm_and_yarn\u002Fbrowserify-16.4.0  7423359\n- 将 browserify 从 16.3.0 升级到 16.4.0  9887e9c\n- 修复 TFJS 的首字母大写问题  0e56b53\n- 合并拉取请求 #147，来自 infinitered\u002Fdependabot\u002Fnpm_and_yarn\u002Ftensorflow\u002Ftfjs-1.2.7  1b1a37a\n- 合并拉取请求 #146，来自 infinitered\u002Fdependabot\u002Fnpm_and_yarn\u002Fjpeg-js-0.3.6  5644748\n- 将 @tensorflow\u002Ftfjs 从 1.2.6 升级到 1.2.7  1ba99e1\n- 将 jpeg-js 从 0.3.5 升级到 0.3.6  32c7fff\n- 合并拉取请求 #145，来自 infinitered\u002Fdependabot\u002Fnpm_and_yarn\u002Ftypes\u002Fjest-24.0.17  4fa75f0\n- 将 @types\u002Fjest 从 24.0.16 升级到 24.0.17  16d05e6\n\nhttps:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcompare\u002Fv2.0.1...v2.1.0","2019-09-04T02:36:26",{"id":195,"version":196,"summary_zh":197,"released_at":198},126989,"v2.0.0","这带来了一些小的改动，但有一个破坏性变更：模型的默认设置已被替换。\n\n若要将这段代码与之前的模型一起使用，你需要在加载时显式指定尺寸：`....load('\u002Fpath\u002Fto\u002Fold\u002Fmodel\u002F', {size: 299})`。由于新的默认模型已更改，当前的默认尺寸为 `224`。","2019-05-02T14:45:28",{"id":200,"version":201,"summary_zh":202,"released_at":203},126990,"v0.1.1","- hosting change  8f32cd0\r\n- Merge pull request #14 from infinitered\u002Fdependabot\u002Fnpm_and_yarn\u002Fts-node-8.0.2  9dc3cbf\r\n- Bump ts-node from 5.0.1 to 8.0.2  799ae03\r\n- Merge pull request #13 from infinitered\u002Fdependabot\u002Fnpm_and_yarn\u002Ftypescript-3.3.3  ea67556\r\n- Merge pull request #12 from infinitered\u002Fdependabot\u002Fnpm_and_yarn\u002F@tensorflow\u002Ftfjs-0.15.2  10cd92a\r\n- Bump typescript from 2.9.2 to 3.3.3  597a13c\r\n- Merge pull request #11 from infinitered\u002Fdependabot\u002Fnpm_and_yarn\u002Ftslint-5.12.1  d76e9d0\r\n- Merge pull request #10 from infinitered\u002Fdependabot\u002Fnpm_and_yarn\u002Fts-jest-24.0.0  7e765bb\r\n- Bump tslint from 5.8.0 to 5.12.1  40d0fa4\r\n- improve tests  e5b59a4\r\n- Bump @tensorflow\u002Ftfjs from 0.12.7 to 0.15.2  c3387e2\r\n- Bump ts-jest from 23.10.5 to 24.0.0  60595f9\r\n- Merge pull request #9 from infinitered\u002Fadd-license-1  754509c\r\n- Add License :memo:  ddbead2\r\n- Merge pull request #8 from infinitered\u002Ffix_netlify  1537779\r\n- hopefully fix netlify jest fight  3acef7f\r\n- Delete example.gif  e1d3cc2\r\n- size up demo  8ba7f14\r\n- switch to better demo GIF  eddcbb5\r\n- more advanced demo GIF :sparkles:  b2754e1\r\n- Merge pull request #7 from infinitered\u002Fmobile  2f90108\r\n- clean up for mobile  1534430\r\n- Merge pull request #6 from infinitered\u002Fadd_tests  c864980\r\n- basic TF checking and testing  a9a5b09\r\n- Ridin Spinners - Merge pull request #5 from infinitered\u002Fspinner  a0b1f87\r\n- spinner added  0a97cac\r\n- Merge pull request #3 from infinitered\u002Fblur  feec19d\r\n- small text change  4431415\r\n- blurring logic  26f6bac\r\n- basics working  fdc3e82\r\n- small readme update  f743527\r\n- fancy up that readme with examples  f583139\r\n- fix classes  278e7a3\r\n- spruce things up  77851bb\r\n- better code comments  df221e6\r\n- shrink gif a lil  08a557e\r\n- Update README.md  e6ce50c\r\n- snazzy README updates :pen:  72b76fc\r\n- add example gif  8539a7b\r\n- Merge pull request #2 from infinitered\u002Fmore_info  dca5c76\r\n- UX upgrades  5a3c0a9\r\n- v0.1.0  7c1b1a4\r\n- NSFWJS ready to roll  22ff130\r\n- upgrade model  8fa24b1\r\n- Merge pull request #1 from infinitered\u002Fflesh_out_site  e7571bb\r\n- site working  6d77d32\r\n- style cleanup  34114c7\r\n- Update README.md  d2f01f3\r\n- dat logo  ad2d7fa\r\n- logo!  8833e15\r\n- no example in npm ty  9ec1526\r\n- adding demo  ddf541f\r\n\r\nhttps:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcompare\u002Fv0.0.3...v0.1.1","2019-02-20T14:46:05",{"id":205,"version":206,"summary_zh":207,"released_at":208},126991,"v0.1.0","Commits:\r\n- NSFWJS ready to roll  22ff130\r\n- upgrade model  8fa24b1\r\n- Merge pull request #1 from infinitered\u002Fflesh_out_site  e7571bb\r\n- site working  6d77d32\r\n- style cleanup  34114c7\r\n- Update README.md  d2f01f3\r\n- dat logo  ad2d7fa\r\n- logo!  8833e15\r\n- no example in npm ty  9ec1526\r\n- adding demo  ddf541f\r\n- v0.0.3  d16f538\r\n- fix double slash  6e4eeaf\r\n- v0.0.2  59b136d\r\n- fix test error  0e72a59\r\n- add npm shipping stuffs  6d899aa\r\n- it compiles  6aa9939\r\n- begin model wrap  2537790\r\n- TS base code  268b543\r\n\r\nCommit Range:\r\n86cd9406cd2e4b926123818b1f1d99d8781496fd...master","2019-02-16T05:12:40",{"id":210,"version":211,"summary_zh":212,"released_at":213},126992,"v0.0.3","Simple bug fix\r\n- fix double slash  6e4eeaf\r\n\r\nhttps:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcompare\u002Fv0.0.2...v0.0.3","2019-02-14T16:52:46",{"id":215,"version":216,"summary_zh":217,"released_at":218},126993,"v0.0.2","- fix test error  0e72a59\r\n- add npm shipping stuffs  6d899aa\r\n- it compiles  6aa9939\r\n- begin model wrap  2537790\r\n- TS base code  268b543\r\n\r\nhttps:\u002F\u002Fgithub.com\u002Finfinitered\u002Fnsfwjs\u002Fcompare\u002F86cd9406cd2e4b926123818b1f1d99d8781496fd...v0.0.2","2019-02-14T15:55:30"]