5

पेपर Girshick, RFast-RCNN (ICCV 2015) में, "3.1 तेजी से पहचान के लिए छिड़काव एसवीडी" अनुभाग का उपयोग करके पूरी तरह से जुड़े (`" इनर प्रोडक्ट "`) परत को कैसे कम करें, लेखक आकार और गणना समय को कम करने के लिए SVD चाल का उपयोग करने का प्रस्ताव करता है पूरी तरह से जुड़े परत का।कटा हुआ एसवीडी

एक प्रशिक्षित मॉडल (deploy.prototxt और weights.caffemodel) को देखते हुए, मैं इस चाल का उपयोग कैसे एक छोटा कर दिया एक के साथ एक पूरी तरह से जुड़ा हुआ परत को बदलने के लिए कर सकते हैं?

उत्तर

7

कुछ रैखिक-बीजगणित पृष्ठभूमि
एकवचन मूल्य अपघटन (SVD) किसी भी मैट्रिक्स W के अपघटन तीन मैट्रिक्स में है:

W = U S V* 

कहाँ U और V ऑर्थो-सामान्य मैट्रिक्स हैं, और S है विकर्ण पर कम परिमाण में तत्वों के साथ विकर्ण। SVD के दिलचस्प गुण यह है कि यह करने के लिए आसानी से एक कम रैंक मैट्रिक्स के साथ अनुमानित W की अनुमति देता है: मान लीजिए आप काट-छांट S केवल अपने k प्रमुख तत्वों के लिए तो

W_app = W S_trunc V* 

(बजाय विकर्ण पर सभी तत्वों का) रैंक kW का अनुमान है। deploy_full.prototxt मॉडल के लिए प्रशिक्षित मापदंडों -

एक पूरी तरह से जुड़ा परत
मान लीजिए हम एक पूरी तरह से जुड़ा परत

# ... some layers here 
layer { 
    name: "fc_orig" 
    type: "InnerProduct" 
    bottom: "in" 
    top: "out" 
    inner_product_param { 
    num_output: 1000 
    # more params... 
    } 
    # some more... 
} 
# more layers... 

इसके अलावा के साथ एक मॉडल deploy_full.prototxt है अनुमान लगाने के लिए SVD का उपयोग करना, हम trained_weights_full.caffemodel है।

  1. कॉपी deploy_full.protoxtdeploy_svd.protoxt करने और अपनी पसंद के संपादक में खोलें। इन दो परतों के साथ पूरी तरह से जुड़ा परत बदलें:

    layer { 
        name: "fc_svd_U" 
        type: "InnerProduct" 
        bottom: "in" # same input 
        top: "svd_interim" 
        inner_product_param { 
        num_output: 20 # approximate with k = 20 rank matrix 
        bias_term: false 
        # more params... 
        } 
        # some more... 
    } 
    # NO activation layer here! 
    layer { 
        name: "fc_svd_V" 
        type: "InnerProduct" 
        bottom: "svd_interim" 
        top: "out" # same output 
        inner_product_param { 
        num_output: 1000 # original number of outputs 
        # more params... 
        } 
        # some more... 
    } 
    
  2. अजगर में, एक छोटे से net surgery:

    import caffe 
    import numpy as np 
    
    orig_net = caffe.Net('deploy_full.prototxt', 'trained_weights_full.caffemodel', caffe.TEST) 
    svd_net = caffe.Net('deploy_svd.prototxt', 'trained_weights_full.caffemodel', caffe.TEST) 
    # get the original weight matrix 
    W = np.array(orig_net.params['fc_orig'][0].data) 
    # SVD decomposition 
    k = 20 # same as num_ouput of fc_svd_U 
    U, s, V = np.linalg.svd(W) 
    S = np.zeros((U.shape[0], k), dtype='f4') 
    S[:k,:k] = s[:k] # taking only leading k singular values 
    # assign weight to svd net 
    svd_net.params['fc_svd_U'][0].data[...] = np.dot(U,S) 
    svd_net.params['fc_svd_V'][0].data[...] = V[:k,:] 
    svd_net.params['fc_svd_V'][1].data[...] = orig_net.params['fc_orig'][1].data # same bias 
    # save the new weights 
    svd_net.save('trained_weights_svd.caffemodel') 
    

अब हम trained_weights_svd.caffemodel साथ deploy_svd.prototxt है कि अब तक के साथ मूल शुद्ध का अनुमान लगाए कम गुणा, और वजन।

+2

एक अच्छा समाधान! – Dale

+1

अद्भुत समाधान :) –

+1

@ मेरा समाधान नहीं है - यह रॉस गिरशिक है। – Shai

1

दरअसल, रॉस गिरशिक के पाई-फास्ट-आरसीएनएन रेपो में एसवीडी चरण: compress_net.py के लिए एक कार्यान्वयन शामिल है।

बीटीडब्ल्यू, आपको आमतौर पर सटीकता को पुनर्प्राप्त करने के लिए संपीड़ित मॉडल को ठीक करने की आवश्यकता होती है (या अधिक परिष्कृत तरीके से संपीड़ित करने के लिए, उदाहरण के लिए देखें "Accelerating Very Deep Convolutional Networks for Classification and Detection", झांग एट अल)।

इसके अलावा, मेरे लिए scipy.linalg.svd numpy के svd से तेज़ी से काम करता है।

+0

इसे याद करने में आसान, संदर्भ के लिए धन्यवाद। –

संबंधित मुद्दे