1. 程式人生 > >keras 對於大資料的訓練,無法一次性載入記憶體,使用迭代器

keras 對於大資料的訓練,無法一次性載入記憶體,使用迭代器

轉處:http://blog.csdn.net/lujiandong1/article/details/54869170

說明:我是在keras的官方demo上進行修改https://github.com/fchollet/keras/blob/master/examples/imdb_cnn.py

1、幾點說明,從檔案中讀入資料,會降低GPU的使用率,如果能夠直接將資料載入記憶體,GPU的使用率會比較高。下面進行對比:

全部資料載入記憶體,GPU的使用率:

使用佇列,邊讀資料邊進行訓練:


結論:全部載入記憶體,GPU的使用率可以達到82%,如果邊載入資料邊訓練,只能達到48%

2、keras 使用迭代器來實現大資料的訓練,其簡單的思想就是,使用迭代器從檔案中去順序讀取資料。所以,自己的訓練資料一定要先隨機打散。因為,我們的迭代器也是每次順序讀取一個batch_size的資料進行訓練。

舉例如下:資料如下,前400維是特徵,後一維是label


keras 官方的demo 如下:

  1. def generate_arrays_from_file(path):  
  2.     while1:  
  3.     f = open(path)  
  4.     for line in f:  
  5.         # create Numpy arrays of input data
  6.         # and labels, from each line in the file
  7.         x, y = process_line(line)  
  8.         yield (x, y)  
  9.     f.close()  
  10. model.fit_generator(generate_arrays_from_file('/my_file.txt'
    ),  
  11.         samples_per_epoch=10000, nb_epoch=10)  
說明:官方的demo還是有瑕疵的,沒有實現batch_size,該demo每次只能提取一個樣本。我針對上述的資料集,實現的batch_size資料提取的迭代器,程式碼如下:
  1. def process_line(line):  
  2.     tmp = [int(val) for val in line.strip().split(',')]  
  3.     x = np.array(tmp[:-1])  
  4.     y = np.array(tmp[-1:])  
  5.     return x,y  
  6. def generate_arrays_from_file(path,batch_size):  
  7.     while1:  
  8.         f = open(path)  
  9.         cnt = 0
  10.         X =[]  
  11.         Y =[]  
  12.         for line in f:  
  13.             # create Numpy arrays of input data
  14.             # and labels, from each line in the file
  15.             x, y = process_line(line)  
  16.             X.append(x)  
  17.             Y.append(y)  
  18.             cnt += 1
  19.             if cnt==batch_size:  
  20.                 cnt = 0
  21.                 yield (np.array(X), np.array(Y))  
  22.                 X = []  
  23.                 Y = []  
  24.     f.close()  

訓練時候的程式碼如下:
  1. model.fit_generator(generate_arrays_from_file('./train',batch_size=batch_size),  
  2.         samples_per_epoch=25024,nb_epoch=nb_epoch,validation_data=(X_test, y_test),max_q_size=1000,verbose=1,nb_worker=1)  

3、關於samples_per_epoch的說明:

我的訓練資料,train只有25000行,batch_size=32。照理說samples_per_epoch=32,但是會有警告.UserWarning: Epoch comprised more than `samples_per_epoch` samples, which might affect learning results


說明:這個出錯的原因是train的數目/batch_size不是整數。可以將samples_per_epoch = ceil(train_num/batch_size) *batch_size.設定完的結果為88.72%:


keras的demo使用的方法是將全部資料載入進來訓練:


demo的結果為88.86%,所以,該資料讀取的方式基本沒問題。但是,一定要將資料先進行打亂。如果能全部載入記憶體,就全部載入記憶體,速度會快不少