theano tutorial -- 用theano實現邏輯迴歸LR(三)theano實現LR算法

>>> import numpy
>>> import theano
>>> import theano.tensor as T
>>> rng = numpy.random

>>> N = 400                                   # 訓練數據的數量 400個樣本
>>> feats = 784                               # 特徵數 784,每一個樣本有784個特徵

# 生成訓練數據: D = ((N, feates), N個隨機數值) ,隨機數是0或者1
>>> D = (rng.randn(N, feats), rng.randint(size=N, low=0, high=2))
>>> training_steps = 10000

# 定義兩個符號變量,x和y,其中x是一個double的matrix,y是一個double的vector
>>> x = T.dmatrix("x")
>>> y = T.dvector("y")

# 隨機初始化參數w,它的大小是feats,向量
#
# 我們把w定義爲共享變量,這樣可以在多次迭代中共享。
>>> w = theano.shared(rng.randn(feats), name="w")

# b也是共享變量,我們不需要隨機初始化,一般bias出初始化爲0就行了。
>>> b = theano.shared(0., name="b")

>>> print("Initial model:")
>>> print(w.get_value()) #  得到共享變量的值
>>> print(b.get_value())

# 構造Theano表達式圖

>>> p_1 = 1 / (1 + T.exp(-T.dot(x, w) - b))   
# 模型輸出1的概率,因爲x是一個矩陣,所以p_1是一個列向量,一次輸出的是N個樣本

>>> prediction = p_1 > 0.5                   
# 基於p_1預測分類,p_1>0.5則prediction 爲1,否則爲0。prediction 是一個只含有(0,1)兩個值得向量

>>> xent = -y * T.log(p_1) - (1-y) * T.log(1-p_1) # Cross-entropy loss function
>>> cost = xent.mean() + 0.01 * (w ** 2).sum()
# loss函數,前面xent是一個向量,所以求mean,然後使用L2 正則化,w越大就懲罰越大

>>> gw, gb = T.grad(cost, [w, b])             # 計算cost對w和b的梯度


'''train是一個函數,它的輸入是x和y,輸出是分類預測prediction和xent,注意updates參數,因爲w和b試共享變量,早就定義好了,
所以不用放到輸入列表中。每次調用train函數之後都會更新w<-w-0.1*gw, b<-b-0.1*gb'''

>>> train = theano.function(
          inputs=[x,y],
          outputs=[prediction, xent],
          updates=((w, w - 0.1 * gw), (b, b - 0.1 * gb)))

# pridict是一個函數,輸入x,輸出prediction
>>> predict = theano.function(inputs=[x], outputs=prediction)

# 訓練,就是用訓練數據x=D[0], y=D[1]進行訓練。
'''也就算調用train函數,train函數會使用當前的w和b“前向”計算出prediction和xent,同時也計算出cost對w和b的梯度。
然後再根據updates參數更新w和b'''
>>> for i in range(training_steps):
    pred, err = train(D[0], D[1])

>>> print("Final model:")
>>> print(w.get_value())
>>> print(b.get_value())
>>> print("target values for D:")
>>> print(D[1])
>>> print("prediction on D:")
>>> print(predict(D[0]))

我們可以看到,在Theano裏,我們實現一個模型非常簡單,我們需要如下步驟:

1. 把輸入和輸出定義成符號變量【有時爲了加速我們可能也會把它定義成共享變量從而讓它放到gpu的顯存裏】

2. 把模型的參數定義成共享變量

3. 然後寫出loss函數的公式,同時定義loss對參數的梯度

4. 定義一個訓練函數train,輸入是模型的輸入變量,輸出是loss【或者prediction,這樣我們可以在訓練的時候打印出預測的準確率】,updates用來更新模型參數

5. 寫有一個for循環不停的調用train

當然這是全量的梯度下降,如果是batch的隨機梯度下降,只需要每次循環傳入一個batch的輸入和輸出就行。

詳見:http://geek.csdn.net/news/detail/131362

發佈了60 篇原創文章 · 獲贊 78 · 訪問量 29萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章