深度学习08-图像预处理(图像数据扩充+图像缩放+流水在线处理+keras+cifar10案例)

1、缺少源数据对建模的影响

如果缺少源数据只有对数据加工后的数据:将cifar10案例的自变量X部分都除以255.这里仅仅展示部分重要,全部代码在后面附上。

X_train1 = X_train1.astype('float32') / 255
X_test1 = X_test1.astype('float32') / 255

这是最后的拟合效果:
在这里插入图片描述

2、图像数据扩充

定义所需的图像变换方法

图像变换使用keras的函数ImageDataGenerator

from keras.preprocessing.image import ImageDataGenerator

img_generator = ImageDataGenerator(
    rotation_range = 90,
    width_shift_range = 0.2,
    height_shift_range = 0.2,
    zoom_range = 0.3
    )

部分参数解析:
rotation_range = 0 : 整数,随机旋转的度数范围,取值为0~180的度数。
width_shift_range / height_shift_range = 0.0 : 浮点数、一维数组或整数。
图片内容在水平和竖直方向随机移动的程度,一般使用原宽度/高度0~1之间的比例。
平移图片的时候会出现超出原图范围的区域,该区域会根据fill_mode的设定来补全。
zoom_range = 0.0 : 浮点数或[lower, upper],随机缩放范围,整数为具体范围。
若为浮点数,则相当于[lower,upper] = [1-zoom_range, 1+zoom_range]。

from keras.preprocessing import image
from matplotlib import pyplot as plt
import numpy as np
from PIL import Image #PIL pakage name is Pillow 

img = plt.imread(r'F:\learning_kecheng\deenlearning\NEW\pic1.jpg')
imgarr = np.array([img * 1.0]) # 将图片矩阵处理为所需的浮点格式
imgarr.shape
Image.fromarray(img)#矩阵转图片

生成新的图像数据

我们先看一个例子,这是手写体的一个样本,原本是这样:
在这里插入图片描述

gen = img_generator.flow(imgarr)
next(gen).shape
Image.fromarray(np.uint8(next(gen)[0]))
plt.imshow(np.uint8(next(gen)[0]))

使用ImageDataGenerator函数变换之后:
在这里插入图片描述
修改参数 rotation_range = 180:
在这里插入图片描述

plt.figure()
for i in range(3):
    for j in range(3):
        x_batch = np.uint8(next(gen)[0])
        idx = (3 * i) + j
        plt.subplot(3, 3, idx + 1, xticks = [], yticks = [])
        plt.imshow(x_batch)

在这里插入图片描述

3、流式在线处理

流式在线处理的优势;

1、可以将待处理数据分批加载,避免硬件资源不足。
2、无需等待全部数据加载/生成完毕,可直接进行后续处理。
3、可以将数据生成器与模型拟合并行运行,以提高效率,例如在CPU上对图像进行实时数据增强,同时在GPU上训练模型。

生成结果迭代器

gen = img_generator.flow(X_train1, y_train1)
# 使用迭代器对模型进行拟合
model.fit_generator(gen, epochs = 10)
model.evaluate_generator(gen)
model.evaluate(X_test1, y_test1)

在这里插入图片描述

图像的缩放

以cifar10数据集的一个图片为例实现对图片进行缩放

from keras.datasets import cifar10

(X_train, y_train), (X_test, y_test) = cifar10.load_data() 
from PIL import Image #PIL pakage name is Pillow 

# 用Image.fromarray将矩阵转换为图像对象
img = Image.fromarray(X_train[0])
img

这是原来的图片:
在这里插入图片描述
原本是3232的矩阵
在这里插入图片描述
使用resizeha函数:变换成224
224

img.resize((224, 224)) 

在这里插入图片描述
使用getdata()将图像对象转换回每个通道对应一维数组的结构

np.array(img.getdata()).shape

重新输出的图片和原放大后图片完全相同

arr = np.array(img.getdata()).reshape(224, 224, 3)
arr.shape
Image.fromarray(np.uint8(arr))

使用Keras的图像预处理模块

直接设定参数target_size 就可以变换大小

from keras.preprocessing import image

# 按照指定大小载入图片
img = image.load_img(r'F:\learning_kecheng\deenlearning\NEW\pic1.jpg', target_size = (512, 512))
print(img)
img
image.img_to_array(img.resize((224, 224))).shape

仍然可以用resize函数变换
在这里插入图片描述

附录:第一小节的代码

from keras.datasets import cifar10

(X_train, y_train), (X_test, y_test) = cifar10.load_data() 
X_train1 = X_train[:1000]; y_train1 = y_train[:1000]
X_test1 = X_test[:1000]; y_test1 = y_test[:1000]
print("训练集:%2.0f,测试集:%2.0f" %(X_train1.shape[0], X_test1.shape[0]))

# 将原始数据转换为[0, 1]区间
X_train1 = X_train1.astype('float32') / 255
X_test1 = X_test1.astype('float32') / 255

import keras

# 类别向量转为多分类矩阵
y_train1 = keras.utils.to_categorical(y_train1, 10)
y_test1 = keras.utils.to_categorical(y_test1, 10)
'''
此处直接套用上一博客中设定的复杂CNN模型框架
'''
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D
# 建立基于keras的cnn模型
model = Sequential()
# 卷积==>卷积==>最大池化
model.add(Conv2D(32, (3, 3), padding = 'same',
                 input_shape = X_train.shape[1:])) # 第一层需要指定数据格式
model.add(Activation('relu'))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size = (2, 2)))
model.add(Dropout(0.25))

# 卷积==>卷积==>最大池化
model.add(Conv2D(64, (3, 3), padding = 'same'))
model.add(Activation('relu'))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size = (2, 2)))
model.add(Dropout(0.25))

# 将数据展平
model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(10))
model.add(Activation('softmax'))
model.summary()
# 均方根反向传播(RMSprop,root mean square prop)优化
opt = keras.optimizers.rmsprop(lr = 0.0001, decay = 1e-6)
 
# 使用均方根反向传播(RMSprop)训练模型
model.compile(loss = 'categorical_crossentropy',
              optimizer = opt,
              metrics = ['accuracy'])

# 使用迭代器对模型进行拟合

# 生成结果迭代器
model.fit(X_train1, y_train1,
              batch_size = 32,
              epochs = 10,
              shuffle = True)
model.evaluate(X_test1, y_test1)

猜你喜欢

转载自blog.csdn.net/qq_42871249/article/details/104769310
今日推荐