एमएनआईएसटी पर प्रशिक्षित मॉडल की अंक पहचान कैसे सुधारें?


12

मैं प्रीप्रोसेसिंग और सेगमेंटेशन के लिए लाइब्रेरी Javaका उपयोग करते हुए OpenCV, और Kerasमान्यता के लिए MNIST (0.98 की सटीकता के साथ) पर प्रशिक्षित मॉडल का उपयोग करते हुए, बहु-अंक मान्यता के साथ काम कर रहा हूं ।

मान्यता एक चीज के अलावा, काफी अच्छी तरह से काम करती है। नेटवर्क अक्सर लोगों को पहचानने में विफल रहता है (संख्या "एक")। यदि यह विभाजन के पूर्वप्रक्रमक / गलत कार्यान्वयन के कारण होता है, या यदि मानक 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);
}

1
आप अपने वर्गीकरण के लिए इनपुट के रूप में मास्क (या नकाबपोश?) मूल ग्रेस्केल पिक्सल का उपयोग कर रहे हैं?
मिका

@ मिका मैं प्रीप्रोसेस्ड (बिनाराइज्ड, इनवर्टेड, पतला) संस्करण का उपयोग कर रहा हूं। एमएनआईएसटी प्रशिक्षण सेट से मेल खाने वाले लोग। मेरी पोस्ट में प्रीप्रोसेसिंग के बाद संख्या "1" के उदाहरण हैं।
यंगपंडा

जवाबों:


5

मेरा मानना ​​है कि आपकी समस्या है प्रक्रिया को पतला करना। मैं समझता हूं कि आप छवि आकारों को सामान्य करना चाहते हैं, लेकिन आपको अनुपात को नहीं तोड़ना चाहिए, आपको एक अक्ष द्वारा अधिकतम वांछित आकार का होना चाहिए (वह है जो किसी अन्य अक्ष आयाम को अधिकतम आकार को पार किए बिना सबसे बड़ा पुन: स्केल करने की अनुमति देता है) और भरें पृष्ठभूमि रंग के साथ शेष छवि। ऐसा नहीं है कि "मानक MNIST ने केवल वह नंबर नहीं देखा है जो आपके परीक्षण मामलों की तरह दिखता है", आप अपनी छवियों को विभिन्न प्रशिक्षित नंबरों की तरह देखते हैं (जो मान्यता प्राप्त हैं)

स्रोत और संसाधित छवियों का ओवरलैप

यदि आपने अपनी छवियों का सही पहलू राशन (स्रोत और पोस्ट-प्रोसेस्ड) बनाए रखा है, तो आप देख सकते हैं कि आपने केवल छवि को आकार नहीं दिया बल्कि इसे "विकृत" किया। यह गैर-सजातीय फैलाव या गलत आकार बदलने का परिणाम हो सकता है


मेरा मानना ​​है कि @ एसआईआर का कुछ वजन है, संख्यात्मक शाब्दिक के पहलू अनुपात को बदलने की कोशिश न करें।
ZdaR

क्षमा करें, मैं काफी अनुसरण नहीं करता। क्या आपको लगता है कि मेरी फैलाव प्रक्रिया या आकार बदलने की प्रक्रिया समस्या है? मैं केवल इस लाइन के साथ शुरुआत में छवि का आकार बदलता हूं Imgproc.resize(image, resized, new Size(), 8, 8, Imgproc.INTER_CUBIC);। यहां पहलू राशन वही रहता है, जहां मैं अनुपात को तोड़ता हूं?
युवापंडा

ऊपर दिए गए आपके संपादनों के जवाब में @SiR: हां, मैं सिर्फ छवि का आकार नहीं बदल रहा हूं, मैं अलग-अलग ऑपरेशन लागू करता हूं, उनमें से एक फैलाव है, जो एक रूपात्मक है, जो मामूली "विकृति" का कारण बनता है क्योंकि यह एक के भीतर उज्ज्वल क्षेत्रों का कारण बनता है "बढ़ने" के लिए छवि। या क्या आपका मतलब बहुत अंत में है, जहां मैं चित्र 28x28 बनाता हूं?
युवापंडित

@youngpanda, आपको यहां चर्चा मिल सकती है stackoverflow.com/questions/28525436/… दिलचस्प। यह आप एक सुराग क्यों अपने दृष्टिकोण अच्छे परिणाम नहीं लाती दे सकता है
महोदय

@ एसआईआर आपको लिंक के लिए धन्यवाद, मैं लेनेट से परिचित हूं, लेकिन इसे फिर से पढ़ना अच्छा है
यंगपंडा

5

