LoginSignup
7
6

More than 3 years have passed since last update.

mean Intersection over Union (mIoU) の理解と実装

Last updated at Posted at 2021-03-30

segmentationの評価手法の一つであるmIoUが計算していることがよくわからなかったので絵にしてみました。

1

$$
mIoU = \frac{1}{k} \sum_{i=1}^k \frac{N_{ii}}{\sum_{i=1}^k N_{ij} + \sum_{j=1}^k N_{ji} - N_{ii}}
$$

  • $N_{ij}$: 正解クラスが$i$であるピクセルをモデルがクラスjに分類した数
  • $k$: クラス数

まとめ

image.png

Accuracyに対するメリット

  • クラスの偏りがあっても不当な評価値になりにくい
    • 例) Accuracyではほとんどのピクセルが1になるようなサンプルでは、全ピクセルで1を出力するモデルでも評価が高くなってしまう。
    • mIoUではざっくりクラスごとに評価してから平均するので、2のラベルの予測が全くできていないとほとんどのピクセルがが1であっても大きく評価値に影響する。

実装

import numpy as np
from sklearn.metrics import confusion_matrix

def mIoU(true: np.ndarray, pred: np.ndarray) -> float:
    """Calculate mIoU between 2 class label arrays

    Parameters
    ----------
    true : np.ndarray
        A 2d class label array
    pred : np.ndarray
        A 2d class label array of the same shape of true

    Return
    ------
    float
        mIoU
    """
    c_matrix = confusion_matrix(true.ravel(), pred.ravel())
    intersection = np.diag(c_matrix)
    union = np.sum(c_matrix, axis=0) + np.sum(c_matrix, axis=1) - intersection
    iou = intersection / union
    miou = np.mean(iou)
    return miou

# Test
true = np.zeros((5, 5))
true[1:3, 1:3] = 1
pred = np.zeros((5, 5))
pred[2:4, 2:4] = 1
assert mIoU(true, pred) == np.mean([1 / 7, (5 * 5 - 7) / (5 * 5 - 1)])
print("true")
print(true)
print("pred")
print(pred)
print("mIoU = %.2f" % mIoU(true, pred))

理解や実装に誤りありましたらご指摘いただけると助かります。

参考

7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6