TensorFlow:Skipping cancelled enqueue attempt with queue not closed

今天運行TensorFlow的代碼,沒運行完一個epoch就直接報錯崩掉了,然后定位錯誤,發現了一個警告信息如下:

_2_index/fraction_of_32_full/fraction_of_32_full:Skipping cancelled enqueue attempt with queue not closed

接著代碼到后面就崩掉了,報錯的信息如下:


tensorflow.python.framework.errors_impl.OutOfRangeError:FIFOQueue '_0_batch_join/fifo_queue' is closed and has insufficient elements(requested 64, current size 59)

[[Node: batch_join =QueueDequeueManyV2[component_types=[DT_FLOAT, DT_INT64], timeout_ms=-1,_device="/job:localhost/replica:0/task:0/cpu:0"](batch_join/fifo_queue,batch_join/n)]]

[[Node: batch_join/_2179 =_Recv[client_terminated=false,recv_device="/job:localhost/replica:0/task:0/gpu:0",send_device="/job:localhost/replica:0/task:0/cpu:0",send_device_incarnation=1, tensor_name="edge_12_batch_join",tensor_type=DT_INT64,_device="/job:localhost/replica:0/task:0/gpu:0"]()]]


大致的意思是,在調用batch_join的時候,隊列需要64個元素(一個batch_size大小),但是隊列中只有59個元素,導致了OutOffRangeError。設置tf.train.batch_join函數中的allow_smaller_final_batch為True可以避免這樣的錯誤發生,不過這會到導致batch_join函數獲得的數據的size是不確定的,會帶來一系列其他的影響。

在追蹤錯誤發生的過程中,我注意到上述的警告信息,其整個報錯和警告關聯的業務代碼簡化版大致如下:


indices_que =tf.train.range_input_producer(range_size, name='index')

deque_op =indices_que.dequeue_many(self.batch_size*self.batch_num,'index_dequeue')

input_queue = tf.FIFOQueue(capacity=100000,dtypes=[tf.string, tf.int64], shapes=[(1,), (1,)], name='input_que')

enque_op = input_queue.enqueue_many([samples],name='enque_op')

batch_sample= tf.train.batch_join(input_queue_list,batch_size= batch_size,enqueue_many=False,capacity=4*num_threads*self.batch_size,allow_smaller_final_batch=False)


其中input_queue_list與input_queue相關,是從input_queue中獲取元素處理的一個list(涉及每個線程處理的具體業務邏輯,因此省略)。

而警告信息來自于其中某一個隊列,可以看出其enqueue的入隊操作沒有完成,然后在運行中我嘗試打印出deueu_op的結果,其結果無誤,每次出對的索引數量都是batch_size*batch_num個,因而問題出現在enque_op部分,猜測是enqueue_many過程沒有完成,隊列就關閉了。

經過反復檢查代碼,發現可能導致隊列關閉的代碼如下:

run_config= tf.ConfigProto()

run_config.operation_timeout_in_ms= 10000

這段代碼為TensorFlow所有的阻塞操作定義了一個毫秒級別的超時時間,猜測由于是非主線程的其他線程進行enqueue_many操作,然后入隊過程中超時,導致了隊列被關閉,但是沒有拋出異常到主線程,導致主線程繼續運行直至報錯。

解決辦法也很簡單,就是不設置超時時間即可。

上述的問題解決過程中可以看到幾點:

1.雖然調用的是enqueue_many操作,但是具體實現的時候,enqueue_many也可能是一個一個元素往隊列中存放的。

2.TensorFlow有可能忽略掉非主線程的異常的拋出,因而在運行調試中,要注意一些警告信息,或者自己指定處理非主線程的其他線程的異常信息。

最后,如果上述無法解決你的Skipping cancelled enqueue attempt with queue not closed的問題,那么嘗試在Session結束的地方,加入

coord.request_stop()

coord.joint(thread)

這個解決辦法來自:http://qiita.com/7of9/items/3b9364444418e128c92a

或者是嘗試更新TensorFlow的版本,有人提及這個可能涉及到TensorFlow的版本BUG,詳情見:https://github.com/TensorBox/TensorBox/issues/25

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • MachineLP閱讀 311評論 0 0
  • Tensorflow的數據讀取有三種方式: Preloaded data: 預加載數據,也就是TensorFlow...
    是neinei啊閱讀 3,859評論 0 2
  • 多次穿梭于主樓與講座樓并切切實實感受著撲面而來的妖風的我們最后坐在了306。 這次依舊一樣,with辣么美來上課,...
    洋相相相閱讀 307評論 0 0
  • 焦慮和恐懼,緊張,全職三年,這種情緒感受的最明顯,特別茆同志回來,看他忙碌的身影,越發焦慮,似乎我需要做些什...
    愛自滿溢閱讀 260評論 0 0
  • 分子集自由人 這一切,源于一碗面的愛情 十二年前 在陜西的一個小縣城 那時候 早戀這件事情是學校明令禁止的 況且是...
    哲神閱讀 888評論 2 5