keras報錯:AttributeError: '_thread._local' object has no attribute 'value'


  需求是使用pyqt5中的槽函數運行keras模型訓練,為了不讓工具在模型訓練的過程中出現假死的現象,於是把訓練操作放到單獨的線程中運行,於是問題來了,訓練操作在主線程運行時正常,但是界面假死,假若訓練在單獨的線程中運行就會出現下面這個問題。

  網上對此錯誤的解釋是keras和TensorFlow的版本不對,但是並沒有解釋為什么,一開始我是懷疑的,為什么在主線程中能夠正常運行,單獨開一個線程時就不行了,這為什么是版本的問題?

 

  定位到錯誤代碼的地方,如下圖所示,問題是_SYMBOLIC_SCOPE這個對象沒有value這個值。

  接着我們定位到_SYMBOLIC_SCOPE創建的位置,如下圖所示,我們發現在這個_SYMBOLIC_SCOPE創建之后馬上就給他賦值value。

 

  那問題來了為什么會出現value找不到呢?其實關鍵是_SYMBOLIC_SCOPE = threading.local()這個函數,作用就是將不同線程的值分隔開,即單獨開一個線程運行時通過_SYMBOLIC_SCOPE是取不到另一個線程中給_SYMBOLIC_SCOPE添加的值。

  那么問題又來了,value值是在哪個線程中賦值的呢?如下圖所示,其實我們可以發現當import keras的時候,會等待一會的時間,其實是TensorFlow會在后台起一個線程作為守護線程,守護線程執行上面的操作,當我們單獨再起一個線程運行時,新的線程是無法取到守護線程賦予的value值,所以就會出錯。具體為什么這樣實現暫時還不清楚,反正就是多線程去運行keras是不可以,我甚至想過結束后台線程或者更改keras的代碼,手動給_SYMBOLIC_SCOPE .value賦值,雖然程序可以正常運行,但是引入了不確定的風險。

  最后回頭去思考版本的問題,出錯的版本的2.3.1,然后找到一個2.2.4版本的keras去看代碼發現沒有_SYMBOLIC_SCOPE這個操作,所以使用這個版本后單獨開一個線程是可以正常運行的。

 

  注意:

  1、keras版本更改之后可能會出現TensorFlow、Numpy報錯現象,可能是版本不匹配,重新選擇一個可用的版本即可,下面是我使用版本

keras == 2.2.4
TensorFlow == 1.13.1
Numpy == 1.16.0
python == 3.7

  2、出錯的文件是keras/backend/tensorflow_backend.py,兩個版本的此文件代碼差異較大。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM