13

cython クラスのインスタンスを保存してロードする必要があります。私のcythonクラスはこれに加えていくつかのメソッドです:

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 モジュールを使用することを考えていました。__reduce__(self) メソッドを実装する必要があることは理解していますが、例を見つけてドキュメントをよく理解するのに問題があります

次のようなものを 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))

助言がありますか?どうもありがとう!!!

4

3 に答える 3

16

あなたがそれを見つけたかどうかはわかりませんが、公式の Python ドキュメントには、拡張タイプのピクルに関するセクションがあります (残念ながら、このドキュメントの Python 3 バージョンはないようですが、Python 3 でも同じように機能します)。

ここで 3 つの問題があると思います。まず、によって返される関数は、__reduce__最初から新しいオブジェクトを作成して返すことになっていますが、rebuild関数はいくつかの属性を設定するだけです。第二に、 によって返されるタプルは__reduce__それ自体が picklable でなければならず、メソッドとして picklable でPerceptron_avg_my.rebuildはありません (これは python 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
于 2012-09-28T21:17:35.003 に答える
3

機能するこの回避策を使用しましたが、それが最善の解決策であるかどうかはわかりません。

reduce によって呼び出される関数を宣言する新しいサポート ファイルを作成しました (cython モジュールに配置すると機能しません)。

#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 モジュールにインポートします。

#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 を実行できます。

誰かがより良い解決策を持っているなら、どうもありがとう!!!

于 2012-10-03T16:11:11.703 に答える