YOLOv8是開發的 YOLO(You Only Look Once)物體檢測和圖像分割模型的最新版本,詳細介紹可以參考發布的網址,可以通過 python 包獲取代碼,暫時還沒有官方公布代碼
安裝 python包
pip install -i https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ ultralytics==0.0.59
pip install -e ultralytics
您可以在 /usr/local/lib/pythonx.x/dist-/ (Ubuntu) 中找到代碼
目錄
1、YOLOv5回顧
這里粗略回顧一下,這里直接提供YOLOv5的整理的結構圖吧:
:結構,主要結構思想的體現在C3模塊,這里也是梯度分流的主要思想所在的地方;
PAN-FPN:雙流的FPN,必須香,也必須快,但是量化還是有些需要圖優化才可以達到最優的性能,比如cat前后的scale優化等等,這里除了上采樣、CBS卷積模塊,最為主要的還有C3模塊;
Head:Coupled Head+Anchor-base,毫無疑問,YOLOv3、YOLOv4、YOLOv5、YOLOv7都是Anchor-Base的;
Loss:分類用BEC Loss,回歸用CIoU Loss。
2、YOLOv8核心介紹
直接上YOLOv8的結構圖吧,小伙伴們可以直接和YOLOv5進行對比,看看能找到或者猜到有什么不同的地方?
下面就直接揭曉答案吧,具體改進如下:
:使用的依舊是CSP的思想,不過YOLOv5中的C3模塊被替換成了C2f模塊,實現了進一步的輕量化,同時YOLOv8依舊使用了YOLOv5等架構中使用的SPPF模塊;
PAN-FPN:毫無疑問YOLOv8依舊使用了PAN的思想,不過通過對比YOLOv5與YOLOv8的結構圖可以看到,YOLOv8將YOLOv5中PAN-FPN上采樣階段中的卷積結構刪除了,同時也將C3模塊替換為了C2f模塊;
-Head:是不是嗅到了不一樣的味道?是的,YOLOv8走向了-Head;
Anchor-Free:YOLOv8拋棄了以往的Anchor-Base,使用了Anchor-Free的思想;
損失函數:YOLOv8使用VFL Loss作為分類損失,使用DFL Loss+CIOU Loss作為分類損失;
樣本匹配:YOLOv8拋棄了以往的IOU匹配或者單邊比例的分配方式,而是使用了Task-Aligned 匹配方式。
2.1、C2f模塊
我們不著急,先看一下C3模塊的結構圖,然后再對比與C2f的具體的區別。針對C3模塊,其主要是借助CSPNet提取分流的思想,同時結合殘差結構的思想,設計了所謂的C3 Block,這里的CSP主分支梯度模塊為模塊,也就是所謂的殘差模塊。同時堆疊的個數由參數n來進行控制,也就是說不同規模的模型,n的值是有變化的。
C3模塊結構圖
其實這里的梯度流主分支,可以是任何之前你學習過的模塊,比如,美團提出的YOLOv6中就是用來重參模塊來替換 Block來作為主要的梯度流分支,而百度提出的PP-YOLOE則是使用了-Block來替換 Block來作為主要的梯度流分支。而YOLOv7則是使用了ELAN Block來替換 Block來作為主要的梯度流分支。
C3模塊的Pytorch的實現如下:
class BottleneckC2f(nn.Module):
# Standard bottleneck
def __init__(self, c1, c2, shortcut=True, g=1, k=(3, 3), e=0.5): # ch_in, ch_out, shortcut, kernels, groups, expand
super().__init__()
c_ = int(c2 * e) # hidden channels
self.cv1 = Conv(c1, c_, k[0], 1)
self.cv2 = Conv(c_, c2, k[1], 1, g=g)
self.add = shortcut and c1 == c2
def forward(self, x):
return x + self.cv2(self.cv1(x)) if self.add else self.cv2(self.cv1(x))
class C2f(nn.Module):
# CSP Bottleneck with 2 convolutions
def __init__(self, c1, c2, n=1, shortcut=False, g=1, e=0.5): # ch_in, ch_out, number, shortcut, groups, expansion
super().__init__()
self.c = int(c2 * e) # hidden channels
self.cv1 = Conv(c1, 2 * self.c, 1, 1)
self.cv2 = Conv((2 + n) * self.c, c2, 1) # optional act=FReLU(c2)
self.m = nn.ModuleList(BottleneckC2f(self.c, self.c, shortcut, g, k=((3, 3), (3, 3)), e=1.0) for _ in range(n))
def forward(self, x):
y = list(self.cv1(x).split((self.c, self.c), 1))
y.extend(m(y[-1]) for m in self.m)
return self.cv2(torch.cat(y, 1))
下面就簡單說一下C2f模塊,通過C3模塊的代碼以及結構圖可以看到,C3模塊和名字思路一致,在模塊中使用了3個卷積模塊(Conv+BN+SiLU),以及n個。
通過C3代碼可以看出,對于cv1卷積和cv2卷積的通道數是一致的,而cv3的輸入通道數是前者的2倍,因為cv3的輸入是由主梯度流分支(分支)依舊次梯度流分支(CBS,cv2分支)cat得到的,因此是2倍的通道數,而輸出則是一樣的。
不妨我們再看一下YOLOv7中的模塊:
YOLOv7通過并行更多的梯度流分支,放ELAN模塊可以獲得更豐富的梯度信息,進而或者更高的精度和更合理的延遲。
C2f模塊的結構圖如下:
我們可以很容易的看出,C2f模塊就是參考了C3模塊以及ELAN的思想進行的設計,讓YOLOv8可以在保證輕量化的同時獲得更加豐富的梯度流信息。
C2f結構圖
C2f模塊對應的Pytorch實現如下:
class?C2f(nn.Module):
????#?CSP?Bottleneck?with?2?convolutions
????def?__init__(self,?c1,?c2,?n=1,?shortcut=False,?g=1,?e=0.5):??#?ch_in,?ch_out,?number,?shortcut,?groups,?expansion
????????super().__init__()
????????self.c?=?int(c2?*?e)??#?hidden?channels
????????self.cv1?=?Conv(c1,?2?*?self.c,?1,?1)
????????self.cv2?=?Conv((2?+?n)?*?self.c,?c2,?1)??#?optional?act=FReLU(c2)
????????self.m?=?nn.ModuleList(Bottleneck(self.c,?self.c,?shortcut,?g,?k=((3,?3),?(3,?3)),?e=1.0)?for?_?in?range(n))
????def?forward(self,?x):
????????y?=?list(self.cv1(x).split((self.c,?self.c),?1))
????????y.extend(m(y[-1])?for?m?in?self.m)
????????return?self.cv2(torch.cat(y,?1))
2.2、SPPF改進了什么?
SPP結構又被稱為空間金字塔池化,能將任意大小的特征圖轉換成固定大小的特征向量。
接下來我們來詳述一下SPP是怎么處理滴~
輸入層:首先我們現在有一張任意大小的圖片,其大小為w * h。
輸出層:21個神經元 -- 即我們待會希望提取到21個特征。
分析如下圖所示:分別對1 * 1分塊,2 * 2分塊和4 * 4子圖里分別取每一個框內的max值(即取藍框框內的最大值),這一步就是作最大池化,這樣最后提取出來的特征值(即取出來的最大值)一共有1 * 1 + 2 * 2 + 4 * 4 = 21個。得出的特征再concat在一起。
而在YOLOv5中SPP的結構圖如下圖所示:
在YOLOv56.0版本中SPPF替換SPP,二者效果一致,但前者較后者的執行時間減少至1/2。
2.3、PAN-FPN改進了什么?
我們先看一下YOLOv5以及YOLOv6的PAN-FPN部分的結構圖:
YOLOv5的Neck部分的結構圖如下:
YOLOv5的neck結構圖
YOLOv6的Neck部分的結構圖如下:
YOLOv6的neck結構圖
我們再看YOLOv8的結構圖:
YOLOv8的neck結構圖
可以看到,相對于YOLOv5或者YOLOv6,YOLOv8將C3模塊以及替換為了C2f,同時細心可以發現,相對于YOLOv5和YOLOv6,YOLOv8選擇將上采樣之前的1×1卷積去除了,將不同階段輸出的特征直接送入了上采樣操作。
2.4、Head部分都變了什么呢?
先看一下YOLOv5本身的Head(Coupled-Head):
YOLOv5的head結構圖
而YOLOv8則是使用了-Head,同時由于使用了DFL 的思想,因此回歸頭的通道數也變成了4*reg_max的形式:
YOLOv8的head結構圖
對比一下YOLOv5與YOLOv8的YAML
2.5、損失函數
對于YOLOv8,其分類損失為VFL Loss,其回歸損失為CIOU Loss+DFL的形式,這里Reg_max默認為16。
VFL主要改進是提出了非對稱的加權操作,FL和QFL都是對稱的。而非對稱加權的思想來源于論文PISA,該論文指出首先正負樣本有不平衡問題,即使在正樣本中也存在不等權問題,因為mAP的計算是主正樣本。
q是label,正樣本時候q為bbox和gt的IoU,負樣本時候q=0,當為正樣本時候其實沒有采用FL,而是普通的BCE,只不過多了一個自適應IoU加權,用于突出主樣本。而為負樣本時候就是標準的FL了。可以明顯發現VFL比QFL更加簡單,主要特點是正負樣本非對稱加權、突出正樣本為主樣本。
針對這里的DFL( Focal Loss),其主要是將框的位置建模成一個 general ,讓網絡快速的聚焦于和目標位置距離近的位置的分布。
DFL 能夠讓網絡更快地聚焦于目標 y 附近的值,增大它們的概率;
DFL的含義是以交叉熵的形式去優化與標簽y最接近的一左一右2個位置的概率,從而讓網絡更快的聚焦到目標位置的鄰近區域的分布;也就是說學出來的分布理論上是在真實浮點坐標的附近,并且以線性插值的模式得到距離左右整數坐標的權重。
2.6、樣本的匹配
標簽分配是目標檢測非常重要的一環,在YOLOv5的早期版本中使用了MaxIOU作為標簽分配方法。然而,在實踐中發現直接使用邊長比也可以達到一阿姨你的效果。而YOLOv8則是拋棄了Anchor-Base方法使用Anchor-Free方法,找到了一個替代邊長比例的匹配方法,。
為與NMS搭配,訓練樣例的Anchor分配需要滿足以下兩個規則:
正常對齊的Anchor應當可以預測高分類得分,同時具有精確定位;
不對齊的Anchor應當具有低分類得分,并在NMS階段被抑制。基于上述兩個目標,設計了一個新的Anchor metric 來在Anchor level 衡量Task-的水平。并且, metric 被集成在了 sample 分配和 loss 里來動態的優化每個 Anchor 的預測。
Anchor metric:
分類得分和 IoU表示了這兩個任務的預測效果,所以,使用分類得分和IoU的高階組合來衡量Task-的程度。使用下列的方式來對每個實例計算Anchor-level 的對齊程度:
s 和 u 分別為分類得分和 IoU 值,α 和 β 為權重超參。從上邊的公式可以看出來,t 可以同時控制分類得分和IoU 的優化來實現 Task-,可以引導網絡動態的關注于高質量的Anchor。
sample :
為提升兩個任務的對齊性,TOOD聚焦于Task- Anchor,采用一種簡單的分配規則選擇訓練樣本:對每個實例,選擇m個具有最大t值的Anchor作為正樣本,選擇其余的Anchor作為負樣本。然后,通過損失函數(針對分類與定位的對齊而設計的損失函數)進行訓練。
參考文章
[1].
[2].
[3].
[4].YOLOv5中的SPP/SPPF結構詳解_tt丫的博客-CSDN博客_sppf.
[5].YOLOv8來啦 | 詳細解讀YOLOv8的改進模塊!YOLOv5官方出品YOLOv8,必卷! - 知乎.
[6].
MySQL數據庫常見報錯案例與錯誤代碼說明
實例報錯問題分析與解決方法:
-報錯1:
Can’t open file: ‘xxx_forums.MYI’. (errno: 145)
問題分析:
這種情況是不能打開 .MYI造成的,引起這種情況可能的原因有:
1、服務器非正常關機,數據庫所在空間已滿,或一些其它未知的原因,對數據庫表造成了損壞。
2、類 unix 操作系統下直接將數據庫文件拷貝移動會因為文件的屬組問題而產生這個錯誤。
解決方法:
1、修復數據表
可以使用下面的兩種方式修復數據表:(第一種方法僅適合獨立主機用戶)
1)使用 ,MySQL 自帶了專門用戶數據表檢查和修復的工具 ——。更改當前目錄到MySQL/bin下面,一般情況下只有在這個下面才能運行命令。常用的修復命令為: -r數據文件目錄/數據表名.MYI;
2)通過 修復, 帶有修復數據表的功能,進入到某一個表中后,點擊“操作”,在下方的“表維護”中點擊“修復表”即可。
注意:以上兩種修復方式在執行前一定要備份數據庫。
2、修改文件的屬組(僅適合獨立主機用戶)
1)復制數據庫文件的過程中沒有將數據庫文件設置為 MySQL 運行的帳號可讀寫(一般適用于 Linux和 FreeBSD 用戶)。
-報錯2:
ERROR 1045 (25000): Access denied for user 'root'@'localhost' (using password: NO)
問題分析:
密碼不正確或者沒有權限訪問。
解決方法:
1)修改 f 主配置文件,在 [mysqld] 下添加 skip-grant-tables,重啟數據庫。
最后修改密碼命令如下:
mysql> use mysql;
mysql> update user set password=password("123qqq...A") where user="root";
刪除剛剛添加的 skip-grant-tables 參數,再重啟數據庫,使用新密碼即可登錄。
2)重新授權,命令如下:
mysql> grant all on *.* to 'root'@'mysql-server' identified by '123qqq...A';
-報錯3:
Duplicate key name ‘xxx’
問題分析:
要創建的索引已經存在,會引發這個錯誤,這個錯誤多發生在升級的時候。可能是已經升級過的,重復升級引起的錯誤。也有可能是之前用戶擅自加的索引,剛好與升級文件中的索引相同了。
解決方法:
看看已經存在的索引和要添加的索引是否一樣,一樣的話可以跳過這條sql語句,如果不一樣那么現刪除已存在的索引,之后再執行。
-報錯4:
Table ‘xxx’ already exists
問題分析:
xxx表已經存在于庫中,再次創建這個名字的表就會引發該錯誤。
解決方法:
查看已經存在的表是否和將要創建的表完全一樣,一樣的話可以跳過不執行這個sql,否則請將存在的表先刪除,再執行。
-報錯5:
InnoDB: Error: page 14518 log sequence number 5698741252 InnoDB: is in the future! Current system log sequence number 5698741252
問題分析:
innodb 數據文件損壞。
解決方法:
修改 f 配置文件,在 [mysqld] 下添加 y=4, 啟動數據庫后備份數據文件,然后再去掉該參數,利用備份文件恢復數據。
-報錯6:
從庫的 狀態為 NO
問題分析:
主庫和從庫的 server-id 值一樣。
解決方法:
修改從庫的 server-id 的值,修改成與主庫不一樣,比主庫低。修改完成后重啟,再同步即可!
-報錯7:
Warning: World-writable config file '/etc/my.cnf' is ignored ERROR! MySQL is running but PID file could not be found
問題分析:
MySQL 的配置文件 /etc/f 權限不對。
解決方法:
chmod 644 /et/my.cnf
-報錯8:
Too many connections (1040)鏈接過多
問題分析:
連接數已經超過了mysql設置的值,與 和 都有關系。的值越大,連接的空閑等待就越長,這樣就會造成當前連接數越大
解決方法:
優化 MySQL 服務器的配置,可參考修改 MySQL 配置文件my.ini或者 f中的參數:
= 1000 ? = 10
修改后重啟 MySQL ,如果經常性的報此錯誤,需做一下服務器的整體優化。
-報錯9:
Can’t connect to MySQL server on ‘localhost’ (10061)
問題分析:
說明機器上沒提供MySQL服務。需要啟動這臺機器上的MySQL服務,如果負載太高也會產生這個錯誤。
解決方法:
啟動這臺機器的mysql服務,如果啟動不成功,多數是因為你的my.ini配置的有問題,重新配置其即可。如果覺得mysql負載異常,可以到mysql/bin 的目錄下執行 -uroot -p123 來查看mysql當前的進程。
-報錯10:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/data/mysql/mysql.sock'
問題分析:
可能是數據庫沒有啟動或者是端口被防火墻禁止。
解決方法:
啟動數據庫或者防火墻開放數據庫監聽端口。
-報錯11:
Error initializing relay log position: I/O error reading the header from the binary log
問題分析:
從庫的中繼日志 relay-bin 損壞.
解決方法:
手動修復,重新找到同步的 binlog 和 pos 點,然后重新同步即可。
mysql> CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.xxx',MASTER_LOG_POS=xxx;
-報錯12:
從庫的 為 NO 問題
問題分析:
造成從庫線程為 NO 的原因會有很多,主要原因是主鍵沖突或者主庫刪除或更新數據, 從庫找不到記錄,數據被修改導致。
通常狀態碼報錯有 1007、1032、1062、1452 等。
解決方法一:
mysql> stop slave;
mysql> set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
mysql> start slave;
解決方法二:設置用戶權限,設置從庫只讀權限
set global read_only=true;
set GLOBAL max_connections=10000;
-報錯13:
客戶端報 Too many
問題分析:
連接數超出 Mysql 的最大連接限制。
解決方法:
在 f 配置文件里面增加連接數,然后重啟 MySQL 服務。 = 10000臨時修改最大連接數,重啟后不生效。需要在 f 里面修改配置文件,下次重啟生效。
-報錯14:
Got error 28 from table handler
問題分析:
數據庫所在磁盤空間已滿。
解決方法:
增加 MySQL 所在的磁盤空間或者清理一些無用文件。
-報錯15:
Can’t create a new thread; if you are not out of available memory, you can consult the manual for a possible OS-dependent bug。
問題分析:
數據庫服務器問題,數據庫操作無法創建新線程。一般是兩個原因:
1.服務器系統內存溢出。
2.環境軟件損壞或系統損壞。
解決方法:
檢查服務器的內存和系統是否正常,如果服務器內存緊張,請排查一下哪些進程消耗了服務器的內存,同時考慮是否增加服務器的內存來提高整個的負載能力。
`Mysql常見錯誤代碼說明:`
130 :文件格式不正確
145 :文件無法打開
1005:創建表失敗
1006:創建數據庫失敗
1007:數據庫已存在,創建數據庫失敗
1008:數據庫不存在,刪除數據庫失敗
1009:不能刪除數據庫文件導致刪除數據庫失敗
1010:不能刪除數據目錄導致刪除數據庫失敗
1011:刪除數據庫文件失敗
1012:不能讀取系統表中的記錄
1020:記錄已被其他用戶修改
1021:硬盤剩余空間不足,請加大硬盤可用空間
1022:關鍵字重復,更改記錄失敗
1023:關閉時發生錯誤
1024:讀文件錯誤
1025:更改名字時發生錯誤
1026:寫文件錯誤
1032:記錄不存在
1036:數據表是只讀的,不能對它進行修改
1037:系統內存不足,請重啟數據庫或重啟服務器
1038:用于排序的內存不足,請增大排序緩沖區
1040:已到達數據庫的最大連接數,請加大數據庫可用連接數
1041:系統內存不足
1042:無效的主機名
1043:無效連接
1044:當前用戶沒有訪問數據庫的權限