पहले से ही कुछ उत्तर पोस्ट किए गए हैं, लेकिन उनमें से कोई भी छवि के बारे में आपके वास्तविक सवाल का जवाब नहीं देता है ।

अपनी बारी में मुझे आपके कार्यान्वयन के साथ कोई महत्वपूर्ण समस्या नहीं दिखती है जब तक कि यह एक अध्ययन परियोजना है, अच्छी तरह से किया गया।

लेकिन ध्यान देने वाली एक बात आपको याद आ सकती है। गणितीय आकृति विज्ञान में बुनियादी ऑपरेशन हैं: क्षरण और फैलाव (आपके द्वारा उपयोग किया गया)। और वहाँ जटिल ऑपरेशन: बुनियादी लोगों के विभिन्न संयोजन (जैसे। उद्घाटन और समापन)। विकिपीडिया लिंक सबसे अच्छा सीवी संदर्भ नहीं है, लेकिन आप विचार प्राप्त करने के लिए इसके साथ शुरू कर सकते हैं।

आमतौर पर कटाव के बजाय उद्घाटन का उपयोग करना बेहतर होता है और फैलाव के बजाय बंद हो जाता है क्योंकि इस मामले में मूल द्विआधारी छवि बहुत कम बदलती है (लेकिन तेज किनारों को साफ करने या अंतराल को भरने का वांछित प्रभाव तक पहुंच जाता है)। तो आपके मामले में आपको क्लोजिंग (एक ही कर्नेल के साथ कटाव के बाद छवि फैलाव) की जांच करनी चाहिए। यदि आप 1 * 1 कर्नेल (1 पिक्सेल छवि के 16% से अधिक है) जो बड़ी छवियों पर कम है, के साथ भी पतला होने पर अतिरिक्त * छोटी छवि 8 * 8 को बहुत संशोधित किया जाता है।

विचार की कल्पना करने के लिए निम्न तस्वीरें (OpenCV ट्यूटोरियल से देखें: 1 , 2 ):

फैलाव: मूल प्रतीक और एक पतला

समापन: मूल प्रतीक और एक बंद

आशा है ये मदद करेगा।


इनपुट के लिए धन्यवाद! वास्तव में यह एक अध्ययन परियोजना नहीं है, इसलिए समस्या क्या होगी? .. जब मैं फैलाव लागू करता हूं, तो मेरी छवि काफी बड़ी है, 8x8 छवि का आकार नहीं है, यह ऊंचाई और चौड़ाई के लिए आकार बदलने वाला कारक है। लेकिन यह अभी भी विभिन्न गणितीय कार्यों को आज़माने के लिए एक सुधार विकल्प हो सकता है। मैं खोलने और बंद करने के बारे में नहीं जानता था, मैं इसे आज़माऊंगा! धन्यवाद।
यंगपांडा

मेरी गलती, गलत आकार कॉल के रूप में यह 8 * 8 नए आकार के साथ था। यदि आप वास्तविक दुनिया में ओसीआर का उपयोग करना चाहते हैं, तो आप अपने उपयोग के क्षेत्र के लिए विशिष्ट डेटा पर अपने मूल नेट को स्थानांतरित करने के विकल्प पर विचार करेंगे। कम से कम यह जांचें कि क्या यह सटीकता में सुधार करता है, आम तौर पर इसे करना चाहिए।
f4f

जांच करने के लिए एक और चीज प्रीप्रोसेसिंग ऑर्डर है: ग्रेस्केल-> बाइनरी-> उलटा-> आकार। आकार बदलना एक महंगा ऑपरेशन है और मुझे इसे रंगीन छवि पर लागू करने की आवश्यकता नहीं है। और प्रतीक विभाजन समोच्च पहचान के बिना किया जा सकता है (कुछ कम लागत के साथ) यदि आपके पास कुछ विशिष्ट इनपुट प्रारूप है, लेकिन इसे लागू करना कठिन हो सकता है।
f4f

अगर मेरे पास MNIST के अलावा एक और डेटासेट होता, तो मैं ट्रांसफर लर्निंग की कोशिश कर सकता था :) मैं प्रीप्रोसेसिंग ऑर्डर को बदलने और आपको वापस पाने की कोशिश करूँगा। धन्यवाद! मुझे अभी तक अपनी समस्या के लिए समोच्च का पता लगाने के अलावा कोई आसान विकल्प नहीं मिला ...
युवा

1
ठीक है। आप अपने आप को उस छवि से डेटासेट एकत्र कर सकते हैं, जिस पर आप OCR का उपयोग करेंगे यह एक आम बात है।
f4f

4

