MNISTに訓練されたモデルの数字認識を改善するには?

youngpanda:

私はと手書き複数桁の認識に取り組んでいますJava使用して、OpenCV前処理とセグメンテーション、およびのためのライブラリをKeras認識するために(0.98の精度で)MNISTに訓練されたモデル。

認識が離れて一つのことから、非常にうまく機能しているようです。ネットワークは、かなり頻繁なもの(番号「1」)を認識できません。それは前処理/セグメンテーションの不正確な実装をするため、発生した場合、私は理解できない、または標準MNISTに訓練されたネットワークは、ちょうど私のテストケースのように見えるナンバーワンを見ていない場合。

ここでは、問題の数字は前処理とセグメンテーションの後にどのように見えるかです:

ここでは、画像の説明を入力します。なりここでは、画像の説明を入力します。とに分類されます4

ここでは、画像の説明を入力します。なりここでは、画像の説明を入力します。とに分類されます7

ここでは、画像の説明を入力します。なりここでは、画像の説明を入力します。とに分類されます4等々...

これは、セグメント化プロセスを改善することにより固定することができ何かか?かトレーニングセットを高めることにより?

編集:私はすでにテストしてい間違いなく助け、希望トレーニングセット(データ増強を)強化、正しい前処理の疑問が残ります。

私の前処理は、グレースケール、二値化、反転、そして拡張への変換、サイズ変更から成ります。ここで、コードは次のとおりです。

Mat resized = new Mat();
Imgproc.resize(image, resized, new Size(), 8, 8, Imgproc.INTER_CUBIC);

Mat grayscale = new Mat();
Imgproc.cvtColor(resized, grayscale, Imgproc.COLOR_BGR2GRAY);

Mat binImg = new Mat(grayscale.size(), CvType.CV_8U);
Imgproc.threshold(grayscale, binImg, 0, 255, Imgproc.THRESH_OTSU);

Mat inverted = new Mat();
Core.bitwise_not(binImg, inverted);

Mat dilated = new Mat(inverted.size(), CvType.CV_8U);
int dilation_size = 5;
Mat kernel = Imgproc.getStructuringElement(Imgproc.CV_SHAPE_CROSS, new Size(dilation_size, dilation_size));
Imgproc.dilate(inverted, dilated, kernel, new Point(-1,-1), 1);

前処理画像は、その後、以下のように個々の桁に分割されます。

List<Mat> digits = new ArrayList<>();
List<MatOfPoint> contours = new ArrayList<>();
Imgproc.findContours(preprocessed.clone(), contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);

// code to sort contours
// code to check that contour is a valid char

List rects = new ArrayList<>();

for (MatOfPoint contour : contours) {
     Rect boundingBox = Imgproc.boundingRect(contour);
     Rect rectCrop = new Rect(boundingBox.x, boundingBox.y, boundingBox.width, boundingBox.height);

     rects.add(rectCrop);
}

for (int i = 0; i < rects.size(); i++) {
    Rect x = (Rect) rects.get(i);
    Mat digit = new Mat(preprocessed, x);

    int border = 50;
    Mat result = digit.clone();
    Core.copyMakeBorder(result, result, border, border, border, border, Core.BORDER_CONSTANT, new Scalar(0, 0, 0));

    Imgproc.resize(result, result, new Size(28, 28));
    digits.add(result);
}
youngpanda:

いくつかの研究と実験の後、私は自分自身を前処理画像が(私は例えば拡張サイズや形状などのいくつかの提案のパラメータを変更しましたが、それらは結果に非常に重要ではなかった)問題ではなかったという結論に達しました。助けをやった、しかし、2次のものがありました。

  1. F4Fが気づい@として、私は実世界のデータを自分のデータセットを収集するために必要。これは、既に途方もなく助けました。

  2. 私は私のセグメンテーションの前処理に重要な変更を行いました。個々の輪郭を取得した後、私は最初に収まるように画像をサイズ正規化20x20(彼らはしているような画素ボックスMNIST)。その後私は、中央のボックスの中心28x28(二値画像の両方の次元にわたる平均値である)の質量の中心を使用して画像。

もちろん、そのようなオーバーラップまたは接続された数字など困難なセグメンテーション例は、まだありますが、上記の変更は、私の最初の質問に答え、私の分類性能を改善しました。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=307715&siteId=1