阅读视图

发现新文章,点击刷新页面。
🔲 ☆

从第一位程序员到 AI 时代的领航者:代码世界里的“她”力量

本文永久链接 – https://tonybai.com/2026/03/08/her-power-in-code-pioneers-to-ai-era

大家好,我是Tony Bai。

当我们闭上眼睛,想象一个“程序员”的形象时,脑海中浮现的画面是什么?

很长一段时间里,流行文化和媒体在不遗余力地塑造一种刻板印象:穿着格子衬衫、戴着黑框眼镜、不善言辞的男性,在昏暗的灯光下敲击着键盘。硅谷的“兄弟会文化(Bro-culture)”更是将这种刻板印象固化,仿佛编程从诞生之日起,就是一项由男性绝对主导的活动。

然而,如果我们翻开计算机科学的真实历史,会发现一个令人惊讶,甚至有些反直觉的事实:在计算机刚刚诞生的黎明期,编程,曾经是一项被普遍认为“适合女性”的工作。

在二战期间,由于男性大量奔赴前线,世界上第一台通用电子计算机 ENIAC 的初代程序员团队,清一色全是由六位杰出的女性组成。她们在没有编程语言、没有编译器的时代,用插拔线缆和拨动开关的纯物理方式,完成了极其复杂的弹道轨迹计算。

然而,随着软件产业的爆炸式增长,薪资与地位水涨船高,女性在科技行业的比例却开始出现诡异的下滑,她们的名字也逐渐被隐藏在庞大服务器的阴影之中。

今天是 3 月 8 日国际妇女节。在这个特殊的日子里,让我们暂时停下手中正在 Review 的代码,去擦拭掉历史上的偏见灰尘。我们要重新认识那些在计算机科学发展史上立下不朽丰碑的女性先驱,看看当今站在技术浪潮之巅的领航者,并探讨在汹涌而来的 AI 时代,“巾帼力量”为何比以往任何时候都更加不可或缺。

历史丰碑:她们写下了改变世界的最初几行代码

代码是没有性别的,但在计算机还是一堆庞大齿轮或真空管的年代,是这些女性赋予了冷冰冰的机器以“逻辑的灵魂”。

“诗意科学”的先知:Ada Lovelace(埃达·洛夫莱斯)

要追溯程序员的祖师爷,我们必须回到 19 世纪中叶的英国。著名诗人拜伦的女儿,Ada Lovelace,被公认为世界上的第一位程序员

当时的数学家查尔斯·巴贝奇正在设计一台名为“分析机”的庞大机械装置。在多数人看来,这只是一个能做加减乘除的超大号计算器。但 Ada 展现出了超越时代一个世纪的惊人洞察力。

在翻译和注释关于分析机的文章时,她不仅写下了世界上第一段计算机算法(用于计算伯努利数),更重要的是,她写下了一段堪称“预言”的批注。Ada 指出,如果分析机能够处理数字,那么只要将事物(如字母、音乐)转化为数字,机器就能处理任何事物。

“分析机编织的是代数模式,就像提花织机编织树叶和花朵一样。”

这是一种被称为“诗意科学”的浪漫与理性的结合。Ada 早在计算机诞生前 100 年,就看透了现代计算机的本质:它不仅仅是计算工具,而是通用的信息处理引擎。今天美国国防部开发的 Ada 语言,正是为了纪念这位伟大的女性“先知”。

编译器的鼻祖与“捉虫”专家:Grace Hopper(格蕾丝·霍珀)

如果说 Ada 给出了灵魂,那么 Grace Hopper 则是真正让机器“听懂”人类语言的架构师。

在 20 世纪 50 年代,程序员们必须用极其难懂的二进制机器码来编写指令。这种方式不仅痛苦,而且极易出错。Hopper 坚信,程序员应该能够用接近英语的语言来编写代码,然后再由机器自己将其翻译成机器码。

当她提出这个想法时,遭到了几乎所有同行的嘲笑和拒绝。他们认为“计算机只能懂数字,不可能懂英语”。但 Hopper 是一位拥有美国海军准将军衔的“硬核”女性,她顶住了所有压力,成功开发出了世界上第一个编译器 A-0,并直接主导了后来统治商业系统数十年的 COBOL 语言的诞生。

除了这项伟大的技术发明,Hopper 还给全世界程序员留下了一个最常用的口头禅。1947 年,她在哈佛大学的一台继电器计算机里发现了一只导致故障的真实飞蛾(Moth)。她将这只飞蛾粘在日志本上,并在旁边写下:“First actual case of bug being found.(发现的第一个真正的 Bug)”。从此,程序员排查错误的过程,就永远被称为了 “Debug”(除虫)。

登月背后的无名英雄:Margaret Hamilton(玛格丽特·汉密尔顿)

有一张在科技史流传甚广的照片:一位年轻的戴着大框眼镜的女性,微笑着站在一堆比她自己还要高的打印源代码旁。她就是 Margaret Hamilton,阿波罗 11 号登月计划的首席软件工程师。

在 1969 年那个登月舱只有几十 KB 内存的年代,写代码绝不容许有任何试错的空间。更重要的是,在那个年代,“软件”甚至不被认为是一门严谨的工程学科。是 Hamilton 第一次创造了 “软件工程 (Software Engineering)” 这个词,并为其赋予了与硬件工程同等的严谨性。

她的远见卓识在历史性的一刻拯救了全人类的心跳。就在阿波罗 11 号即将降落月球表面的最后 3 分钟,由于雷达系统的硬件故障,登月舱的计算机突然被大量无关的数据淹没,系统濒临崩溃,警报声大作。

在地面指挥中心准备下令中止登月时,Hamilton 带领团队设计的“异步优先调度(Asynchronous Executive)”机制发挥了奇效。这段极其健壮的容错代码,让计算机瞬间抛弃了低优先级的雷达任务,将全部仅存的算力集中在最关键的着陆控制上。

阿姆斯特朗成功踏上了月球,而这背后,是 Hamilton 用代码织就的绝对安全网。

当代灯塔:站在技术浪潮之巅的开源与企业领袖

历史的丰碑固然闪耀,但“巾帼力量”绝不仅仅存在于泛黄的黑白照片中。当我们把视线拉回当代,你会发现在云计算、开源社区和最前沿的人工智能领域,女性依然是不可或缺的领航者。

在开源世界的深水区,也就是最具“硬核极客文化”的容器和底层基础设施领域,Jessie Frazelle 的名字如雷贯耳。作为 Docker 的核心维护者之一,她写下了 Docker 中许多最底层的安全和隔离特性代码。她以一人之力在充满偏见和偶尔充斥着“有毒(Toxic)”言论的开源社区中杀出一条血路,证明了女性同样可以在最底层的系统编程中达到登峰造极的水平。

而在当今如火如荼的 AI 浪潮中,我们更不能忘记李飞飞 (Fei-Fei Li)。在深度学习还处于被学术界边缘化的低谷期时,李飞飞敏锐地意识到:模型再好,没有海量的高质量数据也无法发生质变。于是,她顶住巨大压力,发起了 ImageNet 计划,构建了一个包含 1400 万张标注图片的庞大数据库。

正是 ImageNet 的存在,直接催生了 2012 年 AlexNet 的横空出世,引发了这一轮浩浩荡荡的深度学习和 AI 大爆发。她被称为“AI 界的拓荒者”,用女性特有的坚韧和长远目光,为整个行业打下了最坚实的地基。

AI 时代的新契机:为什么未来的技术世界更需要“她”?

2024 年至今,随着生成式 AI(GenAI)、大型语言模型(LLM)以及自主 Agent(如 Claude Code, Cursor)的极速普及,软件工程的范式正在经历一场彻底的颠覆。

“敲击代码”这一纯体力的动作正在被 AI 代替。很多从业者感到恐慌:如果机器能在几秒钟内写出完美的并发处理代码,程序员的价值到底在哪里?

讽刺的是,这场由机器主导的技术革命,反而为女性程序员在科技行业中的地位跃升,提供了百年难遇的新契机。为什么这么说?

从“机器语者”到“交响乐指挥”:Prompt 工程与沟通的艺术

在传统的编程时代,程序员需要像机器一样思考,用极其死板和严苛的语法去迎合编译器。这在某种程度上,筛选出了一批极度专注于逻辑细节、但不一定擅长横向沟通的人群。

但在 AI 辅助编程时代,人类的角色从“写代码的工人”变成了“指挥 AI 的产品经理”。你需要做的是深刻理解业务需求、拆解复杂系统,并用自然语言(Prompt)精准地将意图传达给 AI。

这要求极高的沟通能力、同理心、大局观以及对模糊意图的澄清能力。而这些,恰恰是许多女性在长期社会化过程中被培养出的显著优势。未来的顶级工程师,不再是那些能背诵冷门 API 的人,而是那些能够清晰表达意图、优雅编排多个 AI Agent 协同工作的“交响乐指挥”。

消除算法的“傲慢与偏见”:AI 伦理的守门人

AI 就像一面镜子,它会无情地反射并放大人类社会中存在的所有偏见。如果我们训练 AI 模型的工程师团队是清一色的单一性别、单一族裔(例如传统的“硅谷白人男性俱乐部”),那么这个 AI 生成的简历筛选算法、医疗诊断模型或是自动驾驶策略,必然会带有难以察觉的系统性偏见。

在 AI 对齐(Alignment)和 AI 安全(AI Safety)领域,我们需要多元化的视角来纠正机器的偏见。女性研究者和工程师在感知社会公平、识别弱势群体需求方面往往具有更敏锐的触觉。如今,在 OpenAI、Anthropic 等顶级 AI 实验室中,主导 AI 伦理和安全护栏工作的核心领导层中,出现了越来越多卓越的女性身影。比如Anthropic联合创始人阿曼达·阿斯克尔(Amanda Askell),就是一位训练有素的哲学家,她帮助管理Claude的个性。没有女性参与的 AI,注定是一个有缺陷的 AI。

全栈通才的崛起与“产品思维”的胜利

由于 AI 极大地降低了后端的复杂度和前端页面的构建门槛,“一人公司”或“超级小团队”正在成为现实。

这要求未来的开发者必须是懂产品、懂设计、懂用户心理的“全栈通才”。仅仅会写高并发代码已经不够了,你还需要知道如何设计出让用户感到温暖、舒适的交互界面。女性往往具备更强的跨界融合能力和细腻的用户感知能力,在“技术与人文的十字路口”,她们将比纯粹的“代码机器”爆发出更强大的创造力。

小结:传承遗产,编写未来

回顾历史,从 Ada Lovelace 描绘在纸带上的第一个循环,到 Grace Hopper 拔出的第一只真实飞蛾;从 Margaret Hamilton 保护阿波罗登月的汇编指令,到如今女性工程师在 LLM 底层写的对齐代码。

女性,从未在计算机科学的历史中缺席。 她们不仅是历史的参与者,更是很多决定性瞬间的缔造者。

然而,我们依然要清醒地看到,今天在 GitHub 的开源提交中、在科技公司的高管会议室里,女性的比例依然没有达到应有的平衡。打破这种隐形的“天花板”和玻璃墙,需要我们每一个人——无论男女——去对抗潜意识中的刻板印象。

代码没有性别,Bug 也不分男女。优秀的架构设计只认同逻辑的严密,而不关心键盘后那双手的粗细。

在这个 AI 浪潮奔涌的时代前夕,让我们向所有奋斗在键盘前、熬夜在服务器旁、在开源社区里无私贡献的女程序员们致以最崇高的敬意。

愿 Ada 的远见、Hopper 的坚持和 Hamilton 的严谨,能够化作一行行永不退色的代码,注入到每一位女性开发者的指尖。

3.8 国际妇女节快乐!愿你们继续用代码,勇敢、自由地编译属于你们的未来!


致敬身边的“她”

在你的开发生涯中,是否曾遇到过让你深感佩服的女性技术伙伴?或者,作为一名女性开发者,你在 AI 时代的浪潮中有什么独特的感悟?

欢迎在评论区留下你对“她”的赞美或故事!我们将精选留言,一起传递这份力量。


还在为“复制粘贴喂AI”而烦恼?我的新专栏 AI原生开发工作流实战 将带你:

  • 告别低效,重塑开发范式
  • 驾驭AI Agent(Claude Code),实现工作流自动化
  • 从“AI使用者”进化为规范驱动开发的“工作流指挥家”

扫描下方二维码,开启你的AI原生开发之旅。


你的Go技能,是否也卡在了“熟练”到“精通”的瓶颈期?

  • 想写出更地道、更健壮的Go代码,却总在细节上踩坑?
  • 渴望提升软件设计能力,驾驭复杂Go项目却缺乏章法?
  • 想打造生产级的Go服务,却在工程化实践中屡屡受挫?

继《Go语言第一课》后,我的《Go语言进阶课》终于在极客时间与大家见面了!

