dropblock的作用不在累述,这里只分享使用4行代码实现dropblock。
dropblock的介绍可以参考博主的另一篇文章pytorch 22 8种Dropout方法的简介 及 基于Dropout用4行代码快速实现DropBlock_万里鹏程转瞬至的博客-CSDN博客
1、基本库方法实现这里主要实现三个函数,图片展示、图片读取和tensor转img
from PIL import Image
from matplotlib import pyplot as plt
import paddle
from paddle import nn
def myimshows(imgs, titles=False, fname="test.jpg", size=6):
lens = len(imgs)
fig = plt.figure(figsize=(size * lens,size))
if titles == False:
titles="0123456789"
for i in range(1, lens + 1):
cols = 100 + lens * 10 + i
plt.xticks(())
plt.yticks(())
plt.subplot(cols)
if len(imgs[i - 1].shape) == 2:
plt.imshow(imgs[i - 1], cmap='Reds')
else:
plt.imshow(imgs[i - 1])
plt.title(titles[i - 1])
plt.xticks(())
plt.yticks(())
plt.savefig(fname, bbox_inches='tight')
plt.show()
def read_img_as_nparr(path):
im=Image.open(path)
img=np.array(im)
if len(img.shape)==2:
np_arr=img.reshape((1,1,img.shape[0],img.shape[1]))
else:
img=img.transpose((2,0,1))
np_arr=img.reshape((1,*img.shape))
return np_arr,np.array(im)
def tensor2img(tensor):
np_arr=tensor.numpy()[0]
if np_arr.shape[0]==1:
np_arr=np_arr[0]
else:
np_arr=np_arr.transpose((1,2,0))
if np_arr.max()>1:
np_arr[np_arr>255]=255
np_arr=np_arr.astype(np.uint8)
return np_arr
2、基于dropout实现dropblock
import paddle
from paddle import nn
class DropBlock(nn.Layer):
def __init__(self,block_size,drop_rate,chanel_independent=True):
super(DropBlock, self).__init__()
self.block_size = block_size
self.drop_rate = drop_rate
self.chanel_independent = chanel_independent
def forward(self, x):
if self.training and self.drop_rate>0:
b,c,h,w=x.shape
#确保用户设置的block_size是合法的
if self.block_size[0]>h or self.block_size[1]>w:
raise("The block_size must be smaller or equal to the feature map! \n block_size:(%s,%s) feature map size:(%s,%s)"%(self.block_size[0],self.block_size[1]),h,w)
#针对不同的chanel使用不同的概率进行drop_block, 在提出者的实验中chanel不同的使用不同的mask效果更好
if self.chanel_independent==False:
c=1#针对所有的chanel都采用相同的mask
mask=paddle.ones((b,c,int(h/self.block_size[0]),int(w/self.block_size[1])))
mask_drop = nn.functional.dropout(mask,p=self.drop_rate)
big_mask=nn.functional.upsample(mask_drop,size=(h,w), mode='nearest',data_format='NCHW', name=None)
drop_block_result=x*big_mask#这里用到了自动广播,使big_mask的shape变成了b,c,h,w
return drop_block_result
else:
return x
np_arr_for_tensor,np_arr=read_img_as_nparr("work/img_train/T104281.jpg")
x=paddle.to_tensor(np_arr_for_tensor,dtype=paddle.float32)
dropblock1=DropBlock((80,80),0.3,chanel_independent=False)
drop_block_result1=dropblock1(x)
np_arr_drop_block1=tensor2img(drop_block_result1)
dropblock2=DropBlock((80,80),0.3,chanel_independent=True)
drop_block_result2=dropblock2(x)
np_arr_drop_block2=tensor2img(drop_block_result2)
myimshows([np_arr,np_arr_drop_block1,np_arr_drop_block2],['img','img + dropblock1(chanel_independent=False)','img + dropblock2(chanel_independent=True)'])
这里只强调一点,dropblock应该用在网络的深层,同时drop_rate应该是慢慢变大的,其提出者的多种实验都表明drop_rate为0.1效果最佳。 此外,提出者还将dropblock的block_size设得与feature map同样大,达到了dropout2d的效果,实验表明dropout2d与dropblock配合使用效果更佳。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)