https://paperswithcode.com/sota
“SOTA” 是 “State-of-the-Art” 的縮寫,意為 “最先進技術”。在計算機科學和人工智能領域,SOTA模型指的是當前被認為是在某個特定任務或領域內表現最優秀的模型或方法。這些模型通常代表了當前領域內的最高水平,並在諸如自然語言處理、計算機視覺、語音識別等各種任務中發揮著重要作用。
https://paperswithcode.com/sota
“SOTA” 是 “State-of-the-Art” 的縮寫,意為 “最先進技術”。在計算機科學和人工智能領域,SOTA模型指的是當前被認為是在某個特定任務或領域內表現最優秀的模型或方法。這些模型通常代表了當前領域內的最高水平,並在諸如自然語言處理、計算機視覺、語音識別等各種任務中發揮著重要作用。
下面是四種常見的計算機視覺任務的簡要介紹:
分類任務是將輸入圖像分為不同的類別或類別之一。例如,給定一張圖像,分類任務的目標是確定圖像中顯示的對像是什麼,比如貓、狗、汽車、飛機等。這通常涉及訓練一個分類器,以便它能夠識別圖像中的特定特徵並將其歸類到正確的類別中。
語義分割任務是為圖像中的每個像素分配一個類別標籤,從而實現像素級別的分類。與分類任務不同,語義分割不僅關注對象的類型,還考慮了對象的位置和邊界。這在許多應用中很有用,比如圖像分割、醫學圖像分析等。
語義分割是一種計算機視覺任務,旨在將圖像中的每個像素分配給預定義的語義類別。在語義分割中,每個像素都被標記為屬於某個特定的類別,如人、車、樹等。語義分割遵循像素級別的分類,因此通常使用像素級別的掩碼(即”masks”)來表示圖像中每個類別的區域。這些分割掩碼是二進製圖像,其中每個像素要嘛屬於某個類別,要嘛不屬於。
有名模型: U-Net
和實例分割最大的不同是他的輸入會是兩張圖片,一張為原圖,一張為掩碼的圖
目標檢測任務涉及在圖像中識別並定位多個不同類別的對象。相比於分類任務,目標檢測不僅需要標識對象的類別,還需要確定它們的位置和邊界框。常見的目標檢測算法可以提供每個檢測到的對象的邊界框和類別信息。具代表性的演算法包括Faster R-CNN, YOLO, SSD等
這篇文章介紹了許多我們常用的物件偵測模型: https://zhuanlan.zhihu.com/p/38709522
實例分割任務結合了目標檢測和語義分割的概念,不僅要對每個對象進行分類,還需要在像素級別區分出每個對象的邊界。實例分割旨在識別圖像中的每個獨立實例並為每個實例分配獨特的標籤,從而在一個圖像中區分出不同的對象。
例如: COCO Segmentation
COCO(Common Objects in Context)是一個廣泛使用的圖像識別和分割數據集,其中包含了多種物體類別的圖像以及每個圖像中物體的分割標註。 COCO Segmentation 數據集中的分割信息通常是用多邊形輪廓來表示物體的形狀。這種分割方法在標註上更靈活,可以準確地表示物體的複雜形狀,但同時也需要更多的標註工作。
Collecting package metadata (current_repodata.json): failed CondaSSLError: OpenSSL appears to be unavailable on this machine. OpenSSL is required to download and install packages. Exception: HTTPSConnectionPool(host=’conda.anaconda.org’, port=443): Max retries exceeded with url: /conda-forge/win-64/current_repodata.json (Caused by SSLError(“Can’t connect to HTTPS URL because the SSL module is not available.”))
使用pip install/conda install跳出的錯誤
在anaconda3>Library>bin尋找這兩個檔案
然後複製到anaconda3>DLLs.
GITHUB: https://github.com/albumentations-team/albumentations
官方文檔: https://albumentations.ai/docs/getting_started/transforms_and_targets/
Albumentations 是一個流行的計算機視覺數據增強庫,專門設計用於圖像分類、目標檢測、分割等任務。它提供了豐富的圖像增強技術,可以幫助您在訓練深度學習模型時提升模型的性能和魯棒性。 Albumentations 支持多種常用的深度學習框架,如PyTorch和TensorFlow。
以下是 Albumentations 的一些特點和功能:
以下是一個使用 Albumentations 的簡單示例,演示如何將一些常見的增強操作應用於圖像數據:
import albumentations as A
from albumentations.pytorch import ToTensorV2
import cv2
import matplotlib.pyplot as plt
# 示例图像路径
image_path = 'path_to_your_image.jpg'
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# 定义增强操作
transform = A.Compose([
A.Resize(width=256, height=256),
A.HorizontalFlip(p=0.5),
A.VerticalFlip(p=0.5),
A.Rotate(limit=30, p=0.5),
A.RandomBrightnessContrast(p=0.2),
A.Normalize(),
ToTensorV2(),
])
# 应用增强
transformed_image = transform(image=image)['image']
# 可视化原始图像和增强后的图像
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.imshow(image)
plt.title('Original Image')
plt.subplot(1, 2, 2)
plt.imshow(transformed_image[0]) # 转换后的图像是 PyTorch 张量,选择通道 0 进行显示
plt.title('Transformed Image')
plt.show()
官方網站: https://github.com/ultralytics/JSON2YOLO
JSON2YOLO 是一個用於將JSON格式標註數據轉換為YOLO格式標註數據的工具。 YOLO(You Only Look Once)是一種流行的目標檢測算法,它能夠在單次前向傳遞中同時預測圖像中的多個目標邊界框和類別。
在計算機視覺中,標註數據用於告知模型在圖像中的哪些位置存在目標以及目標的類別。 JSON和YOLO是兩種常用的標註數據格式,其中JSON通常用於描述目標的邊界框和類別,而YOLO格式則將目標的邊界框和類別信息結合在一起,以便更有效地訓練目標檢測模型。
JSON2YOLO 工具的主要目的是簡化將JSON格式標註數據轉換為YOLO格式標註數據的過程。通常,這種轉換涉及將目標的邊界框坐標映射到YOLO格式的網格單元,並將類別信息進行編碼。這使得標註數據能夠更好地適應YOLO模型的訓練和預測需求。
當我們使用別人的資料集,很有可能別人並不是使用YOLO格式去輸出資料集的,如果我們想要使用YOLO做訓練,勢必就得做標註資料的轉換,針對YOLO的狀況,就會需要使用這個轉換工具來將其他格式轉為YOLO標記格式
或者像是roboflow支持的輸出格式並不包含YOLO semgemt,所以也會需要先下載一般JSON格式的標記,再使用這個工具來做轉換
Roboflow支持的輸出格式
接著再呼叫JSON2YOLO-master>python general_json2yolo.py
轉換好的資料就會出現在new_dir
文檔: https://docs.roboflow.com/
Roboflow 是一個用於計算機視覺項目的平台,它旨在幫助開發人員和團隊更輕鬆地構建、訓練和部署計算機視覺模型。 Roboflow 提供了一系列工具和功能,使您能夠有效地處理圖像數據、訓練機器學習模型,並將這些模型集成到您的應用程序中。以下是 Roboflow 的一些主要特點和功能:
這個功能是我覺得Roboflow大勝labelImg的原因,當團隊有很多人要負責標記時,這個工具可以非常方便的檢視、確認、共同標記。
Roboflow可以直接匯入以標記好的檔案,可以在線上去觀察以標記的資料的標記樣態,這些都是labelImg沒有辦法做到的,我們可以直接把含有標記和圖片的資料夾拉近網頁裡面,他會問你是否資料夾內的檔案全部放入,選擇Upload
就會可以看到已經標記好的狀況,我覺得這個功能在使用別人標記的圖檔時非常重要,才可以知道別人是如何去標記圖片的
Roboflow 提供了豐富的在線數據增強工具,用於處理圖像數據,改善數據集的多樣性,提高模型的泛化能力。數據增強是在保持圖像語義信息的前提下,通過應用各種變換和處理來生成多樣性的圖像,從而增加模型對於不同場景的適應能力。以下是 Roboflow 在線數據增強工具的一些功能和特點:
按Generate可以做圖像預處理並選擇資料增強的方法,不過這邊圖片要輸出的若太多,就會要升級方案,免費方案沒辦法輸出破千張
選擇Deploy頁籤,可以線上建模,並可以看到在測試資料及上的偵測狀況,我覺得最酷的是這一切都完全使用點、按就可以達成,完全no code
以下為官網的一個範例程式
from ultralytics import YOLO
# Load a model
model = YOLO('yolov8n.yaml') # build a new model from YAML
model = YOLO('yolov8n.pt') # load a pretrained model (recommended for training)
model = YOLO('yolov8n.yaml').load('yolov8n.pt') # build from YAML and transfer weights
# Train the model
results = model.train(data='coco128.yaml', epochs=100, imgsz=640)
範例中三種載入方式的比較
ultralytics\cfg\models\v8
)YOLOv8 模型的每個類別中有五個模型
YOLOv8n | YOLOv8s | YOLOv8m | YOLOv8l | YOLOv8x |
YOLOv8 使用了以下預訓練模型:
IoU(Intersection over Union)是一個用於評估目標檢測和分割任務的常用指標。它主要用於衡量預測的目標與實際目標之間的重疊程度。在機器學習和計算機視覺領域中,IoU通常用於衡量模型的預測準確度,特別是在處理像目標檢測、物體定位和分割等任務時。
IoU的計算方式是將預測的目標區域(通常是矩形框或分割區域)與實際目標區域的交集面積除以它們的聯集面積。公式如下:
其中,交集是預測區域和實際區域的重疊部分,聯集是預測區域和實際區域的整體合併部分。
在目標檢測中,當模型預測的目標框與實際目標框之間的IoU值越高,表示模型的預測越準確。通常,當IoU超過一個預定的閾值(例如0.5或0.7)時,可以將該預測視為成功檢測。這種指標可以用於計算Precision-Recall曲線以及平均精度(Average Precision)等性能指標。
在分割任務中,IoU用於衡量模型預測的分割區域與實際分割區域之間的相似度。當分割區域的IoU越高,表示模型的分割結果越準確。
mAP50(B) 是指”Mean Average Precision at IoU 0.50 for Large Objects”,意思是在IoU(Intersection over Union,重疊度)為0.50 的情況下,針對較大目標計算的平均精度(AP)值的均值。 mAP 是模型在不同類別上的平均精度值,而 mAP50(B) 是針對較大目標計算的平均精度值。
mAP50-95(B) 是指 “Mean Average Precision across IoU 0.50 to 0.95 for Large Objects”,意思是在 IoU 從 0.50 到 0.95 範圍內,針對較大目標計算的平均精度值的均值。這個指標更全面地評估了模型在不同重疊度下的性能。
precision(B) 是針對較大目標計算的精確率,即模型在預測中有多少是正確的,相對於所有預測中的正確和錯誤。它是衡量模型預測的準確性的指標之一。
recall(B) 是針對較大目標計算的召回率,即模型正確預測的目標數與實際目標數之比。它表示模型能夠檢測到多少實際目標。召回率是衡量模型識別能力的指標之一。
dfl_loss 是一種在YOLO目標檢測中引入的特殊損失函數,它是基於焦點損失(Focal Loss)的改進。焦點損失的主要目標是應對樣本不平衡問題,即正負樣本比例嚴重失衡。在目標檢測中,負樣本(即不含目標的區域)遠遠多於正樣本(含有目標的區域)。 dfl_loss 試圖通過放大難以分類的正樣本的損失,來應對這種不平衡,從而使模型更關注難以識別的目標。
這是用於衡量預測框位置的損失函數。在目標檢測中,模型不僅要預測目標的類別,還要預測框的位置,即邊界框的中心坐標、寬度和高度。 box_loss 的目標是使模型的位置預測更接近真實目標框的位置。這有助於確保檢測到的框與真實目標框的位置相匹配,從而提高目標定位的準確性。
cls_loss 用於分類目標的類別。在YOLO中,每個檢測框需要預測它所屬的目標類別。 cls_loss 的作用是確保模型的類別預測盡可能準確。這對於準確地將檢測框與正確的目標類別關聯非常重要,從而實現了目標分類的準確性。
這邊深藍色的是使用YOLOv8m.pt做預訓練模型、淺藍色的是使用YOLOv8n,深藍色的跑了2個多小時(100次),淺藍色的因為懶得跑完只做了60幾次。橘色的是別人訓練的歷程。
為什麼自己訓練的結果即使所有資料集都一樣卻有不同的狀況,需要進一步去了解。
GitHub位置: https://github.com/ultralytics/ultralytics
官方網站: https://ultralytics.com/
YOLOv8 最初由 Ultralytics 公司的開發人員開發和發布,旨在在目標檢測任務中提供高性能和高效率的解決方案。 基於深度學習和計算機視覺領域的前沿進步而構建,在速度和準確性方面提供無與倫比的性能。其流線型設計使其適用於各種應用程序,並可輕鬆適應從邊緣設備到雲 API 的不同硬件平台。
與之前的 YOLO 版本相比,YOLOv8 引入了一些新的設計思想和技術,以提高模型的精度和速度。它在模型結構、數據增強、網絡設計等方面進行了優化,使得在目標檢測任務中取得了出色的結果。 YOLOv8 不僅可以在通用的目標檢測任務中表現良好,還可以應用於各種應用領域,如自動駕駛、工業檢測、物體識別等。
官方的教學提供了非常明確的指導: https://docs.ultralytics.com/quickstart/
在這邊我選擇了使用pip安裝,只需要打下這一行就可以了
pip install ultralytics
用command line執行的方式如下
yolo predict model=yolov8n.pt source='https://ultralytics.com/images/bus.jpg'
用python執行偵測的方式
from ultralytics import YOLO
# Load a model
model = YOLO("yolov8n.yaml") # build a new model from scratch
model = YOLO("yolov8n.pt") # load a pretrained model (recommended for training)
# Use the model
model.train(data="coco128.yaml", epochs=3) # train the model
metrics = model.val() # evaluate model performance on the validation set
results = model("https://ultralytics.com/images/bus.jpg") # predict on an image
path = model.export(format="onnx") # export the model to ONNX format
建立一個物件偵測模型,需要做標註、影像增強、修改、訓練、佈署,以及將模型整合至使用端的程式。對於這些流程,Yolo提供了很完整的生態鏈去實現這些步驟
下面是官方網站內一個包含建模、預測、輸出模型的程式碼範例
from ultralytics import YOLO
# Create a new YOLO model from scratch
model = YOLO('yolov8n.yaml')
# Load a pretrained YOLO model (recommended for training)
model = YOLO('yolov8n.pt')
# Train the model using the 'coco128.yaml' dataset for 3 epochs
results = model.train(data='coco128.yaml', epochs=3)
# Evaluate the model's performance on the validation set
results = model.val()
# Perform object detection on an image using the model
results = model('https://ultralytics.com/images/bus.jpg')
# Export the model to ONNX format
success = model.export(format='onnx')
我自己嘗試使用原有的模型訓練新的資料,在訓練過程中,會出現下面這樣的模型訊息
上面那些數值的解釋如下
以上圖而言,在第23輪的訓練其精度為48.4%,F1召回率為59%
YOLO原本建模時所使用的是COCO的資料集,在這個資料集裡面,圖片的長、寬皆為640px,但是實際上我們應用上所使用的圖片很可能並不是640×640的尺寸,這時候就要先對圖片做處理。
如果只是要做預測,可以直接使用resize_with_pad來對圖片做縮放,這個函數可以保持長寬比相同且不失真,將圖像大小調整為目標寬度和高度。如果目標尺寸與圖像尺寸不匹配,則會調整圖像大小,然後用零填充以匹配請求的尺寸。
但對於訓練,您還需要相應地調整邊界框的大小和填充邊界框,這並非易事。
這是如何完成此操作的示例https://nbviewer.jupyter.org/github/aleju/imgaug-doc/blob/master/notebooks/B02%20-%20Augment%20Bounding%20Boxes.ipynb
以下為幾個主要手法:
無論你選擇哪種方法,都需要注意到調整輸入尺寸可能會對模型性能產生影響,特別是在目標檢測任務中。你可能需要在實際場景中進行測試和調整,以找到最適合你應用的方法。
相關教學文章: https://github.com/pytorch/pytorch
首先,PyTorch需要 Python 3.8.1以上的環境,先安裝Anaconda,接著設定一個虛擬環境使用py3.8.1
conda create -n aia16 python=3.8.1
conda activate aia16
切換到新創建的環境之後,就依照下面的步驟下載PyTorch
git clone --recursive https://github.com/pytorch/pytorch
cd pytorch
# if you are updating an existing checkout
git submodule sync
git submodule update --init --recursive
當你運行python setup.py develop
來安裝PyTorch(或任何其他Python套件)時,這個命令的目的是在”開發模式”下安裝該套件。這意味著源代碼的更改會立即反映到Python環境中,無需重新安裝。
但是對於像PyTorch這樣的大型項目,這個過程可能會變得相對緩慢。如果你只是想試用PyTorch而不是開發它,那麼通常建議直接從官方渠道安裝預編譯的版本,這樣會快得多。(可以跳過此步驟)
安裝編譯所需工具
conda install cmake ninja
# Run this command from the PyTorch directory after cloning the source code using the “Get the PyTorch Source“ section below
pip install -r requirements.txt
# Add this package on intel x86 processor machines only
conda install mkl mkl-include
# Add these packages if torch.distributed is needed
conda install pkg-config libuv
開始編譯
python3 setup.py develop
使用預編譯的二進制檔案安裝PyTorch是相對簡單的。以下是使用pip或conda安裝PyTorch的方法:
使用pip安裝
pip install torch torchvision
使用conda安裝
conda install pytorch torchvision -c pytorch
https://github.com/pytorch/ios-demo-app
首先要先安裝依賴管理套件cocoapods,安裝指令如下:
sudo gem install cocoapods
cocoapods安裝失敗解決方法
用homebrew安裝
brew install cocoapods
先把目錄切到有PodFile的位置,然後下指令
pod install
教程網址: https://github.com/tensorflow/tfjs-models/tree/master/coco-ssd
目標檢測模型,旨在定位和識別單個圖像中的多個目標。
該模型是 COCO-SSD 模型的 TensorFlow.js 移植。有關 Tensorflow 對象檢測 API 的更多信息,請查看 tensorflow/object_detection中的自述文件。
該模型檢測 COCO 數據集中定義的對象,這是一個大規模的對象檢測、分割和字幕數據集。您可以在這裡找到更多信息。該模型能夠檢測80 類物體。(SSD 代表單次多盒檢測)。
此 TensorFlow.js 模型不需要您了解機器學習。它可以將輸入作為任何基於瀏覽器的圖像元素(例如<img>
、<video>
、<canvas>
元素),並返回帶有類名稱和置信度的邊界框數組。
<!-- Load TensorFlow.js. This is required to use coco-ssd model. -->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"> </script>
<!-- Load the coco-ssd model. -->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/coco-ssd"> </script>
<!-- Replace this with your image. Make sure CORS settings allow reading the image! -->
<img id="img" src="cat.jpg"/>
<!-- Place your code in the script tag below. You can also use an external .js file -->
<script>
// Notice there is no 'import' statement. 'cocoSsd' and 'tf' is
// available on the index-page because of the script tag above.
const img = document.getElementById('img');
// Load the model.
cocoSsd.load().then(model => {
// detect objects in the image.
model.detect(img).then(predictions => {
console.log('Predictions: ', predictions);
});
});
</script>
以下為一個簡單讀取攝像機並且作物件偵測的程式範例
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Test</title>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"> </script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/coco-ssd"> </script>
</head>
<body>
<div class="select">
<label for="videoSource">Video source: </label><select id="videoSource"></select>
</div>
<button id="showVideo">Open camera</button>
<br />
<!-- Video element to capture camera input -->
<video id="video" autoplay playsinline style="position: absolute;z-index: -999;"></video><canvas id="canvas"
width="100%"></canvas>
<div id="message"></div>
<script>
const video = document.getElementById('video');
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
document.querySelector('#showVideo').addEventListener('click', e => init(e));
const videoSelect = document.querySelector('select#videoSource');
function gotDevices(deviceInfos) {
console.log(deviceInfos)
deviceInfos.forEach(deviceInfo => {
if (deviceInfo.kind == "videoinput") {
const option = document.createElement('option');
option.value = deviceInfo.deviceId;
option.text = deviceInfo.label || `camera ${videoSelect.length + 1}`;
videoSelect.appendChild(option);
}
});
}
function gotStream(stream) {
window.stream = stream; // make stream available to console
videoElement.srcObject = stream;
// Refresh button list in case labels have become available
return navigator.mediaDevices.enumerateDevices();
}
window.onload = () => {
navigator.mediaDevices.enumerateDevices().then(gotDevices).catch(handleError);
const constraints = {
audio: { deviceId: audioSource ? { exact: audioSource } : undefined },
video: { deviceId: videoSource ? { exact: videoSource } : undefined }
};
navigator.mediaDevices.getUserMedia(constraints).then(gotStream).then(gotDevices).catch(handleError);
}
function getRandomColor() {
const randomColor = Math.floor(Math.random() * 16777215).toString(16);
return "#" + ("000000" + randomColor).slice(-6);
}
function handleSuccess(stream) {
const videoTracks = stream.getVideoTracks();
var predictions = [];
video.srcObject = stream;
// When the video is playing, draw it on the canvas
video.addEventListener('play', () => {
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
// Continuously draw the video frames on the canvas
function drawFrame() {
// Draw the video frame on the canvas
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
const scaleX = canvas.width / video.videoWidth;
const scaleY = canvas.height / video.videoHeight;
// Draw the bounding boxes on the canvas
predictions.forEach(prediction => {
const x = prediction.bbox[0] * scaleX;
const y = prediction.bbox[1] * scaleY;
const width = prediction.bbox[2] * scaleX;
const height = prediction.bbox[3] * scaleY;
ctx.strokeStyle = 'blue';
ctx.lineWidth = 2;
ctx.strokeRect(x, y, width, height);
ctx.fillStyle = 'blue';
ctx.font = '18px Arial';
ctx.fillText(prediction.class, x, y);
});
// Call the drawFrame function again to continuously update the canvas
requestAnimationFrame(drawFrame);
}
// Start drawing video frames
drawFrame();
// Load the model.
cocoSsd.load().then(model => {
function detectFrame() {
// detect objects in the image.
model.detect(video).then(preds => {
predictions = preds
setTimeout(detectFrame, 100);
});
}
detectFrame()
});
});
}
function handleError(error) {
if (error.name === 'OverconstrainedError') {
const v = constraints.video;
alert(`The resolution ${v.width.exact}x${v.height.exact} px is not supported by your device.`);
} else if (error.name === 'NotAllowedError') {
alert('Permissions have not been granted to use your camera and ' +
'microphone, you need to allow the page access to your devices in ' +
'order for the demo to work.');
}
alert(`getUserMedia error: ${error.name}`, error);
}
async function init(e) {
try {
const stream = await navigator.mediaDevices.getUserMedia({ audio: false, video: { deviceId: videoSelect.value ? { exact: videoSelect.value } : undefined } });
handleSuccess(stream);
e.target.disabled = true;
} catch (e) {
handleError(e);
}
}
</script>
</body>
</html>
以下為範例執行程式: https://claire-chang.com/wp-content/uploads/2023/08/sample.html
要開啟鏡頭權限需要至網站設定開啟權限