yolov5をrknnモデルに変換する

コンテンツ

1変換方法

2yolov5バージョンの問題

3yolov5出力フォーマットの問題

4rknnモデルに変換する際のフォーマットの問題


1変換方法

yolov5のp番目のモデルをrknnモデルに変換します。特定の方法は、2つのステップに分かれています。

  1. yolov5プロジェクトに付属のexport.pyを使用して、ptモデルをonnxモデルに変換します
  2. 次のスクリプトを使用して、rknnモデルを生成します

onnxモデルをRV1126プラットフォームのrknnモデルに変換します-cumtchw-CSDNブログ

このメモは、特定の変換方法を紹介するためではなく、中間変換プロセスでいくつかの問題を記録するためのものです。

2yolov5バージョンの問題

Rockchipのボード上のyolov5のrknnモデルを推測するために、C ++を使用したいと考えています。現在、通常、Rockchipが提供するC++デモを使用しています。

RockchipRV1126のYOLOv5公式推論デモ

このデモの後処理は3出力モデルを対象としています。このデモを使用する場合、v5.0バージョンモデルにはv6.0バージョンではなく、v5.0バージョンを使用する必要があります。 3つの出力、v6.0バージョンは最終的に3つの出力を組み合わせます。

3yolov5出力フォーマットの問題

標準のyolov5-5.0には3つの出力があります。

1x255x80x80

1x255x40x40

1x255x20x20

 その中で、255は85 * 3であり、3は3つのアンカーによって生成された3つのボックスを指します(RGB 3チャネルではなく、最終出力にはRGBの概念はありません)。ここで85は5 + 80=85を指します。 80はカテゴリの数であり、各カテゴリはラベルスコア、合計80のラベルスコアに対応し、5はボックスの4つの座標とボックススコアを表します。

yolov5-6.0バージョンの場合、6.0は3つの出力を組み合わせ、配置はxywh box_score id Id1_score id2_score .... idn_score、3 * 80 * 80 * 12の場合、出力カテゴリの数は7ではなく6です。 IDの計算に相当するIDが含まれており、yolov5-5.0バージョンの3つの出力が組み合わされていないため、カテゴリスコアのみがあり、カテゴリはありません。

4rknnモデルに変換する際のフォーマットの問題

ここでは、3つのラベル(マスクなし、マスクを正しく着用、マスクを誤って着用)を使用したマスク認識モデルを例として取り上げます。3つのラベルを使用したマスク認識モデルの出力は次のとおりです。そのうち24はの出力です。 3チャネル*8、8の出力はxywh box_score Id1_scoreid2_scoreid3_scoreです。

1 * 24 * 80 * 80

1 * 24 * 40 * 40

1 * 24 * 20 * 20

初めて変換したとき、RockchipのRV1126ボードで推論すると、転送されたrknnモデルの結果が完全に間違っていることがわかりました。全体像にさまざまな小さなボックスがありました。検索したところ、出力形式が正しくないことがわかりました。 1. * 24 * 20 * 20ですが、1 * 3 * 20 * 20 * 8のようになったので、export.pyを使用してonnxモデルを生成する前に、yolov5-5.0プロジェクトのyolo.pyを次のように変更しました。次に、export.pyを使用してonnxモデルを生成し、それをrknnモデルに変換します。

変更は順列を削除することであり、view()にself.naとself.noが乗算されることに注意してください。

または、次のように変更し、self.training | = self.exportをコメントアウトしてから、エクスポートブランチを直接追加します。

    def forward(self, x):
        # x = x.copy()  # for profiling
        z = []  # inference output
       # self.training |= self.export
        if self.export:
            for i in range(self.nl):
                x[i] = self.m[i](x[i])
                bs, _, ny, nx = x[i].shape  # x(bs,48,20,20) to x(bs,3,20,20,16)
                x[i] = x[i].view(bs, self.na*self.no, ny, nx).contiguous()

            return x

        for i in range(self.nl):
            x[i] = self.m[i](x[i])  # conv
            bs, _, ny, nx = x[i].shape  # x(bs,255,20,20) to x(bs,3,20,20,85)
            x[i] = x[i].view(bs, self.na, self.no, ny, nx).permute(0, 1, 3, 4, 2).contiguous()
        .......后面代码........

この変更後の出力形式は次のとおりです。

netronがonnxモデルを見るとき

 netronがrknnモデルを見るとき:

 RV1126ボードで実行した場合の印刷は次のとおりです。

おすすめ

転載: blog.csdn.net/u013171226/article/details/123401225