在训练图像识别的深度神经网络时,使用大量更多的训练数据,可能会使网络得到更好的性能,例如提高网络的分类准确率,防止过拟合等。获取更多的训练样本其实是很好的想法。但是,这个方法的代价很大,在实践中常常是很难达到的。不过还有一种方法能够获得类似的效果,那就是人为扩展训练数据(Artificially expanding the training data)。
对于图像数据我们可以通过旋转,转换,扭曲图像等方式来扩展训练数据,人为扩展训练数据时对数据的操作最好能反映真实世界的变化。例如在2003年Patrice Simard等人所著的一篇论文中[1]他们把MNIST手写数字数据集通过旋转,转换和扭曲进行扩展。通过在这个扩展后的数据集上的训练,他们把MNIST手写数字识别的准确率提升到了98.9%。然后还在“弹性扭曲”的数据集上进行了实验,这是一种特殊的为了模仿手部肌肉的随机抖动的图像扭曲方法。通过使用弹性扭曲扩展的数据,他们最终达到了99.3%的分类准确率。
本文会先对两个类别图像数据进行不同形式的拓展,然后用拓展后的两个类别的数据在超参数调整稳定的深度神经网络上训练,用得到的分类准确率和未拓展的数据训练得到的分类准确率做对比。如果分类准确率有明显的提升,说明我们对数据所做的拓展操作是良性的,能够“反映真实世界的变化”,就会被用到整个数据集的扩展。反之,则说明不能用此操作对数据集进行拓展。
当然,我们选择的图像操作也是有一定的现实意义的。由于原有数据集中的图像是渔船的监控画面图像,通过对大部分图像的观察我们考虑下面几种图像操作的方式作为人为扩展训练数据集的方法。当然这些方法只是我们最初的选择,而这些选择只是根据我对数据集的初级理解,方法的正确与否我们还要经过试验来进行判断。
1.镜像翻转:可以很清楚的看到图像上下翻转肯定是行不通的,所以我们选择图像的左右翻转作为第一种扩展数据集的方法。
2.添加椒盐噪声:可以给图像添加一些椒盐噪声来扩展数据。
镜像翻转
python 代码:
#coding=utf-8
import os
from PIL import Image
import matplotlib.pyplot as plt
dictOfFish={
'ALB':'110000',
'BET':'210000',
}
for key in dictOfFish:
a=os.listdir("./origin/"+key)
count=1
for x in a:
oldname="./origin/"+key+"/"+x
img=Image.open(oldname)
dst=img.transpose(Image.FLIP_LEFT_RIGHT)#左右互换
newname="./transpose"+"/"+key+"/"+str(int(dictOfFish[key])+count)+".jpg"
dst.save(newname)
count+=1
给图像添加椒盐噪声
python代码:
#coding=utf-8
import os
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
dictOfFish={
'ALB':'120000',
'BET':'220000'
}
for key in dictOfFish:
a=os.listdir("./origin/"+key)
count=1
for dirx in a:
oldname="./origin/"+key+"/"+dirx
img=np.array(Image.open(oldname))
#随机生成5000个椒盐
rows,cols,dims=img.shape
for i in xrange(5000):
x=np.random.randint(0,rows)
y=np.random.randint(0,cols)
img[x,y,:]=255
img.flags.writeable = True # 将数组改为读写模式
dst=Image.fromarray(np.uint8(img))
newname="./transpose+30"+"/"+key+"/"+str(int(dictOfFish[key])+count)+".jpg"
dst.save(newname)
count+=1