問題描述:
Tensorflow 訓練時運行越來越慢,重啟后又變好。
用的是Tensorflow-GPU 1.2版本,在GPU上跑,大概就是才開始訓練的時候每個batch的時間很低,然后隨着訓練的推進,每個batch的耗時越來越長,但是當我重啟后,又一切正常了?
問題查找:
一開始查到的原因是batch_size 和 batch_num的問題,通過python yield 數據生成器解決,確保內存每次處理的數據確定是batch_size大小,但是發現運行效率還是不高,所以查閱google的一些資料找到如下解決辦法。
問題解決:
因為在運行時的session里定義了tf的op導致的。這樣每一次迭代都會在graph里增加新的節點,導致memory leak,程序越來越慢,最后強行退出。至於在運行時程序有沒有增加節點,可以在session里定義graph.finalize()鎖定graph,如果跑的時候報錯就證明程序在動態添加節點導致的越來越慢。
修改前代碼如下:
def one_hot(labels): labels_num = [strnum_convert(i) for i in labels ] batch_size = tf.size(labels_num) labels = tf.expand_dims(labels_num, 1) indices = tf.expand_dims(tf.range(0, batch_size, 1), 1) concated = tf.concat([indices, labels],1) onehot_labels = tf.sparse_to_dense(concated, tf.stack([batch_size, 8]), 1, 0) #all_hot_labels = tf.reshape(onehot_labels,(1,612)) return onehot_labels
修改后代碼如下:
def one_hot(labels): one_hot_label = np.array([int(i == int(labels)) for i in range(8)])
... ... return one_hot_label
大家可以看到罪魁禍首就是就是這個tf版本的one_hot操作,修改成numpy版本完美解決運行效率問題。
思考:
方法二:
上面問題的原因是GPU memory leak,我們也可以用的是一種曲線救國的方法;每隔1000個batch,當速度明顯變慢的時候,就reset graph,然后才重新build模型,再load之前儲存的參數tf.reset_default_graph()self.build_model();
方法三:
我們在用tensorflow進行數據集制作的時候,發現當我運行eval()函數的時候,程序會越跑越跑慢,eval()生成的數值沒有刪除,然后會越占越多內存,解決辦法是使用del命令就行,一般寫成。
data=Var.eval() #save data to file del data