簡體   English   中英

當我向theano函數中的給定參數發送numpy數組時,為什么會出現此Theano TypeError

[英]When I send a numpy array to a givens parameter in a theano function, why do I get this Theano TypeError

我是theano的新手,一方面仍在努力解決theano的“偽代碼”風格,另一方面仍在進行嚴格的類型檢查。 我更多是C程序員和python程序員。 有人可以指出在此示例代碼中哪里出了問題,該示例代碼使用預測的y點與訓練y點之間的均方誤差作為x值,以獲得線性擬合的最佳斜率和截距?

代碼如下:

import numpy as np
import theano
import theano.tensor as T
from collections import OrderedDict

class LinearModel:
    def __init__(self,num_points):
        self.m = theano.shared(value=0.1,name='m')
        self.b = theano.shared(value=1, name='b')
        self.params = [self.m, self.b]

        def step(x_t):
            y_t = self.m * x_t + self.b
            return y_t

        self.x = T.matrix('x',dtype=theano.config.floatX)
        self.y, _ = theano.scan(
                        fn=step,
                        sequences=self.x,
                    ) 

        self.loss = lambda y_train: self.mse(y_train)

    def mse(self, y_train):
        return T.mean((self.y - y_train) ** 2)

    def fit(self,x, y, learning_rate=0.01, num_iter=100):
        trainset_x = theano.tensor._shared(x.astype(np.dtype(np.float32)),borrow=True)
        trainset_y = theano.tensor._shared(y.astype(np.dtype(np.float32)),borrow=True)
        n_train = trainset_x.get_value(borrow=True).shape[0]

        cost = self.loss(trainset_y)
        gparams = T.grad(cost,self.params)

        l_r = T.scalar('l_r', dtype=theano.config.floatX)

        updates = OrderedDict()
        for param,gparam in zip(self.params,gparams):
            updates[param] = param - l_r * gparam

        self.train_model = theano.function(  inputs=[l_r],
                                        outputs=[cost,self.y],
                                        updates=updates,
                                        givens={
                                              self.x: trainset_x,
                                            }
                                        )

        epoch = 0
        while epoch < num_iter:
            cost, _ = self.train_model(learning_rate)
            m = self.m.get_value()
            b = self.b.get_value()
            print "epoch: ",epoch," cost: ",cost," m: ",m," b: ",b


if __name__ == '__main__':
    lin = LinearModel(10)
    x = np.arange(10)
    y = np.random.rand(10)
    lin.fit(x,y,learning_rate=0.01,num_iter=100)

錯誤是:

追溯(最近一次通話):文件“〜/ EclipseWorkspace / MemoryNetworkQA.Theano / linear_regression.py”,第70行,位於lin.fit(x,y,learning_rate = 0.01,num_iter = 100)文件“〜/ EclipseWorkspace / MemoryNetworkQA .theano / linear_regression.py”,第54行,適合self.x:trainset_x,文件“ /usr/local/lib/python2.7/dist-packages/theano/compile/function.py”,第266行,在函數中profile = profile)文件“ /usr/local/lib/python2.7/dist-packages/theano/compile/pfunc.py”,行489,在pfunc中no_default_updates = no_default_updates)文件“ / usr / local / lib / python2。 7 / dist-packages / theano / compile / pfunc.py“,第217行,位於rebuild_collect_shared中,引發TypeError(err_msg,err_sug)

TypeError :('更新必須與原始共享變量具有相同的類型(shared_var = b,shared_var.type = TensorType(int64,標量),update_val = Elemwise {sub,no_inplace} .0,update_val.type = TensorType(float64 ,標量))。','如果差異與廣播模式有關,則可以調用tensor.unbroadcast(var,axis_to_unbroadcast [,...])函數刪除可廣播的尺寸。')