1045:不能連接數據庫,用戶名或密碼錯誤
1048:字段不能為空
1049:數據庫不存在
1050:數據表已存在
1051:數據表不存在
1054:字段不存在
1065:無效的 SQL 語句,SQL 語句為空
1081:不能建立 Socket 連接
1114:數據表已滿,不能容納任何記錄
1116:打開的數據表太多
1129:數據庫出現異常,請重啟數據庫
1130:連接數據庫失敗,沒有連接數據庫的權限
1133:數據庫用戶不存在
1141:當前用戶無權訪問數據庫
1142:當前用戶無權訪問數據表
1143:當前用戶無權訪問數據表中的字段
1146:數據表不存在
1147:未定義用戶對數據表的訪問權限
1149:SQL 語句語法錯誤
1158:網絡錯誤,出現讀錯誤,請檢查網絡連接狀況
1159:網絡錯誤,讀超時,請檢查網絡連接狀況
1160:網絡錯誤,出現寫錯誤,請檢查網絡連接狀況
1161:網絡錯誤,寫超時,請檢查網絡連接狀況
1062:字段值重復,入庫失敗
1169:字段值重復,更新記錄失敗
1177:打開數據表失敗
1180:提交事務失敗
1181:回滾事務失敗
1203:當前用戶和數據庫建立的連接已到達數據庫的最大連接數,請增大可用的數據庫連接數或重啟數據庫
1205:加鎖超時
1211:當前用戶沒有創建用戶的權限
1216:外鍵約束檢查失敗,更新子表記錄失敗
1217:外鍵約束檢查失敗,刪除或修改主表記錄失敗
1226:當前用戶使用的資源已超過所允許的資源,請重啟數據庫或重啟服務器
1227:權限不足,您無權進行此操作
1235:MySQL 版本過低,不具有本功能
1250:客戶端不支持服務器要求的認證協議,請考慮升級客戶端。
1251:Client 不能支持 authentication protocol 的要求 Client does not support authentication protocol requested by server; consider upgrading MySQL clientQuote:
1267:不合法的混合字符集。
2002:服務器端口不對。
2003:MySQL 服務沒有啟動,請啟動該服務。
2008:MySQL client ran out of memory 錯誤指向了 MySQL 客戶 mysql。這個錯誤的原因很簡單,客戶沒有足夠的內存存儲全部結果。
2013:遠程連接數據庫是有時會有這個問題,MySQL 服務器在執行一條 SQL 語句的時候失去了連接造成的。
10048: 建議在 my.ini 文件中修改最大連接數, 把 mysql_connect () 方法都改成了 mysql_pconnect () 方法。要修改 mysql_pconnect (),可以在論壇的 data 目錄的 sql_config.php 中 p c o n n e c t = 0 ; // 是 否 持 久 連 接 修 改 成 pconnect = 0; // 是否持久連接 修改成 pconnect=0;// 是否持久連接修改成 pconnect = 1; 開啟防刷新,嚴禁刷新太快.
10055: 沒有緩存空間可利用,查看下你的 C 盤空間是否已經滿,清除一些沒有用的文件。可以在后臺的 "論壇核心設置","核心功能設置" 里 "進程優化" 開啟,"GZIP 壓縮輸出" 關閉。查找了一下 10055(沒有緩存空間可利用)
10061: 啟動這臺機器上的 MySQL 服務 如服務啟動失敗,一定是你的 my.ini 文件出了差錯, MySQL 服務不能正常啟動 你刪除了它后,MySQL 就會按其默認配置運行, 那就沒有問題了。
如果您喜歡本文,就請動動您的發財手為本文點贊評論轉發,讓我們一起學習更多運維相關知識,最后請記得關注我。