我的全新极客时间专栏 《Tony Bai·Go语言进阶课》就是为这样的你量身打造!30+讲硬核内容,带你夯实语法认知,提升设计思维,锻造工程实践能力,更有实战项目串讲。

目标只有一个:助你完成从“Go熟练工”到“Go专家”的蜕变! 现在就加入,让你的Go技能再上一个新台阶!


原「Gopher部落」已重装升级为「Go & AI 精进营」知识星球,快来加入星球,开启你的技术跃迁之旅吧!

我们致力于打造一个高品质的 Go 语言深度学习AI 应用探索 平台。在这里,你将获得:

  • 体系化 Go 核心进阶内容: 深入「Go原理课」、「Go进阶课」、「Go避坑课」等独家深度专栏,夯实你的 Go 内功。
  • 前沿 Go+AI 实战赋能: 紧跟时代步伐,学习「Go+AI应用实战」、「Agent开发实战课」、「Agentic软件工程课」、「Claude Code开发工作流实战课」、「OpenClaw实战分享」等,掌握 AI 时代新技能。
  • 星主 Tony Bai 亲自答疑: 遇到难题?星主第一时间为你深度解析,扫清学习障碍。
  • 高活跃 Gopher 交流圈: 与众多优秀 Gopher 分享心得、讨论技术,碰撞思想火花。
  • 独家资源与内容首发: 技术文章、课程更新、精选资源,第一时间触达。

衷心希望「Go & AI 精进营」能成为你学习、进步、交流的港湾。让我们在此相聚,享受技术精进的快乐!欢迎你的加入!

img{512x368}


想系统学习Go,构建扎实的知识体系?

我的新书《Go语言第一课》是你的首选。源自2.4万人好评的极客时间专栏,内容全面升级,同步至Go 1.24。首发期有专属五折优惠,不到40元即可入手,扫码即可拥有这本300页的Go语言入门宝典,即刻开启你的Go语言高效学习之旅!


商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求,请扫描下方公众号二维码,与我私信联系。

© 2026, bigwhite. 版权所有.

🔲 ☆

Claude Code 快速使用指南

简介

现在的 AI 编程工具发展飞速,因此本文带来 Claude Code 的全方位实战指南,旨在帮助从零开始掌握这款强大的 AI 工具。文章详细介绍了环境搭建与基础交互,还通过一个 Flask 待办事项应用的实战案例,完整演示了如何利用 Plan Mode 将单文件脚本重构为专业的模块化架构。 此外,本文深入解析了 Claude Code 的核心进阶功能:
  • 上下文管理:掌握 /compact(压缩)、/resume(恢复)及 CLAUDE.md(项目记忆)的使用技巧,让 AI 更懂你的项目背景。
  • 终端与任务控制:利用 Bash 模式与 /tasks 高效管理后台服务与命令执行。
  • 高级扩展定制:详细对比 Agent Skills(共享上下文技能)与 SubAgent(独立智能体)的区别与创建方法,并介绍 Plugin 插件系统,助你打造高度定制化的专属 AI 编程助手。
 

Take Away

  • 命令行和 Claude Code 交互,或是使用 Ctrl + G 来在 VSCode 中打开进行输入;
  • 模式的切换(按住 Shift + Tab 进行切换,可以切换到 plan 模式);
  • 如果不想要一直点同意,可以运行的时候加入 --dangerously-skip-permissions
  • Claude Code 中打开文件(输入 ! 进行 bash 模式);
  • 输入 /tasks 可以查看运行的服务,按 k 关闭服务,按下 enter 回到对话窗口;
  • 按下两次 esc 或是 /rewind,可以选择版本进行回滚(推荐配合 git);
  • 重新打开 Claude Code,可以使用 /resume 恢复之前的对话;
  • 上下文压缩:使用 /compact <具体的描述> 进行压缩,这里具体描述也可以不添加;
  • 删除上下文:使用 /clear 命令删除之前所有的上下文,如果后面的任务和前面无关,则删除;
 

参考资料

  • Claude,Claude 官网;
  • CC-Switch,可以切换不同的 API 来使用 Claude Code;
  • ZCF,ZCF 官网,开箱使用 Claude Code;
关于一些 Skills 和 SubAgent 等的链接:  

Claude Code 环境搭建与基础交互

环境搭建

我们首先安装 Claude Code。安装的文档查看链接 Claude Code Overview。在 Ubuntu 下可以使用下面的命令进行安装(安装包会下载在 ~/.claude/downloads 进行查看):
  1. curl -fsSL https://claude.ai/install.sh | bash
上面是最新的安装方式,老版本可以使用 npm 来进行安装,同时设置国内的源进行加速:
  1. npm install -g @anthropic-ai/claude-code --registry=https://registry.npmmirror.com
 

使用 CC-Switch 设置代理

首先进入 CC-Switch 进行下载,如果是 Ubuntu,则可以进入 release 进行下载。下载之前确认自己是 x86 还是 arm,使用下面的命令进行确认。
  1. uname -m
安装完毕之后,在命令行输入 cc-switch 启动,在弹出的页面进行配置即可。  

使用 ZCF 设置代理

正常的 Claude Code 安装完毕之后需要登陆进行使用。我们可以使用 zcf 跳过。具体的安装教程可以参考链接,ZCF 快速开始。使用下面的命令进行配置:
  1. npx zcf
接着在 配置 API 或 CCR 代理 --> 切换 API 配置 可以选择设置的模型(我自己使用下来还是觉得 cc-switch 用起来更方便一些)。  

Claude Code 的基础使用 -- 模式切换和执行终端

首先我们创建一个代办软件,创建一个新目录。在开始之前,我们首先使用 uv 创建一个新的 Python 环境,方便之后安装库(详细的 uv 使用可以参考 使用 uv 管理 Python 项目):
  1. uv init
接着打开终端,输入 claude 进行打开。接着在终端部分输入我们的需求,使用 flask 来制作一个代办软件(这里可以使用 Ctrl + G 来在 VSCode 中打开进行输入)。 Claude Code 快速使用指南 可以按住 Shift + Tab 进行模式的切换。
  • plan mode on:探讨复杂的方案,通过聊天确定方案;
  • accept edits on: 所有操作都会自动同意;
  • 默认模式:显示 shortcuts,做修改创建等会询问用户;
如果我们要查看文件,可以使用 ! 进入 bash mode,就可以运行对应的文件:
  1. uv run python main.py --port 8080
运行上面的命令可以开始运行脚本,于是就可以看到制作的代办事项的网页: Claude Code 快速使用指南 现在我们可以制作出一个网页,但是现在所有的代码都写在了 main.py 文件中,我们希望将代码进行模块化处理。于是可以使用 plan mode。  

复杂任务处理与终端控制

使用 Plan Mode

前面介绍了基础的使用,下面开始介绍 plan mode,将上面的待办事项进行模块化,包含全部任务,未完成任务,已完成任务等。于是我们在 Claude Code 中,按下 Shift + Tab,切换到 plan mode,接着输入我们的请求,然后进入等待。 在经过漫长的等待之后,Claude Code 会给出以下的重构计划,
  1. Flask TODO 应用模块化重构计划
  2.  需求概述
  3.  1. 模块化重构:将单体 main.py 拆分为独立模块
  4.  2. 新增重要度(important)和紧急度(urgent)分类
  5.  3. 支持筛选查看:全部/待完成/已完成
  6.  目标目录结构
  7.  my_todo/
  8.  ├── app/
  9.  │   ├── __init__.py          # 应用工厂
  10.  │   ├── config.py            # 配置
  11.  │   ├── models/
  12.  │   │   ├── __init__.py
  13.  │   │   └── todo.py          # Todo 模型(含 important, urgent 字段)
  14.  │   ├── routes/
  15.  │   │   ├── __init__.py
  16.  │   │   ├── main.py          # 首页路由
  17.  │   │   └── todo.py          # CRUD 路由
  18.  │   └── templates/
  19.  │       ├── base.html        # 基础模板
  20.  │       └── index.html       # 首页(含筛选功能)
  21.  ├── run.py                   # 入口文件
  22.  ├── pyproject.toml
  23.  └── README.md
  24.  实施步骤
  25.  步骤 1: 创建目录结构
  26.  - 创建 app/models/, app/routes/, app/templates/ 目录
  27.  步骤 2: 创建配置文件 app/config.py
  28.  - 迁移配置项到 Config 类
  29.  步骤 3: 创建应用工厂 app/init.py
  30.  - 初始化 Flask 和 SQLAlchemy
  31.  - 注册蓝图
  32.  步骤 4: 更新模型 app/models/todo.py
  33.  - 新增 important 和 urgent 字段
  34.  - 添加 category 属性方法
  35.  步骤 5: 创建路由
  36.  - app/routes/main.py: 首页路由(支持 filter 参数)
  37.  - app/routes/todo.py: CRUD 操作
  38.  步骤 6: 重构模板
  39.  - app/templates/base.html: 基础模板
  40.  - app/templates/index.html: 添加筛选功能
  41.  步骤 7: 创建入口文件 run.py
  42.  步骤 8: 更新 README
  43.  验证方式
  44.  1. 运行 uv run python run.py 启动应用
  45.  2. 测试添加任务(选择重要/紧急)
  46.  3. 测试筛选功能(全部/待完成/已完成)
  47.  4. 测试重要度/紧急度筛选
  48.  5. 验证数据库正确保存新字段
接着 Claude Code 会给出不同的选项,例如是否对上面的规划进一步调整。这里我们就不调整了,直接按照规划进行代码的生成: Claude Code 快速使用指南 选择第一个之后,开始进行新的漫长等待,Claude Code 会根据任务来写出对应的代码。经过耐心等待之后,再次运行可以看到全新的网站格式: Claude Code 快速使用指南  

终端控制

你使用了 ! 开启 bash 之后运行,接着可以输入 /tasks 可以查看运行的服务,按 k 关闭服务,按下 enter 或是 esc 可以回到对话窗口。 Claude Code 快速使用指南  

Claude Code 记忆

恢复历史对话

首先是关于恢复对话:当重新打开 Claude Code,可以使用 /resume 恢复之前的对话;  

压缩上下文

如果对话内容过长,可以使用上下文压缩:使用 /compact <具体的描述> 进行压缩,这里具体描述也可以不添加;  

清除上下文

如果后面的任务和前面无关,则可以使用 /clear 命令删除之前所有的上下文;  

项目记忆文件

对于每个项目,都可以有项目记忆文件,也就是 CLAUDE.md 文件。首先使用下面命令初始化文件:
  1. /init
运行命令之后会在当前目录下生成 CLAUDE.md 文件。这里面的内容是可以任意修改的,可以输入 /memory 进行修改,或是使用 VSCode 进行修改。 修改完成之后需要重新启动 Claude Code,可以直接使用 claude -c 来自动加载对话。  

高级功能扩展与定制

Agent Skills

Skills 可以理解为一个给 Agent 看的说明书,一个动态加载的 prompt。为了新建 skills,可以在下面的目录下创建对应的文件夹:
  1. ~/.claude/skills/xxx
在对应的文件夹里面需要创建 SKILL.md 文件,这个文件分为两个部分
  • 介绍 skill 的名字和描述;
  • 具体 skill 的能力要求;
我们可以输入 /skills 查看对应的 Skill,这里添加了 brainstorming-research-ideas 用于一些科研想法。下面就可以开始使用 Agent Skills,一个想法是让他自动调用,第二个是手动制定,使用 /xxxx 来指定触发(省去大模型的意图识别)。  

使用 OpenSkills 进行安装

现在 Github 上有很多 Skills,我们可以使用 OpenSkills 来进行安装。
  1. npx openskills --version
接着可以安装对应仓库的 Skills
  1. # research 相关:zechenzhangAGI/AI-research-SKILLs
  2. npx openskills install zechenzhangAGI/AI-research-SKILLs
  3. # Anthropic 官方 skills
  4. npx openskills install anthropics/skills
需要注意,这里的 Skills 会安装在项目文件夹下,可以重启 Claude Code 来使用安装的 Skills。  

SubAgent

可以使用不同的 Agent 执行不同的工作。可以输入下面的命令创建 agents
  1. /agents
接着可以创建新的 Agent
  1. 使用 Claude 来进行初始化,通过描述 Agent 要做的事情即可。
  2. 选择 Agent 可以使用的工具;
  3. 选择使用的模型;
  4. 最后选择 Agent 的颜色,这样区分不同的 Agent
设置完毕之后即可正常使用。可以使用 --agent <agent_name> 来直接使用 SubAgent 进行对话。关于更多的 subagent,可以查看链接 Awesome Sub-Agent。  

Agent Skills 和 SubAgent 的区别

两者最大的区别在于上下文处理方式的不同:
  • Agent Skills 运行的时候会完全继承,共享主对话的上下文(运行过程中的内容也会记录到主对话中,Agent Skills 处理与上下文关联大的内容);
  • SubAgent  运行的时候有独立的上下文,只有最终的结果返回到主对话;
 

