2012-09-28 18 views
6

मुझे साइथन क्लास उदाहरण को सहेजना और लोड करना है।अचार साइथन वर्ग

import numpy as np 
cimport numpy as np 
cimport cython  
cdef class Perceptron_avg_my: 
    cdef int wlen,freePos 
    cdef np.ndarray w,wtot,wac,wtotC#np.ndarray[np.int32_t] 
    cdef np.ndarray wmean #np.ndarray[np.float32_t]  
    cdef public dict fpos  

    def __cinit__(self,np.int64_t wlen=4*10**7): 
     self.fpos= dict() 
     self.freePos=1 
     self.wlen=wlen 
     self.w=np.zeros(wlen,np.int32) 
     self.wtot=np.zeros(wlen,np.int32) 
     self.wac=np.zeros(wlen,np.int32) 
     self.wtotc=np.zeros(wlen,np.int32) 
     self.wmean=np.zeros(wlen,np.float32) 

    cpdef evaluate_noavg(self,list f): 
     cdef np.ndarray[np.int32_t] w = self.w 
     cdef dict fpos = self.fpos   
     cdef bytes ff 
     cdef int i 
     cdef long int score=0 

     for ff in f: 
      i=fpos.get(ff,0) 
      if i != 0: 
       score += w[i] 
     return score 

मैं cPickle मॉड्यूल का उपयोग करने के लिए सोच रहा था: मेरे cython वर्ग इस के साथ साथ कई तरीके है। मैं समझता हूँ कि मैं एक __reduce __ (स्वयं) विधि को लागू करने के लिए है कि, लेकिन मैं एक उदाहरण खोजने के लिए और अच्छी तरह से समझने के लिए प्रलेखन

मैं Perceptron_avg_my नहीं बल्कि काम करता है के लिए कुछ इस तरह जोड़ने की कोशिश की कुछ समस्या है:

def rebuild(self,l): 
     self.fpos=l[0] 
     self.freePos=l[1] 

    def __reduce__(self): 
     #print 'reduce call' 
     return (Perceptron_avg_my.rebuild,(self.fpos,self.freePos)) 

कोई सुझाव? बहुत बहुत धन्यवाद !!!

+0

यहां सहायक चर्चा भी है: https://ask.sagemath.org/question/8376/pickling-extension-classes/ –

उत्तर

9

मुझे नहीं पता कि आपको यह पता चला है, लेकिन आधिकारिक पायथन दस्तावेज़ में a section on pickling extension types है (दुर्भाग्य से इस दस्तावेज़ का पाइथन 3 संस्करण प्रतीत नहीं होता है, लेकिन यह पायथन 3 में भी काम करता है)।

मुझे लगता है कि आपको यहां तीन समस्याएं हैं। सबसे पहले, __reduce__ द्वारा वापस किया गया फ़ंक्शन स्क्रैच से एक नई ऑब्जेक्ट बनाना और इसे वापस करना है, जबकि आपका rebuild फ़ंक्शन बस कुछ विशेषताओं को सेट करता है। दूसरा, __reduce__ द्वारा लौटाया गया टुपल खुद को चुनने योग्य होना चाहिए, और एक विधि के रूप में, Perceptron_avg_my.rebuild पिकलेबल नहीं है (मुझे लगता है कि यह पाइथन 3.3 या 3.4 में तय होने की उम्मीद है)। इसके बजाए, आप इसे मॉड्यूल-स्तरीय फ़ंक्शन में बदल सकते हैं। अंत में, (self.fpos,self.freePos) तर्क rebuild पर अलग-अलग पास किए जाते हैं - आपको स्वयं को टपले को अनपैक करने की आवश्यकता नहीं है।

निम्नलिखित मेरे लिए काम करने लगता है (हालांकि आप शायद बहुत अन्य विशेषताओं के मान संग्रहीत करना चाहते हैं, अन्यथा वे सिर्फ __init__ द्वारा निर्धारित प्रारंभिक मान होगा):

#inside the class definition 
def __reduce__(self): 
    return (rebuild, (self.wlen, self.fpos, self.freePos)) 

#standalone function 
def rebuild(wlen, fpos, freePos): 
    p = Perceptron_avg_my(wlen) 
    p.fpos = fpos 
    p.freePos = freePos 
    return p 
+1

धन्यवाद जेम्स और क्षमा करें अगर मैं अभी जवाब दूंगा !!! मुझे लगता है कि एक और समस्या भी है: \____ द्वारा वापस किया गया फ़ंक्शन साइथन मॉड्यूल में नहीं हो सकता है (मैं ईमानदारी से समझ में नहीं आता क्यों)। मैं एक कामकाज के साथ एक जवाब जोड़ूंगा जो मेरे लिए काम करता है ... लेकिन मुझे नहीं पता कि कोई बेहतर समाधान है या नहीं। – Francesco

+0

यह अजीब बात है: यह मॉड्यूल के अंदर परिभाषित होने पर मेरे लिए काम करता है। फ़ंक्शन को परिभाषित करने के लिए आपने 'def' के बजाय गलती से' cdef' का उपयोग नहीं किया था, है ना? या शायद हम सिथन या पायथन के विभिन्न संस्करणों का उपयोग कर रहे हैं (मैंने इसे पायथन 3.2.3/साइथन 0.17, और पायथन 2.7.2/साइथन 0.15.1 के साथ कोशिश की)। – James