在解決以下問題之前,該代碼將不會執行。

  1. 在問題報告的錯誤是由於類型self.b不匹配的更新類型self.b self.b沒有指定類型,因此可以推斷出一個。 初始值為Python整數,因此推斷的類型為int64 由於學習率是floatX所以更新為floatX 您不能使用floatX更新int64 解決方案是將初始值設為Python浮點數,從而得出推斷的floatX類型。 self.b = theano.shared(value=1, name='b')更改為self.b = theano.shared(value=1., name='b') (注意1后面的小數點)。

  2. 下一個問題是self.x被定義為矩陣,但是在最后一行的函數調用中傳遞的值是向量。 一種解決方案是將x重塑為矩陣,例如將x = np.arange(10)更改為x = np.arange(10).reshape(1,10)

  3. 訓練集共享變量的類型為float32但這與使用floatX的代碼的其他區域沖突。 如果您的floatX=float32則應該沒有問題,但是更簡單地使用floatX來始終保持相同的float類型會更安全。 trainset_x = theano.tensor._shared(x.astype(np.dtype(np.float32)),borrow=True)更改trainset_x = theano.tensor._shared(x.astype(theano.config.floatX),borrow=True) ,同樣適用於trainset_y

  4. 當前的時期數沒有任何效果,因為沒有增加epoch while epoch < num_iter:更改for epoch in xrange(num_iter):中的epoch = 0並刪除epoch = 0

此外,

  • 參數看起來好像沒有更新,但這是一個錯誤的視圖。 由於上面的問題4,迭代很快通過並且永不停止,並且學習率足夠大,可以使模型非常快速地收斂。 嘗試將學習率更改為較小的值,例如0.0001,然后僅查看前100個時期的輸出。

  • 我建議避免使用theano.tensor._shared除非您確實需要在device=gpu時強制將共享變量分配到CPU上。 首選方法是theano.shared

  • n_train變量沒有在任何地方使用。

  • 您正在使用givens不一致。 我建議將其同時用於xy ,或者都不使用。 看看Logistic回歸教程,以獲取更多有關此方面的指導。

  • Theano函數在每次fit調用時都會重新編譯,但最好只編譯一次,並在每次fit重新使用。

  • 無需使用scan即可實現此模型。 通常,通常僅在步驟的輸出是先前步驟的輸出的函數時才需要scan scan通常也比其他方法慢得多,應盡可能避免。 您可以self.y = self.m * self.x + self.b使用self.y = self.m * self.x + self.b刪除scan

  • 如果您確實使用掃描,則最好通過在scan調用中使用strict=True啟用嚴格模式。

  • 最好為所有共享變量提供類型。 你做到這一點的trainset_xtrainset_y但不self.mself.b

好的,我發現問題確實出在自我上。b。 用顯式float對其進行初始化后,類型錯誤消失了。

但是仍然是theano共享變量並通過更新傳遞的斜率和截距(self.m和self.b)並沒有真正得到更新。 如果有人能告訴我原因,那將是很大的幫助。 謝謝。

import numpy as np
import theano
import theano.tensor as T
from collections import OrderedDict

class LinearModel:
    def __init__(self,num_points):
        self.m = theano.shared(value=0.1,name='m')
        self.b = theano.shared(value=1.0, name='b')
        self.params = [self.m, self.b]

        def step(x_t):
            y_t = self.m * x_t + self.b
            return y_t

        #self.x = T.matrix('x',dtype=theano.config.floatX)
        #self.x = T.dmatrix('x')
        self.x = T.vector('x',dtype=theano.config.floatX)
        self.y, _ = theano.scan(
                        fn=step,
                        sequences=self.x,
                    ) 

        self.loss = lambda y_train: self.mse(y_train)

    def mse(self, y_train):
        return T.mean((self.y - y_train) ** 2)

    def fit(self,x, y, learning_rate=0.01, num_iter=100):
        trainset_x = theano.tensor._shared(x.astype(np.dtype(np.float32)),borrow=True)
        trainset_y = theano.tensor._shared(y.astype(np.dtype(np.float32)),borrow=True)
        n_train = trainset_x.get_value(borrow=True).shape[0]

        cost = self.loss(trainset_y)
        gparams = T.grad(cost,self.params)

        l_r = T.scalar('l_r', dtype=theano.config.floatX)

        updates = OrderedDict()
        for param,gparam in zip(self.params,gparams):
            updates[param] = param - l_r * gparam

        self.train_model = theano.function(  inputs=[l_r],
                                        outputs=[cost,self.y],
                                        updates=updates,
                                        givens={
                                              self.x: trainset_x,
                                            }
                                        )


        epoch = 0
        while epoch < num_iter:
            cost, _ = self.train_model(learning_rate)
            m = self.m.get_value()
            b = self.b.get_value()
            print "epoch: ",epoch," cost: ",cost," m: ",m," b: ",b
            epoch += 1


if __name__ == '__main__':
    lin = LinearModel(10)
    x = np.array([1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0])
    y = np.random.rand(10)
    lin.fit(x,y,learning_rate=0.01,num_iter=100)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM