【轉發】實現yolo3模型訓練自己的數據集總結

  原文鏈接實現yolo3模型訓練自己的數據集總結

  經過兩天的努力,借鑒網上眾多博客,在自己電腦上實現了使用yolo3模型訓練自己的數據集并進行測試圖片。本文主要是我根據下面參考文章一步步實施過程的總結,可能沒參考文章中那么詳細,但是會包含一些參考文章中沒提及的容易掉坑的小細節,建議讀者結合參考文章一起看,一步步走即可。首先貼出本文主要參考的文章以及代碼出處:

代碼:https://github.com/qqwweee/keras-yolo3

參考文章:https://blog.csdn.net/patrick_Lxc/article/details/80615433

一.下載項目源碼,進行快速測試

  從上面代碼鏈接處下載整個項目源碼。下載好后,首先根據github中指引進行快速測試。

  yolo web:https://pjreddie.com/darknet/yolo

  對應操作如下(命令行操作):

  1.? wget https://pjreddie.com/media/files/yolov3.weights ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

  注釋:這里wget為linux命令,windows系統可以直接訪問后面鏈接來下載yolov3權重文件,也可以訪問yolo web去下載。

  2. python convert.py yolov3.cfg yolov3.weights model_data/yolo.h5

  注釋:執行convert.py文件,此為將darknet的yolo轉換為可以用于keras的h5文件,生成的h5被保存在model_data下。命令中的convert.py和yolov3.vfg克隆下來后已經有了,不需要單獨下載。

  3.用已經被訓練好的yolo.h5進行圖片識別測試。執行:python yolo.py

  執行后會讓你輸入一張圖片的路徑,因為我準備的圖片(網上隨便找的)放在yolo.py同級目錄,所以直接輸入圖片名稱,沒有加路徑。

  過程和結果如下圖所示:

  以上結果表明快速開始項目成功,接下來我們進行搭建自己的數據集,進行模型的訓練以及訓練后模型用于測試圖片識別。

二.準備自己的數據集

  可以按照上面參考文章里面做法下載VOC數據集,然后清空里面內容,保留文件目錄結構。也可以直接手動創建如下目錄結構:

  這里面用到的文件夾是Annotation、ImageSets和JPEGImages。注意:需要在VOC2007再創建一個上級目錄VOCdevkit。

  其中文件夾Annotation中主要存放xml文件,每一個xml對應一張圖像,并且每個xml中存放的是標記的各個目標的位置和類別信息,命名通常與對應的原始圖像一樣;而ImageSets我們只需要用到Main文件夾,這里面存放的是一些文本文件,通常為train.txt、test.txt等,該文本文件里面的內容是需要用來訓練或測試的圖像的名字;JPEGImages文件夾中放我們已按統一規則命名好的原始圖像。

  原始圖片就不解釋了,而與原始圖片一 一對應的xml文件,可以使用LabelImg工具,具體使用方法百度即可。工具可以從參考的博客中的附帶地址下載,也可以自己網上找,很容易。

  將自己的圖片以及xml按照要求放好后,在VOC2007的同級目錄下建立convert_to_txt.py文件,拷貝下面的代碼,然后運行該py文件。該代碼是讀取上面的xml文件中圖片名稱,并保存在ImageSets/Main目錄下的txt文件中。注意:此處txt中僅有圖片名稱。

代碼:

 1 import os
 2 import random
 3  
 4 trainval_percent = 0.1
 5 train_percent = 0.9
 6 xmlfilepath = 'Annotations'
 7 txtsavepath = 'ImageSets\Main'
 8 total_xml = os.listdir(xmlfilepath)
 9  
