在中国大陆地区,iPhone Safari 上使用 Google 搜索引擎会显示 “点击查看xxx在 google.com.hk 的搜索结果”。

这个问题的原因是 iPhone Safari 将大陆地区 Google 搜索引擎 url 配置为 google.cn,而这个网站是无法使用的。

一个解决问题的思路是修改梯子的配置文件,将所有 google.cn 的请求重定向到 google.com。

大陆苹果用户如何优雅的在 Safari 上使用 Google 搜索? - 毒奶 - 欢迎使用代理访问本站。

这篇文章提供了在 Quantumult X, Surge, Shadowrocket 这几个梯子中配置重定向的方法。本文将补充如何在 Clash 中进行类似的配置。

启用 MitM 功能

由于 iOS14.6 将原本搜索引擎使用的 http 协议升级为 https 协议,我们需要先启用 MitM 功能,才能顺利重定向。

MitM – Stash 用户文档

参考文档的“使用图形界面配置 MitM”部分完成 CA 证书MitM 列表的配置。

检验:点击 Stash 首页的 MitM 选项,应该可以看到 *.google.cn 已经添加到列表中。

配置重定向

设置 ➡️ 配置文件 ➡️ 可视化编辑 ➡️ HTTP 重写

进行如下配置

表项 内容
Match ^https?://(www.)?google.cn
URL https://www.google.com
Action Redirect 302

至此,我们可以在 Safari 中直接访问 Google 了。

这是一篇关于 Vision Transformer 的随笔。

将 Transformer 应用于视觉任务的难点

Transformer 能够处理的序列长度远少于图片像素,比如 BERT 中一次处理的序列长度为 512,但是图像分类任务中一张图片可能有几万个像素点。

思路

本文的大致思路很简单。把图片分割成 16*16 的块,把每个块当成 NLP 中的单词,把整个图片当成句子,然后直接用 Transformer 做。

本文是对 Attention is All You Need 这篇论文的一篇随笔,简单记录了对 Transformer 架构中概念的理解。

Attention 函数

Q 形状 (n, dk),K 形状 (m, dk),V 形状 (m, dv)。以机器翻译为例,n 的含义是目标语句的长度,m 的含义是源语句的长度。

Attention 函数将 Q, K, V 映射成一个形状为 (n, dv) 的矩阵,代表目标语句的向量序列,其长度为目标语句长度,向量值为 V 每个向量加权和。

Transformer 架构

架构

在编码器和解码器的第一个注意力层,输入同时作为 Q, K, V,这种机制被称为自注意力机制。

假设输入的序列长度为 n,向量维度为 d。输出序列长度为 m。

对于编码器的注意力层,由于自注意力机制,输入和输出长度和向量维度是一样的。因此输出实际上是输入的加权和,并且同一个位置的权重最大,如果输入序列中有其他向量和该位置的向量类似,则也会有较大的权重。

对于解码器的第一个注意力层,同样由于自注意力机制,输出也是输入的加权和。但需要注意这里加了掩码,所以当前时刻后面的权重全部为 0。

对于解码器的第二个注意力层,其 K, V 来自于编码器,其 Q 来自于解码器的上一个注意力层。

这是一篇关于 CLIP 模型的随笔。

概览

CLIP 模型的主题是图像分类。

思路

基于配对的文本和图片进行对比学习,训练文本编码器和图片编码器。

将任意分类标准(如 ImageNet 的 1k 个类别)转换为文本再输入进文本编码器,将图片输入图片编码器,找到最接近的类别编码。

整体思路如下图所示

思路

启发

原始文字代替固定标签

CLIP 的强大之处在于可以直接联系原始文字和图片,摆脱了固定标签的限制。过去的 CIFAR, ImageNet 等都给图片固定了标签。而 CLIP 可以直接关联自然语言文本和图片。

规模带来质变

其实在 2020 年就有很多类似 CLIP 的工作,但是它们的数据集、参数量远不如 CLIP(CLIP 用了 400M 的数据和 Vit-Large),因此效果也比不上 CLIP。这个现象体现了 Scale Law。

作者还发现,迁移学习(Zero-shot)的能力基本和模型大小成正相关。

本文是对 Meta SAM 论文的一篇随笔,主要记录了文章带来的启发。

概览

