Einops.rearrange 的理解
einops 有很多人已经使用过了,它在深度学习,尤其是在 computer vision 中对 tensor 的操作上,显得非常方便。
由于已经有相当多的文档来讲它的基础,所以一般性的内容我就不再提了。本文只讲 einops.rearrange 里面一个我之前一直没弄明白的操作,来源于文档:https://einops.rocks/1-einops-basics/
rearrange(ims, 'b h w c -> h (b w) c')
v.s.
rearrange(ims, 'b h w c -> h (w b) c')
这两个操作的目的,都是为了对一个 batch 的图片进行一个转换。原始的 tensor 形状为4维,即 ( b , h , w , c ) (b, h, w, c) (b,h,w,c),我们想将它拉平成三维,并做可视化。上面的两个方法,都能将形状变成 ( b , h ∗ w , c ) (b, h*w, c) (b,h∗w,c),那它们最终的结果有何不同呢?
其中,如果使用 ‘b h w c -> h (b w) c’,它的结果如下:
但如果使用的是 ‘b h w c -> h (w b) c’,结果则变成了下面这样:
我找了很多地方都没有找到一个比较好的描述,ChatGPT (GPT-4)的结果也很糟心,说了一堆废话,最后还是靠 Claude 帮我有了一个比较好的理解,Claude 的总结如下:
主要区别在于合并批次和宽度维度的顺序:
第一个操作是 (b w),意味着先完整排列第一张图像,然后是第二张,以此类推
第二个操作是 (w b),意味着先排列所有图像的第一列,然后是第二列,以此类推
用我自己的话总结一下就是,如果维度变成 ( b w ) (b\ w) (b w),其实可以把它理解成 ( b ( w ) ) (b (w)) (b(w)),也即这个维度先会分成 b 块,然后每一块都需要先填满长度为 w w w 的内容,即当前图片的内容,所以就是 6 × w 6 \times w 6×w。
而如果是 ( w b ) (w\ b) (w b),虽然最后的总长度一样,但相当于是先要把这个维度分成 w w w 块,每一块再填满长度为 b b b(这个例子中是 6)的内容。因此从上面的图中可以看到,它是由不同的颜色条交替出现的,每 6 条为一组,总共有 w w w 组。
希望能帮大家更好地理解这一块的内容。