तो, आपको पिछले परिणामों के आधार पर अपने कंप्यूटिंग कैस्केड के हर चरण के लिए एक जटिल दृष्टिकोण की आवश्यकता है। आपके एल्गोरिथ्म में आपके पास अगली विशेषताएं हैं:

  1. छवि प्रीप्रोसेसिंग

जैसा कि पहले उल्लेख किया गया है, यदि आप आकार परिवर्तन लागू करते हैं, तो आप छवि के पहलू अनुपात के बारे में जानकारी खो देते हैं। प्रशिक्षण प्रक्रिया में निहित एक ही परिणाम प्राप्त करने के लिए आपको अंकों की छवियों का एक ही पुनर्संसाधन करना होगा।

बेहतर तरीका अगर आप निश्चित आकार के चित्रों द्वारा छवि को काटते हैं। उस संस्करण में आपको प्रशिक्षण प्रक्रिया से पहले अंक छवि खोजने और आकार बदलने की आवश्यकता नहीं होगी। तब आप बेहतर पहचान के लिए अपनी फसल एल्गोरिथ्म में थोड़ा बदलाव कर सकते हैं: साधारण समोच्च को ढूंढें और मान्यता के लिए प्रासंगिक छवि फ्रेम के केंद्र में आकार दिए बिना अपना अंक डालें।

इसके अलावा, आपको बिनाराइजेशन एल्गोरिदम पर अधिक ध्यान देना चाहिए। मेरे पास सीखने की त्रुटि पर द्विनेद्रीकरण सीमा मूल्यों के प्रभाव का अध्ययन करने का अनुभव है: मैं कह सकता हूं कि यह एक बहुत महत्वपूर्ण कारक है। इस विचार को जांचने के लिए आप एक अन्य एल्गोरिदम का उपयोग कर सकते हैं। उदाहरण के लिए आप वैकल्पिक बायनेरीज़ एल्गोरिदम के परीक्षण के लिए इस लाइब्रेरी का उपयोग कर सकते हैं ।

  1. लर्निंग एल्गोरिदम

मान्यता की गुणवत्ता में सुधार के लिए आप प्रशिक्षण प्रक्रिया में क्रॉस-मान्यता का उपयोग करते हैं । यह आपको अपने प्रशिक्षण डेटा के लिए ओवरफिटिंग की समस्या से बचने में मदद करता है । उदाहरण के लिए आप इस लेख को पढ़ सकते हैं, जिसमें बताया गया है कि इसे केरस के साथ कैसे उपयोग किया जाए।

कभी-कभी सटीकता माप के उच्च दर वास्तविक मान्यता गुणवत्ता के बारे में कुछ नहीं कहते हैं क्योंकि प्रशिक्षित एएनएन को प्रशिक्षण डेटा में पैटर्न नहीं मिला है। इसे प्रशिक्षण प्रक्रिया या इनपुट डेटासेट के साथ जोड़ा जा सकता है, जैसा कि ऊपर बताया गया है, या यह ANN आर्किटेक्चर के कारण हो सकता है।

  1. एएनएन वास्तुकला

यह एक बड़ी समस्या है। कार्य को हल करने के लिए बेहतर एएनएन वास्तुकला को कैसे परिभाषित किया जाए? उस चीज़ को करने के कोई सामान्य तरीके नहीं हैं। लेकिन आदर्श के करीब पहुंचने के कुछ तरीके हैं। उदाहरण के लिए आप इस पुस्तक को पढ़ सकते हैं । यह आपकी समस्या के लिए बेहतर दृष्टि बनाने में आपकी मदद करता है। इसके अलावा, आप अपने ANN के लिए छिपी हुई परतों / तत्वों की संख्या को फिट करने के लिए यहाँ कुछ अनुमान के सूत्र पा सकते हैं । यहां भी आपको इसके लिए थोड़ा अवलोकन मिलेगा।

मुझे उम्मीद है कि इससे मदद मिलेगी।


1. अगर मैं आपको सही तरीके से समझूं, तो मैं निश्चित आकार में फसल नहीं ले सकता, यह एक बहु अंकों की तस्वीर है, और सभी मामले आकार / जगह आदि में भिन्न हैं या क्या आपका मतलब कुछ अलग है? हां, मैंने अलग-अलग द्विपदीकरण विधियों और टेडेड मापदंडों की कोशिश की, यदि आपका यही मतलब है। 2. वास्तव में MNIST पर मान्यता बहुत अच्छी है, कोई भी ओवरफिटिंग नहीं हो रही है, मैंने जो सटीकता का उल्लेख किया है वह परीक्षण सटीकता है। न तो नेटवर्क या उसके प्रशिक्षण की समस्या है। 3. सभी लिंक के लिए धन्यवाद, मैं अपनी वास्तुकला से काफी खुश हूं, हालांकि, निश्चित रूप से सुधार के लिए हमेशा जगह है।
युवापंडा

