python 3.x - तंत्रिका नेटवर्क हमेशा एक ही वर्ग की भविष्यवाणी करता है




python-3.x numpy (2)

मैं एक तंत्रिका नेटवर्क को लागू करने की कोशिश कर रहा हूं जो दो असतत श्रेणियों में से एक में छवियों को वर्गीकृत करता है। हालाँकि, समस्या यह है कि यह वर्तमान में किसी भी इनपुट के लिए हमेशा 0 की भविष्यवाणी करता है और मुझे यकीन नहीं है कि क्यों।

यहाँ मेरी सुविधा निष्कर्षण विधि है:

def extract(file):
    # Resize and subtract mean pixel
    img = cv2.resize(cv2.imread(file), (224, 224)).astype(np.float32)
    img[:, :, 0] -= 103.939
    img[:, :, 1] -= 116.779
    img[:, :, 2] -= 123.68
    # Normalize features
    img = (img.flatten() - np.mean(img)) / np.std(img)

    return np.array([img])

यहाँ मेरी ढाल मूल दिनचर्या है:

def fit(x, y, t1, t2):
    """Training routine"""
    ils = x.shape[1] if len(x.shape) > 1 else 1
    labels = len(set(y))

    if t1 is None or t2 is None:
        t1 = randweights(ils, 10)
        t2 = randweights(10, labels)

    params = np.concatenate([t1.reshape(-1), t2.reshape(-1)])
    res = grad(params, ils, 10, labels, x, y)
    params -= 0.1 * res

    return unpack(params, ils, 10, labels)

यहाँ मेरे आगे और पीछे (ढाल) प्रचार हैं:

def forward(x, theta1, theta2):
    """Forward propagation"""

    m = x.shape[0]

    # Forward prop
    a1 = np.vstack((np.ones([1, m]), x.T))
    z2 = np.dot(theta1, a1)

    a2 = np.vstack((np.ones([1, m]), sigmoid(z2)))
    a3 = sigmoid(np.dot(theta2, a2))

    return (a1, a2, a3, z2, m)

def grad(params, ils, hls, labels, x, Y, lmbda=0.01):
    """Compute gradient for hypothesis Theta"""

    theta1, theta2 = unpack(params, ils, hls, labels)

    a1, a2, a3, z2, m = forward(x, theta1, theta2)
    d3 = a3 - Y.T
    print('Current error: {}'.format(np.mean(np.abs(d3))))

    d2 = np.dot(theta2.T, d3) * (np.vstack([np.ones([1, m]), sigmoid_prime(z2)]))
    d3 = d3.T
    d2 = d2[1:, :].T

    t1_grad = np.dot(d2.T, a1.T)
    t2_grad = np.dot(d3.T, a2.T)

    theta1[0] = np.zeros([1, theta1.shape[1]])
    theta2[0] = np.zeros([1, theta2.shape[1]])

    t1_grad = t1_grad + (lmbda / m) * theta1
    t2_grad = t2_grad + (lmbda / m) * theta2

    return np.concatenate([t1_grad.reshape(-1), t2_grad.reshape(-1)])

और यहाँ मेरी भविष्यवाणी समारोह है:

def predict(theta1, theta2, x):
    """Predict output using learned weights"""
    m = x.shape[0]

    h1 = sigmoid(np.hstack((np.ones([m, 1]), x)).dot(theta1.T))
    h2 = sigmoid(np.hstack((np.ones([m, 1]), h1)).dot(theta2.T))

    return h2.argmax(axis=1)

मैं देख सकता हूं कि प्रत्येक पुनरावृत्ति के साथ त्रुटि दर धीरे-धीरे कम हो रही है, आम तौर पर लगभग 1.26e-05 में परिवर्तित होती है।

मैंने अब तक क्या प्रयास किया है:

  1. पीसीए
  2. विभिन्न डेटासेट (स्केरन से आइरिस और कौरसेरा एमएल कोर्स से हस्तलिखित संख्या, दोनों पर लगभग 95% सटीकता प्राप्त करना)। हालांकि, उन दोनों को एक बैच में संसाधित किया गया था, इसलिए मैं मान सकता हूं कि मेरा सामान्य कार्यान्वयन सही है, लेकिन या तो मैं कुछ गलत कर रहा हूं कि मैं सुविधाओं को कैसे निकालूं, या मैं क्लासिफायर ट्रेन कैसे करूं।
  3. स्केलेन की SGDClassifier की कोशिश की और यह बहुत अच्छा प्रदर्शन नहीं किया, जिससे मुझे ~ 50% सटीकता मिली। सुविधाओं के साथ कुछ गलत है, तो?

संपादित करें : h2 का औसत आउटपुट निम्न जैसा दिखता है:

[0.5004899   0.45264441]
[0.50048522  0.47439413]
[0.50049019  0.46557124]
[0.50049261  0.45297816]

तो, सभी सत्यापन उदाहरणों के लिए बहुत समान सिग्मोइड आउटपुट हैं।


मेरा नेटवर्क हमेशा एक ही कक्षा की भविष्यवाणी करता है। समस्या क्या है?