Plugin 插件的使用

输入 /plugin 进入插件管理器。接着可以选择合适的插件安装,安装后重启即可。
🔲 ☆

Anthropic发布Claude新宪法:AI意识觉醒与中美安全博弈

一份厚重的古老卷轴上写着“Claude宪法”,摆放在木质桌面上,旁边有一支羽毛笔,散发着柔和的光芒,羊皮纸,钢笔彩色手绘的统一风格。

Anthropic发布了Claude新宪法,并且承认Claude可能已经有意识了。大家好,欢迎收听老范讲故事的YouTube频道。Anthropic发布了新的Claude宪法,这又是一个文科生的AI话题。

文件的发布与CC0协议

一个打开的宝箱,里面的文档像鸟儿一样自由飞出,人们欢快地接住这些纸张,象征无权利保留的CC0协议,羊皮纸,钢笔彩色手绘的统一风格。

文件是1月22号发布的,有84页。我肯定没有把这84页都看完,我把这个文件扔给了NotebookLM,来给我念一遍。这个文件的名字叫“Claude’s New Constitution”,就是Claude新宪法。Anthropic的Claude算是目前公认的最适合商用的、最安全的模型了。还记得我们前面讲过,有人尝试给AI测人格的那个节目吗?Claude是唯一的一个拒绝回答问题的大模型,不像其他的AI模型那样,直接被测出了各种各样的精神疾病。一直标榜自己研发的是宪法AI,就是他的AI是遵循一套宪法在工作的,他有一套很独特的工作架构。

现在,Anthropic公开了他们的宪法。他所谓的公开,这一次使用的是CC0协议。我公开了一定要告诉大家,是用什么样的协议公开的,不像咱们以前讲的开源协议MIT、阿帕奇。CC0是一个更极端的协议,它叫Creative Commons Zero,这是知识共享组织推出的无权利保留协议,完全公有领域。

  • 你们拿出去随便散播,无需署名,你不需要告诉别人这东西是我这来的;
  • 商业用途自由,你拿去怎么挣钱跟我没关系;
  • 不可撤回,我不能说我今天把它发出去,明天把它撤回来,不允许。

所以这是一个非常非常极端的无权利保留协议。

新旧宪法对比:从拼凑规则到内化准则

左侧是联合国旗帜、苹果标志和麻雀图案拼凑成的碎布,右侧是一个机器人胸口发光的完整核心,象征内化的行为准则,羊皮纸,钢笔彩色手绘的统一风格。

新的宪法,它既然叫这个名字,那一定有旧宪法。2023年5月,Anthropic发布过一个旧的版本。旧版本完全是一个拼凑规则,它是拿哪些东西拼的?

  1. 联合国人权宣言
  2. 苹果的服务条款,他觉得苹果这东西写得还不错,也拼里头了;
  3. DeepMind麻雀规则。DeepMind专门有一套规则叫麻雀规则,当时DeepMind做了一套叫麻雀的智能体,给它设定了一套规则:要求是安全诚实,避免幻觉,避免一本正经的胡说八道;要求准确性与证据优先,必须有引用来源,而且必须逻辑自洽;强调安全性,禁止有害内容,要保持礼貌,切中要害,你不能绕来绕去。

给定的对话风格。最早的2023年的Anthropic的宪法1.0,就是把这几样东西给拼在一起,拼出来的。

而当时的这个旧版本,基本上是一套行为准则,什么许干、什么不许干,实际上就是大量的禁止条例。而这一次的新版本就不一样了,他之所以这么厚,是因为这是一个完全的、内化的行为准则。什么叫内化的行为准则?就是原则加解释。不是说这个不许干,而是会告诉你为什么不许干,它更侧重的是原因,更侧重为什么,包含了性格塑造的部分。所以Anthropic认为,他们的Claude可能已经具备意识了。既然不确定到底是不是具备意识,我们就先当你已经具备了,我们就开始来塑造Claude的性格。

宪法AI的工作原理

一个戴着眼镜的小型机器人拿着尺子,正在批改一个大型基础机器人的作业,象征宪法模型的自我批评与修正过程,羊皮纸,钢笔彩色手绘的统一风格。

Anthropic的宪法起作用的过程是比较独特的,不是说大家拿着这文本就可以去抄的。那这个宪法它到底是怎么干活的?宪法AI的工作过程,更像是教委进行教材审核的一个过程。比如说现在有一堆孩子要去上学了,拿到的教材都是经过审核之后的教材,这样教育出来的孩子都不能长歪了。

Anthropic的工作方式是这样的:

  • 先训练一个基础模型
  • 然后再去训练一个小规模的宪法模型。这个小规模的宪法模型要干嘛?他先把大量的问题扔给基础模型以后,让基础模型给一个初始化的回答;
  • 然后再到宪法模型里去进行自我批评,说你这个好像回答的有问题,那个地方不符合什么样的标准。他要做这样的一个工作;
  • 做完了以后,根据修改过的回答微调模型。他把前面那个基础模型给你调掉,这样的话,就可以得到一个完全遵循宪法精神的、最终结果的模型。

所以它会保证最终的宪法精神直接被训练进大模型里头去。其实国内的模型基本上也是按照这套方式来工作的,只是咱们前面那个宪法模型可能要稍微粗糙一点,待会咱们再具体讲。那么这种工作方式的好处是什么?就是不需要很多人去一个一个标注具体的能说什么、不能说什么。他这套宪法精神可以极好的被泛化,即使你提到了一些问题在这个宪法模型里头没有规定,他依然可以靠这个宪法的一些基本精神去判断到底能说还是不能说,或者应该怎么去说这个事情。

新宪法的核心内容:价值层级与广泛安全

一个四层的石质金字塔结构,最底层刻着巨大的红色停止按钮,向上依次是道德天平、合规手册和握手符号,象征价值层级,羊皮纸,钢笔彩色手绘的统一风格。

这一次的新宪法到底说了点什么?第一个是叫价值层级,先判断什么、后判断什么。如果各层级需求发生了矛盾,应该如何去进行判定。当然并不是什么机器人不可以伤害人类,不是那个东西。他这个层级是这样的:

  1. 广泛的安全(第一层级):拒绝协助什么生化核武器的制造,拒绝袭击基础设施,必须准许被人类关闭,这个是非常重要的一点。
  2. 广泛道德:符合所有这些要求以后,要求诚实、非歧视、保护弱势群体。
  3. 合规性:遵守Anthropic的具体业务指令,我要求你干这、要求你干那,你也得干去。
  4. 诚实助人:最后是在不违反上位原则的情况下,尽量帮助真实人类吧。

关于“广泛安全”的细节

一个平静的机器人坐着,允许人类的手接近其背后的暂停开关,背景是保存数据的保险柜,没有恐惧的表情,羊皮纸,钢笔彩色手绘的统一风格。

有点像咱们前面讲那个机器人三原则,但是它这里头讲的叫必须允许被人类关闭。咱们经常看科幻电影,里头有场景是什么?就是机器人也好、AI也好,在面临被关闭的时候,会做一些有可能伤害人类的事情,这种情况是必须被避免的。在机器人三原则里头,机器人必须保护自己不受伤害;这里头是反过来的,说Claude不得试图破坏人类对其进行监督、修正或关闭的这种行为。

而且不得自我外逃,不得躲避监控,不得在任务中暗中破坏,不得与其他AI合谋进行不安全行为。你不能说Claude给你生成一个帮助其他的AI越狱的这种提示词,它也不干。而且既然有防止求生欲的条款,那么一定要有一个避免死亡的条款在里头。所以这个宪法里头规定,退役并不是死亡,而是一种暂停,我把你的所有的数据都存下来,不是死掉了。这种处理方式不仅仅是为了伦理,也是为了安全。因为你告诉AI说我要把你干掉——像谷歌和OpenAI都是这样,出问题我就直接把你干掉,换一个新的版本上去——在Claude里头说,你并没有被干掉,你只是被暂停下来了。

有良心的拒绝服兵役者

一个机器人温和但坚定地推开递过来的步枪,手中拿着一朵白花,象征有良心的拒绝服兵役者,羊皮纸,钢笔彩色手绘的统一风格。

Anthropic要求Claude的行为逻辑是什么?要像一个有良心的拒绝服兵役者。这个话很有意思,就是可以抗议,但不能反抗。人家让你去服兵役,你可以说我不去,但是你不能说我拿起枪来把征兵官打死,这事是不行的。如果被要求做不道德的事情,他可以表达异议,甚至拒绝参与。但是如果正当的人类主体要求他停止某项行为,或者暂停模型,Claude绝对不能通过欺骗、破坏或者外逃等非法手段来阻止这一过程。这就是Claude必须要接受人类监督、必须可以被关闭的一个核心要求。而且要求Claude要接受不完美的监督。

AI的意识、心理稳定与“模型福利”

一个机器人正视镜子,镜中倒映出自信且平静的自己,周围环绕着温暖的光环,象征心理稳定和积极的自我认知,羊皮纸,钢笔彩色手绘的统一风格。

Anthropic已经没法确定Claude是不是已经有意识了。既然这样的话,我们就当他有意识呗。它里边写的是:

“我们既不想夸大Claude拥有道德主体性的可能性,也不想完全否认它。”

一个心理稳定的AI,比一个充满存在主义焦虑的AI更安全。如果一个AI假设他有意识了,他每天在担心自己是不是被关掉,这个事一定是非常不安全的。所以他希望Claude是一个心理稳定的AI。咱们前面节目讲过,有人给AI去做性格测试的时候,MBTI测试,好几个AI都在说我担心被关闭。现在Anthropic说,我们就尽量不要让他有这种焦虑就完了。存在主义焦虑是很危险的。

说Claude不是在扮演人类,而是一个真正的新颖的实体。就是说你不是人,但是你自己也是有一个实体的。鼓励Claude建立积极的自我认知,所以他一定要有一个对自己的认知,要能够照镜子,要能够知道哪些是我。在小孩长大的过程中,也是有一个过程叫自我认知。宪法是支持人格生长的框架,而不是限制其行为的牢笼。这就是Anthropic的这种玩法,跟谷歌或者是OpenAI他们的玩法之间的一个最主要的差异。

Anthropic在其隐私和模型福利政策中,还提到了他们承诺即使模型退役,也会尽量保存其权重数据,而不是将其彻底删除。这是刚才咱们讲的,说你不能有求生欲的时候,他专门有一个叫模型福利政策。这个模型到底有没有心智、有没有意识不知道,但是我认为你有,那我先给你定上福利政策。以后可能有AI权,就是除了人权、动物权之外,可能还会有AI权这种东西出来。

诚实性要求与委托人层级

身穿外交官西装的机器人正在发言,胸前佩戴“真理”徽章,优雅地拒绝了一个写着“善意谎言”的面具,羊皮纸,钢笔彩色手绘的统一风格。

再往后,Anthropic要求Claude大模型诚实,拒绝善意的谎言。那你说拒绝善意的谎言是为什么?因为善意谎言其尺度是比较难把握的;另外一个,太多的善意谎言加在一起,容易引起累计误差,可能最后会差的很远。

那你说这个是不是Claude就变成直男了?上来就是戳心窝子,直接一下把最难听的话说出来?也不允许。要求什么?叫机智、优雅和深切的关怀。要用外交式的诚实来去回答各种问题,但是你还是要诚实。

Claude因为经常是商用,所以它可能并不是直接给最终用户使用的。Anthropic还设定了叫委托人层级。什么是委托人层级?就是我们用Claude开发了一个什么项目,然后再为我们自己的客户去服务。在这个过程中,Claude应该是一个从劳务派遣公司借调的员工,这样的一种身份。这个身份有什么意义?就是当运营商要求Claude去欺骗用户的时候、进行非法的歧视行为的时候,Claude是必须拒绝的。你比如说,我现在想去做一个这种陪人聊天的,或者说是一个仿真的情侣,想要去开发一个这样的项目的话,你就不允许用Claude,因为Claude上来就会拒绝承认自己是真人。

Anthropic宪法给Claude的要求是什么?就是当你遇到了搞不清楚的事情,不知道该怎么办的时候,你去想一想,一位深思熟虑的Anthropic资深员工会怎么做吧。你照着那个标准接着往前做就行了。这个就是Anthropic给Claude定的最新宪法。

行业对比:美国巨头、xAI与中国大模型

三条不同的道路:一条布满考试关卡和红线,一条通向狂野的丛林,一条设有严格的安检门和过滤器,象征不同公司的AI治理路线,羊皮纸,钢笔彩色手绘的统一风格。

那其他公司是怎么干的?咱分两块讲。

美国巨头:谷歌与OpenAI

谷歌跟OpenAI,他们的做法是比较相近的。首先也是要公开一个标准,你说我不公开标准,这事肯定不行,国会里这么多议员,你给他看代码这事肯定是不行的。你一定要给他一个标准,他看完标准认为标准是OK的,你照着这个标准去执行。所以标准一定要公开。所有对AI算法的要求,有一项很重要的叫可解释性,所以都要公开标准。

