[英]Tensorflow graph nodes are exchange
我已經通過微調預訓練 model ssd_mobilenet_v2_coco_2018
。 在這里,我使用了完全相同的 pipeline.config 文件進行訓練,該文件位於ssd_mobilenet_v2_coco_2018
預訓練文件夾中。 我只刪除了batch_norm_trainable: true
標志並更改了類數(4)。 在使用具有 4 個類的自定義數據集訓練 model 后,我發現concat
和concat_1
節點相互交換。 預訓練的 model 有| concat | 1x1917x1x4 |
| concat | 1x1917x1x4 |
訓練后就變成了| concat | 1x1917x5 |
| concat | 1x1917x5 |
我附上了兩個張量板圖形可視化圖像。 第一張圖片是預訓練圖ssd_mobilenet_v2_coco_2018
。
節點交換可以在圖像的最右角看到。 與預訓練圖一樣, Postprocess layer
與concat_1
連接, Squeeeze
與concat
連接。 但是在訓練之后,圖表顯示完全相反。 像Prosprocess layer
連接concat
和Squeeeze
連接concat_1
。 此外,我還在預訓練的 model 圖中發現Preprocessor
接受輸入ToFloat
,而在訓練后,該圖顯示 Cast 作為Preprocessor
的輸入。 我已將輸入作為 tfrecords 提供給tfrecords
。
最有可能的是,區別不在於圖形,而只是節點的名稱,即左側的節點concat
和concat_1
與 resp 是相同的節點。 concat_1
和concat
在右邊。
問題是,當您沒有為節點提供明確的名稱時,tensorflow 需要提出一個,而且它的命名約定相當缺乏創造性。 第一次需要命名一個節點時,它會使用它的類型。 當它再次遇到這種情況時,它只是在名稱中添加_
+一個遞增的數字。
舉個例子:
import tensorflow as tf
x = tf.placeholder(tf.float32, (1,), name='x')
y = tf.placeholder(tf.float32, (1,), name='y')
z = tf.placeholder(tf.float32, (1,), name='z')
xy = tf.concat([x, y], axis=0) # named 'concat'
xz = tf.concat([x, z], axis=0) # named 'concat_1'
該圖如下所示:
現在,如果我們構建相同的圖,但這次在xy
之前創建xz
,我們將得到以下圖:
所以圖表並沒有真正改變——只有名字改變了。 這可能是您的情況發生的情況:創建了相同的操作,但順序不同。
像concat
這樣的無狀態節點的名稱更改這一事實並不重要,因為例如在加載保存的 model 時,不會錯誤路由權重。 盡管如此,如果命名穩定性對您很重要,您可以為您的操作提供明確的名稱或將它們放在不同的范圍內:
xy = tf.concat([x, y], axis=0, name='xy')
xz = tf.concat([x, z], axis=0, name='xz')
如果變量切換名稱,問題就會大得多。 這就是為什么tf.get_variable
(它強制變量具有名稱並在發生名稱沖突時引發錯誤)是 TF2 之前時代處理變量的首選方式的原因之一。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.