这篇工作的主题是图像分割。主要贡献有:

  • 提出任务 promptable segmentation task:在有提示的情况下进行图像分割。
  • 模型 SAM:能够根据提示快速生成掩码。
  • 数据引擎:可以自动生成掩码数据用于训练模型。
  • 数据集 SA-1B:1B 大小的掩码数据集。

任务*

新任务是本文的亮点之一。本文提出了一个新任务:在有提示的情况下进行图像分割。提示的灵感来自于 NLP 领域。

本文使用的提示包括前景点(如鼠标点击)、粗略的框、文本。如下图所示

模型

本文的模型比较简单,基本是由之前的模型改造+组装得到的。

模型大致结构如图

alt text

数据引擎*

数据引擎实际上就是通过原始图像生成掩码数据的一套流程。数据引擎也是本文的一大亮点,具体有以下几个开创性成就:

  • 本文一共生成了 1B 的掩码数据。这大概是 COCO 的一万倍。
  • 这么多数据其中有九成是完全自动生成的,剩下的部分也有计算机辅助。这极大减少了人工数据标注的工作量。
  • 数据引擎不局限于某个特定的数据集,可以应用于任意的图片。

零样本迁移

文章在这一块做了很多论述,但是因为主要在说明效果而不是原理,所以我没有细看。

启发

这篇帖子从 data-centric AI 的角度解读了 SAM 的意义。我觉得很有启发性。

https://www.zhihu.com/question/593888697/answer/2972047807

总的来说有以下几点启发:

  • 数据是目前 AI 研究的瓶颈和重心之一。我们需要更好、更多、更快的数据。
  • 我们应该有一种系统化的方法获取和处理数据,比如本文的数据引擎。

需要学习的地方

  • ViT
  • CLIP
  • 零样本迁移

Docker 会从 Docker Hub 拉取镜像,但国内访问不了。可以配置代理解决这个问题。

如果使用了 Docker Desktop,在 Settings -> Resources -> Proxies 里配置代理。

Kubernetes 在 cluster 中无法使用 127.0.0.1:7890 作为代理,因为 cluster 使用独立的网络环境,127.0.0.1 不指向宿主机。可以先获取宿主机的局域网 ip,再将代理设置成局域网 ip。

我目前主要使用 Vscode 作为代码编辑器。但是有些场合免不了使用 Vim。

Vim 指令很多。本文摘录了最基本、最常用的一些命令,以供参考。

文件操作

:w 保存

:q! 不保存强制退出

:wq 保存退出

移动光标

基本移动

hjkl 移动一格

ctrl up down 移动半页

0 $ 移动到行开头或结尾

单词移动

w 跳到下一个单词的开头

b 跳到上一个单词的开头

e 跳到下一个单词的结尾

行移动

G 移动到最后一行行首

<num>G 移动到 num 行行首

搜索移动

/ ? 向前或向后搜索

n N 下一个上一个

编辑

插入

i 在光标位置插入

a 在光标之后插入

删除

dw de 删除单词

d$ 删除光标到当前行结尾

dd 删除当前行

重复操作

数字加操作可以重复多次操作。

创建文档时需要制定 channel

官方文档的 Create a New Document 部分的例子有错误。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
DIGEST=`echo -n sgwuser1:password | base64`

curl --location --request PUT 'http://localhost:4984/traveldb/hotel_88801' \
--header "Authorization: Basic $DIGEST" \
--header 'Content-Type: application/json' \
--data-raw '{
"_id": "hotel_88801",
"id": "88801",
"type": "hotel",
"name": "Verify-Install Topic",
"address": "The Shambles",
"city": "Manchester",
"country": "United Kingdom"
}'

应该在请求体中加上 "channels": ["public"]。这样后面 GET 才能正常读取,否则会出现 403 Forbidden

1
2
3
4
// greeter.proto
syntax = "proto3";
package greeter;
option go_package = "./api/v1/greeter;greeterPb";

package greeter 指的是 proto 体系中的包名为 greeter。用于在其他 proto 文件中导入该 proto 文件。和 go 语言无关。

如在另一个 proto 文件中

1
2
3
4
5
// farewell.proto
import "greeter.proto"
message FarewellReply {
greeter.UserInfo ...
}

这里使用了 greeter 中定义的 UserInfo

1
option go_package = "<path>;<go_package>"

path 指的是生成 go 文件的位置。go_package 指的是生成 go 文件的包名。一般 go_package 就是在 proto package 后面加上一个 Pb