मेरे पास यह कई बार था। हालाँकि मैं वर्तमान में आपके कोड से गुजरने में बहुत आलसी हूं, लेकिन मुझे लगता है कि मैं कुछ सामान्य संकेत दे सकता हूं जो दूसरों को भी मदद कर सकते हैं जिनके लक्षण समान हैं लेकिन शायद अलग-अलग अंतर्निहित समस्याएं हैं।

तंत्रिका नेटवर्क डिबगिंग

एक आइटम डेटासेट फिटिंग

प्रत्येक वर्ग के लिए मुझे नेटवर्क की भविष्यवाणी करने में सक्षम होना चाहिए, निम्नलिखित की कोशिश करें:

  1. कक्षा i के केवल एक डेटा बिंदु का डेटासेट बनाएँ।
  2. इस डेटासेट में नेटवर्क फिट करें।
  3. क्या नेटवर्क "क्लास आई" की भविष्यवाणी करना सीखता है?

यदि यह काम नहीं करता है, तो चार संभावित त्रुटि स्रोत हैं:

  1. छोटी गाड़ी प्रशिक्षण एल्गोरिथ्म : एक छोटे मॉडल का प्रयास करें, बहुत सारे मूल्यों को प्रिंट करें जो बीच में गणना की जाती है और देखें कि क्या वे आपकी अपेक्षा से मेल खाते हैं।
    1. 0 से विभाजित: हर में एक छोटी संख्या जोड़ें
    2. 0 / ऋणात्मक संख्या का लघुगणक: 0 से विभाजित करने जैसा
  2. डेटा : यह संभव है कि आपके डेटा में गलत प्रकार हो। उदाहरण के लिए, यह आवश्यक हो सकता है कि आपका डेटा float32 लेकिन वास्तव में पूर्णांक हो।
  3. मॉडल : यह भी संभव है कि आपने केवल एक मॉडल बनाया है जो संभवतः यह अनुमान नहीं लगा सकता है कि आप क्या चाहते हैं। यह तब प्रकट किया जाना चाहिए जब आप सरल मॉडल की कोशिश करते हैं।
  4. इनिशियलाइज़ेशन / ऑप्टिमाइज़ेशन : मॉडल के आधार पर, आपका इनिशियलाइज़ेशन और आपका ऑप्टिमाइज़ेशन एल्गोरिथम एक महत्वपूर्ण भूमिका निभा सकते हैं। शुरुआती लोगों के लिए जो मानक स्टोचस्टिक ग्रेडिएंट वंश का उपयोग करते हैं, मैं कहूंगा कि वजन को बेतरतीब ढंग से शुरू करना मुख्य रूप से महत्वपूर्ण है (प्रत्येक वजन एक अलग मूल्य)। - यह भी देखें: यह सवाल / जवाब

सीखने की अवस्था

विवरण के लिए sklearn देखें।

विचार एक छोटे प्रशिक्षण डाटासेट (शायद केवल एक आइटम) के साथ शुरू करना है। तब मॉडल को डेटा को पूरी तरह से फिट करने में सक्षम होना चाहिए। यदि यह काम करता है, तो आप थोड़ा बड़ा डेटासेट बनाते हैं। आपका प्रशिक्षण त्रुटि कुछ बिंदु पर ऊपर जाना चाहिए। यह डेटा को मॉडल करने की आपकी मॉडल क्षमता को प्रकट करता है।

डेटा विश्लेषण

जांचें कि अन्य वर्ग कितनी बार दिखाई देते हैं। यदि एक वर्ग दूसरों पर हावी है (जैसे एक वर्ग 99.9% डेटा है), तो यह एक समस्या है। "बाह्य पहचान" तकनीकों के लिए देखें।

अधिक

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

साधारण गलती

यह reddit से प्रेरित है:

  • आप प्रीप्रोसेसिंग लागू करना भूल गए
  • मर रहा है ReLU
  • बहुत छोटी / बहुत बड़ी सीखने की दर
  • अंतिम परत में गलत सक्रियण समारोह:
    • आपके लक्ष्य एक राशि में नहीं हैं? -> सॉफ्टमैक्स का उपयोग न करें
    • आपके लक्ष्य के एकल तत्व नकारात्मक हैं -> सॉफ्टमैक्स, ReLU, सिग्मॉइड का उपयोग न करें। टैन एक विकल्प हो सकता है
  • बहुत गहरा नेटवर्क: आप प्रशिक्षित करने में विफल रहते हैं। पहले एक सरल तंत्रिका नेटवर्क का प्रयास करें।
  • तेजी से असंतुलित डेटा: आप imbalanced-learn चाहते imbalanced-learn

एक हफ़्ते के शोध के बाद मुझे लगता है कि मैं समझता हूं कि मुद्दा क्या है। कोड में कुछ भी गलत नहीं है। केवल दो मुद्दे जो मेरे कार्यान्वयन को सफलतापूर्वक वर्गीकृत करने से रोकते हैं, वे हैं सीखने का समय और सीखने की दर / नियमितीकरण मापदंडों का उचित चयन।

मेरे पास सीखने की दिनचर्या अब कुछ tome के लिए चल रही है, और यह पहले से ही 75% सटीकता पर जोर दे रहा है, हालांकि सुधार के लिए अभी भी बहुत जगह है।





gradient-descent