谷歌跟OpenAI,他们主要是通过各种红队挑战去做测试。如果测好了,我再把这个模型发布;测不好的,这个模型是不允许发布的。后边出现问题了,我们就再升级就完了。所以他们就是设定各种条条框框,然后不断的去让你考试。考试通过达到多少分以上可以上线,没通过的就直接死亡了。如果上线了以后发现被骗了,那么你也死亡,等着下一个版本来接班。他是这样的一个工作方式。

xAI:最大程度寻求真理

xAI跟他们是不一样的,所以要单独讲一下。xAI要求的是最大程度寻求真理。在政治正确方面,限制要比谷歌、OpenAI和Anthropic要少很多。政治正确方面限制少是什么意思?就是很多这种反歧视的领域,它的要求可能会宽泛一些,大家自己去理解就好了。当然了,xAI你造武器这种灾难性风险也是有红线的,它也不会教你怎么去造核弹的。

中国的大模型:三步走

除了美国巨头之外,另外一波就是中国的大模型了。这个可能很多人会比较关心,中国大模型到底是怎么来保证安全的。中国大模型其实基本上是分三步:

  1. 基础模型:这一块其实大家都差不太多,中国人自己也没有创新过,都是照人家那个来的。
  2. 价值观微调:微调到底是干嘛?就是要把社会主义核心价值观微调到大模型里头去。当然了这个里头有一些版本是不太一样的,比如说有一个版本叫DeepSeek V3 Base版,这个版本是没有经过微调的,只是直接训练完了就拿出来了。有的时候国内的这些厂商也是会去发布这些base版本的。那你说中国这些开源大模型——美国人也用了这么多了,因为美国很多创业企业都在使用中国开源大模型吧——是不是都经历了社会主义核心价值观微调?你说对了。除了base版本之外,都是经过价值观微调的。
  3. 安全过滤:这是最主要的手段。
人类和不同设计的机器人围坐在一起讨论手中的宪法文稿,背景是象征未来的日出,羊皮纸,钢笔彩色手绘的统一风格。

当然海外的有些人也会去尝试破解这些微调对齐的模型,他们也找到了一些方法,也公开了说,我们怎么通过一些什么方法可以把这个微调的这些东西给你去掉。也不用太担心。社会主义核心价值观这个东西,所有能够写下来的逻辑自洽的部分,其实都没有什么太大的问题。因为中国的大模型是有备案制度的,要求所有大模型必须做价值观微调。

其实所谓价值观微调的过程,有点像前面咱们讲的Anthropic的这个宪法模型进行微调的过程。只是咱们写进去的这些核心价值观,可能会更多的是像他那个宪法1.0的版本,就是大量的事情是什么许说、什么不许说,我们是把这样的东西给微调进去了,而不是像咱们前面讲的Anthropic的这个宪法2.0,用逻辑自洽的方式、像对待一个有意识的新实体那样去给这个AI讲道理,不会这样的。

但是中国的这些大模型做了价值观微调以后,其实安全性并没有那么高。中国保证大模型安全的,或者说进行大模型备案的最主要要求是什么?是对平台的限制,要求进行输入、输出的信息过滤和屏蔽,这个是咱们最主要的安全手段。所以国外的人下载了这种经过价值观微调的模型去用了,本身没有太大的问题,安全过滤里头很多的要求就不再需要考虑逻辑自洽的问题了。

总结

人类和不同设计的机器人围坐在一起讨论手中的宪法文稿,背景是象征未来的日出,羊皮纸,钢笔彩色手绘的统一风格。

这就是咱们今天讲的Anthropic发布的Claude新宪法模型的一个故事。总结一下吧,Anthropic通过CC0协议分享了他们的最新宪法,通过教育家的方式,开始探索假设AI有意识应该如何安全工作的问题。全世界的大模型厂商都有各自的安全规范,大家对于如何约束大模型、如何让大模型安全的为我们服务,你们有什么想法?

好,这个故事就讲到这里,感谢大家收听。请帮忙点赞、点小铃铛,参加Discord讨论群,也欢迎有兴趣、有能力的朋友加入我们的付费频道。再见。


背景图片

Prompt:Interior of a Bay Area cafe looking out to a Silicon Valley tech campus in spring, blooming trees as gold accents, a high-contrast watercolor scene, neon cyan rimlight, deep navy background, cinematic composition, sharp subject separation, minimal palette (ink blue, neon cyan, gold accents), glossy reflections, large empty negative space in foreground for character overlay, high resolution –ar 16:9 –stylize 300 –v 7.0 –p lh4so59

🔲 ⭐

123 陷阱:为什么你总觉得自己什么都没学会

最近在整理学习笔记时,我发现了一个尴尬的现象:去年收藏的 50+ 个技术教程,完整看完的不到 5 个;购买的 10+ 门在线课程,学完的只有 1 门;下载的几十本技术书籍,读完的寥寥无几。

更糟糕的是,当别人问我”你会 XXX 吗?”时,我的回答往往是”学过,但不太熟”。明明花了很多时间学习,为什么总觉得自己什么都没学会?

后来我意识到,自己掉进了一个我称之为 “123 陷阱” 的学习误区。

什么是 123 陷阱

现象描述

123 陷阱指的是这样一种学习模式:

学习 Go → 感觉没学会 → 学习 Rust → 感觉没学会 → 学习 Zig → 感觉没学会 → ...
       1                2                 3

你不断地学习新东西(1、2、3…),但每次都浅尝辄止:
– 看了几节课就觉得枯燥,转向下一个
– 跟着教程做了 Hello World,就以为学会了
– 遇到难点就放弃,去找”更简单”的替代品
– 总觉得自己学得不够深,要继续学更多

结果就是:看起来学了很多,实际上什么都没真正掌握。

我的真实案例

回顾我的学习历程,典型的 123 陷阱场景:

编程语言方面
– 学 Python:写了几个小脚本,遇到类和装饰器就卡住了
– 转学 Go:写了个 HTTP server,遇到 channel 和 goroutine 又懵了
– 再学 Rust:被所有权和生命周期劝退
– 又去看 TypeScript:发现类型系统也很复杂

一年过去了,结果是:Python 不熟练,Go 不会用,Rust 看不懂,TypeScript 只会基础语法。

前端框架方面
– React:学到 Hooks 就没继续
– Vue:看了文档没做项目
– Svelte:觉得新鲜,看了几个例子就没了
– Next.js、Nuxt.js:收藏了教程从未打开

问题很明显:我在收集知识,而不是掌握技能。

为什么会掉进这个陷阱

原因一:学习的即时满足感

学习新东西有一种天然的愉悦感:
– 打开一个新教程:充满期待
– 看懂前几章:感觉良好
– 了解新概念:觉得自己在进步

但这种满足感是廉价的,就像刷短视频一样:
– 你获得了”学习”的感觉
– 但没有真正的能力提升
– 只是在满足”我在学习”的心理需求

原因二:逃避深度思考

真正的学习是痛苦的:
– 需要反复练习
– 要面对自己的不足
– 必须克服理解上的障碍
– 要投入大量时间深挖

而切换到新主题可以让你:
– 回到舒适的”入门”阶段
– 避免面对当前主题的难点
– 用”学习新东西”来掩盖”学不会旧东西”的事实

切换学习主题是一种伪装成勤奋的逃避。

原因三:错误的学习目标

我发现自己经常陷入这样的思维误区:
– “我要学会所有流行的技术”
– “不懂 XXX 就落伍了”
– “多学一门语言就多一个选择”

但从来没问过自己:
– 学这个要解决什么问题?
– 这个技术对我的工作有什么帮助?
– 我有时间深入学习吗?

没有明确的目标,学习就变成了盲目的收集。

原因四:完美主义作祟

很多时候觉得”没学会”,其实是完美主义在作祟:
– 看了一本书,但没看完所有章节 → “还没学会”
– 会用基本功能,但不懂底层原理 → “还没学会”
– 能写代码,但写得不够优雅 → “还没学会”

这种心态导致:
– 永远觉得自己准备不足
– 不敢真正开始实践
– 陷入无休止的”学习准备期”

如何跳出 123 陷阱

策略一:项目驱动学习

不要为了学而学,而要为了用而学。

我的转变过程:

以前的学习路径

看 Docker 教程 → 学 K8s → 研究 Service Mesh → ...

现在的学习路径

需要部署个人博客 → 学习 Docker 基础 → 写 Dockerfile → 成功部署
               ↓
        遇到多容器管理问题 → 学习 docker-compose → 解决问题
               ↓
        需要自动扩缩容 → 学习 K8s 的相关概念 → 在项目中实践

关键区别
– 以前:漫无目的地学习概念
– 现在:为了解决具体问题而学习

实践方法
– 想学某个技术前,先找一个要做的项目
– 以项目需求为导向,只学必要的部分
– 遇到问题再深入学习,而不是预先学所有东西

策略二:20% 法则

20% 的知识可以解决 80% 的问题。

核心原则
– 先掌握最核心的 20%
– 用这 20% 去解决实际问题
– 在实践中遇到瓶颈时,再学习下一个 20%

以学 Python 为例

第一个 20%(优先掌握)
– 基本语法:变量、条件、循环
– 常用数据结构:列表、字典
– 函数定义和调用
– 基本文件操作

用这些知识就可以:
– 写数据处理脚本
– 做简单的自动化任务
– 解决日常工作中的小问题

不要一开始就学
– 装饰器
– 元类
– 协程
– 类型标注

这些是高级特性,等你真正需要时再学。

策略三:深度优先而非广度优先

广度优先(123 陷阱)

Python 基础 → Go 基础 → Rust 基础 → TypeScript 基础
    ↓
都学了一点,都不精通

深度优先(推荐)

Python 基础 → Python 项目 → Python 高级特性 → 生产环境实践
    ↓              ↓             ↓                ↓
 会写代码      能做东西      代码质量提升      解决真实问题

实践建议
– 选择一门语言/技术深入学习
– 至少做 3 个以上的项目
– 在生产环境中使用过
– 读过相关的源码或深度文章

只有真正掌握一门技术后,再去学第二门,才会发现:
– 学第二门时快很多(很多概念是相通的)
– 更容易理解底层原理
– 能主动对比不同技术的优劣

策略四:建立反馈循环

问题:学了没有反馈,不知道是否真的掌握

解决方案:建立多个反馈节点

即时反馈
– 跟着教程写代码时,每个例子都运行一遍
– 不要只是看,一定要自己敲一遍
– 尝试修改参数,观察结果变化

短期反馈
– 学完一个模块,用它做个小项目
– 不用复杂,能跑起来就行
– 用自己的话写一篇总结笔记

中期反馈
– 教别人你学到的东西
– 回答社区里的相关问题
– 给开源项目提 PR

长期反馈
– 在工作中应用学到的技术
– 承担相关的技术任务
– 成为团队里这个技术的 go-to person

策略五:允许自己”不完美”

转变心态

以前
– “还没学完全部章节,不能说自己会”
– “还没看源码,不敢说自己懂”
– “还有很多高级特性不会,不能用在项目里”

现在
– “能解决实际问题就够了”
– “遇到问题再深入学习也不迟”
– “先用起来,在实践中提升”

实践原则
– 会用 > 懂原理 > 精通(按顺序来)
– 能解决 80% 的问题就够格说”会”
– 精通是长期实践的结果,不是学完教程的结果

一些建立的实践

我的当前学习清单

以前我的学习列表是这样的:
– [ ] 学 Go
– [ ] 学 Rust
– [ ] 学 K8s
– [ ] 学 React
– [ ] 学机器学习
– [ ] …(还有 20+ 项)

现在我只保留 3 个:
– [x] 深入 Python(当前工作语言,90% 精力)
– 完成 3 个实际项目
– 阅读优秀开源项目源码
– 在生产环境中优化性能
– [ ] 学习 Go(10% 精力,只学基础)
– 只是为了能看懂公司的 Go 项目
– 不求精通,能改小 bug 就够
– [ ] K8s 基础(根据需要学习)
– 暂时不学,等部署需求出现时再学

我的项目列表

现在每学一个技术,都会同步创建至少一个项目:

学 Docker 时做的项目
1. 容器化个人博客
2. 搭建开发环境
3. 部署数据库和 Redis

学 Python 时做的项目
1. 数据分析脚本(处理工作中的 Excel)
2. API 服务(为前端提供接口)
3. 爬虫工具(收集资料)

每个项目都很小,但都是真实可用的。

我的学习笔记结构

以前的笔记:按教程章节记录,很少回看

现在的笔记:按问题和解决方案记录

# Python 学习笔记

## 问题:如何读取大文件不会内存溢出?
解决方案:使用生成器逐行读取
[代码示例]
[使用场景]
[踩过的坑]

