1. 程式人生 > >Tensorflow object detection API 搭建屬於自己的物體識別模型——常見問題彙總 Q&A

Tensorflow object detection API 搭建屬於自己的物體識別模型——常見問題彙總 Q&A

建議 Ctrl + F 在頁面內搜尋問題。

如果對問題有新的更好的解決方案歡迎留言。

Q:Image size must contain 3 elements.

圖片大小必須包括3元素

A:圖片不是標準的RGB3通道圖片,把圖片轉化成標準的RGB格式或者刪除有問題的圖片。

如果目錄下有很多圖片,可以用下面的命令來檢查哪些圖片不是標準RGB格式:

from PIL import Image     
import os       
path = '/Users/lyz/Desktop/dataset/images/' #圖片目錄 
for file in os.listdir(path):      
     extension = file.split('.')[-1]
     if extension == 'jpg':
           fileLoc = path+file
           img = Image.open(fileLoc)
           if img.mode != 'RGB':
                 print(file+', '+img.mode)

Q: 提取frozen_inference_graph.pb 這一檔案時,出現了資料型別錯誤

TypeError: x and y must have the same dtype, got tf.float32 != tf.int32

A:在 post_processing_builder.py 檔案中,修改下面這個函式:

def _score_converter_fn_with_logit_scale(tf_score_converter_fn, logit_scale):
  """Create a function to scale logits then apply a Tensorflow function."""
  def score_converter_fn(logits):
    cr = logit_scale
    cr = tf.constant([[cr]],tf.float32)
    print(logit_scale)
    print(logits)
    scaled_logits = tf.divide(logits, cr, name='scale_logits') #change logit_scale
    return tf_score_converter_fn(scaled_logits, name='convert_scores')
  score_converter_fn.__name__ = '%s_with_logit_scale' % (
      tf_score_converter_fn.__name__)
  return score_converter_fn

Q:輸出圖片失真,偏藍色

A:opencv的輸出imwrite函式引數調整,輸出標準RGB格式。

Q:能否識別中文的標籤?

A:沒有測試過,可以試試在訓練檔案裡標註中文。

Q:訓練過程中被打斷,報錯提示

Invalid GIF data, size 247023

A:GIF 檔案過大,不支援格式。(小的GIF是否支援我不清楚,請測試過的讀者告知)

Q:訓練正常,但是效果很差。

A:

1、迭代次數不夠,預設設定200000次,在Tensorboard中檢視,Loss趨於穩定後差不多可以結束訓練;

2、訓練資料少,理論上講,訓練、測試資料數量越多、資料質量約好,效果越好;

3、不同模型效果差異,model zoo上訓練的模型準確率基於公開資料集,雖然速度快的模型不一定效果差,往往是總體準確率高的模型效果好一些。

4、如果本身你自己的資料集較大,類別數量很多,那麼20W次迭代可能還是不夠,看整體損失函式的下降情況而定。

Q: module 'tensorflow.contrib.data' has no attribute 'parallel_interleave'

A: 新舊版本的模組名稱不同,升級到最新版Tensorflow可以解決。

Q:csv檔案轉換為tfrecord檔案出錯

A:

幾點需要確認一下:

1.      在object_detection.py 程式裡,確認 NUM_CLASSES = 你自己的類別數

2.    確認一下執行時候的路徑有沒有錯(python generate_tfrecord.py --csv_input=data/tv_vehicle_labels.csv  --output_path=train.record)

3.      .config 檔案裡 num_classes: 你自己的類別數

4.      .pbtxt 檔案下 item序號與名稱與generate_tfrecord.py 裡的序號名稱必須一一對應。


Q: 執行 xml_to_csv.py 時出錯,ParseError: not well-formed (invalid token): line 1, column 0

A:

 .xml標註檔案裡含有非法字元,是不是用了一些特殊符號?或者改成英文試試。

參考:

Q: 

tensorflow.python.framework.errors_impl.NotFoundError: NewRandomAccessFile failed to Create/Open: /yourpath/....jpg; No such process

A: 各個步驟檔名或者路徑的問題,可以先檢查一下。

如果不確定,可以把 報錯的.jpg 以及對應的 .xml檔案開啟檢視一下,確定.xml裡的檔名也是對的,有讀者遇到 images6.jpg 無法開啟報錯,發現images6.xml裡的 filename 是 image6 而不是image6.jpg,這可能是標註軟體Labellmg的問題。

Q: can not reshape array of size 345600 into shape (240,360,3)

A: 圖片大小或者格式不標準,可以檢查一下是不是所有圖片都有這個問題

Q: TypeError: None has type NoneType, but expected one of: int, long

A: 

方案1:

class_text_to_int

函式中定義了不同類別返回的數字:

def class_text_to_int(row_label):

    if row_label == 'tv':

        return 1

    else:

        None

把else: 後面的 “None” 改成“return 0,即

