用einops直观任性 *** 作Tensor,解决Patch Embedding问题

用einops直观任性 *** 作Tensor,解决Patch Embedding问题,第1张

用einops直观任性 *** 作Tensor,解决Patch Embedding问题

首先看一下原图:

是一张jpg格式,512x512分辨率的图像,解码为RGB格式时,shape为[3, 512, 512]

导入einops相关函数

from einops import rearrange, reduce, repeat

常用的就是这三个了,文末有官方教程地址,可全面学习,解决Transform中的第一步的Patch Embedding,rearrange(重新排列,重新整理)就足够了

先增加一个b维度

img = rearrange(img, 'c h w -> 1 c h w')
# print(img.shape) # torch.Size([1, 3, 512, 512])

img就是上图,'c h w’对应你数据最开始的shape,'1 c h w’对应你想要的shape,增加一个维度的话,直接在前面加个1,完事

开始分割成Patch并重新排列

img = rearrange(img, 'b c (h p1) (w p2) -> b (h w) (p1 p2 c)', p1=256, p2=256)
# print(img.shape) # torch.Size([1, 4, 196608])

原来的’b c h w’,现在要在’h w’维度开始分割patch,p1,p2就是patch的大小,因为我原图为512x512,这里简单起见,我就直接分成4块,那每一块就是256x256,这个在后面p1=256,p2=256指定,指定后,它会自动计算h w变为多少,这里肯定是2了,最后转换的shape,因为要送到神经网络中去,shape应该为[b, d1, d2],一个三维的tensor,这里就把分割好的h w重新放到括号里,p1,p2,c作为patch,按照经典思路,打平即可

这样就获得了我们想要的结果,shape:[1, 4, patch打平后的数值],4是patch个数

这样就解决了当分辨率增大时,采用通道数不变,将图像空间所有打平,数据太大的问题

下面是可视化代码,想看看它是不是按照我们的想法分割为patch了,直接放全部代码和结果了

# 接上面 *** 作,看shape变化
img = reduce(img, 'b n p2 -> n p2', 'mean')
# print(img.shape) # torch.Size([4, 196608])

img = rearrange(img, 'n (p1 p2 c) -> n p1 p2 c', p1=256, p2= 256, c=3)
# print(img.shape) # torch.Size([4, 256, 256, 3])

# 画图,因为我是把图像ndarray转成tensor *** 作的,
# 所以要显示,就把它转换回numpy
fig, ax = plt.subplots(2, 2, figsize=(5, 5))
ax[0][0].imshow(img[0].data.numpy(), cmap='gray')
ax[0][1].imshow(img[1].data.numpy(), cmap='gray')
ax[1][0].imshow(img[2].data.numpy(), cmap='gray')
ax[1][1].imshow(img[3].data.numpy(), cmap='gray')
plt.show()

结果如下:

官方教程:
官方教程

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5657652.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存