Keras 在fit_generator训练方式中加入图像random_crop操作

使用Keras作前端写网络时,由于训练图像尺寸较大,需要做类似 tf.random_crop 图像裁剪操作。

为此研究了一番Keras下已封装的API。

Data Augmentation(数据扩充)

Data Aumentation 指使用下面或其他方法增加输入数据量。我们默认图像数据。

旋转&反射变换(Rotation/reflection): 随机旋转图像一定角度; 改变图像内容的朝向;

翻转变换(flip): 沿着水平或者垂直方向翻转图像;

缩放变换(zoom): 按照一定的比例放大或者缩小图像;

平移变换(shift): 在图像平面上对图像以一定方式进行平移;

可以采用随机或人为定义的方式指定平移范围和平移步长, 沿水平或竖直方向进行平移. 改变图像内容的位置;

尺度变换(scale): 对图像按照指定的尺度因子, 进行放大或缩小; 或者参照SIFT特征提取思想, 利用指定的尺度因子对图像滤波构造尺度空间. 改变图像内容的大小或模糊程度;

对比度变换(contrast): 在图像的HSV颜色空间,改变饱和度S和V亮度分量,保持色调H不变. 对每个像素的S和V分量进行指数运算(指数因子在0.25到4之间), 增加光照变化;

噪声扰动(noise): 对图像的每个像素RGB进行随机扰动, 常用的噪声模式是椒盐噪声和高斯噪声;

Data Aumentation 有很多好处,比如数据量较少时,用数据扩充来增加训练数据,防止过拟合。

ImageDataGenerator

在Keras中,ImageDataGenerator就是专门做数据扩充的。

from keras.preprocessing.image import ImageDataGenerator

注:Using TensorFlow backend.

官方写法如下:

(x_train, y_train), (x_test, y_test) = cifar10.load_data()

datagen = ImageDataGenerator(
 featurewise_center=True,
 ...
 horizontal_flip=True)

# compute quantities required for featurewise normalization
datagen.fit(x_train)

# 使用fit_generator的【自动】训练方法: fits the model on batches with real-time data augmentation
model.fit_generator(datagen.flow(x_train, y_train, batch_size=32),
   steps_per_epoch=len(x_train), epochs=epochs)

# 自己写range循环的【手动】训练方法
for e in range(epochs):
 print 'Epoch', e
 batches = 0
 for x_batch, y_batch in datagen.flow(x_train, y_train, batch_size=32):
 loss = model.train(x_batch, y_batch)
 batches += 1
 if batches >= len(x_train) / 32:
  # we need to break the loop by hand because
  # the generator loops indefinitely
  break

ImageDataGenerator的参数说明见官网文档

上面两种训练方法的差异不讨论,我们要关注的是:官方封装的训练集batch生成器是ImageDataGenerator对象的flow方法(或flow_from_directory),该函数返回一个和python定义相似的generator。在它前一步,数据变换是ImageDataGenerator对象的fit方法。

random_crop并未在ImageDataGenerator中内置,但参数中给了一个preprocessing_function,我们可以利用它自定义my_random_crop函数,像下面这样写:

def my_random_crop(image):
 random_arr = numpy.random.randint(img_sz-crop_sz+1, size=2)
 y = int(random_arr[0])
 x = int(random_arr[1])
 h = img_crop
 w = img_crop
 image_crop = image[y:y+h, x:x+w, :]
 return image_crop

datagen = ImageDataGenerator(
 featurewise_center=False,
 ···
 preprocessing_function=my_random_crop)

datagen.fit(x_train)

fit方法调用时将预设的变换应用到x_train的每张图上,包括图像crop,因为是单张依次处理,每张图的crop位置随机。

在训练数据(x=image, y=class_label)时这样写已满足要求;

但在(x=image, y=image_mask)时该方法就不成立了。图像单张处理的缘故,一对(image, image_mask)分别crop的位置无法保持一致。

虽然官网也给出了同时变换image和mask的写法,但它提出的方案能保证二者内置函数的变换一致,自定义函数的random变量仍是随机的。

fit_generator

既然ImageDataGenerator和flow方法不能满足我们的random_crop预处理要求,就在fit_generator函数处想方法修改。

先看它的定义:

def fit_generator(self, generator, samples_per_epoch, nb_epoch,
   verbose=1, callbacks=[],
   validation_data=None, nb_val_samples=None,
   class_weight=None, max_q_size=10, **kwargs):

第一个参数generator,可以传入一个方法,也可以直接传入数据集。前面的 datagen.flow() 即是Keras封装的批量数据传入方法。

显然,我们可以自定义。

