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 如下:
- def generate_arrays_from_file(path):
- while1:
- f = open(path)
- for line in f:
- # create Numpy arrays of input data
- # and labels, from each line in the file
- x, y = process_line(line)
- yield (x, y)
- f.close()
- model.fit_generator(generate_arrays_from_file('/my_file.txt'
- samples_per_epoch=10000, nb_epoch=10)
- def process_line(line):
- tmp = [int(val) for val in line.strip().split(',')]
- x = np.array(tmp[:-1])
- y = np.array(tmp[-1:])
- return x,y
- def generate_arrays_from_file(path,batch_size):
- while1:
- f = open(path)
- cnt = 0
- X =[]
- Y =[]
- for line in f:
- # create Numpy arrays of input data
- # and labels, from each line in the file
- x, y = process_line(line)
- X.append(x)
- Y.append(y)
- cnt += 1
- if cnt==batch_size:
- cnt = 0
- yield (np.array(X), np.array(Y))
- X = []
- Y = []
- f.close()
訓練時候的程式碼如下:
- model.fit_generator(generate_arrays_from_file('./train',batch_size=batch_size),
- 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%,所以,該資料讀取的方式基本沒問題。但是,一定要將資料先進行打亂。如果能全部載入記憶體,就全部載入記憶體,速度會快不少