图像生成器+增强

为数据生成器公开有用的参数

这很短(尽管这是我上次对自己说的话)。

假设我们在Python中有一个生成器,看起来像这样:

  def generate_data(data): 
我= 0
随机播放(数据)
 而True: 
#如果到达数据结尾,请重新启动并重新排列
如果我> = len(数据):
随机播放(数据)
我= 0
 产生data [i] .image,data [i] .mask 
  #前进到下一张图片 
我+ = 1

为了使我们的生活更轻松,我们假设我们有一种将特定增强器(来自imgaug库)应用于某些数据的方法。 它具有以下签名:

  def gain_data(数据,扩充器): 
#方法实现

我们关心两个主要参数:

  • 要使用的特定增强器(应用哪种增强以及频率/频率)
  • “ k”:我们拥有的每个图像要生成多少个增强图像

参数:增强器

这很简单。 我们只是向我们的generate_data()方法添加了一个额外的参数,并让用户指定了哪些扩充功能,频率以及扩充的各种设置/选项。

现在,我们的生成器如下所示:

  def generate_data(数据,扩充器):#新:参数`augmenter` 
我= 0
随机播放(数据)
 而True: 
#如果到达数据结尾,请重新启动并重新排列
如果我> = len(数据):
随机播放(数据)
我= 0
  #新:现在我们生成增强数据(仅) 
产生yield_data(data [i],Enhancer.to_deterministic())
 我+ = 1 

参数:增强数(每个图像)

能够控制(有效)训练数据集中的增强量通常很有用。 考虑这一点的最简单方法是从1张原始图像中生成1张,而不是“ k张”增强图像(因此我们有k + 1张相关图像)。

但是,如果您尝试以这种方式实现它,这样做会有些尴尬,并且如果“ k”很大,那么您将一次用一堆非常相似的图像来训练网络,这不是您想要的去做。 这可能导致该训练步骤的收敛性较差。

因此,我们将不再考虑数量,而是根据比例和概率重新构造实现。 对于单个图像,我们将以k /(k + 1)的概率对其进行扩增,而不是产生“ k”个增强的图像和1个原始图像,而以1 /(k + 1)的概率将其保留下来。

随着时间的流逝,我们(最有可能)将图像与增强图像的比例大致为1:k,但代码却少得多。 我们的生成器现在看起来像这样:

  def generate_data(数据,增强器,num_augs):#新:`num_augs` 
我= 0
随机播放(数据)
  #新:以一定的概率增加 
扩充器= iaa。有时(num_augs /(num_augs +1),扩充器)
 而True: 
#如果到达数据结尾,请重新启动并重新排列
如果我> = len(数据):
随机播放(数据)
我= 0
  #在这里,我们有时会产生增强数据 
产生yield_data(data [i],Enhancer.to_deterministic())
 我+ = 1 

等等,就是这样吗? 这是一个非常简单的更改,但这也意味着我们不必花太多时间。 引入批处理之后,我们实际上不需要太多更改代码:

  def generate_data(数据,扩充器,num_augs,batch_size): 
我= 0
随机播放(数据)
  #以一定的概率增加 
扩充器= iaa。有时(num_augs /(num_augs +1),扩充器)
 而True: 
#如果到达数据结尾,请重新启动并重新排列
如果我> = len(数据):
随机播放(数据)
我= 0

#建立`batch_size`数据列表,然后将它们全部扩充
#注意:`min(i + batch_size,len(data))确保我们不
#超出数据集的大小
批次= []
对于范围内的j(i,min(i + batch_size,len(data))):
batch.append(data [j])
  #在这里,我们产生了一批数据,其中一些得到了扩充 
产生yield_data(batch,Enhancer.to_deterministic())
  #我们向前移动数组中的`batch_size`元素 
我+ = batch_size