Python基于卷积神经⽹络(CNN)使⽤图像增强来训练⼩数据集(完成狗猫数
据集的两阶段分。。。
使⽤图像增强来训练⼩数据集⽬录
@ 什么是 overfitting(过拟合) 及 数据增强?
overfitting(): 过拟合(over-fitting)也称为过学习,它的直观表现是算法在训练集上表现好,但在测试集上表现不好,泛化性能差。过拟合是在模型参数拟合过程中由于训练数据包含抽样误差,在训练时复杂的模型将抽样误差也进⾏了拟合导致的。
所谓 抽样误差 ,是指抽样得到的样本集和整体数据集之间的偏差。
直观来看,引起过拟合的可能原因有以下⼏点
模型本⾝过于复杂,以⾄于拟合了训练样本集中的噪声。此时需要选⽤更简单的模型,或者对模型进⾏裁剪。
训练样本太少或者缺乏代表性。此时需要增加样本数,或者增加样本的多样性。
训练样本噪声的⼲扰,导致模型拟合了这些噪声,这时需要剔除噪声数据或者改⽤对噪声不敏感的模型。
数据增强: data augmentation,它的意思是让有限的数据通过某种变换操作产⽣更多的等价数据的过程。数据增强主要⽤来防⽌过拟合,⽤于datat较⼩的时候。
数据增强可以分为,有监督的数据增强 和⽆监督的数据增强 ⽅法
有监督的数据增强分为 单样本数据增强 和多样本数据增强 ⽅法;
⽆监督的数据增强分为 ⽣成新的数据 和学习增强策略 两个⽅向。
数据增强类型初略解释
单样本数据增强所谓单样本数据增强,即增强⼀个样本的时候,全部围绕着该样本本⾝进⾏操作,包括⼏何变换类(包括翻转,旋转,裁剪,变形,缩放...),颜⾊变换类(包括噪声、模糊、颜⾊变换、擦除、填充...)等
多样本数据增强不同于单样本数据增强,多样本数据增强⽅法利⽤多个样本来产⽣新的样本,包括SMOTE、 SamplePairing、mixup等⽣成新的数据通过模型学习数据的分布,随机⽣成与训练数据集分布⼀致的图⽚,代表⽅法GAN
学习增强策略
通过模型,学习出适合当前任务的数据增强⽅法,代表⽅法AutoAugment
解决计算机视觉运算应⽤到⼩数据集问题的策略
从头开始训练⼀个⼩型模型
使⽤预先训练的模型进⾏特征提取
微调预先训练的模型
⼀、查看运⾏的环境
(这⾥Tensorflow和 Keras的版本要对应,否则要出错!)
Platform Windows-7-6.1.7601-SP1
Tensorflow version 1.2.1
过拟合
Keras version 2.1.2
Platform Windows-7-6.1.7601-SP1
import platform
import tensorflow
import keras
print("Platform: {}".format(platform.platform()))
print("Tensorflow version: {}".format(tensorflow.__version__))
print("Keras version: {}".format(keras.__version__))
我没时间⼆、数据集准备
touch the ground下载图像数据集train.zip,在同⼀⽬录下(Home)新建⼦⽬录"data",把下载的图像数据集train.zip复制到"data"⽬录并解压缩。具体如图所⽰
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
from IPython.display import Image
import os
根⽬录路径
root_dir = os.getcwd()
存放图像数据集的⽬录
data_path = os.path.join(root_dir,'data')
come out
import os,shutil
原始数据集的路径
original_datat_dir = os.path.join(data_path,'train')
存储⼩数据集的⽬标
ba_dir = os.path.join(data_path,'cats_and_dogs_small')
if not ists(ba_dir):
os.mkdir(ba_dir)
训练图像的⽬录
train_dir = os.path.join(ba_dir,'train')
if not ists(train_dir):
os.mkdir(train_dir)
验证图像的⽬录
validation_dir = os.path.join(ba_dir,'validation')
if not ists(validation_dir):
os.mkdir(validation_dir)
测试资料的⽬录
test_dir = os.path.join(ba_dir,'test')
if not ists(test_dir):
os.mkdir(test_dir)
猫的图⽚的训练资料的⽬录
train_cats_dir = os.path.join(train_dir,'cats')
ifnot ists(train_cats_dir):
os.mkdir(train_cats_dir)
狗的图⽚的训练资料的⽬录
train_dogs_dir = os.path.join(train_dir,'dogs')
if not ists(train_dogs_dir):
os.mkdir(train_dogs_dir)
猫的图⽚的验证集⽬录
validation_cats_dir = os.path.join(validation_dir,'cats')
if not ists(validation_cats_dir):
os.mkdir(validation_cats_dir)
狗的图⽚的验证集⽬录
validation_dogs_dir = os.path.join(validation_dir,'dogs')
if not ists(validation_dogs_dir):
os.mkdir(validation_dogs_dir)
猫的图⽚的测试数据集⽬录
发呆英文test_cats_dir = os.path.join(test_dir,'cats')
if not ists(test_cats_dir):
os.mkdir(test_cats_dir)
狗的图⽚的测试数据集⽬录
test_dogs_dir = os.path.join(test_dir,'dogs')
if not ists(test_dogs_dir):
wish的用法os.mkdir(test_dogs_dir)
wrong
复制前600个猫的图⽚到train_cats_dir
fnames =['cat.{}.jpg'.format(i)for i in range(600)]
for fname in fnames:
src = os.path.join(original_datat_dir,fname)
dst = os.path.join(train_cats_dir,fname)
if not ists(dst):
print("Copy next 600 cat images to train_cats_dir complete!") Copy next 600 cat images to train_cats_dir complete!
复制后⾯400个猫的图⽚到validation_cats_dir
fnames =['cat.{}.jpg'.format(i)for i in range(1000,1400)]
for fname in fnames:
src = os.path.join(original_datat_dir,fname)
dst = os.path.join(validation_cats_dir,fname)
if not ists(dst):
print('Copy next 400 cat images to validation_cats_dir complete!')
Copy next 400 cat images to validation_cats_dir complete!
复制400张猫的图⽚到test_cats_dir
l hou
fnames =['cat.{}.jpg'.format(i)for i in range(1500,1900)]
for fname in fnames:
src = os.path.join(original_datat_dir,fname)
dst = os.path.join(test_cats_dir,fname)
if not ists(dst):
print("Copy next 400 cat images to test_cats_dir complete!")
Copy next 400 cat images to test_cats_dir complete!
复制前600张狗的图⽚到train_dogs_dir
fnames =['dog.{}.jpg'.format(i)for i in range(600)]
vrrpfor fname in fnames:
src = os.path.join(original_datat_dir,fname)
dst = os.path.join(train_dogs_dir,fname)
if not ists(dst):
print("Copy first 600 dog images to train_dogs_dir complete!")
Copy first 600 dog images to train_dogs_dir complete!
复制后⾯400个狗的图⽚到validation_dogs_dir
fnames =['dog.{}.jpg'.format(i)for i in range(1000,1400)]
for fname in fnames:
src = os.path.join(original_datat_dir, fname)
dst = os.path.join(validation_dogs_dir, fname)
if not ists(dst):
print('Copy next 400 dog images to validation_dogs_dir complete!') Copy next 400 dog images to validation_dogs_dir complete!
复制400张狗的图⽚到test_dogs_dir
fnames =['dog.{}.jpg'.format(i)for i in range(1500,1900)]
for fname in fnames:
src = os.path.join(original_datat_dir, fname)
dst = os.path.join(test_dogs_dir, fname)
if not ists(dst):
print('Copy next 400 dog images to test_dogs_dir complete!')
Copy next 400 dog images to test_dogs_dir complete!
会计实操班进⾏⼀次检查,计算每个分组中有多少张照⽚(训练/验证/测试)
print('total training cat images:',len(os.listdir(train_cats_dir)))
print('total training dog images:',len(os.listdir(train_dogs_dir)))
print('total validation cat images:',len(os.listdir(validation_cats_dir))) print('total validation dog images:',len(os.listdir(validation_dogs_dir))) print('total test cat images:',len(os.listdir(test_cats_dir)))
print('total test dog images:',len(os.listdir(test_dogs_dir)))
total training cat images: 600
total training dog images: 600
total validation cat images: 400
total validation dog images: 400
total test cat images: 400
total test dog images: 400
有1200个训练图像,然后是800个验证图像,800个测试图像,其中每个分类都有相同数量的样本,是⼀个平衡的⼆元分类问题,意味着分类准确度将是合适的度量标准。
三、资料预处理
⽹络的预处理步骤:
读⼊图像
将JPEG内容解码为RGB⽹格的像素
将其转换为浮点张量
将像素值(0和255之间)重新缩放到[0,1]间隔
数据应该先被格式化成适当的预处理浮点张量,然后才能输⼊到神经⽹络中。
from keras.preprocessing.image import ImageDataGenerator
# 所有的图像将重新进⾏归⼀化处理 Rescaled by 1./255
train_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)
# 直接从⽬录读取图像数据
train_generator = train_datagen.flow_from_directory(
# 训练图像的⽬录
train_dir,
# 所有图像⼤⼩会被转换成150x150
target_size=(150,150),
# 每次产⽣20个图像的批次
batch_size =20,
# 由于这是⼀个⼆元分类问题,y的label值也会被转换成⼆元的标签
class_mode ='binary')
# 直接从⽬录读取图像数据
validation_generator = test_datagen.flow_from_directory(
validation_dir,
target_size=(150,150),
batch_size =20,
class_mode='binary')
Found 1200 images belonging to 2 class.
Found 800 images belonging to 2 class.
图像张量⽣成器(generator)的输出,它产⽣150x150 RGB图像(形状"(20,150,150,3)")和⼆进制标签(形状"(20,)")的批次张量。20是每个批次中的样品数(批次⼤⼩)
for data_batch,labels_batch in train_generator:
机制英文print('data batch shape:',data_batch.shape)
print('labels batch shape:',labels_batch.shape)
break
data batch shape: (20, 150, 150, 3)
labels batch shape: (20,)
四、⽹络模型