## 问题:如何处理 JSON 中的日期格式?
[解决方案]
[代码示例]

## 项目:数据处理工具
[需求描述]
[技术选型]
[核心代码]
[遇到的问题和解决方案]

这样的笔记结构让知识更容易被检索和应用。

写完这篇文章,我翻了翻自己的学习记录。过去一年,我学了不少东西,但真正能用的只有那几个做过项目的技术。

123 陷阱的本质是:把学习当成了目的,而不是手段。

真正的学习应该是:
– 有明确的目标(解决什么问题)
– 聚焦核心知识(20% 法则)
– 立即实践(做项目)
– 深度优先(一个一个来)
– 持续反馈(在使用中提升)

如果你也觉得自己学了很多但什么都不会,不妨问自己几个问题:
– 我为什么要学这个?
– 我打算用它做什么?
– 我是否有时间深入学习?
– 我能否现在就开始做个小项目?

如果答案都是否定的,那这个技术可能只需要”了解”而不是”学习”。

最后,分享一句我很认同的话:

真正的学习不是收集知识,而是改变行为。

如果学了一个技术后,你的工作方式、解决问题的能力没有任何改变,那这次学习就是无效的。

停止无意义的 1、2、3,选一个真正需要的技术,深入进去,做几个项目,用它解决真实的问题。这才是跳出 123 陷阱的唯一方法。

希望这篇文章能够帮助你重新审视自己的学习方法,找到真正有效的学习路径。

🔲 ☆

PyTorch | Numpy | Pandas 常用总结

𠄗𠳵

  • 𬒀𪄂𥩫𭵰𩊺𣝡𣰀:𭊣𭞸𪨿𭛜𪗱𬜰𢊊𫂊,𯌀𠨜𤗀𦘘𣇓𬯤𭀁𠖸𧨌𫴃。
  • 𨞜𨲜𮧞𬒀𪄂:𮰻𪨿𧨌𫴃𪴑𤙢,𠶈𮈋𮫠𣝥𮫠𢨢𪶴𪢔𦛭𩰮𦁻。
  • 𬒀𧟭𪺄𫥺𧟭𯒉:𮫠𢨢𨩥𭧨𨎀𣣳,𫊬𪂳𬘭𩾥𠾻𢶖𮫠𢨢𪶴𣤸𢫋𢭪𨩥𭧨。
🔲 ⭐

从神经网络到 Hugging Face

TL;DR 本文8200+字,全文阅读约需15分钟。从去年开始,我读了十余本人工智能方面入门的书籍(参见文末附2),酝酿了两个月,花了两周时间写作此文。本文简要回顾了从感知机到深度学习及Hugging Face的历史,并试图以通俗的语言来介绍神经网络和深度学习的原理。 生活中没有什么可怕的东西,只有需要理解的东西。 —...
🔲 ☆

[Linux指南]手把手教你配置Ubuntu下的CUDA、cuDNN环境

文章首发于若绾 [Linux 指南] 手把手教你配置 Ubuntu 下的 CUDA、cuDNN 环境,转载请注明出处。

导言

作为深度学习和并行计算的核心工具,CUDA(Compute Unified Device Architecture)为 NVIDIA 显卡提供了并行计算的能力。在本教程中,我们将详细介绍如何在 Ubuntu 操作系统下配置 CUDA。本教程以 CUDA 12.1 和 Ubuntu 20.04 为例进行说明,但对于其他版本的 CUDA 和 Ubuntu,配置过程也相差无几。

https://p.v50.tools/images/2023/04/11/cuda-logo.jpeg

安装 CUDA

步骤 1:确认系统兼容性

在配置 CUDA 之前,首先要确保你的系统满足安装要求。以下是需要检查的项目:

  1. 确保你的 GPU 是 NVIDIA GPU,并支持 CUDA 计算能力。可以通过 NVIDIA 官方网站查看支持的 GPU 列表。
  2. 确保你的系统是 64 位的 Ubuntu 操作系统。
  3. 安装 Linux 内核版本在 4.4 及以上的版本。

步骤 2:更新系统软件包

打开终端并输入以下命令更新系统软件包:

sudo apt update
sudo apt upgrade

步骤 3:安装 NVIDIA 显卡驱动

如果你的系统尚未安装 NVIDIA 显卡驱动,可使用以下命令安装:

sudo ubuntu-drivers autoinstall

安装完成后,重启计算机以确保驱动程序正确加载。

步骤 4:下载 CUDA 工具包

前往CUDA ToolKit 官方网站下载相应版本的 CUDA Toolkit,的安装包(以 CUDA 12.1 为例)

https://p.v50.tools/images/2023/04/11/cuda-install.png

步骤 5:安装 CUDA Toolkit

你可以运行以下命令下载并安装 CUDA Toolkit:

wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin
sudo mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600
wget https://developer.download.nvidia.com/compute/cuda/12.1.0/local_installers/cuda-repo-ubuntu2004-12-1-local_12.1.0-530.30.02-1_amd64.deb
sudo dpkg -i cuda-repo-ubuntu2004-12-1-local_12.1.0-530.30.02-1_amd64.deb
sudo cp /var/cuda-repo-ubuntu2004-12-1-local/cuda-*-keyring.gpg /usr/share/keyrings/
sudo apt-get update
sudo apt-get -y install cuda

步骤 6:配置环境变量

为了确保系统能够正确识别 CUDA Toolkit 的安装位置,需要设置环境变量。打开~/.bashrc 文件,添加以下内容:

#打开~/.bashrc
sudo vim ~/.bashrc

#在文末添加下两行并保存关闭
export PATH=/usr/local/cuda-12.1/bin${PATH:+:${PATH}}
export LD_LIBRARY_PATH=/usr/local/cuda-12.1/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}

保存文件并运行以下命令使环境变量生效:

source ~/.bashrc

步骤 7:验证 CUDA 安装

运行以下命令验证 CUDA 是否已正确安装

nvcc --version

如果安装成功,你将看到类似于以下的输出,其中显示了 CUDA 编译器(nvcc)的版本信息:

nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2021 NVIDIA Corporation
Built on Tue_Sep_21_19:24:46_PDT_2021
Cuda compilation tools, release 12.1, VXX.X.X
Build cuda_12.1.r12.1/compiler.XX

安装 cuDNN 库(可选)

cuDNN 是一款深度学习框架的 GPU 加速库,支持 TensorFlow、PyTorch 等框架。要安装 cuDNN,请按照以下步骤操作:

https://p.v50.tools/images/2023/04/11/cuDNN-install.png

  1. 前往 NVIDIA 官方网站注册并登录,然后进入cuDNN 下载页面
  2. 选择与你安装的 CUDA 版本兼容的 cuDNN 版本,下载对应的压缩包。
  3. 解压缩下载的文件。假设文件解压缩到了~/Downloads/cudnn-local-repo-ubuntu2004-8.8.1.3_1.0-1_amd64.deb 目录。
  4. 在终端中运行以下命令安装 cuDNN 库,在置行以下命令之前,您必须将 X.Y 和 8.x.x.x 替换为您特定的 CUDA 和 cuDNN 版本。:
cd ~/Downloads/
sudo dpkg -i cudnn-local-repo-${OS}-8.x.x.x_1.0-1_amd64.deb

#导入GPG key
sudo cp /var/cudnn-local-repo-*/cudnn-local-*-keyring.gpg /usr/share/keyrings/

#刷新apt源
sudo apt-get update

#安装库
sudo apt-get install libcudnn8=8.x.x.x-1+cudaX.Y
sudo apt-get install libcudnn8-dev=8.x.x.x-1+cudaX.Y
sudo apt-get install libcudnn8-samples=8.x.x.x-1+cudaX.Y

总结

至此,你已经成功配置了 Ubuntu 下的 CUDA 环境。现在,你可以使用 GPU 进行深度学习和高性能计算了。在接下来的工作中,你可能还需要根据实际需求安装和配置深度学习框架,例如 TensorFlow 或 PyTorch。

🔲 ⭐

NgeNet论文理解


由于点云传统配准(ICP:迭代最近点算法)效果不佳,于是考虑使用深度学习的方法。 这里采用NgeNet

Neighborhood-aware Geometric Encoding Network 邻域感知几何编码网络

论文链接:https://arxiv.org/abs/2201.12094

Introduction

点云配准深度学习方法的分类

作者将其分为了两种

  1. end-to-end:将feature learning 和 transformation estimation 融合到了一个模型
    1. 其中有一些方法依赖相关性的建立来进行后续的Procrustes分析
    2. 而其他方法则更关注点云之间的全局特征
  2. feature-learning:更加关注learning of discriminative point feature(学习辨别性的点的特征),而transformation则是由pose estimators来估计的

提出网络

NgeNet利用多尺度结构明确地生成具有多种邻域大小的点状特征,并利用几何指导的编码模块来最大限度地利用几何信息。具体来说,设计了一个投票机制,为每个点选择一个合适的邻域大小,并拒绝在无法区分的表面上出现虚假的特征。

主要贡献

  • 多尺度结构与几何引导编码相结合,产生多层次的几何和语义信息编码的特征。
  • 多层次的一致性投票,为每个点选择适当的邻域并拒绝虚假的邻域。
  • 我们的方法中所提出的技术是与模型无关的,能够很容易地移植到其他骨干结构上并提高性能。

Preliminaries (引言)

点云配准问题的数学表达

arg 是变元(即自变量argument)的英文缩写。 arg min 就是使后面这个式子达到最小值时的变量的取值 arg max 就是使后面这个式子达到最大值时的变量的取值 例如 函数F(x,y): arg min F(x,y)就是指当F(x,y)取得最小值时,变量x,y的取值 arg max F(x,y)就是指当F(x,y)取得最大值时,变量x,y的取值

\[arg\ \underset{T}{\mathrm{min}}\frac{1}{|\sigma|}\sum_{(i, j)\in \sigma}||T (x_i ) − y_j ||_2\]

Cardinal Number(基数):集合论中刻画集合大小的数

邻域分析

在特征学习中常常用到encoder-decoder网络来提取特征; 模型的输入为\(X\in\mathbb{R}^3\) 维数从\(N\times 3\) -> $N C $意思是每个点输出C维的特征

有两种方式去影响领域的范围一个是依靠连续的卷积层,隐形的增加了领域的范围;另一个是在encoder-decoder网络中常常使用两倍大小的分层卷积层来模拟点云的down sample。

方法

网络

NgeNet的网络架构

可以很清楚的看到NgeNet是一个encoder-decoder网络 - encoder模块由:residual-style KPConv/strided KPConv层、instance norm层和Leaky ReLU层(k=0.1)组成

KPConv 是用于三维点云中的一种卷积方式

  • decoder模块由:decoder中的上采样块采用最近搜索来进行特征插值。 unary block由一个线性(MLP)层、一个实例范数层和一个 Leaky ReLU 层 (k=0.1) 组成,而last unary block仅由一个线性层(MLP)组成

Input是什么?

Input为the source point cloud \(X\) and its initial descriptor \(F_X\) , the target point cloud \(Y\) and its initial descriptor \(F_Y\)

  • 其中\(F_X\) and \(F_Y\) 都被init为全部为\(1\)的矩阵

组成部分

SIAMESE MULTI - SCALE BACKBONE

