深度學習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)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章