def class_text_to_int(row_label):

    if row_label == 'tv':

        return 1

    else:

        return 0

方案2:

部分圖片格式問題,轉化後再試一試。

Q: TypeError: `pred` must be a Tensor, or a Python bool, or 1 or 0. Found instead: None

A: 

change 109 line in ssd_mobilenet_v1_feature_extractor.py:
from

              is_training=None, regularize_depthwise=True)):

to

              is_training=True, regularize_depthwise=True)):

Q: 開始訓練以後顯示的loss有兩行,

INFO tensorflow global step 1 loss=1.1555

INFO tensorflow global step 1 loss=1.1555

INFO tensorflow global step 2 loss=1.1556

INFO tensorflow global step 2 loss=1.1556


A: 這個問題不是很清楚,歡迎讀者討論。

Q: 不訓練自己的模型,直接呼叫官方模型,但是隻用於識別特定一個或者幾個物體可以嗎?

A: 

這裡有一個只識別交通訊號燈的例子,可以看看參考一下。

Q: 按照上述步驟訓練後,匯出模型測試圖片,但輸出的圖片與原始圖片一樣,沒有進行任何標註,請問可能是哪裡出錯了?

A:

原因可能又很多: 

1、標籤名稱是否正確,包括labelimage內部,generate_tfrecord.py 裡面 def class_text_to_int(row_label): 這個函式中的設定,以及config資料夾下 .pbtxt 檔案。 上述檔案中標籤的名字及對應序號必須相同。 

2、再次檢查檔名稱已經資料夾路徑是否正確。 

3、Number of classes 是否修改正確。 

4、訓練過程是否有異常之處,通過tensorboard視覺化檢視訓練過程。 

5、訓練的資料過少也有可能。 

6、試一試其他預先訓練好的模型。

Q: 在我進行模型訓練的時候出現了以下問題: Instructions for updating: Please switch to tf.train.create_global_step Traceback (most recent call last): 。。。 TypeError: __init__() got an unexpected keyword argument 'dct_method'

A: 

這個應該是由於Tensorflow版本的問題,我的是基於1.4版本,你的應該是1.5版本。 可以在 models/research/object_detection/data_decoders/tf_example_decoder.py 檔案的第110行, 刪去 “dct_method=dct_method”這一句。 

具體請看下面這個網址: 

https://stackoverflow.com/questions/48920762/tensorflow-error-typeerror-init-got-an-unexpected-keyword-argument-dct

Q: 訓練中斷,怎樣繼續進行?

A: 只要training 資料夾下的檔案沒有動,那麼重新輸入訓練的命令,就會從上次自動儲存的斷點繼續訓練。

Q: 執行train.py的時候報錯 IndexError: list index out of range 

A:直接原因是引用了不存在的編號,可以檢查一下訓練的檔案跟生成的csv表格是不是有不存在的圖片名稱

Q: 在訓練時一直出現ValueError: axis = 0 not in [0, 0),不知道怎麼解決,看您視訊也出現這個問題,但是沒有說解決方案就跳過去了,麻煩您說明一下。

A:

在pipeline.config 檔案中,找到 loss{}這一類,

loss {
classification_loss {
weighted_sigmoid {
}
}
localization_loss {
weighted_smooth_l1 {
}
}
hard_example_miner {
num_hard_examples: 3000
iou_threshold: 0.99
loss_type: CLASSIFICATION
max_negatives_per_positive: 3
min_negatives_per_image: 0
}
classification_weight: 1.0
localization_weight: 1.0
}

改成如下部分:

loss {
  classification_loss {
    weighted_sigmoid {
    anchorwise_output: true  #add this
    }
  }
  localization_loss {
    weighted_smooth_l1 {
    anchorwise_output: true  #add this
    }
  }
  hard_example_miner {
    num_hard_examples: 3000
    iou_threshold: 0.99
    loss_type: CLASSIFICATION
    max_negatives_per_positive: 3
    min_negatives_per_image: 0
  }
  classification_weight: 1.0
  localization_weight: 1.0
}

參考:https://github.com/datitran/raccoon_dataset/issues/45

Q: File "C:\ProgramData\anaconda3.1\lib\xml\etree\ElementTree.py", line 597, in parse self._root = parser._parse_whole(source) File "", line unknown ParseError: not well-formed (invalid token): line 1, column 0 請問該如何解決呢

A:

可能在檔案中包含了非法字元,可以在檢查一下,另外我建議標籤用英文。如果還沒解決,看一下這個網址的問題:https://stackoverflow.com/questions/13046240/parseerror-not-well-formed-invalid-token-using-celementtree,裡面有類似問題的解決方案,把xml_to_csv.py裡對應的部分改一下

Q: 博主 ssd_mobile這個模型我可以執行的完美 但換成別的模型 如faster_rcnn_inception_resnet_v2_atrous_coco,會出現下面的問題:ValueError: Tried to convert 't' to a tensor and failed. Error: Argument must be a dense tensor: range(0, 3) - got shape [3], but wanted [].有人用別的模型成功過的嗎

