YOLO-NAS 物体検出 導入YOLO (You Only Look Once) は、ディープ ニューラル ネットワーク モデル、具体的には畳み込みニューラル ネットワークを使用して、オブジェクトをリアルタイムで検出および分類するオブジェクト検出アルゴリズムです。このアルゴリズムは、2016 年の論文「You Only Look Once: Unified Real-time Object Detection」で初めて提案されました。 YOLO はリリース以来、その高い精度と速度により、物体検出および分類タスクで最も人気のあるアルゴリズムの 1 つになりました。さまざまな物体検出ベンチマークで最先端のパフォーマンスを実現します。 YOLOアーキテクチャ 2023 年 5 月の第 1 週に、YOLO-NAS モデルが、YOLOv7 や YOLOv8 などの他のモデルを上回る比類のない精度と速度を備えて機械学習の分野に導入されました。 YOLO-NASと他モデルの比較 YOLO-NAS モデルは、COCO や Objects365 などのデータセットで事前トレーニングされているため、実際のアプリケーションに適しています。これは現在、分類、検出、セグメンテーションなどのさまざまなコンピューター ビジョン タスクを実行するための約 40 個の事前トレーニング済みモデルを含む PyTorch ベースのライブラリである Deci の SuperGradients で利用できます。 それでは、SuperGradients ライブラリをインストールして、YOLO-NAS を使い始めましょう。 # Installing supergradients lib !pip install super-gradients==3.1.0 YOLO-NASのインポートとロード#importing models from supergradients' training module from super_gradients.training import models
次のステップはモデルを初期化することです。 YOLO-NASにはさまざまなモデルがありますが、この記事では pretrained_weights = 'coco'のyolo_nas_l 。 さまざまなモデルの詳細については、この GitHub ページをご覧ください。 # Initializing model yolo_nas = models.get("yolo_nas_l", pretrained_weights = "coco") モデルアーキテクチャ以下のコード セルでは、torchinfo のサマリーを使用して YOLO-NAS のアーキテクチャを取得します。これは、モデルの動作を理解するのに非常に役立ちます。 # Yolo NAS architecture !pip install torchinfo from torchinfo import summary summary(model = yolo_nas, input_size = (16,3,640,640), col_names = ['input_size', 'output_size', 'num_params', 'trainable'], col_width = 20, row_settings = ['var_names']) ================================================================================================================================================= Layer (type (var_name)) Input Shape Output Shape Param # Trainable ================================================================================================================================================= YoloNAS_L (YoloNAS_L) [16, 3, 640, 640] [16, 8400, 4] -- True ├─NStageBackbone (backbone) [16, 3, 640, 640] [16, 96, 160, 160] -- True │ └─YoloNASStem (stem) [16, 3, 640, 640] [16, 48, 320, 320] -- True │ │ └─QARepVGGBlock (conv) [16, 3, 640, 640] [16, 48, 320, 320] 3,024 True │ └─YoloNASStage (stage1) [16, 48, 320, 320] [16, 96, 160, 160] -- True │ │ └─QARepVGGBlock (downsample) [16, 48, 320, 320] [16, 96, 160, 160] 88,128 True │ │ └─YoloNASCSPLayer (blocks) [16, 96, 160, 160] [16, 96, 160, 160] 758,594 True │ └─YoloNASStage (stage2) [16, 96, 160, 160] [16, 192, 80, 80] -- True │ │ └─QARepVGGBlock (downsample) [16, 96, 160, 160] [16, 192, 80, 80] 351,360 True │ │ └─YoloNASCSPLayer (blocks) [16, 192, 80, 80] [16, 192, 80, 80] 2,045,315 True │ └─YoloNASStage (stage3) [16, 192, 80, 80] [16, 384, 40, 40] -- True │ │ └─QARepVGGBlock (downsample) [16, 192, 80, 80] [16, 384, 40, 40] 1,403,136 True │ │ └─YoloNASCSPLayer (blocks) [16, 384, 40, 40] [16, 384, 40, 40] 13,353,733 True │ └─YoloNASStage (stage4) [16, 384, 40, 40] [16, 768, 20, 20] -- True │ │ └─QARepVGGBlock (downsample) [16, 384, 40, 40] [16, 768, 20, 20] 5,607,936 True │ │ └─YoloNASCSPLayer (blocks) [16, 768, 20, 20] [16, 768, 20, 20] 22,298,114 True │ └─SPP (context_module) [16, 768, 20, 20] [16, 768, 20, 20] -- True │ │ └─Conv (cv1) [16, 768, 20, 20] [16, 384, 20, 20] 295,680 True │ │ └─ModuleList (m) -- -- -- -- │ │ └─Conv (cv2) [16, 1536, 20, 20] [16, 768, 20, 20] 1,181,184 True ├─YoloNASPANNeckWithC2 (neck) [16, 96, 160, 160] [16, 96, 80, 80] -- True │ └─YoloNASUpStage (neck1) [16, 768, 20, 20] [16, 192, 20, 20] -- True │ │ └─Conv (reduce_skip1) [16, 384, 40, 40] [16, 192, 40, 40] 74,112 True │ │ └─Conv (reduce_skip2) [16, 192, 80, 80] [16, 192, 80, 80] 37,248 True │ │ └─Conv (downsample) [16, 192, 80, 80] [16, 192, 40, 40] 332,160 True │ │ └─Conv (conv) [16, 768, 20, 20] [16, 192, 20, 20] 147,840 True │ │ └─ConvTranspose2d (upsample) [16, 192, 20, 20] [16, 192, 40, 40] 147,648 True │ │ └─Conv (reduce_after_concat) [16, 576, 40, 40] [16, 192, 40, 40] 110,976 True │ │ └─YoloNASCSPLayer (blocks) [16, 192, 40, 40] [16, 192, 40, 40] 2,595,716 True │ └─YoloNASUpStage (neck2) [16, 192, 40, 40] [16, 96, 40, 40] -- True │ │ └─Conv (reduce_skip1) [16, 192, 80, 80] [16, 96, 80, 80] 18,624 True │ │ └─Conv (reduce_skip2) [16, 96, 160, 160] [16, 96, 160, 160] 9,408 True │ │ └─Conv (downsample) [16, 96, 160, 160] [16, 96, 80, 80] 83,136 True │ │ └─Conv (conv) [16, 192, 40, 40] [16, 96, 40, 40] 18,624 True │ │ └─ConvTranspose2d (upsample) [16, 96, 40, 40] [16, 96, 80, 80] 36,960 True │ │ └─Conv (reduce_after_concat) [16, 288, 80, 80] [16, 96, 80, 80] 27,840 True │ │ └─YoloNASCSPLayer (blocks) [16, 96, 80, 80] [16, 96, 80, 80] 2,546,372 True │ └─YoloNASDownStage (neck3) [16, 96, 80, 80] [16, 192, 40, 40] -- True │ │ └─Conv (conv) [16, 96, 80, 80] [16, 96, 40, 40] 83,136 True │ │ └─YoloNASCSPLayer (blocks) [16, 192, 40, 40] [16, 192, 40, 40] 1,280,900 True │ └─YoloNASDownStage (neck4) [16, 192, 40, 40] [16, 384, 20, 20] -- True │ │ └─Conv (conv) [16, 192, 40, 40] [16, 192, 20, 20] 332,160 True │ │ └─YoloNASCSPLayer (blocks) [16, 384, 20, 20] [16, 384, 20, 20] 5,117,700 True ├─NDFLHeads (heads) [16, 96, 80, 80] [16, 8400, 4] -- True │ └─YoloNASDFLHead (head1) [16, 96, 80, 80] [16, 68, 80, 80] -- True │ │ └─ConvBNReLU (stem) [16, 96, 80, 80] [16, 128, 80, 80] 12,544 True │ │ └─Sequential (cls_convs) [16, 128, 80, 80] [16, 128, 80, 80] 147,712 True │ │ └─Conv2d (cls_pred) [16, 128, 80, 80] [16, 80, 80, 80] 10,320 True │ │ └─Sequential (reg_convs) [16, 128, 80, 80] [16, 128, 80, 80] 147,712 True │ │ └─Conv2d (reg_pred) [16, 128, 80, 80] [16, 68, 80, 80] 8,772 True │ └─YoloNASDFLHead (head2) [16, 192, 40, 40] [16, 68, 40, 40] -- True │ │ └─ConvBNReLU (stem) [16, 192, 40, 40] [16, 256, 40, 40] 49,664 True │ │ └─Sequential (cls_convs) [16, 256, 40, 40] [16, 256, 40, 40] 590,336 True │ │ └─Conv2d (cls_pred) [16, 256, 40, 40] [16, 80, 40, 40] 20,560 True │ │ └─Sequential (reg_convs) [16, 256, 40, 40] [16, 256, 40, 40] 590,336 True │ │ └─Conv2d (reg_pred) [16, 256, 40, 40] [16, 68, 40, 40] 17,476 True │ └─YoloNASDFLHead (head3) [16, 384, 20, 20] [16, 68, 20, 20] -- True │ │ └─ConvBNReLU (stem) [16, 384, 20, 20] [16, 512, 20, 20] 197,632 True │ │ └─Sequential (cls_convs) [16, 512, 20, 20] [16, 512, 20, 20] 2,360,320 True │ │ └─Conv2d (cls_pred) [16, 512, 20, 20] [16, 80, 20, 20] 41,040 True │ │ └─Sequential (reg_convs) [16, 512, 20, 20] [16, 512, 20, 20] 2,360,320 True │ │ └─Conv2d (reg_pred) [16, 512, 20, 20] [16, 68, 20, 20] 34,884 True ================================================================================================================================================= Total params: 66,976,392 Trainable params: 66,976,392 Non-trainable params: 0 Total mult-adds (T): 1.04 ================================================================================================================================================= Input size (MB): 78.64 Forward/backward pass size (MB): 27238.60 Params size (MB): 178.12 Estimated Total Size (MB): 27495.37 ================================================================================================================================================= 画像上の物体検出これで、さまざまな画像上のオブジェクトを検出するモデルの能力をテストできます。 次のコードでは、画像を含む URL を受け取る image という変数を初期化します。次に、predict メソッドと show メソッドを使用して、モデルの予測を含む画像を表示できます。 image = "https://i.pinimg.com/736x/b4/29/48/b42948ef9202399f13d6e6b3b8330b20.jpg" yolo_nas.predict(image).show() yolo_nas.predict(画像).show() 上の画像では、各オブジェクトに対して行われた検出と、モデルが独自の予測に対して持つ信頼スコアを確認できます。たとえば、床にある白い物体がカップであるとモデルが 97% 確信していることがわかります。しかし、この画像には多くの物体があり、モデルがニンテンドー64を車と間違えていることがわかります。 検出のしきい値として機能する conf パラメータを調整することで、結果を改善できます。たとえば、この値を conf = 0.50 に変更すると、モデルは信頼レベルが 50% を超える検出のみを表示します。試してみましょう。 image = "https://i.pinimg.com/736x/b4/29/48/b42948ef9202399f13d6e6b3b8330b20.jpg" yolo_nas.predict(image, conf = 0.50).show() YOLO-NAS: 画像上の物体検出 現在、モデルは、カップ、テレビ、リモコンなど、検出に少なくとも 50% の信頼度があるオブジェクトのみを表示します。 さらに多くの画像をテストできます。 YOLO-NAS: 画像上の物体検出 ビデオ上の物体検出YOLO-NAS モデルを使用して、ビデオ上でリアルタイムのオブジェクト検出を実行することもできます。 次のコードでは、IPython ライブラリの YouTubeVideo モジュールを使用して、好きな YouTube ビデオを選択して保存します。 from IPython.display import YouTubeVideo # Importing YouTubeVideo from IPython's display module video_id = "VtK2ZMlcCQU" # Selecting video ID video = YouTubeVideo(video_id) # Loading video display(video) # Displaying video ビデオを選択したので、youtube-dl ライブラリを使用してビデオを .mp4 形式でダウンロードします。 完了したら、ビデオを input_video_path 変数に保存します。この変数は、モデルが検出を実行するための入力として機能します。 # Downloading video video_url = f'https://www.youtube.com/watch?v={video_id}' !pip install -U "git+https://github.com/ytdl-org/youtube-dl.git" !python -m youtube_dl -f 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/mp4' "$video_url" print('Video downloaded') # Selecting input and output paths input_video_path = f"/kaggle/working/Golf Rehab 'Short Game' Commercial-VtK2ZMlcCQU.mp4" output_video_path = "detections.mp4" 次に、PyTorch をインポートして GPU を有効にします。 import torch device = 'cuda' if torch.cuda.is_available() else "cpu" 次に、to() メソッドを使用して GPU 上で YOLO-NAS モデルを実行し、predict() メソッドを使用して input_video_path 変数に保存されているビデオの予測を実行します。 save() メソッドは、検出結果を含むビデオを保存するために使用されます。保存パスは output_video_path によって指定されます。 yolo_nas.to(device).predict(input_video_path).save(output_video_path) # Running predictions on video Video downloaded Predicting Video: 100%|██████████| 900/900 [33:15<00:00, 2.22s/it] 完了したら、IPython を再度使用して、この Kaggle ノートブックで表示するために.gif 形式でダウンロードされたビデオを含む .gif ファイルを表示します。 from IPython.display import Image with open('/kaggle/input/detection-gif/detections.gif','rb') as f: display(Image(data=f.read(), format='png')) 結論は新しくリリースされた YOLO-NAS モデルを使用して、画像とビデオに対する初期のオブジェクト検出タスクを実行しました。カスタム データセットを使用してこのモデルを微調整し、特定のオブジェクトでのパフォーマンスを向上させることができます。 |