文章參考:https://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):
while 1:
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)
說明:官方的demo還是有瑕疵的,沒有實作batch_size,該demo每次隻能提取一個樣本。我針對上述的資料集,實作的batch_size資料提取的疊代器,代碼如下:
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):
while 1:
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%,是以,該資料讀取的方式基本沒問題。但是,一定要将資料先進行打亂。如果能全部載入記憶體,就全部載入記憶體,速度會快不少