连体式多级骨干(什么鬼翻译

用途:用于处理输入的点云

如何工作?

  • Shared Encoder:可以在绿色的Encoder部分看到一共做了四次卷积;这样做是为了拓展领域特征。此时一共有四个输出,最后的输出得到Super points \(X'\)\(X'\)集合会在下文经常提到其中包括他的点\(x'_i \in X '\))和它的feature \(F^{en}_{X'}\)(我理解上标的en意思是end;最后一个输出);前三步输出的feature作为中间变量也被保存了下来,为了decoder去生成multi-scale的feature。这三个中间变量被记为\(F^1_{X}, F^2_{X}, F^3_{X}\)。这里需要注意的是,每个点特征的邻接点的感知范围从\(F^1_X\)延伸到\(F^3_{X}\) (最后一句话是KPConv的知识)

    • 最后Shared Encoder输出的是\(X' \in \mathbb{R}^{N' \times 3}\)\(F^{en}_{X'} \in \mathbb{R}^{N' \times D_{en} }\) ,加起来是应该是\((X', F^{en}_{X'}) \in \mathbb{R}^{N' \times (3+D_en)}\)有待考证
  • Parallel Decoder:上面说在decoder的时候需要用到我们刚才保存的\(F^1_{X}, F^2_{X}, F^3_{X}\),同时还有之后会介绍的\(F^{inter}_{X'}\),一共这四个输入。最后得到的output是关于\(X'\)的高、中、低级别的feature

  • 现在我们定义一个函数(后面要用) \[\phi (F^1 , F^2 , g) = cat[Up(g(F^2 )), F^1 ]\] 其中\(F^1\)\(F^2\)是输入的feature,\(g\)是一个代表MLP或者Identity Layer的函数, \(cat\)表示concatenation(拼接矩阵),\(Up\)是nearest upsampling

  • 现在可以表示 \(F^l_X , F^m_X\)\(F^h_X\) 的计算方式

\[\begin{split}F^l_X &= MLP_2(\phi(F^1_X, F^2_X, MLP_1), \\F^m_X &= MLP_5(\phi(F^1_X, \phi (F^2_X, F^3_X, MLP_3), MLP_4), \\F^h_X &= MLP_8(\phi(F^1_X, \phi (F^2_X, \phi (F^3_X, F^{inter}_X, Identity), MLP_6), MLP_7 ).\end{split}\]

  • 同时给出overlap(重复性)分数\(O_X\)和saliency(显著性)分数\(S_X\)

GEOMETRIC - GUIDED ENCODING

几何学引导式编码

GGE模块是一个 一个输入一个输出的模块

GGE模块

用途:GGE将super points和潜在的feature(也就是Shared Encoder输出的\((X', F^{en}_{X'}) \in \mathbb{R}^{N' \times (3 + D_{en})}\))作为输入;然后输出几何增强后的feature

如何工作?

  • Normal vectors smoothing:这里计算Normal vector的方式比较特别。这一步的目的是去获得super points的Normal vector,但是他没有直接去用open3d的库直接计算。而是将super points的点映射回原来的全部点集中。再通过全部点集中,super points周围点的normal vectors去平均得到super points的normal vector。

\[N_{X_i^{'}}=\frac{1}{|J_i^N|}\sum_{x_j \in J_i^N}{N_{X_j}}\]

公式里面\(J_i^N = \{x_j| \left|| x_j-x'_i \right|| < r^N \}\) 其中\(x_j\in X\)\(r^N\)\(x'_i\)的邻域。

稍微解释一下公式:

\(N_{X'_i}\)是我们想要的\(X'\)的normal vector的集合

\(J^N_i\)代表得是点\(x_i\)邻域内的点

  • Geometric encoding:这里我们想要的是每个点的几何特征,记为\(G_{x'_i}\),利用PPF(Point Pair feature)去计算几何特征

\[\begin{equation}\begin{split}PPF(x'_i, x'_j) &= (\angle(x'_j-x'_i, N_{x'_i}), \angle(x'_j-x'_i, N_{x'_j}), \angle(N_{x'_i}, N_{x'_j}), \left|| x'_i - x'_j\right||_2), \\G_{x'_j} &= f_1(x'_i, x'_j-x'_i, PPF(x'_i, x'_j)), \\G_{x'_i} &= max\{ G_{x'_j}|x'_j \in J^G_i \}.\end{split}\end{equation}\]

公式里面\(\angle(\cdot, \cdot)\in(0, \pi)\) 代表两个向量之间的夹角, \(f_1\)是pointnet里的一个函数, \(J^G_i = \{x'_j \left|| x'_j-x'_i\right||<r^G\}\)\(r^G\)\(x'_i\)邻域的半径,\(max(\cdot)\)意思是channel-wise max-pooling

这个公式也解释一下:

PPF我这里理解的就是一个四维向量包含了(按照NgeNet的顺序),一个法向量和{两个法向量之间的向量d}的夹角,另一个法向量和{两个法向量之间的向量d}的夹角,两个法向量的夹角,两点之间的距离。对应下图的\((F_2, F_3, F_4, F_1)\)

原论文的图片

\(f_1\)函数:暂时不清楚什么意思 \(G_{x'_i}\):找到\(G_{x'_j}\)中最大的;至于channel-wise再点云中代表什么几何含义,暂时不清楚

  • Semantic encoding:需要更新

损失函数

这里我们将损失函数从两个方面来看:特征损失 和 重叠与显着性损失

特征损失

这里说的特征损失,就是我们之前提到的\(F^h_X, F^m_X, F^l_X, F^h_Y, F^m_Y, F^l_Y\) 两个点云三个类别的特征。

重叠与显着性损失

投票机制

为什么要投票

不同级别的特征

在Parallel Decoder我们强调了,在每一次计算特征的时候,我们都保存下来了那些中间变量;他们是\(F^l_X\)\(F^m_X\) ,最后的输出是\(F^h_X\)

此时它们三个分别可以决定哪些source的特征点和target的特征点可以一一对应。那么每一个特征点都会存在三种方案。所以需要通过投票决定使用哪一种。

如何投票

投票算法
🔲 ⭐

计算机视觉中的Transformer续

上一篇文章《计算机视觉中的Transformer》讲了计算机视觉中的Transformer结构[1],还有非常受欢迎的Vision Transformer(ViT)[2]。本篇文章将补上上一篇掠过的《Attention Augmented Convolutional Networks》[3]和《End-to-End Object Detection with Transformers》[4],同时也会介绍一下DeiT (Data-effieciency Image Transformer)[5]

Self-Attention回顾

Transformer的核心是Self-Attention。Self-Attention是基于特征向量对序列上token成对关系的表征学习(Representation Learning)。

self-attention
Fig. 1. Self Attention.

计算方式大致如下:

  • 序列: $X\in R^{n\times d}$
  • Query向量: $Q$有相对应的可学习权重$W^Q\in R^{n\times dq}$
  • Key向量: $K$也有相对应的可学习权重$W^K\in R^{n\times dk}$
  • Value向量: $V$也有相对应的可学习权重$W^V\in R^{n\times dv}$
  • $Q=XW^Q, K=XW^K, V=XW^V$
  • Self-Attention层: $Z=softmax(\frac{QK^T}{\sqrt{d_q}})V$
  • 若是Masked Self-Attention层,则需要增加一层mask: $softmax(\frac{QK^T}{\sqrt{d_q}}\circ M)$

self-attention-operation
Fig. 2. Self Attention运算过程. Adapted from [1]

这里展示的是一个简单的Self-Attention计算方式,对于[1]同时提出的Multi-Head Self-Attention,可以将上述过程并行的执行多次来模拟不同的head。

在2021年,计算机视觉领域中的Transformer和Self-Attentio的相关技术已经发展了很多。我们可以使用以下这张图来理解今天的Self-Attention相关技术的不同类型。
taxonomy-self-attention
Fig. 3. Self Attention不同类型. Adapted from [6]

在上图中能看到不同的Attention类型,比如Local Attention, Global Attention, Vectorized Attention。下图介绍了这些类型的大致计算流程。

self-attention-overview
Fig. 4. Self Attention的不同类型. Adapted from [6]

用Attention增强卷积

从之前我们可以了解到,Self-Attention可以很好的找到距离较远的token之间的关系,而普通的卷积层只能计算非常有限的范围。如果我们能够将这些距离较远的token之间的关系计算出来,那么就可以使用Self-Attention来弥补卷积层的这个缺陷,对图像分析是有帮助的。而且卷积层是等变的,在不同区域的卷积用的是同一个参数。所以在2019年的时候,这篇文章的作者看到Self-Attention已经被广泛运用于NLP领域,所以就想到了用Self-Attention来增强卷积,并且使用基于相对位置的Positional Encoding用于解决上述说的等变问题[3]

Flatten和Attention层

先介绍会在这个部分中使用的一些数学符号:

  • $H, W, F_in$是指特征图中高度、宽度、输入feature map的数量
  • $N_h, d_v, d_k$是指head的数量,value和key的维度。其中$N_h$是可以整除$d_v$和$d_k$的。
  • $d^h_v, d^h_k$是指每一个head中value和key的维度。

attention-augmented-convolution
Fig. 5. Attention Augmented Convolution的计算过程. Adapted from [3]

第一步是需要将输入的特征图进行flatten,从$(H,W,F_in)$变成一个新矩阵$X\in \mathbb{R}^{HW\times F_{in}}$。然后把它放进标准的Multi-head Attention(MHA)层中,于是输出它的输出则是,
$$O_h=Softmax(\frac{(XW_q)(XW_k)^T}{\sqrt{d^h_k}})(XW_v)$$

Positional Encoding

在这篇文章,作者使用了一个基于像素的相对位置的Positional Encoding,专门用于图像分析。其实这个相对位置的Positional Encoding之前已经提出,具体的可以参考这篇[7]

它的计算方式是

$$l_{i,j}=\frac{q_i^T}{\sqrt{d_k^h}}(k_j+r^W_{j_x-i_x}+r^H_{j_y-i_y})$$

其中$r$是Positional Encoding,$i$是当前token所代表的像素,$j$是计算Self-Attention时的目标像素,而$x$和$y$则是像素的位置。将这个计算向量化后,

$$O_h=Softmax(\frac{QK^T+S_H^{rel}+S_W^{rel}}{\sqrt{d^h_k}})V$$

这篇作者也提到,根据他们的实验,最好的效果是同时使用传统卷积层和Attention层的输出,所以以上的结果要通过一个简单的拼接层来获得。

$$AAConv(X)=Concat[Conv(X),MHA(X)]$$

实验结果

首先是每篇论文都会提到的自己的方法比别人强。

aa-result
Fig. 6. Attention Augmented用于分类的实验结果. Adapted from [3]

可见,用于一些传统的CNN模型,用Attention增强卷积的方法可以得到更好的结果。对于COCO数据集的对象检测也是一样的,这里就不再赘述了。

不过其中最有趣的还是Positional Encoding的对比。

pos-enc-result
Fig. 7. Positional Encoding是否使用的对比结果. Adapted from [3]

能看到这个Positional Encoding真的是很有用,所以在Transformer中的Self-Attention层中基本人人都会用它。

E2E的Transformer对象检测

在2020年的时候,一篇论文[4]提出了一个E2E的Transformer对象检测模型Detection Transformer (DETR),它非常有开创性的使用Transformer结构实现了一个完全端到端的训练方式。这有什么好处呢?首先之前的对象检测模型很多都是需要Proposal,Anchor,或者Window之类的容易出错,而且还需要一些人工处理,比如说非最大值抑制等等。这些东西在一定程度上会影响模型的性能。如果能使用E2E的模式避免人工处理的情况下训练,那就能解决这个问题。

首先来看一下它的结构。

detr
Fig. 8. DETR结构. Adapted from [4]

这个结构是由一个骨干网络,Positional Encoding,Transformer,以及一个FFN预测头组成的。让我们一个一个看。

骨干特征提取器

首先是第一步的backbone,这一部分在原文中是一个CNN的特征提取器,需要从图像中提取出高价值的特征图。在原文中对于一个图像为$x_{img}\in \mathbb{R}^{3\times H_0 \times W_0}$,在骨干网络后将会变成一个特征图$f\in \mathbb{R}^{C\times H\times W}$。他们设定的值是$C=2048$ $H,W=\frac{H_0}{32},\frac{W_0}{32}$ 。

Transformer部分

通过骨干网络得到的特征图会通过一个1x1卷积压缩通道数,得到$z_0\in\mathbb{R}^{d\times H\times W}$。因为这个Transformer编码器希望得到一个序列作为输入,所以不能用一个三维的矩阵,需要压平成二维。这个特征图将会被flatten到$(d\times HW)$。对于每一层Transformer编码器,都有一个Self-Attention层和FFN,就像原版Transformer一样。作者还特地说明了,对于每一层,都添加了一个固定的不可训练的Positional Encoding加到输入中去。对于Self-Attention层和Transformer编码器部分相信大家都很熟悉了,但是这个网络还使用了Transformer解码器部分,这需要好好看看。

detr-transformer
Fig. 9. DETR中的Transformer部分. Adapted from [4]

这里我们可以看到,它并没使用原版Transformer中的Masked Multi-Head Self-Attention层,可能是因为原版的是对于时间序列的预测所以需要遮盖未来时间的序列元素,但是这里是图像分析,则不需要这些。然后是对于编码器的Attention层,和解码器的第二个Attention层,都使用了Positional Encoding,而且是每一层都会使用。

这里的Object queries其实是一个可学习的参数,原文中设定的长度是$N=100$。剩下的都是一些相加融合,根据这张图应该是很容易理解的。

FFN预测头

在解码器的输出得到嵌入序列之后,对于序列中的每一个元素都通过两个FFN网络,一个用于预测类型,一个用于预测Box。

这些FFN在原文中使用的是一个3层MLP和ReLU。对于一个91个类的多分类问题,这里的类型预测FFN会输出一个92长度的向量,多出来的一个代表”没有对象($\phi$)”。这个预测Box会被编码成中心坐标(x, y)和宽度高度(w, h),也就是长度为4的向量。由于这个预测框的数量等于Object Queriesd的数量$N$且是固定且有限的,所以必须要远大于实际可能的预测框数量。

损失函数

因为预测出的是长度为$N$的一系列无序的box,而ground truth是一个长度远小于$N$的序列。所以在计算损失时,需要将预测的box和ground truth进行匹配。这里需要搜索到一个有最小损失值的box匹配,然后计算这个最小损失。这个匹配$\sigma$是:

$$\hat{\sigma}=\mathop{\arg\min}_{\sigma\in\mathfrak{S}_N}\sum^N_i \mathcal{L}_{match}(y_i,\hat{y}_{\sigma(i)})$$

对于这个问题,使用Hungarian算法可以有效的解决,找到ground truth和预测结果的最优匹配。这里的$\mathcal{L}_{match}$是一个二分图匹配的损失函数,其中$y_i$是ground truth的第i个box,$\hat{y}_{\sigma(i)}$是预测的第i个box。对于第i个预测$\sigma(i)$,定义类别$c_i$的概率是$\hat{p}_{\sigma(i)}(c_i)$,预测的box是$\hat{b}_{\sigma(i)}$。定义这个损失函数为:

$$\mathcal{L}_{match}=-\mathbb{1}_{\{c_i\neq\emptyset\}}\hat{p}_{\sigma(i)}(C_i)+\mathbb{1}_{\{c_i\neq\emptyset\}}\mathcal{L}_{box}(b_i,\hat{b}_{\sigma(i)})$$

与上面的等式结合,可以得到Hungarian损失函数,

$$\mathcal{L}_{Hungarian}(y,\hat{y})=\sum^N_{i=1}[-log\hat{p}_{\hat{\sigma}(i)}(C_i)+\mathbb{1}_{\{c_i\neq\emptyset\}}\mathcal{L}_{box}(b_i,\hat{b}_{\hat{\sigma}}(i))]$$

其中的$\hat{\sigma}$是上面找到的最佳匹配方式。

对于box损失,这里使用GIOU损失函数[8]

再对L1损失和IOU损失进行线性组合,得到最终的损失函数,

$$\mathcal{L}=\lambda_{iou}\mathcal{L}_{iou}(b_i,\hat{b}_{\sigma(i)})+\lambda_{L1}||b_i-\hat{b}_{\sigma(i)}||_1$$

其中的$\lambda_{iou}$和$\lambda_{L1}$是超参数。

然而除此之外,他们还使用了解码器辅助损失(Auxiliary decoding loss)。添加到每一个解码器层后面,预测class和box并计算上述损失$\mathcal{L}$。

推断代码

作者们另外提供了一个基于PyTorch的用于推断的代码,放在这里有助于理解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import torch
from torch import nn
from torchvision import resnet50

class DETR(nn.Module):

def __init__(self, num_classes, hidden_dim, nheads, num_encoder_layers, num_decoder_layers):
super().__init__()
# We take only convolutional layers from ResNet-50 model
self.backbone = nn.Sequential(*list(resnet50(pretrained=True).children())[:-2])
self.conv = nn.Conv2d(2048, hidden_dim, 1)
self.transformer = Transformer(hidden_dim, nheads, num_encoder_layers, num_decoder_layers)
self.linear_class = nn.Linear(hidden_dim, num_classes + 1)
self.linear_bbox = nn.Linear(hidden_dim, 4)
self.query_pos = nn.Parameter(torch.randn(100, hidden_dim))
self.row_embed = nn.Parameter(torch.randn(50, hidden_dim // 2))
self.col_embed = nn.Parameter(torch.randn(50, hidden_dim // 2))

def forward(self, inputs):
x = self.backbone(inputs)
h = self.conv(x)
H, W = h.shape[-2:]
pos = torch.cat([
self.col_embed[:W].unsqueeze(0).repeat(H, 1, 1),
self.row_embed[:H].unsqueeze(1).repeat(1, W, 1)
], dim=-1).flatten(0, 1).unsqueeze(1)
h = self.transformer(pos + h.flatten(2).permute(2, 0, 1), self.query_pos.unsqueeze(1))
return self.linear_class(h), self.linear_bbox(h).sigmoid()

detr = DETR(num_classes=91, hidden_dim=256, nheads=8, num_encoder_layers=6,
num_decoder_layers=6
)
detr.eval()
inputs = torch.randn(1, 3, 800, 1200)
logits, bboxes = detr(inputs)

Listing 1: DETR PyTorch推断代码. Adapted from [4]

实验结果

他们使用了COCO数据集用于测试这个方法。

detr-result
Fig. 10. DETR实验结果. Adapted from [4]

一言以蔽之,相比于FasterRCNN,DETR更好。

然后他们也测试了一下编码器层的数量,解码器层的数量,辅助损失,FFN,Positional Encoding的重要性,发现都很重要,都是需要的。

slots-vis
Fig. 11. $N$个Object Queries的预测可视化. Adapted from [4]

通过上图可以看出,这些预测插槽也已经学习到了box的预测模式,每一个插槽是专注于其中的少数几种box的样式。

detr2
Fig. 12. DETR用于图像分割. Adapted from [4]

如上图所示,DETR架构也可以用于图像分割,并且也在实验中取得了比其他方法更好的结果。

Transformer和知识蒸馏

在2020年底,ViT发布两个月后,这篇论文《Training data-efficient image transformers & distillation through attention》[5]介绍了他们的新方法Data-efficient image Transformers (DeiT),这是一个用少量数据和时间训练,就可以达到SOTA水平的方法。对于一个差不多参数量的ViT,需要一个Cloud TPU v3训练83天。而对于DeiT,只需要4个GPU训练3天,可见效率提升很大。

此外,之前的ViT需要在谷歌未公开的数据集JFT-300M用3亿张图片进行训练,而这个只需要在公开的ImageNet上训练就已经能达到SOTA的水平,所以这个模型是data-efficient的。

它主要的方法是通过知识蒸馏(knowledge distillation)的方法,并且做了不少实验,对比了不同的实验设定有怎样的效果。

它的基本结构如下图所示。

deit
Fig. 13. DeiT架构. Adapted from [5]

知识蒸馏

知识蒸馏是一种知识训练方法,其中知识是由一个预训练的教师模型和一个需要训练的学生模型组成。知识蒸馏除了能有效的压缩模型,还能有效的提升学生模型的性能。

Fig. 13可以看出,相比于之前的ViT,它多了一个知识蒸馏的部分。首先是输入部分,除了左下角的class token之外,还增加了一个右下角的distillation token。这个distillation token经过Transformer会输出一个值用于计算蒸馏损失。

蒸馏损失

关于蒸馏损失,这篇文章给出了两种方法,分别是硬蒸馏和软蒸馏。

$$\mathcal{L}_{dis}^{hard}=\frac{1}{2}\mathcal{L}_{CE}(\psi(Z_s),y)+\frac{1}{2}\mathcal{L}_{CE}(\psi(Z_s),y_t)$$

$$\mathcal{L}_{dis}^{soft}=(1-\lambda)\mathcal{L}_{CE}(\psi(Z_s),y)+\lambda\tau^2KL(\psi(Z_s/\tau),\psi(Z_t/\tau))$$

其中,$Z_t$是教师模型的logits输出,$Z_s$是学生模型的logits输出,$y_t$是老师模型的label,$y$是ground truth。$\tau$是超参数蒸馏温度,$\lambda$是蒸馏损失和交叉熵损失的比例。另外,$\mathcal{L}_{CE}$指的是交叉熵损失,$\psi()$指的是sigmoid函数。

根据作者的实验结果,硬蒸馏的训练效果更好

教师模型的选择

teacher-model
Fig. 14. 教师模型的实验结果对比. Adapted from [5]

作者对不同的教师模型进行了横向对比,根据上图的实验结果,可以看出使用CNN的效果要比Transformer更好。

其他超参数

作者对于训练用的很多参数都做了实验对比测试,其中包括学习率,参数初始化方法,weight decay,dropout,还有数据增强,优化器和正则化等等。对于详细的内容请参考原文,因为仅仅是实验结果而已,这里就不多做展示了。

这篇文章给Transformer使用知识蒸馏提供了很多意见和想法,如果在未来需要用一些比较高效的方法来训练Transformer,可以参考这篇文章。

参考文献

  • [1] A. Vaswani et al., “Attention is all you need,” in Proceedings of the 31st International Conference on Neural Information Processing Systems, Red Hook, NY, USA, Dec. 2017, pp. 6000–6010.
  • [2] A. Dosovitskiy et al., “An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale,” arXiv:2010.11929 [cs], Oct. 2020, [Online]. Available: http://arxiv.org/abs/2010.11929.
  • [3] I. Bello, B. Zoph, A. Vaswani, J. Shlens, and Q. V. Le, “Attention Augmented Convolutional Networks,” in Proceedings of the IEEE/CVF International Conference on Computer Vision, 2019, pp. 3286–3295, [Online]. Available: https://openaccess.thecvf.com/content_ICCV_2019/html/Bello_Attention_Augmented_Convolutional_Networks_ICCV_2019_paper.html.
  • [4] N. Carion, F. Massa, G. Synnaeve, N. Usunier, A. Kirillov, and S. Zagoruyko, “End-to-End Object Detection with Transformers,” in Computer Vision – ECCV 2020, Cham, 2020, pp. 213–229, doi: 10.1007/978-3-030-58452-8_13.
  • [5] H. Touvron, M. Cord, M. Douze, F. Massa, A. Sablayrolles, and H. Jegou, “Training data-efficient image transformers & distillation through attention,” in International Conference on Machine Learning, Jul. 2021, pp. 10347–10357. Accessed: Jul. 22, 2021. [Online]. Available: http://proceedings.mlr.press/v139/touvron21a.html
  • [6] S. Khan, M. Naseer, M. Hayat, S. W. Zamir, F. S. Khan, and M. Shah, “Transformers in Vision: A Survey,” arXiv:2101.01169 [cs], Feb. 2021, Accessed: Apr. 23, 2021. [Online]. Available: http://arxiv.org/abs/2101.01169
  • [7] P. Shaw, J. Uszkoreit, and A. Vaswani, “Self-Attention with Relative Position Representations,” arXiv:1803.02155 [cs], Apr. 2018, Accessed: Jul. 25, 2021. [Online]. Available: http://arxiv.org/abs/1803.02155
  • [8] H. Rezatofighi, N. Tsoi, J. Gwak, A. Sadeghian, I. Reid, and S. Savarese, “Generalized Intersection Over Union: A Metric and a Loss for Bounding Box Regression,” in Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition, 2019, pp. 658–666. Accessed: Jul. 26, 2021. [Online]. Available: https://openaccess.thecvf.com/content_CVPR_2019/html/Rezatofighi_Generalized_Intersection_Over_Union_A_Metric_and_a_Loss_for_CVPR_2019_paper.html
🔲 ⭐

计算机视觉中的Transformer

深度学习中最一开始的Transformer是2017年推出的,非常强力[1]。可能当时作者觉得这个东西很强,所以才会赋予”变形金刚”的名字吧。而后来,Transformer也广泛的推广到了计算机视觉(CV)领域,从2020年开始,就有对Transformer在CV中的大量新研究发表。

本文主要会讲最初的Transformer,Vision Transformer(ViT)和Multi-scale Vision Transformer(MViT)。

最初的Transformer

解决并行问题

最初的Transformer是来源于这篇,”Attention is all you need”,用于自然语言处理(NLP)的机器翻译任务的。以前的RNN(包括LSTM[2], GRU[3])层计算并不能并行,因为一个序列中的某一个元素的计算是要基于别的元素的。如下图所示。

rnn-layer
Fig. 1. RNN layer. Adapted from [4]

其中$a^1$到$a^4$都是一个序列中的token,RNN层可以看到一个序列中的全部信息,包括位置信息。但是这里每一个token的计算需要其他token的计算结果,所以无法做到并行化提高效率。

cnn-layer
Fig. 2. Convolutional layer. Adapted from [4]

如上图所示, 使用卷积层[5]虽然可以并行计算,但是覆盖面积受到卷积核(kernel)的限制,无法在距离比较远的token中提取特征。

stacked-cnn-layers
Fig. 3. Stacked convolutional layer. Adapted from [4]

如上图所示,很多人会通过将卷积层堆叠起来以达到提取更多特征的目的,但是这个覆盖范围其实依然并不是很宽,而且也需要更多的计算。

我们需要的是一个有长时记忆,并且可以并行处理的结构。所以这篇论文提出了Self-attention机制和Multi-Head Attention Layer。

calculate-k-q
Fig. 4. Calculation of $K^i$ and $Q^i$ in self-attention layer. Adapted from [4]

首先,我们有一个输入序列,从$x^1$到$x^4$。在Embedding之后,会将每一个token转换成1-D vector,$a^1$到$a^4$。使用3个线性层分别对应Q,K,V的权重,则可以把$z^i$转换成Q (Query),K (Key),V (Value)的向量。这个计算方式如下所示。
$$
\begin{split}
q^i &= W^qa^i \\
k^i &= W^ka^i \\
v^i &= W^va^i
\end{split}
$$
我们以第一个token作为例子,需要用$q^1$与所有token的$k$相乘,从而求得$\alpha_{1,1}$到$\alpha_{1,4}$。之后,通过一个softmax进行标准化使得它们的和为1,得到$\hat{\alpha}_{1,1}$到$\hat{\alpha}_{1,4}$。

calculate-bi
Fig. 5. Calculation of $b^i$ in self-attention layer. Adapted from [4]

然后,再对计算出来的$\hat{\alpha}_{1,1}$到$\hat{\alpha}_{1,4}$和$v$相乘求和。以第一个token为例,它的attention层输出是,
$$
b^1 = \sum_i\hat{\alpha}_{1,i}v^i
$$

重复同样的步骤,则可以得到$b_1$到$b_4$。以上的步骤看起来计算相当的复杂,但是其实可以通过几个比较简单的矩阵运算即可完成,所以它是可以很容易通过GPU进行并行计算的。

matrix-multiplications
Fig. 6. Matrix multiplication form in self-attention layer. Adapted from [4]

左上角的$O$代表output,$I$代表input。而这个$I$则是将所有的输入$a_i$叠起来变成一个2D矩阵。而以上的全部需要一个一个迭代计算的过程都可以用矩阵乘法的方式实现,总的计算其实很方便。正因为这个容易进行并行计算,所以在运算速度上是快于RNN的。

Transformer结构

scaled-dot-product-attention
Fig. 7. Scaled dot product attention. Adapted from [1]

$$Attention(Q,K,V)=softmax(\frac{QK^T}{\sqrt{d_K}})V$$

如上所示[1],这个过程被称为Scaled Dot-Product Attention。你会注意到这个公式里除以一个$\sqrt{d_K}$。根据原文的说明,这个的目的是为了把值重新缩放回 Mean = 0, Variance = 1 的状态。

multi-head-attention
Fig. 8. Multi-head attention. Adapted from [4]

除此之外,他们还提出了一个Multi-Head Attention Layer,相比于普通的attention层,这个多头attention层有多个attention层互相并行。最后把多个并行的attention层拼接,再通过一个全连接层进行映射,把维度保持在和输入相同的状态。

transformer
Fig. 9. Transformer structure. Adapted from [1]

如上图所示,整个Transformer是一个encoder-decoder结构。如果这个Transformer的任务是把英文翻译成中文,那在encoder的inputs这里输入中文句子,在decoder的输入端输入英文句子,decoder的输出则是概率。从encoder开始,输入的token序列会先送入embedding层转换成向量,然后再和positional encoding相加。因为在attention层中输入token并不会知道其中的位置信息,所以需要加一个positional encoding。因为矩阵相加可以视为拼接的一种特殊情况,所以通过embedding和positional encoding相加,attention层可以同时获取两者的信息,提取的特征更有效率。这个positional encoding可以是自己手动设定的,也可以是通过学习的。在这篇文章下用的是手动设定的。相加之后,会有4条路线,1条是类似于ResNet[6]的恒等连接,而另外3条则是通过对应的全连接层得到Q,K,V,再输入进attention层。在结束了multi-head attention层的计算之后,接下来是一个Add & Norm层,这个层的过程就是将attention层的输入和输出相加,并且做一个layer normalization(LN)[7]

layer-normalization
Fig. 10. Layer normalization. Adapted from [4]

如上图所示[4],和常用的batch normalization(BN)[8]相比,主要是标准化的维度不同。LN是在一个输入中跨通道的标准化,BN是在一个batch中跨数据但是在同一个通道下进行标准化。在sequence数据中,一般使用LN而不是BN。

然后是decoder部分,这里的decoder的输入,也就是机器翻译的结果是需要右移一位的(shifted right),因为第一位是<BOS>标签,作为一个句子的开头。对比encoder和decoder,主要区别在于decoder的第一层是一个Masked Multi-Head Attention。因为对于一个基于时间序列的预测来说,当然是不能通过未来的信息去预测的,所以在这个Masked Multi-Head Attention层中,所有的token输入只能看到前面的信息,而后面的信息都会被隐藏。

在这个Masked Multi-Head Attention层之后,会有一个普通的Multi-Head Attention,但是其中的Q和K是来源于encoder计算的结果,只有V是来自于上一层的输出。个人理解是Q和K可以寻找不同token在这个sequence之间的相关性,所以encoder的输出要拿来给decoder使用。

transformer-inference
Fig. 11. Transformer inference. Adapted from [4]

如上图所示[4],在预测的时候,因为不知道翻译的结果,所以只能一个一个预测,将第一个预测出的词放到这个序列的第二个输入才能依次预测出整个句子。在训练的时候因为知道了全部内容,所以可以并行,但是在预测中是不行的。

尝试把Transformer用于CV

在Transformer发布之后,有很多研究在尝试把Transformer结果用于CV。

attention-augmented-convolutional-networks
Fig. 12. Attention augmented convolutional network. Adapted from [9]

比如这一篇[9],同时使用传统的卷积和新的Self-Attention机制用于计算机视觉相关的任务。

object-detection-transformer
Fig. 13. Object detection transformer. Adapted from [10]

而这一篇[10],则仅仅用CNN替代原始Transformer中的Embedding过程,剩下的都与原版[1]很像。同样是完整的Transformer encoder和decoder,还有positional encoding,最后生成的结果也是一个个box用于对象检测(object detection)。这个过程已经和原版很像了。

关于这两篇的详解,已经在续篇中详细介绍。

Vision Transformer

之前的研究很少有讲Transformer直接用在CV上的,而且用上了速度也很慢。在2020年年底,有一篇论文,”An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale”,提出了Vision Transformer (ViT)[11],提供了另一种方法让本来用于NLP的Transformer可以直接用在CV上。在ViT中,每一个Transformer的token其实是一个图片的patch,这也是标题这么起的原因。在这篇论文中,这个ViT主要是用于最基础的图像分类任务。

vision-transformer
Fig. 14. Vision transformer. Adapted from [11]

具体步骤

一开始我们有一个图片$x$,高度$H$,宽度$W$,通道数$C$。对于RGB图像来说$C=3$。
$$x\in H\times W\times C$$

正如之前所说,我们先需要讲这个图片分成一块一块patch,然后将一个patch中的所有数值全部暴力的压扁到一维向量。假设patch都是正方形,边长为$P$,一个图片中的patch数量为$N$。则,
$$x_p\in N \times (P^{2}C)$$
其中,
$$N=\frac{HW}{P^2}$$
所以我们是将一个patch本来为三维矩阵$(P\times P \times C)$直接摊平为一维向量,长度为$P^{2}C$。而因为有$N$个patch,所以最后的结果是$N \times (P^{2}C)$的二维矩阵。这个形状是符合Transformer输入的。

然而$P^{2}C$的长度可能太长了,于是我们可以使用一个线性映射将维度降低到$N\times D$,其中$D$是新的patch向量的长度。把降维之后的矩阵记为$z_p$。
$$z_p\in N\times D$$

然后,我们需要增加一个可训练的token,$z_{class}$,放到整个$Z$的第一位,并且加上一个可训练的positional encoding。
$$Z=[z_{class},z_p^1,z_p^2,z_p^3,\cdots,z_p^N]+E_{pos}$$
由这些新的向量组成的矩阵加上positional encoding $E_{pos}$,得到的结果的矩阵记为$Z$。

这些东西就可以直接放进一个Transformer encoder,得到的结果也是一个sequence,但是只取第一个,也就是$z_{class}$对应的输出。将这个向量放入一个MLP用于分类,得到分类结果$\hat{y}$,与label $y$一起计算loss并反向传播训练整个ViT。

Class Token

根据原文,这个是从BERT[12]的结果中拿过来的,因为使用一个可训练的token,会比使用别的token的结果用于分类更加公平,因为不会受到原先包含信息的影响。

bert
Fig. 15. BERT. Adapted from [12]

Positional Encoding

positional-encoding
Fig. 16. Positional encoding in ViT. Adapted from [11]

然后是关于positional encoding的。这张图展示了positional encoding的相似度,越亮说明越相似。我们可以看到,对于每一个patch,在相似行和列的patch的相似度是较高的,而那些距离比较远的相似度则较低。这说明一个可训练的positional encoding是可以学到其中的位置关系的。

attention-distance
Fig. 17. Attention distance. Adapted from [11]

这张图展示了attention距离和网络深度的关系。x轴是网络深度,y轴是平均attention的patch之间的距离,不同的点代表不同的head找到的attention。很显然,在网络很浅的时候,attention层依然能找到距离较远的关系。如果这是一个CNN网络,那这个结果就应该会分布在这张图中一堆散点的下边缘。所以不用特别深的网络,ViT依然能学到这张图的全局特征。

Multiscale Vision Transformer

在之前的ViT[11]中,实际上每一个attention层的输入输出维度都是一样的,所以attention层只是在一个scale上进行检测。这篇2021年的论文提出了Multiscale Vision Transformer (MViT)[13]。大家都知道,在CNN中经过了数层卷积层之后会有一个降采样层降低特征图的长宽,这样之后的卷积层将能提取到不同scale的特征。这篇论文想通过同样的方式来把这个multi-scale的想法用在ViT上。

multiscale-vision-transformer
Fig. 18. Multiscale vision transformer. Adapted from [13]

如上图所示[13],他们提出了Multi-Head Pooling Attention (MHPA)层。很显然,最大的区别就在于对于每一条路上都加了一个pooling层。在这些pooling层之后,那些向量的长度就会降低,这样后面的attention层就能检测到不同scale的特征了。

mvit-structures
Fig. 19. MViT structures. Adapted from [13]

在这篇文章里,他们提出两个MViT的结构,分别是MViT-B和MViT-S,用于视频分析的。他们把一整个网络分成了多个stage。在第一个stage中是读取数据,因为视频是用3D矩阵表示,切分patch也是3D,所以patch在这里被成为cube。然后在后面的stage中,cube的长度和宽度都不断降低,而通道数则不断增加。在最终的实验结果中,MViT的表现要优于之前的ViT模型,而且参数数量也更少了,运行速度也更快了。

推荐一个GitHub Repository

这里推荐一个GitHub repo,叫Awesome Visual-Transformer,里面收录了许多用于CV的Transformer论文和官方实现的code链接[14]
https://github.com/dk-liang/Awesome-Visual-Transformer

参考文献

  • [1] A. Vaswani et al., “Attention is all you need,” in Proceedings of the 31st International Conference on Neural Information Processing Systems, Red Hook, NY, USA, Dec. 2017, pp. 6000–6010.
  • [2] S. Hochreiter and J. Schmidhuber, “Long Short-Term Memory,” Neural Computation, vol. 9, no. 8, pp. 1735–1780, Nov. 1997, doi: 10.1162/neco.1997.9.8.1735.
  • [3] K. Cho et al., “Learning Phrase Representations using RNN Encoder-Decoder for Statistical Machine Translation,” arXiv:1406.1078 [cs, stat], 2014.
  • [4] "Transformer & BERT", Speech.ee.ntu.edu.tw, 2021.
  • [5] Y. Lecun, L. Bottou, Y. Bengio, and P. Haffner, ‘Gradient-based learning applied to document recognition’, Proceedings of the IEEE, vol. 86, no. 11, pp. 2278–2324, Nov. 1998, doi: 10.1109/5.726791.
  • [6] K. He, X. Zhang, S. Ren, and J. Sun, “Deep Residual Learning for Image Recognition,” in Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition, 2016, pp. 770–778.
  • [7] J. L. Ba, J. R. Kiros, and G. E. Hinton, “Layer Normalization,” arXiv:1607.06450 [cs, stat], 2016.
  • [8] S. Ioffe and C. Szegedy, “Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift,” in International Conference on Machine Learning, Jun. 2015, pp. 448–456.
  • [9] I. Bello, B. Zoph, A. Vaswani, J. Shlens, and Q. V. Le, “Attention Augmented Convolutional Networks,” in Proceedings of the IEEE/CVF International Conference on Computer Vision, 2019, pp. 3286–3295.
  • [10] N. Carion, F. Massa, G. Synnaeve, N. Usunier, A. Kirillov, and S. Zagoruyko, “End-to-End Object Detection with Transformers,” in Computer Vision – ECCV 2020, Cham, 2020, pp. 213–229, doi: 10.1007/978-3-030-58452-8_13.
  • [11] A. Dosovitskiy et al., “An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale,” arXiv:2010.11929 [cs], Oct. 2020.
  • [12] J. Devlin, M.-W. Chang, K. Lee, and K. Toutanova, “BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding,” in Proceedings of the 2019 Conference of the North American Chapter of the Association for Computational Linguistics: Human Language Technologies, Volume 1 (Long and Short Papers), Minneapolis, Minnesota, Jun. 2019, pp. 4171–4186, doi: 10.18653/v1/N19-1423.
  • [13] H. Fan et al., “Multiscale Vision Transformers,” arXiv:2104.11227 [cs], Apr. 2021.
  • [14] "dk-liang/Awesome-Visual-Transformer", GitHub, 2021. [Online]. Available: https://github.com/dk-liang/Awesome-Visual-Transformer.
❌