def img2col_py(Ipad, block_size):
[row, col] = Ipad.shape
row_block = row/block_size
col_block = col/block_size
block_num = int(row_block*col_block)
img_col =torch.zeros([block_size**2, block_num])
count = 0
for x in range(0, row-block_size+1, block_size):
for y in range(0, col-block_size+1, block_size):
img_col[:, count] = Ipad[x:x+block_size, y:y+block_size].reshape([-1])
count = count + 1
return img_col
aaaa=img2col_py(Ipad,2)
举例:输入是[6,4],block_size为2
output:
Ipad:torch.Size([6, 4])
tensor([[0.1626, 0.0097, 0.6918, 0.7405],
[0.9155, 0.6619, 0.6529, 0.5635],
[0.6905, 0.3335, 0.4947, 0.8756],
[0.4966, 0.2286, 0.1669, 0.5582],
[0.8993, 0.0986, 0.5191, 0.6391],
[0.7639, 0.0883, 0.9952, 0.4410]])
aaaa:torch.Size([4, 6])
tensor([[0.1626, 0.6918, 0.6905, 0.4947, 0.8993, 0.5191],
[0.0097, 0.7405, 0.3335, 0.8756, 0.0986, 0.6391],
[0.9155, 0.6529, 0.4966, 0.1669, 0.7639, 0.9952],
[0.6619, 0.5635, 0.2286, 0.5582, 0.0883, 0.4410]])
还有一个函数可以做到滑动取块
步长为2
步长为1
patches_0= patches.transpose(1, 2)
output:
patches_0:torch.Size([1, 9, 4])
tensor([[[ 1.0127, 0.7128, -0.3260, -0.1183],
[ 0.7128, 0.4439, -0.1183, -1.0749],
[ 0.4439, 1.2473, -1.0749, -0.7125],
[-0.3260, -0.1183, 1.1466, -1.0475],
[-0.1183, -1.0749, -1.0475, 0.1535],
[-1.0749, -0.7125, 0.1535, 0.9636],
[ 1.1466, -1.0475, -0.4800, 1.3628],
[-1.0475, 0.1535, 1.3628, -0.0427],
[ 0.1535, 0.9636, -0.0427, -0.7177]]])
也就是说patches_0 = torch.nn.functional.unfold(inp, (2, 2)).transpose(1, 2)
w = torch.randn(1, 1, 2, 2)
output:
w :torch.Size([1, 1, 2, 2])
tensor([[[[ 0.5352, -1.6392],
[-0.3645, -1.4205]]]])
w0=w.view(w.size(0), -1)
w0:torch.Size([1, 4])
tensor([[ 0.5352, -1.6392, -0.3645, -1.4205]])
w1=w.view(w.size(0), -1).t()
w1:torch.Size([4, 1])
tensor([[ 0.5352],
[-1.6392],
[-0.3645],
[-1.4205]])
shape_patches_0 = patches_0.shape
shape_patches_0:torch.Size([1, 9, 4])
w2=w.view(w.size(0), -1).t().repeat(1, shape_patches_0[1])
w2:torch.Size([4, 9])
tensor([[ 0.5352, 0.5352, 0.5352, 0.5352, 0.5352, 0.5352, 0.5352, 0.5352, 0.5352],
[-1.6392, -1.6392, -1.6392, -1.6392, -1.6392, -1.6392, -1.6392, -1.6392,-1.6392],
[-0.3645, -0.3645, -0.3645, -0.3645, -0.3645, -0.3645, -0.3645, -0.3645,-0.3645],
[-1.4205, -1.4205, -1.4205, -1.4205, -1.4205, -1.4205, -1.4205, -1.4205,-1.4205]])
out_unf = (patches_0 - w.view(w.size(0), -1).t().repeat(1, shape_patches_0[1]))
qq:torch.Size([1,4, 9])
tensor([[[ 1.0127, 0.7128, 0.4439, -0.3260, -0.1183, -1.0749, 1.1466,-1.0475, 0.1535],
[ 0.7128, 0.4439, 1.2473, -0.1183, -1.0749, -0.7125, -1.0475, 0.1535, 0.9636],
[-0.3260, -0.1183, -1.0749, 1.1466, -1.0475, 0.1535, -0.4800,1.3628, -0.0427],
[-0.1183, -1.0749, -0.7125, -1.0475, 0.1535, 0.9636, 1.3628,-0.0427, -0.7177]]])
ww:torch.Size([4, 9])
tensor([[ 0.5352, 0.5352, 0.5352, 0.5352, 0.5352, 0.5352, 0.5352, 0.5352, 0.5352],
[-1.6392, -1.6392, -1.6392, -1.6392, -1.6392, -1.6392, -1.6392, -1.6392,-1.6392],
[-0.3645, -0.3645, -0.3645, -0.3645, -0.3645, -0.3645, -0.3645, -0.3645, -0.3645],
[-1.4205, -1.4205, -1.4205, -1.4205, -1.4205, -1.4205, -1.4205, -1.4205, -1.4205]])
ee=qq-ww :torch.Size([1,4, 9])
tensor([[[ 0.4775, 0.1776, -0.0913, -0.8612, -0.6535, -1.6101, 0.6114,-1.5827, -0.3817],
[ 2.3520, 2.0831, 2.8865, 1.5209, 0.5643, 0.9267, 0.5917,1.7927, 2.6028],
[ 0.0385, 0.2462, -0.7104, 1.5111, -0.6830, 0.5180, -0.1155, 1.7273, 0.3218],
[ 1.3022, 0.3456, 0.7080, 0.3730, 1.5740, 2.3841, 2.7833,1.3778, 0.7028]]])
确实是对应位置相减的。
下面看,多通道,是否能扩展。
unfold和fold作用刚好相反
w=torch.tensor([77,1,8,8])
inp_w = torch.nn.functional.unfold(w, (4,4),stride=4) #当kernelsize=strdie,就是非重叠取块
afterinp_w = torch.nn.functional.fold(inp_w,output_size=(8,8), kernel_size=(4,4), stride=4)
结果是:
w:torch.Size([77, 1, 8, 8])
inp_w:torch.Size([77, 16, 4])
afterinp_w:torch.Size([77, 1, 8, 8])