模型的逻辑理解

模型的逻辑理解

很多同学初学神经网络,理解了正向反向,训练测试,但是对于为什么要这么构造神经网络,各部分的描述,还少了一些逻辑层面的理解,导致了会用,但不知道怎么改,也不知道如何讲故事。在此准备以一个模型的结构图为例,介绍一下神经网络的逻辑理解。在具体介绍模型之前,先明确几个概念。

特征包含的语义信息 #

在机器学习中,特征、嵌入、表示、向量,其实都是一个东西,是用来指代一个对象的。其中的语义信息,就是指的原始输入中包含的重要内容。可见,原始输入的语义信息是最充足的。但为什么不使用原始输入来做后续处理呢?当然也是可以的,很早很早期的SVM之类的,就直接拿着图像像素、句子中涉及的单词表之类原始输入作为输入来做分类任务。这里面最大的问题有两个:

  1. 这些表太稀疏了,非常浪费计算资源和存储资源;
  2. 这些表中的噪声太大了,非常影响计算结果。

那要怎么处理呢?

  • 对于问题1:把这些原始输入转化为嵌入向量就可以了嘛。简单理解,原始输入本质上也是一个特征(向量),对原始输入做一个压缩,是不是可以降低它的稀疏性?形式化可描述为:对原始特征$\mathbf{v}_o\in \mathbb{R}^{m}$,通过矩阵$\mathbf{W}\in \mathbb{R}^{m\times n}(m \gg n)$,可形成一个更紧凑的特征$\mathbf{v}_e \in \mathbb{R}^{n}$,where $\mathbf{v}_e = \mathbf{v}_o \cdot \mathbf{W}$。由于$\mathbb{W}$总是存在广义逆矩阵,所以可以认为,$\mathbf{v}_e$与$\mathbf{v}_o$包含相同的语义信息。从另一个角度来说:

语义向量的维度大小与包含的语义无关,在实操中可以根据网络结构做适当调整。

  • 对于问题2:在神经网络中,扔掉一部分信息就可以了呀。至于哪些信息是有用的,哪些是无用的,就是神经网络自主从数据中去学习的了。你问怎么扔的?非线性激活、池化、注意力机制,这些都是手段,根据需求灵活选用即可。

由此可知,任何一个实体、概念,都可以转化成为一个向量来表示了,这就是我们说的语义特征、表示、语义向量,等等了。这些向量中包含的语义,与我们期望它具有的能力之间的差异,就叫语义鸿沟。更好的特征,理论上语义鸿沟就更好,因为它能够产生更接近我们期望的结果。

语义空间及特征比对 #

假设某对象的向量为$\mathbf{a}$,另一对象的向量为$\mathbf{b}$。若$\mathbf{a} = \mathbf{b}$,那这俩对象一样吗?

答案是否定的!因为从语义层面,需要考虑向量所在的语义空间。类似于我们的成绩,两个同学都得了5分,其中一个同学是5分制,另一个是100分制,他们的成绩肯定是不一样的。那如何确定两个向量是相同的语义空间呢?两种方式:

  1. 在相同空间的$x1$与$x2$,经过同一个函数$f(x|\theta)$,得到的结果是同一个语义空间。注意,这里用到的$\theta$必须是同一个。如果使用了两次训练得到的$\theta$,不能算是同一个语义空间。
  2. 在训练过程中,在语义层面做过约束的向量,可以认为是在同一空间。例如,图像$v_m$与文本$v_t$,如果有loss约束他们一致,那么这两个向量就是在同一空间的。

只有在同一空间内的特征,才能够做比对,相同相异均是如此!!

例:我们在使用过程中,要用到文本检索图像,应该怎么做呢?

  • 方法一:各自使用模型预提特征,然后通过各自的投影矩阵,映射到同一个空间中,加约束训练,使得特征可比对。
  • 方法二:使用CLIP等训练过程中对文本和图像特征做过约束的模型,提特征,即可直接得到可比对特征。

Tensor的逻辑含义 #

对于一个Tensor $\mathcal{T} \in \mathbb{R}^{2\times 4\times 2048}$,从逻辑上它表示了什么呢?

这里就要强调一下变量的逻辑意义了。一定要摆脱它的物理结构(三维数组)来考虑。如果学过动态规划的同学,应该更容易理解。

在这里,$\mathcal{T}$的shape为$[2,4,2048]$,那么,按照一般的习惯,最后一个维度都用于表示特征。于是这个Tensor可以看作是一个$2\times 4$的矩阵,矩阵里的每一项使用了一个$2048$维的矩阵描述了一个对象。如果需要64维的特征怎么办呢?把$[2,4,2048]$投影到$[2,4,64]$的Tensor就可以了。

接下来看$2\times 4$的矩阵表示什么含义。这里就需要看论文里作者的定义了。可以看作是:$2$个样本,每个样本为长度为$4$的序列;也可以看作:$2\times 4$的图像分块。这就是逻辑描述。具体要取第2个样本的全部序列的特征,就用:$T[1,:,:]$即可。

更高维的Tensor也是类似的道理,不要把这些值看作维度,理解成特定的含义就可以了。

特征长度的取值 #

很多同学很困惑,为什么特征要取2048维?为什么序列长度要取77?为什么不取78?为什么batchsize要取1,不能是2?这里面有几个原因:

  1. 最直接的原因:预训练模型就是这么定的,为了与模型对接,那就必须使用相同的值。如果值不同,就需要训练一个特征转换矩阵,比较麻烦。
  2. 不得已的原因:现在模型都比较大,占用GPU资源多,如果把特征设大了,或者batchsize设为2,就跑不动了。一般会挑一个GPU条件能够承受的最大值。
  3. 数据的原因:模型是基于数据集训练的,训练集中序列长度最长也就75,设多了也没用。多加两个提供开始结束符号已经够意思了。资源能省就省。
  4. 经验的原因:早期大家做过大量尝试。最早以为batchsize设得大会收敛得比较快比较好。后面发现,batchsize大了前期快,但模型稳定之后,很难收敛到更好的结果。相反batchsize设小一些有助于更好的拟合数据(在测试数据上效果也很好)所以有时候在预训练模型上用batchsize为1来微调可能能够更快得到想要的结果。

事实上,除了经验的要素,其实这些超参想设成多少都可以,无非就是再调调其他超参训练一遍而已。一般情况下,在保留backbone要求的情况下,靠感觉调吧。

神经网络的结构 #

有同学很纠结,为啥某些地方合并直接加就可以了,某些地方要用cross-attention,有些地方要用FC。其实神经网络已经很工程化了,科研主要是要找到逻辑上的理由,然后调整结构就可以了。

常用的几个套路:

  1. 引入新的语义信息。例如加一点别的文本之类的,本质上就是输入增加了一个分支,想办法并到网络里就可以。
  2. 从现有语义信息中提取新的语义内容。本质上是以某一层特征的输出为输入建立一个新的分支。

里面涉及几个变化:

  1. 分支合并。可以直接用分支相加,cross-attention,等等。也就是把多个分支的输出想办法整合起来形成一个输出就可以了。从逻辑层面,可以认为这个输出包含各分支提取的语义信息。
  2. 增加分支。把某一层的输出,作为输入加到一个新分支中。从逻辑层面,可以认为是要从输出的特征中提取出一些新的语义描述。
  3. 特征对齐。对于原本在同一空间的特征(参考前面特征空间的介绍),可以直接做加法;对于不在同一空间的特征,至少需要有一个特征做投影;对于维度不同的特征,简单做投影即可。

备案号:苏ICP备2022019698号-1