最近在做一個鑒黃的項目,數據量比較大,有幾百個G,一次性加入內存再去訓練模青型是不現實的。
查閱資料發現keras中可以用兩種方法解決,一是將數據轉為tfrecord,但轉換后數據大小會方法不好;另外一種就是利用generator,先一次加入所有數據的路徑,然后每個batch的讀入
# 讀取圖片函數
def get_im_cv2(paths, img_rows, img_cols, color_type=1, normalize=True): ''' 參數: paths:要讀取的圖片路徑列表 img_rows:圖片行 img_cols:圖片列 color_type:圖片顏色通道 返回: imgs: 圖片數組 '''
# Load as grayscale
imgs = [] for path in paths: if color_type == 1: img = cv2.imread(path, 0) elif color_type == 3: img = cv2.imread(path) # Reduce size
resized = cv2.resize(img, (img_cols, img_rows)) if normalize: resized = resized.astype('float32') resized /= 127.5 resized -= 1. imgs.append(resized) return np.array(imgs).reshape(len(paths), img_rows, img_cols, color_type)
def get_train_batch(X_train, y_train, batch_size, img_w, img_h, color_type, is_argumentation): ''' 參數: X_train:所有圖片路徑列表 y_train: 所有圖片對應的標簽列表 batch_size:批次 img_w:圖片寬 img_h:圖片高 color_type:圖片類型 is_argumentation:是否需要數據增強 返回: 一個generator,x: 獲取的批次圖片 y: 獲取的圖片對應的標簽 '''
while 1: for i in range(0, len(X_train), batch_size): x = get_im_cv2(X_train[i:i+batch_size], img_w, img_h, color_type) y = y_train[i:i+batch_size] if is_argumentation: # 數據增強
x, y = img_augmentation(x, y) # 最重要的就是這個yield,它代表返回,返回以后循環還是會繼續,然后再返回。就比如有一個機器一直在作累加運算,但是會把每次累加中間結果告訴你一樣,直到把所有數加完
yield(np.array(x}, np.array(y))
result = model.fit_generator(generator=get_train_batch(X_train, y_train, train_batch_size, img_w, img_h, color_type, True), steps_per_epoch=1351, epochs=50, verbose=1, validation_data=get_train_batch(X_valid, y_valid, valid_batch_size,img_w, img_h, color_type, False), validation_steps=52, callbacks=[ckpt, early_stop], max_queue_size=capacity, workers=1)
參考:https://www.jianshu.com/p/5bdae9dcfc9c
https://keras.io/zh/models/model/