def generate_batch_data_random(x, y, batch_size):
 """分批取batch数据加载到显存"""
 total_num = len(x)
 batches = total_num // batch_size
 while (True):
 i = randint(0, batches)
 x_batch = x[i*batch_size:(i+1)*batch_size]
 y_batch = y[i*batch_size:(i+1)*batch_size]
 random_arr = numpy.random.randint(img_sz-crop_sz+1, size=2)
 y_pos = int(random_arr[0])
 x_pos = int(random_arr[1])
 x_crop = x_batch[:, y_pos:y_pos+crop_sz, x_pos:x_pos+crop_sz, :]
 y_crop = y_batch[:, y_pos:y_pos+crop_sz, x_pos:x_pos+crop_sz, :]
 yield (x_crop, y_crop)

这样写就符合我们同组image和mask位置一致的random_crop要求。

注意:

由于没有使用ImageDataGenerator内置的数据变换方法,数据扩充则也需要自定义;由于没有使用flow(…, shuffle=True,)方法,每个epoch的数据打乱需要自定义。

generator自定义时要写成死循环,因为在每个epoch内,generate_batch_data_random是不会重复调用的。

补充知识:tensorflow中的随机裁剪函数random_crop

tf.random_crop是tensorflow中的随机裁剪函数,可以用来裁剪图片。我采用如下图片进行随机裁剪,裁剪大小为原图的一半。

如下是实验代码

import tensorflow as tf
import matplotlib.image as img
import matplotlib.pyplot as plt
sess = tf.InteractiveSession()
image = img.imread('D:/Documents/Pictures/logo3.jpg')