A:我之前用1.4版本的時候是成功過的。你的問題我谷歌上搜了一下似乎是相容性的問題,github上有相關的解決方法你可以參考一下:

https://github.com/tensorflow/models/issues/3705#issuecomment-375563179 https://github.com/tensorflow/models/issues/3752

Q: 為什麼我的結果沒有畫框?

A: 

來自 @kurumi233

對最後測試沒有畫框的人,我希望我的回答可以幫到你們,你可以列印一下測試demo程式碼最後的output_dict,裡面有box的座標還有分數之類的,你看一下分數就知道了,你如果標籤之類的沒問題的話,肯定分數很低的,可能只有0.0幾,然而你可以看下視覺化函式,用來畫框的那個函式,visualization_utils.py裡的visualize_boxes_and_labels_on_image_array,有個引數是min_score_thresh,代表最小的閾值,預設是0.5,也就是分數在50%以上才會畫框,你極限一點調成0就可以看到最多20個框了,這個20也是在那邊設定的,說了這麼多屁話,總結就是,訓練樣本和次數太少了,導致預測的框的分數低於最低的閾值了,所以不畫出來,或者手動降低閾值檢視效果,希望我的回答可以幫到你(=・ω・=)(=・ω・=)

Q: 由於我的圖片畫素比較高,導致測試時的準確度字型太小,只有20個畫素點大小,比如說tv:98%,我應該在哪裡修改一下?還有一個問題就是在圖片標註的時候,是不是需要儘可能的只把目標物標註出來,其他的干擾儘量避免?
A: 在object_detection/utils資料夾下,找到visualization_utils.py 檔案開啟, 搜尋 font = ImageFont.truetype 這一行,後面的數字“24”就是字型大小,改大一些,儲存,關閉所有檔案,重新執行程式,應該就可以了,在我的電腦上親測可行。 

對於第二個問題,我個人認為是的,減少干擾意味這更高質量的訓練資料集,應該有利於得到更好的結果

Q: 博主,你好!我做的專案是灰度圖(單通道圖片)。在最後測試效果時,報錯說,要求輸入的圖片是3通道的,而我輸入的是單通道。而且這個引數好像是從訓練完後的一個檔案中讀取的,不知從哪去改,無從下手。博主能指點一下迷途的小白嗎。謝謝了!!!!

A:

你這個問題,直接原因是程式碼裡預設讀取的圖片是RGB 3通道的,應該把對應的部分改成單通道就可以了。 在object_detection.py 程式碼裡 load_image_into_numpy_array 這個函式作用就是把 image函式轉換成numpy矩陣,3通道是3階,單通道應該就是一階。你可以上網搜一下numpy怎麼讀取單通道圖片,把這個函式裡面的引數改一下應該就可以了,你可以試試!
來自提問者自己的回答:這幾天被這個折騰得頭疼.... 1.一開始我打算繼續用單通道圖片一條路走到黑,發現在 export_inferebce_graph.py 這個程式碼裡,我們還可以指定 input_shape 這個命令列引數(博主有空可以瞭解一下),但在輸出 frozen_inference_graph.pb 這個檔案時。會報錯 左右兩個圖片的 shape 不一致,查閱網上資料,說是把checkpoints檔案刪除乾淨,但我刪完了,還是報一樣的錯,估計是沒刪完吧,單都不知道這個檔案都儲存在哪些路徑裡,頭疼..... 2.按照博主提供的思路,我把單通道圖片轉換成三通道圖片,emmmmmm.....一路暢通的做下來,不過結果是瞎**框,損失值有點大.....再瞎**搞一下吧 總之,謝謝博主啦!!!!!

Q:

如果沒改 load_image_into_numpy_array 裡的引數,報錯是: ValueError: cannot reshape array of size 65536 into shape (256,256,3) 改了之後是: ValueError: Cannot feed value of shape (1, 256, 256, 1) for Tensor 'image_tensor:0', which has shape '(?, ?, ?, 3)' 我找了半天,沒找到 image_tensor:0 定義在哪,只找出它是從frozen_inference_graph.pb這個檔案裡讀取,但這個檔案我不知道怎麼去改裡面的引數....

A: 我查了資料,貌似這些 .pb 的model都是適用與RGB格式的,解決方法是把單通道改成3通道。 https://github.com/tensorflow/models/issues/3369 https://github.com/tensorflow/models/issues/2679

Q: 訓練了一些資料後,想額外新增更多資料集,可以嗎?

A: 可以的。把新增的資料集另外再生成一個 .record檔案,然後修改 .config 檔案

train_input_reader: {
  tf_record_input_reader {
    input_path: ["path/to/first.record", "path/to/second.record"]
  }
label_map_path: "..."
}
在input_path 裡面新增新的 .record 檔案即可。