हाँ, आप इसे प्राप्त करें। लेकिन आपके पास हमेशा अपने डेटासेट को अधिक एकीकृत बनाने की संभावना होती है। आपके मामले में पहले से ही अंकों की छवियों को बेहतर बनाने के लिए जैसा कि आप पहले से ही करते हैं। लेकिन इसके बाद x और y स्केल द्वारा अंकीय छवि के अधिकतम आकार के अनुसार अपनी अंक छवियों को एकीकृत आकार में विस्तारित करना बेहतर होगा। आप उस चीज़ को करने के लिए अंक समोच्च क्षेत्र के केंद्र को प्राथमिकता दे सकते हैं। यह आपके प्रशिक्षण एल्गोरिथ्म के लिए आपके अधिक स्वच्छ इनपुट डेटा देगा।
ईगोर ज़मोटेव

क्या आपका मतलब है कि मुझे फैलाव छोड़ना होगा? अंत में मैं पहले से ही छवि को केंद्र में रखता हूं, जब मैं सीमा लागू करता हूं (प्रत्येक तरफ 50 पीएक्स)। उसके बाद मैं प्रत्येक अंक को 28x28 का आकार दे रहा हूं, क्योंकि यह वह आकार है जिसे हमें MNIST के लिए आवश्यक है। क्या आपका मतलब है कि मैं 28x28 का आकार बदल सकता हूं?
यंगपंडा

1
हां, फैलाव अवांछनीय है। आपके कंटेस्टेंट्स की ऊंचाई और चौड़ाई के हिसाब से अलग-अलग अनुपात हो सकते हैं, इसीलिए आपको यहाँ अपने एल्गोरिथ्म के सुधार की आवश्यकता है। कम से कम आपको एक ही अनुपात के साथ चित्र आकार बनाना चाहिए। चूंकि आपके पास 28x28 इनपुट चित्र आकार हैं, इसलिए आपको x और y तराजू द्वारा समान 1: 1 अनुपात के साथ चित्र तैयार करने होंगे। आपको प्रत्येक चित्र पक्ष के लिए 50 px बॉर्डर नहीं मिलना चाहिए, लेकिन X, Y px बॉर्डर जो इस शर्त को पूरा करते हैं: contourSizeX + borderSizeX == contourSizeY + borderSizeY। बस इतना ही।
ईगोर ज़मोटेव

मैंने पहले ही बिना किसी झुकाव के प्रयास किया (पोस्ट में उल्लेख करना भूल गया)। इसने कोई परिणाम नहीं बदला ... मेरी सीमा संख्या प्रयोगात्मक थी। आदर्श रूप से मुझे 20x20 बॉक्स (साइज में सामान्यीकृत) के रूप में फिट करने के लिए मेरे अंकों की आवश्यकता होगी और इसके बाद इसे द्रव्यमान के केंद्र का उपयोग करके स्थानांतरित कर दिया जाएगा ...
युवापृष्ट

1

कुछ शोध और प्रयोगों के बाद, मैं इस नतीजे पर पहुंचा कि इमेज प्रीप्रोसेसिंग ही समस्या नहीं थी (मैंने कुछ सुझाए गए मापदंडों को बदल दिया, जैसे कि फैलाव आकार और आकार लेकिन वे परिणामों के लिए महत्वपूर्ण नहीं थे)। हालाँकि, 2 चीजों के बाद क्या मदद मिली:

  1. जैसा कि @ f4f ने देखा, मुझे वास्तविक दुनिया डेटा के साथ अपने स्वयं के डेटासेट एकत्र करने की आवश्यकता थी। इससे पहले से ही काफी मदद मिली।

  2. मैंने अपने सेगमेंट प्रीप्रोसेसिंग में महत्वपूर्ण बदलाव किए। व्यक्तिगत आकृति प्राप्त करने के बाद, मैं सबसे पहले छवियों को एक 20x20पिक्सेल बॉक्स में फिट करने के लिए सामान्य करता हूं (जैसा कि वे हैं MNIST)। उसके बाद मैं 28x28द्रव्यमान के केंद्र का उपयोग करके छवि के बीच में बॉक्स को केंद्रित करता हूं (जो द्विआधारी छवियों के लिए दोनों आयामों में औसत मूल्य है)।

बेशक, अभी भी कठिन विभाजन के मामले हैं, जैसे ओवरलैपिंग या जुड़े हुए अंक, लेकिन उपरोक्त परिवर्तनों ने मेरे प्रारंभिक प्रश्न का उत्तर दिया और मेरे वर्गीकरण के प्रदर्शन में सुधार किया।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.