+0

मैं अजगर 2.7.3/साइथन 0.17 का उपयोग करता हूं। – Francesco

3

मैं इस समाधान का इस्तेमाल किया यह काम करता है लेकिन मुझे यकीन नहीं है कि यह सबसे अच्छा समाधान है।

#perceptron_supp.py 

from perceptron import Perceptron 

def rebuild_perceptron(wlen,freePos,fpos,w,nw_avg,wtot_avg,wsup_avg,wmean_avg,wtot_my,wac_my,wtotc_my,wmean_my): 
    return Perceptron(wlen,True,freePos,fpos,w,nw_avg,wtot_avg,wsup_avg,wmean_avg,wtot_my,wac_my,wtotc_my,wmean_my) 

और फिर मैं cython मॉड्यूल में इस समारोह का आयात:

मैं समारोह को कम (अगर मैं इसे cython मॉड्यूल यह नहीं काम करता है में डाल) द्वारा कहा जाता है की घोषणा करने के लिए एक नया समर्थन फ़ाइल बनाई

#perceptron.pyx 

import numpy as np 
cimport numpy as np 
cimport cython 

#added 
from perceptron_supp import rebuild_perceptron 

cdef class Perceptron: 
    cdef int wlen,freePos 
    cdef dict fpos 

    cdef np.ndarray w #np.ndarray[np.int32_t] 

    cdef int nw_avg 
    cdef np.ndarray wtot_avg,wsup_avg #np.ndarray[np.int32_t] 
    cdef np.ndarray wmean_avg #np.ndarray[np.float64_t] 

    cdef np.ndarray wtot_my,wac_my,wtotc_my #np.ndarray[np.int32_t] 
    cdef np.ndarray wmean_my #np.ndarray[np.float64_t] 

    def __cinit__(self,int wlen=4*10**7,setValues=False,freePos=0,fpos=0,w=0,nw_avg=0,wtot_avg=0,wsup_avg=0,wmean_avg=0,wtot_my=0,wac_my=0,wtotc_my=0,wmean_my=0): 
     if not setValues:    
      self.wlen=wlen 
      self.freePos=1 
      self.fpos= dict() 

      self.w=np.zeros(wlen,np.int32) 

      self.nw_avg=1 
      self.wtot_avg=np.zeros(wlen,np.int32)    
      self.wsup_avg=np.zeros(wlen,np.int32) 
      self.wmean_avg=np.zeros(wlen,np.float64) 

      self.wtot_my=np.zeros(wlen,np.int32)  
      self.wac_my=np.zeros(wlen,np.int32) 
      self.wtotc_my=np.zeros(wlen,np.int32) 
      self.wmean_my=np.zeros(wlen,np.float64) 
     else:   
      self.wlen=wlen 
      self.freePos=freePos 
      self.fpos=fpos 

      self.w=w 

      self.nw_avg=nw_avg 
      self.wtot_avg=wtot_avg 
      self.wsup_avg=wsup_avg 
      self.wmean_avg=wmean_avg 

      self.wtot_my=wtot_my 
      self.wac_my=wac_my 
      self.wtotc_my=wtotc_my 
      self.wmean_my=wmean_my 

    def __reduce__(self): 
     return (rebuild_perceptron,(self.wlen,self.freePos,self.fpos,self.w,self.nw_avg,self.wtot_avg,self.wsup_avg,self.wmean_avg,self.wtot_my,self.wac_my,self.wtotc_my,self.wmean_my)) 

जब मैं अपने परसेप्ट्रॉन मॉड्यूल का उपयोग करता हूं तो मुझे बस इतना करना है: पेरिसट्रॉन आयात सेसेप्ट्रॉन से और अब जब मुझे आवश्यकता हो तो मैं cPyckle.dump या cPickle.load कर सकता हूं।

अगर किसी के पास बेहतर समाधान है तो बहुत बहुत धन्यवाद !!!

3

सिथन 0.26 (जुलाई 2017 जारी) के रूप में, अचार प्रोटोकॉल को लागू करने के लिए अब आवश्यक नहीं है। सभी सीडीईएफ कक्षाएं जिनमें पॉइंटर्स या यूनियन नहीं होते हैं, स्वचालित रूप से मसालेदार हो सकते हैं। Structs युक्त कक्षाओं के लिए स्वचालित पिकलिंग डिफ़ॉल्ट रूप से अक्षम है, अन्य कारणों के कारण (उच्च कारणों से) उच्च कोड ओवरहेड। @cython.auto_pickle(True) सजावट का उपयोग करके स्ट्रक्चर के साथ कक्षाओं के लिए स्वचालित पिकलिंग सक्षम किया जा सकता है।

अधिक जानकारी changelog और the website of Stefan Behnel पर मिल सकती है।

+1

नई रिलीज देखने के लिए खुशी हुई! हालांकि मुझे अभी भी अपनी खुद की पिकलिंग तंत्र को लागू करना था b/c 'TypeError: गैर-तुच्छ __cinit__' के कारण कोई डिफ़ॉल्ट __reduce__ नहीं –

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