1. 程式人生 > 程式設計 >keras使用Sequence類呼叫大規模資料集進行訓練的實現

keras使用Sequence類呼叫大規模資料集進行訓練的實現

使用Keras如果要使用大規模資料集對網路進行訓練,就沒辦法先載入進記憶體再從記憶體直接傳到視訊記憶體了,除了使用Sequence類以外,還可以使用迭代器去生成資料,但迭代器無法在fit_generation裡開啟多程序,會影響資料的讀取和預處理效率,在本文中就不在敘述了,有需要的可以另外去百度。

下面是我所使用的程式碼

class SequenceData(Sequence):
  def __init__(self,path,batch_size=32):
    self.path = path
    self.batch_size = batch_size
    f = open(path)
    self.datas = f.readlines()
    self.L = len(self.datas)
    self.index = random.sample(range(self.L),self.L)
  #返回長度,通過len(<你的例項>)呼叫
  def __len__(self):
    return self.L - self.batch_size
  #即通過索引獲取a[0],a[1]這種
  def __getitem__(self,idx):
    batch_indexs = self.index[idx:(idx+self.batch_size)]
    batch_datas = [self.datas[k] for k in batch_indexs]
    img1s,img2s,audios,labels = self.data_generation(batch_datas)
    return ({'face1_input_1': img1s,'face2_input_2': img2s,'input_3':audios},{'activation_7':labels})

  def data_generation(self,batch_datas):
    #預處理操作
    return img1s,labels

然後在程式碼裡通過fit_generation函式呼叫並訓練

這裡要注意,use_multiprocessing引數是是否開啟多程序,由於python的多執行緒不是真的多執行緒,所以多程序還是會獲得比較客觀的加速,但不支援windows,windows下python無法使用多程序。

D = SequenceData('train.csv')
model_train.fit_generator(generator=D,steps_per_epoch=int(len(D)),epochs=2,workers=20,#callbacks=[checkpoint],use_multiprocessing=True,validation_data=SequenceData('vali.csv'),validation_steps=int(20000/32)) 

同樣的,也可以在測試的時候使用

model.evaluate_generator(generator=SequenceData('face_test.csv'),steps=int(125100/32),workers=32)

補充知識:keras資料自動生成器,繼承keras.utils.Sequence,結合fit_generator實現節約記憶體訓練

我就廢話不多說了,大家還是直接看程式碼吧~

#coding=utf-8
'''
Created on 2018-7-10
'''
import keras
import math
import os
import cv2
import numpy as np
from keras.models import Sequential
from keras.layers import Dense

class DataGenerator(keras.utils.Sequence):
  
  def __init__(self,datas,batch_size=1,shuffle=True):
    self.batch_size = batch_size
    self.datas = datas
    self.indexes = np.arange(len(self.datas))
    self.shuffle = shuffle

  def __len__(self):
    #計算每一個epoch的迭代次數
    return math.ceil(len(self.datas) / float(self.batch_size))

  def __getitem__(self,index):
    #生成每個batch資料,這裡就根據自己對資料的讀取方式進行發揮了
    # 生成batch_size個索引
    batch_indexs = self.indexes[index*self.batch_size:(index+1)*self.batch_size]
    # 根據索引獲取datas集合中的資料
    batch_datas = [self.datas[k] for k in batch_indexs]

    # 生成資料
    X,y = self.data_generation(batch_datas)

    return X,y

  def on_epoch_end(self):
    #在每一次epoch結束是否需要進行一次隨機,重新隨機一下index
    if self.shuffle == True:
      np.random.shuffle(self.indexes)

  def data_generation(self,batch_datas):
    images = []
    labels = []

    # 生成資料
    for i,data in enumerate(batch_datas):
      #x_train資料
      image = cv2.imread(data)
      image = list(image)
      images.append(image)
      #y_train資料 
      right = data.rfind("\\",0)
      left = data.rfind("\\",right)+1
      class_name = data[left:right]
      if class_name=="dog":
        labels.append([0,1])
      else: 
        labels.append([1,0])
    #如果為多輸出模型,Y的格式要變一下,外層list格式包裹numpy格式是list[numpy_out1,numpy_out2,numpy_out3]
    return np.array(images),np.array(labels)
  
# 讀取樣本名稱,然後根據樣本名稱去讀取資料
class_num = 0
train_datas = [] 
for file in os.listdir("D:/xxx"):
  file_path = os.path.join("D:/xxx",file)
  if os.path.isdir(file_path):
    class_num = class_num + 1
    for sub_file in os.listdir(file_path):
      train_datas.append(os.path.join(file_path,sub_file))

# 資料生成器
training_generator = DataGenerator(train_datas)

#構建網路
model = Sequential()
model.add(Dense(units=64,activation='relu',input_dim=784))
model.add(Dense(units=2,activation='softmax'))
model.compile(loss='categorical_crossentropy',optimizer='sgd',metrics=['accuracy'])
model.compile(optimizer='sgd',loss='categorical_crossentropy',metrics=['accuracy'])
model.fit_generator(training_generator,epochs=50,max_queue_size=10,workers=1)

以上這篇keras使用Sequence類呼叫大規模資料集進行訓練的實現就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。