10 num = len(total_xml)
11 list = range(num)
12 tv = int(num * trainval_percent)
13 tr = int(tv * train_percent)
14 trainval = random.sample(list, tv)
15 train = random.sample(trainval, tr)
16  
17 ftrainval = open('ImageSets/Main/trainval.txt', 'w')
18 ftest = open('ImageSets/Main/test.txt', 'w')
19 ftrain = open('ImageSets/Main/train.txt', 'w')
20 fval = open('ImageSets/Main/val.txt', 'w')
21  
22 for i in list:
23     name = total_xml[i][:-4] + '\n'
24     if i in trainval:
25         ftrainval.write(name)
26         if i in train:
27             ftest.write(name)
28         else:
29             fval.write(name)
30     else:
31         ftrain.write(name)
32  
33 ftrainval.close()
34 ftrain.close()
35 fval.close()
36 ftest.close()

  然后,回到從github上下載的源碼所在目錄,執行其中的voc_annotation.py,會在當前目錄生成新的三個txt文件,手動去掉名稱中2007_部分。當然,可以自己進入voc_annotation.py修改代碼,使生成的txt文件名中不包含2007_。

  注意:一開始VOC2007,也可以叫VOC2008之類,這樣此處的txt就會成為2008_xxx.txt。此外,有一個很關鍵的地方需要注意,必須修改,不然此處生成的三個新的txt文件中僅僅比前面Main下的txt中多了圖片路徑而已,并不包含框box的信息,這樣的話在后面的訓練步驟,由于沒有框的信息,僅僅是圖片路徑和名稱信息,是訓練不好的,即使可以得到訓練后的h5文件,但是當用這樣的h5文件去執行類似前面所說的測試圖片識別,效果就是將整幅圖框住,而不是框住你所要識別的部分。

  故所要做的是:在執行voc_annotation.py之前,打開它,進行修改。將其中最上面的sets改為你自己的,比如2012改為我得2007,要和前面的目錄年份保持一致。還需要將最上面的classes中的內容,改為你自己xml文件中object屬性中name屬性的值。你有哪些name值,就改為哪些,不然其中讀取xml框信息的代碼就不會執行。

上面是我的xml中一個object截圖,這里的name實際上為你用LableIma工具畫框時候給那個框的命名值。

至此,自己數據集的準備工作就完成了。

三.修改一些文件,然后執行訓練

  首先是修改model_data下的文件,放入你的類別,coco,voc這兩個文件都需要修改。這里的命名會成為最終檢測圖片時候框的框上的名稱。

  其次是yolov3.cfg文件

  這一步事后我和同學討論了下,得出的結論是,從0開始訓練自己的模型,則不需要下面的修改步驟,而如果想用遷移學習思想,用已經預訓練好的權重接著訓練,則需要下面的修改步驟。

  DE里直接打開cfg文件,ctrl+f搜 yolo, 總共會搜出3個含有yolo的地方。

  每個地方都要改3處,filters:3*(5+len(classes));

???????????????????????????????????   classes: len(classes) = 1,我只識別一種,所以為1

???????????????????????????????????   random:原來是1,顯存小改為0 ??

  如果要用預訓練的權重接著訓練,則需要執行以下代碼:然后執行原train.py就可以了。原train.py中有加載預訓練權重的代碼,并凍結部分層數,在此基礎上進行訓練。可以修改凍結層數。

  python convert.py -w yolov3.cfg yolov3.weights model_data/yolo_weights.h5

這個在github和參考的文章中均提到。