reshaped_image = tf.cast(image,tf.float32)
size = tf.cast(tf.shape(reshaped_image).eval(),tf.int32)
height = sess.run(size[0]//2)
width = sess.run(size[1]//2)
distorted_image = tf.random_crop(reshaped_image,[height,width,3])
print(tf.shape(reshaped_image).eval())
print(tf.shape(distorted_image).eval())

fig = plt.figure()
fig1 = plt.figure()
ax = fig.add_subplot(111)
ax1 = fig1.add_subplot(111)
ax.imshow(sess.run(tf.cast(reshaped_image,tf.uint8)))
ax1.imshow(sess.run(tf.cast(distorted_image,tf.uint8)))
plt.show()

如下是随机实验两次的结果

以上这篇Keras 在fit_generator训练方式中加入图像random_crop操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 浅谈keras通过model.fit_generator训练模型(节省内存)

    前言 前段时间在训练模型的时候,发现当训练集的数量过大,并且输入的图片维度过大时,很容易就超内存了,举个简单例子,如果我们有20000个样本,输入图片的维度是224x224x3,用float32存储,那么如果我们一次性将全部数据载入内存的话,总共就需要20000x224x224x3x32bit/8=11.2GB 这么大的内存,所以如果一次性要加载全部数据集的话是需要很大内存的. 如果我们直接用keras的fit函数来训练模型的话,是需要传入全部训练数据,但是好在提供了fit_generator,

  • 使用Keras中的ImageDataGenerator进行批次读图方式

    ImageDataGenerator位于keras.preprocessing.image模块当中,可用于做数据增强,或者仅仅用于一个批次一个批次的读进图片数据.一开始以为ImageDataGenerator是用来做数据增强的,但我的目的只是想一个batch一个batch的读进图片而已,所以一开始没用它,后来发现它是有这个功能的,而且使用起来很方便. ImageDataGenerator类包含了如下参数:(keras中文教程) ImageDataGenerator(featurewise_cen

  • 浅谈keras2 predict和fit_generator的坑

    1.使用predict时,必须设置batch_size,否则效率奇低. 查看keras文档中,predict函数原型: predict(self, x, batch_size=32, verbose=0) 说明: 只使用batch_size=32,也就是说每次将batch_size=32的数据通过PCI总线传到GPU,然后进行预测.在一些问题中,batch_size=32明显是非常小的.而通过PCI传数据是非常耗时的. 所以,使用的时候会发现预测数据时效率奇低,其原因就是batch_size太小

  • keras实现图像预处理并生成一个generator的案例

    如下所示: 接下来,给出我自己目前积累的代码,从目录中自动读取图像,并产生generator: 第一步:建立好目录结构和图像 可以看到目录images_keras_dict下有次级目录,次级目录下就直接包含照片了 **第二步:写代码建立预处理程序 # 先进行预处理图像 train_datagen = ImageDataGenerator(rescale=1./255, rotation_range=50, height_shift_range=[-0.005, 0, 0.005], width_

  • Keras 在fit_generator训练方式中加入图像random_crop操作

    使用Keras作前端写网络时,由于训练图像尺寸较大,需要做类似 tf.random_crop 图像裁剪操作. 为此研究了一番Keras下已封装的API. Data Augmentation(数据扩充) Data Aumentation 指使用下面或其他方法增加输入数据量.我们默认图像数据. 旋转&反射变换(Rotation/reflection): 随机旋转图像一定角度; 改变图像内容的朝向; 翻转变换(flip): 沿着水平或者垂直方向翻转图像; 缩放变换(zoom): 按照一定的比例放大或者

  • keras多显卡训练方式

    使用keras进行训练,默认使用单显卡,即使设置了os.environ['CUDA_VISIBLE_DEVICES']为两张显卡,也只是占满了显存,再设置tf.GPUOptions(allow_growth=True)之后可以清楚看到,只占用了第一张显卡,第二张显卡完全没用. 要使用多张显卡,需要按如下步骤: (1)import multi_gpu_model函数:from keras.utils import multi_gpu_model (2)在定义好model之后,使用multi_gpu

  • keras 两种训练模型方式详解fit和fit_generator(节省内存)

    第一种,fit import keras from keras.models import Sequential from keras.layers import Dense import numpy as np from sklearn.preprocessing import LabelEncoder from sklearn.preprocessing import OneHotEncoder from sklearn.model_selection import train_test_s

  • 浅谈TensorFlow中读取图像数据的三种方式

    本文面对三种常常遇到的情况,总结三种读取数据的方式,分别用于处理单张图片.大量图片,和TFRecorder读取方式.并且还补充了功能相近的tf函数. 1.处理单张图片 我们训练完模型之后,常常要用图片测试,有的时候,我们并不需要对很多图像做测试,可能就是几张甚至一张.这种情况下没有必要用队列机制. import tensorflow as tf import matplotlib.pyplot as plt def read_image(file_name): img = tf.read_fil

  • 利用OpenCV中对图像数据进行64F和8U转换的方式

    在OpenCV中很多对数据的运算都需要转换为64F类型,比如伽玛变换,这个很明显要求幂的底数是double类型~ 而cvShowImage()又要求是U8才能显示,否则显示出来是一片空白! 所以经常要进行转换,怎么做呢?看了下面的几行代码你就知道了! IplImage *pSrcImage = cvLoadImage("pout.jpg", CV_LOAD_IMAGE_UNCHANGED); IplImage *pGrayImage_8U = cvCreateImage(cvGetSi

  • Keras之fit_generator与train_on_batch用法

    关于Keras中,当数据比较大时,不能全部载入内存,在训练的时候就需要利用train_on_batch或fit_generator进行训练了. 两者均是利用生成器,每次载入一个batch-size的数据进行训练. 那么fit_generator与train_on_batch该用哪一个呢? train_on_batch(self, x, y, class_weight=None, sample_weight=None) fit_generator(self, generator, samples_

  • keras之权重初始化方式

    在神经网络训练中,好的权重 初始化会加速训练过程. 下面说一下kernel_initializer 权重初始化的方法. 不同的层可能使用不同的关键字来传递初始化方法,一般来说指定初始化方法的关键字是kernel_initializer 和 bias_initializer model.add(Dense(64, kernel_initializer=initializers.random_normal(stddev=0.01))) # also works; will use the defau

  • Keras预训练的ImageNet模型实现分类操作

    本文主要介绍通过预训练的ImageNet模型实现图像分类,主要使用到的网络结构有:VGG16.InceptionV3.ResNet50.MobileNet. 代码: import keras import numpy as np from keras.applications import vgg16, inception_v3, resnet50, mobilenet # 加载模型 vgg_model = vgg16.VGG16(weights='imagenet') inception_mo

  • Python OpenCV中的numpy与图像类型转换操作

    Python OpenCV存储图像使用的是Numpy存储,所以可以将Numpy当做图像类型操作,操作之前还需进行类型转换,转换到int8类型 import cv2 import numpy as np # 使用numpy方式创建一个二维数组 img = np.ones((100,100)) # 转换成int8类型 img = np.int8(img) # 颜色空间转换,单通道转换成多通道, 可选可不选 img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) cv2

  • Python中人脸图像特征提取方法(HOG、Dlib、CNN)简述

    目录 人脸图像特征提取方法 (一)HOG特征提取 (二)Dlib库 (三)卷积神经网络特征提取(CNN) 人脸图像特征提取方法 (一)HOG特征提取 1.HOG简介 Histogram of Oriented Gridients,缩写为HOG,是目前计算机视觉.模式识别领域很常用的一种描述图像局部纹理的特征.它的主要思想是在一副图像中,局部目标的表象和形状能够被梯度或边缘的方向密度分布很好地描述.其本质为:梯度的统计信息,而梯度主要存在于边缘的地方. 2.实现方法 首先将图像分成小的连通区域,这

随机推荐