如果不用預訓練的權重,上一步不用執行(執行也沒影響),但是下面的train.py需要修改,改為如下所示(代碼出處為上文提到的參考博客中):直接復制替換原train.py即可

  1 """
  2 Retrain the YOLO model for your own dataset.
  3 """
  4 import numpy as np
  5 import keras.backend as K
  6 from keras.layers import Input, Lambda
  7 from keras.models import Model
  8 from keras.callbacks import TensorBoard, ModelCheckpoint, EarlyStopping
  9  
 10 from yolo3.model import preprocess_true_boxes, yolo_body, tiny_yolo_body, yolo_loss
 11 from yolo3.utils import get_random_data
 12  
 13  
 14 def _main():
 15     annotation_path = 'train.txt'
 16     log_dir = 'logs/000/'
 17     classes_path = 'model_data/voc_classes.txt'
 18     anchors_path = 'model_data/yolo_anchors.txt'
 19     class_names = get_classes(classes_path)
 20     anchors = get_anchors(anchors_path)
 21     input_shape = (416,416) # multiple of 32, hw
 22     model = create_model(input_shape, anchors, len(class_names) )
 23     train(model, annotation_path, input_shape, anchors, len(class_names), log_dir=log_dir)
 24  
 25 def train(model, annotation_path, input_shape, anchors, num_classes, log_dir='logs/'):
 26     model.compile(optimizer='adam', loss={
 27         'yolo_loss': lambda y_true, y_pred: y_pred})
 28     logging = TensorBoard(log_dir=log_dir)
 29     checkpoint = ModelCheckpoint(log_dir + "ep{epoch:03d}-loss{loss:.3f}-val_loss{val_loss:.3f}.h5",
 30         monitor='val_loss', save_weights_only=True, save_best_only=True, period=1)
 31     batch_size = 10
 32     val_split = 0.1
 33     with open(annotation_path) as f:
 34         lines = f.readlines()
 35     np.random.shuffle(lines)
 36     num_val = int(len(lines)*val_split)
 37     num_train = len(lines) - num_val
 38     print('Train on {} samples, val on {} samples, with batch size {}.'.format(num_train, num_val, batch_size))
 39  
 40     model.fit_generator(data_generator_wrap(lines[:num_train], batch_size, input_shape, anchors, num_classes),
 41             steps_per_epoch=max(1, num_train//batch_size),
 42             validation_data=data_generator_wrap(lines[num_train:], batch_size, input_shape, anchors, num_classes),
 43             validation_steps=max(1, num_val//batch_size),
 44             epochs=500,
 45             initial_epoch=0)
 46     model.save_weights(log_dir + 'trained_weights.h5')
 47  
 48 def get_classes(classes_path):
 49     with open(classes_path) as f:
 50         class_names = f.readlines()
 51     class_names = [c.strip() for c in class_names]
 52     return class_names
 53  
 54 def get_anchors(anchors_path):
 55     with open(anchors_path) as f:
 56         anchors = f.readline()
 57     anchors = [float(x) for x in anchors.split(',')]
 58     return np.array(anchors).reshape(-1, 2)
 59  
 60 def create_model(input_shape, anchors, num_classes, load_pretrained=False, freeze_body=False,
 61             weights_path='model_data/yolo_weights.h5'):
 62     K.clear_session() # get a new session
 63     image_input = Input(shape=(None, None, 3))
 64     h, w = input_shape
 65     num_anchors = len(anchors)
 66     y_true = [Input(shape=(h//{0:32, 1:16, 2:8}[l], w//{0:32, 1:16, 2:8}[l], \
 67         num_anchors//3, num_classes+5)) for l in range(3)]
 68  
 69     model_body = yolo_body(image_input, num_anchors//3, num_classes)
 70     print('Create YOLOv3 model with {} anchors and {} classes.'.format(num_anchors, num_classes))
 71  
 72     if load_pretrained:
 73         model_body.load_weights(weights_path, by_name=True, skip_mismatch=True)
 74         print('Load weights {}.'.format(weights_path))
 75         if freeze_body:
 76             # Do not freeze 3 output layers.
 77             num = len(model_body.layers)-3
 78             for i in range(num): model_body.layers[i].trainable = False
 79             print('Freeze the first {} layers of total {} layers.'.format(num, len(model_body.layers)))
 80  
 81     model_loss = Lambda(yolo_loss, output_shape=(1,), name='yolo_loss',
 82         arguments={'anchors': anchors, 'num_classes': num_classes, 'ignore_thresh': 0.5})(
 83         [*model_body.output, *y_true])
 84     model = Model([model_body.input, *y_true], model_loss)
 85     return model
 86 def data_generator(annotation_lines, batch_size, input_shape, anchors, num_classes):
 87     n = len(annotation_lines)
 88     np.random.shuffle(annotation_lines)
 89     i = 0
 90     while True:
 91         image_data = []
 92         box_data = []
 93         for b in range(batch_size):
 94             i %= n
 95             image, box = get_random_data(annotation_lines[i], input_shape, random=True)
 96             image_data.append(image)
 97             box_data.append(box)
 98             i += 1
 99         image_data = np.array(image_data)
100         box_data = np.array(box_data)
101         y_true = preprocess_true_boxes(box_data, input_shape, anchors, num_classes)
102         yield [image_data, *y_true], np.zeros(batch_size)
103  
104 def data_generator_wrap(annotation_lines, batch_size, input_shape, anchors, num_classes):
105     n = len(annotation_lines)
106     if n==0 or batch_size<=0: return None
107     return data_generator(annotation_lines, batch_size, input_shape, anchors, num_classes)
108  
109 if __name__ == '__main__':
110     _main()???

  我是在cpu版本tensorflow上跑的,故特別慢,有運算資源的就不說了,如果資源有限,建議少弄些圖片和xml文件,這樣最后的txt文件中數據就少,跑起來輕松點。其次可以修改train.py中的迭代次數epochs的值,該值原作者設置的為500;也可以修改batch_size = 10的大小。

  注意:我第一次訓練時候,確實在目錄下自動生成了logs文件夾,并在其中生成000文件夾,然后里面放的是自己訓練好的h5文件。但是后來我調試代碼,刪除該目錄,再次訓練時,報如下錯誤:

?

  此時只需要手動創建logs文件夾和其內的000文件夾即可。嫌名字不好,可以自己修改train.py文件,改里面的保存目錄。

  下面為成功測試截圖:

  四.用自己訓練的h5文件進行測試

  先修改yolo.py文件中的模型路徑,如下所示,改為自己訓練后生成的h5文件路徑。

  然后執行,測試過程和前面所講一樣,因為我得沒怎么訓練,就不貼出很挫的測試效果圖了。在最初沒有框信息的txt文件訓練后,執行測試很慢,因為訓練時候根本不知道要框什么,改為正常txt后,訓練后的模型進行測試,速度就會很快。

轉載于:https://www.cnblogs.com/ilyar1015/p/10694897.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/249177.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/249177.shtml
英文地址,請注明出處:http://en.pswp.cn/news/249177.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

詳解 vue-cli 的打包配置文件代碼(帶注釋)

一、前言 對于webpack基礎不好&#xff0c;node指令不通的童鞋。估計對自己搭建Vue、react腳手架是相當頭疼的&#xff0c;有種無從下手的感覺。然而&#xff0c;從頭看這2塊&#xff0c;耗時太長&#xff0c;而且說實話得練才行&#xff0c;不練練手看不明白。那大多數人就采取…

NoClassDefFoundError

技術之路最公平也最殘酷的原因是&#xff1a;沒有捷徑&#xff0c;需要日積月累的積累&#xff0c;以及對技術持久的熱情。NoClassDefFoundError這個錯誤一般就兩種情況&#xff1a;1、沒有引入相應的jar包2、兩個jar包中都有這個class&#xff0c;無法確認是引用的哪一個&…

【記錄一下】從0到1 我的python開發之路

請設計實現一個商城系統&#xff0c;商城主要提供兩個功能&#xff1a;商品管理、會員管理。商品管理&#xff1a;- 查看商品列表 - 根據關鍵字搜索指定商品 - 錄入商品會員管理&#xff1a;【無需開發&#xff0c;如選擇則提示此功能不可用&#xff0c;正在開發中&#xff0c;…

Python10/22--面向對象編程/類與對象/init函數

類&#xff1a; 語法: class關鍵字 類名# 類名規范 大寫開頭 駝峰命名法class SHOldboyStudent: # 描述該類對象的特征 school "上海Oldboy" name "矮根" age 68 gender "unknown" # 在定義階段 # 只要包含該類的py被…

Django Form和ModelForm組件

Form介紹 我們之前在HTML頁面中利用form表單向后端提交數據時&#xff0c;都會寫一些獲取用戶輸入的標簽并且用form標簽把它們包起來。 與此同時我們在好多場景下都需要對用戶的輸入做校驗&#xff0c;比如校驗用戶是否輸入&#xff0c;輸入的長度和格式等正不正確。如果用戶輸…

ESLint 規則詳解

前端界大神 Nicholas C. Zakas 在 2013 年開發的 ESLint&#xff0c;極大地方便了大家對 Javascript 代碼進行代碼規范檢查。這個工具包含了 200 多條 Javascript 編碼規范且運行迅速&#xff0c;是幾乎每個前端項目都必備的輔助工具。可是&#xff0c;這么多規則&#xff0c;每…

全文搜索引擎 ElasticSearch 還是 Solr?

原文鏈接 最近項目組安排了一個任務&#xff0c;項目中用到了全文搜索&#xff0c;基于全文搜索 Solr&#xff0c;但是該 Solr 搜索云項目不穩定&#xff0c;經常查詢不出來數據&#xff0c;需要手動全量同步&#xff0c;而且是其他團隊在維護&#xff0c;依賴性太強&#xff0…

對局匹配

問題描述小明喜歡在一個圍棋網站上找別人在線對弈。這個網站上所有注冊用戶都有一個積分&#xff0c;代表他的圍棋水平。小明發現網站的自動對局系統在匹配對手時&#xff0c;只會將積分差恰好是K的兩名用戶匹配在一起。如果兩人分差小于或大于K&#xff0c;系統都不會將他們匹…

NodeJS作為Web架構中間層的使用

截至2016年12月&#xff0c;中國網民規模已達7.31億。傳統的網站系統是否能夠支撐得起如此龐大的且不斷增長的用戶訪問并且為用戶提供體驗友好的頁面&#xff1f; 一、傳統的前后端&#xff1a; 二、傳統的前后端分離問題&#xff1a; 性能問題&#xff1a; 1、渲染、數據都在…

Springboot項目修改html后不需要重啟---springboot項目的熱部署

一、spring-boot-devtools 在pom中直接引入依賴 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional> </dependency> 設置以下兩項&#xff08…

Hibernate中session的get方法和load方法的區別

一.發送SQL時機&#xff1a; load方法采用延遲加載&#xff08;lazy懶加載&#xff09;&#xff0c;執行到這行代碼的時候&#xff0c;不會發送SQL語句&#xff0c;當真正使用這個對象的數據&#xff08;對象的數據不包括主鍵&#xff09;的時候才發送SQL語句&#xff1b; get…

Node.js Web 開發框架大全《中間件篇》

這篇文章與大家分享優秀的 Node.js 中間件模塊。Node 是一個服務器端 JavaScript 解釋器&#xff0c;它將改變服務器應該如何工作的概念。它的目標是幫助程序員構建高度可伸縮的應用程序&#xff0c;編寫能夠處理數萬條同時連接到一個&#xff08;只有一個&#xff09;物理機的…

windows server 2012 流媒體服務器搭建(直播與點播)

IIS Live Smooth Streaming&#xff08;實時平滑流式處理&#xff09;是微軟下一代流媒體解決方案。該技術是在IIS web中集成媒體傳輸平臺IIS media services&#xff0c;實現利用標準 HTTP Web 技術以及高級 Silverlight 功能&#xff0c;確保在互聯上傳輸質量最佳、播放流暢音…

團隊項目第一篇——NABCD

團隊名稱&#xff1a;筑夢之舟 團隊項目名稱&#xff1a;跑跑 N&#xff08;Need&#xff09;需求&#xff1a; 有許多人在跑步時想了解自己的移動軌跡和跑步距離很不便利&#xff0c;無法了解跑步的日程&#xff0c;我們的軟件就是為了更加方便熱愛跑步的人能夠參加到跑步之中…

Vue warn Failed to mount component: template or render function not defined

問題如圖&#xff0c;造成這類的問題一般有這么幾個原因。 代碼的拼寫問題&#xff0c;當然這是最低級的錯誤vue定義的問題&#xff0c;這里我說明兩點 在組件內部定義組件時&#xff0c;template 對應的必須是html字符串引用外部組件時&#xff0c;vue文件必須以template標簽…

Python實現線性回歸2,梯度下降算法

接上篇 4.梯度下降算法 《斯坦福大學公開課 &#xff1a;機器學習課程》吳恩達講解第二課時&#xff0c;是直接從梯度下降開始講解&#xff0c;最后采用向量和矩陣的方式推導了解析解&#xff0c;國內很多培訓視頻是先講解析解后講梯度下降&#xff0c;個人認為梯度下降算法更為…

在centos和redhat上安裝docker

前置條件 64-bit 系統kernel 3.101.檢查內核版本&#xff0c;返回的值大于3.10即可。$ uname -r 2.使用 sudo 或 root 權限的用戶登入終端。 3.卸載舊版本(如果安裝過舊版本的話) $ yum remove docker \docker-common \docker-selinux \docker-engine 4.安裝需要的軟件包 #yum-…

mac 下用 brew 安裝mongodb

mac 下安裝mongoDB一般倆種方法. (1)下載源碼,解壓,編譯,配置,啟動 比較艱難的一種模式. (2)brew install mongodb ,然后就可以悠閑的品一口茶,順便瞄一眼網易新聞,這是一種傻瓜模式. 但傻瓜模式也有人為干預的時候,粗略說一下使用brew 安裝mongodb 1 zhangzhimoke:~/code$…

比較python類的兩個instance(對象) 是否相等

http://www.yihaomen.com/article/python/281.htm 比較python類的兩個instance(對象) 是否相等 作者:輕舞肥羊 日期:2012-10-25 字體大小: 小 中 大對于同一個Class,可以創建不同的實例(instance), 如何比較這兩個 instance 是否相等呢&#xff1f;我們知道&#xff0c;對于計算…

Mybaits插入記錄返回主鍵值

某些情況進行insert時不知道主鍵值&#xff08;主鍵為自增&#xff09;&#xff0c;例如系統新增用戶時&#xff0c;有用戶序號&#xff08;主鍵 自增&#xff09;&#xff0c;用戶名&#xff0c;密碼。插入時只需插入用戶名和密碼&#xff0c;之后取得mysql自增的序號。 如下為…