乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      從原理到代碼,輕松深入邏輯回歸模型!

       昵稱42427018 2019-08-13

      【導語】學習邏輯回歸模型,今天的內(nèi)容輕松帶你從0到100!阿里巴巴達摩院算法專家、阿里巴巴技術(shù)發(fā)展專家、阿里巴巴數(shù)據(jù)架構(gòu)師聯(lián)合撰寫,從技術(shù)原理、算法和工程實踐3個維度系統(tǒng)展開,既適合零基礎(chǔ)讀者快速入門,又適合有基礎(chǔ)讀者理解其核心技術(shù);寫作方式上避開了艱澀的數(shù)學公式及其推導,深入淺出。

      0、前言

      簡單理解邏輯回歸,就是在線性回歸基礎(chǔ)上加一個 Sigmoid 函數(shù)對線性回歸的結(jié)果進行壓縮,令其最終預測值 y 在一個范圍內(nèi)。這里 Sigmoid 函數(shù)的作用就是將一個連續(xù)的數(shù)值壓縮到一定范圍內(nèi),它將最終預測值 y 的范圍壓縮到在 0 到 1 之間。雖然邏輯回歸也有回歸這個詞,但由于這里的自變量和因變量呈現(xiàn)的是非線性關(guān)系,因此嚴格意義上講邏輯回歸模型屬于非線性模型。邏輯回歸模型通常用來處理二分類問題,如圖 4-4 所示。在邏輯回歸中,計算出的預測值是一個 0 到 1 的概率值,通常的,我們以 0.5 為分界線,如果預測的概率值大于 0.5 則會將最終結(jié)果歸為 1 這個類別,如果預測的概率值小于等于 0.5 則會將最終結(jié)果歸為 0 這個類別。而 1 和 0 在實際項目中可能代表了很多含義,比如 1 代表惡性腫瘤,0 代表良性腫瘤,1 代表銀行可以給小王貸款,0 代表銀行不能給小王貸款等等。

      圖4-4 邏輯回歸分類示意圖

      雖然邏輯回歸很簡單,但它被廣泛應用在實際生產(chǎn)之中,而且通過改造邏輯回歸也可以處理多分類問題。邏輯回歸不僅本身非常受歡迎,它同樣也是我們將在第 5 章介紹的神經(jīng)網(wǎng)絡的基礎(chǔ)。普通神經(jīng)網(wǎng)絡中,常常使用 Sigmoid 對神經(jīng)元進行激活。關(guān)于神經(jīng)網(wǎng)絡的神經(jīng)元,第 5 章會有詳細的介紹(第 5 章會再次提到 Sigmoid 函數(shù)),這里只是先提一下邏輯回歸和神經(jīng)網(wǎng)絡的關(guān)系,讀者有個印象。

      1、Sigmoid 函數(shù)

      Sigmoid 的函數(shù)表達式如下:

      該公式中,e 約等于 2.718,z 則是線性回歸的方程式,p 為計算出來的概率,范圍在 0 到 1 之間。接下來我們將這個函數(shù)繪制出來,看看它的形狀。使用 Python 的 Numpy 以及 Matplotlib 庫進行編寫,代碼如下:

      import numpy as npimport matplotlib.pyplot as plt
      def sigmoid(x): y = 1.0 / (1.0 np.exp(-x)) return y
      plot_x = np.linspace(-10, 10, 100)plot_y = sigmoid(plot_x)plt.plot(plot_x, plot_y)plt.show()

      效果如圖 4-5 所示: 

      圖4-5 Sigmoid函數(shù)

      我們對上圖做一個解釋,當 x 為 0 的時候,Sigmoid 函數(shù)值為 0.5,隨著 x 的不斷增大,對應的 Sigmoid 值將無線逼近于 1;而隨著 x 的不斷的減小,Sigmoid 值將不斷逼近于 0 。所以它的值域是在 (0,1) 之間。由于 Sigmoid 函數(shù)將實數(shù)范圍內(nèi)的數(shù)值壓縮到(0,1)之間,因此也被稱為壓縮函數(shù)。但這里多提一下,壓縮函數(shù)其實可以有很多,比如 tanh 可以將實數(shù)范圍內(nèi)的數(shù)值壓縮到(-1,1)之間,因此 tanh 有時也會被成為壓縮函數(shù)。

      2、 梯度下降法

      在學習 4.1.1 小節(jié)的時候,我們在介紹一元線性回歸模型的數(shù)學表達之后又介紹了一元線性回歸模型的訓練過程。類似的,在 4.2.1 小節(jié)學習完邏輯回歸模型的數(shù)學表達之后我們來學習邏輯回歸模型的訓練方法。首先與 4.1.1 小節(jié)類似,我們首先需要確定邏輯回歸模型的評價方式,也就是模型的優(yōu)化目標。有了這個目標,我們才能更好地“教”模型學習出我們想要的東西。這里的目標也和 4.1.1 一樣,定義為

      接下來是選擇優(yōu)化這個目標的方法,也就是本小節(jié)中重點要介紹的梯度下降法。

      首先帶大家簡單認識一下梯度下降法。梯度下降算法(Gradient Descent Optimization)是常用的最優(yōu)化方法之一?!白顑?yōu)化方法”屬于運籌學方法,它指在某些約束條件下,為某些變量選取哪些的值,使得設(shè)定的目標函數(shù)達到最優(yōu)的問題。最優(yōu)化方法有很多,常見的有梯度下降法、牛頓法、共軛梯度法等等。由于本書重點在于帶大家快速掌握“圖像識別”技能,因此暫時不對最優(yōu)化方法進行展開,感興趣的讀者可以自行查閱相關(guān)資料進行學習。由于梯度下降是一種比較常見的最優(yōu)化方法,而且在后續(xù)第 5 章、第 7 章的神經(jīng)網(wǎng)絡中我們也將用到梯度下降來進行優(yōu)化,因此我們將在本章詳細介紹該方法。

      接下來我們以圖形化的方式帶領(lǐng)讀者學習梯度下降法。

      我們在 Pycharm 新建一個 python 文件,然后鍵入以下代碼:

      import numpy as npimport matplotlib.pyplot as pltif __name__ == '__main__':    plot_x = np.linspace(-1, 6, 141) #從-1到6選取141個點    plot_y = (plot_x - 2.5) ** 21 #二次方程的損失函數(shù)    plt.scatter(plot_x[5], plot_y[5], color='r') #設(shè)置起始點,顏色為紅色    plt.plot(plot_x, plot_y)    # 設(shè)置坐標軸名稱    plt.xlabel('theta', fontproperties='simHei', fontsize=15)    plt.ylabel('損失函數(shù)', fontproperties='simHei', fontsize=15)    plt.show()

      通過上述代碼,我們就能畫出如圖 4-6 所示的損失函數(shù)示意圖,其中 x 軸代表的是我們待學習的參數(shù) (theta),y 軸代表的是損失函數(shù)的值(即 loss 值),曲線 y 代表的是損失函數(shù)。我們的目標是希望通過大量的數(shù)據(jù)去訓練和調(diào)整參數(shù),使損失函數(shù)的值最小。想要達到二次方程的最小值點,可以通過求導數(shù)的方式,使得導數(shù)為 0 即可。也就是說,橫軸上 2.5 的位置對應損失最小,在該點上一元二次方程 切線的斜率則為 0。暫且將導數(shù)描述為 ,其中 J 為損失函數(shù),為待求解的參數(shù)。

      梯度下降中有個比較重要的參數(shù):學習率 (讀作eta,有時也稱其為步長),它控制著模型尋找最優(yōu)解的速度。加入學習率后的數(shù)學表達為  。

      圖4-6 損失函數(shù)示意圖

      接下來我們畫圖模擬梯度下降的過程。

      1. 首先定義損失函數(shù)及其導數(shù)

      def J(theta): #損失函數(shù) return (theta-2.5)**2 -1
      def dJ(theta): #損失函數(shù)的導數(shù) return 2 * (theta - 2.5)

      2. 通過 Matplotlib 繪制梯度下降迭代過程,具體代碼如下:

      theta = 0.0 #初始點theta_history = [theta]eta = 0.1 #步長epsilon = 1e-8 #精度問題或者eta的設(shè)置無法使得導數(shù)為0while True:    gradient = dJ(theta) #求導數(shù)    last_theta = theta #先記錄下上一個theta的值    theta = theta - eta * gradient #得到一個新的theta    theta_history.append(theta)    if(abs(J(theta) - J(last_theta)) < epsilon):       break #當兩個theta值非常接近的時候,終止循環(huán)plt.plot(plot_x,J(plot_x),color='r')plt.plot(np.array(theta_history),J(np.array(theta_history)),color='b',marker='x')plt.show()      #一開始的時候?qū)?shù)比較大,因為斜率比較陡,后面慢慢平緩了print(len(theta_history)) #一共走了46步

      我們來看下所繪制的圖像是什么樣子的,可以觀察到  從初始值 0.0 開始不斷的向下前進,一開始的幅度比較大,之后慢慢趨于緩和,逐漸接近導數(shù)為 0,一共走了 46 步。如圖 4-7 所示:

      圖4-7 一元二次損失函數(shù)梯度下降過程示意圖


      3、學習率的分析

      上一小節(jié)我們主要介紹了什么是梯度下降法,本小節(jié)主要介紹學習率對于梯度下降法的影響。

      第一個例子,我們將  設(shè)置為 0.01(之前是 0.1 ),我們會觀察到,步長減少之后,藍色的標記更密集,說明步長減少之后,從起始點到導數(shù)為 0 的步數(shù)增加了。步數(shù)變?yōu)榱?424 步,這樣整個學習的速度就變慢了。效果如圖 4-8 所示:

      圖4-8 學習率時,一元二次損失函數(shù)梯度下降過程示意圖

      第二個例子,我們將  設(shè)置為 0.8,我們會觀察到,代表藍色的步長在損失函數(shù)之間跳躍了,但在跳躍過程中,損失函數(shù)的值依然在不斷的變小。步數(shù)是 22 步,因此當學習率為 0.8 時,優(yōu)化過程時間縮短,但是最終也找到了最優(yōu)解。效果如圖 4-9 所示:

      圖4-9 學習率  時,一元二次損失函數(shù)梯度下降過程示意圖

      第三個例子,我們將設(shè)置為1.1,看一下效果。這里注意,學習率本身是一個 0 到 1 的概率,因此 1.1 是一個錯誤的值,但為了展示梯度過大會出現(xiàn)的情況,我們暫且用這個值來畫圖示意。我們會發(fā)現(xiàn)程序會報這個錯誤 OverflowError: ( 34, 'Result too large' )。我們可以想象得到,這個步長跳躍的方向?qū)е铝藫p失函數(shù)的值越來越大,所以才報了“Result too large”效果,我們需要修改下求損失函數(shù)的程序:

      def J(theta): try: return (theta-2.5)**2 -1 except: return float('inf')
      i_iter= 0    n_iters = 10    while i_iter < n_iters:        gradient = dJ(theta)        last_theta = theta        theta = theta - eta * gradient        i_iter  = 1        theta_history.append(theta)        if (abs(J(theta) - J(last_theta)) < epsilon):            break # 當兩個theta值非常接近的時候,終止循環(huán)

      另外我們需要增加一下循環(huán)的次數(shù)。

      我們可以很明顯的看到,我們損失函數(shù)在最下面,學習到的損失函數(shù)的值在不斷的增大,也就是說模型不會找到最優(yōu)解。如圖 4-10 所示:

      圖4-10  學習率時,一元二次損失函數(shù)不收斂


      通過本小節(jié)的幾個例子,簡單講解了梯度下降法,以及步長  的作用。從三個實驗我們可以看出,學習率是一個需要認真調(diào)整的參數(shù),過小會導致收斂過慢,而過大可能導致模型不收斂。

      4、邏輯回歸的損失函數(shù)

      邏輯回歸中的 Sigmoid 函數(shù)用來使值域在(0,1)之間,結(jié)合之前所講的線性回歸,我們所得到的完整的公式其實是:,其中的   就是之前所介紹的多元線性回歸。

      現(xiàn)在的問題就比較簡單明了了,對于給定的樣本數(shù)據(jù)集 X,y,我們?nèi)绾握业絽?shù) theta ,來獲得樣本數(shù)據(jù)集 X 所對應分類輸出 y(通過p的概率值)

      需要求解上述這個問題,我們就需要先了解下邏輯回歸中的損失函數(shù),假設(shè)我們的預測值為:

             

      損失函數(shù)假設(shè)為下面兩種情況,y 表示真值;表示為預測值:

             

      結(jié)合上述兩個假設(shè),我們來分析下,當 y 真值為 1 的時候,p 的概率值越?。ㄔ浇咏?),說明y的預測值偏向于0,損失函數(shù) cost 就應該越大;當 y 真值為 0 的時候,如果這個時候 p 的概率值越大則同理得到損失函數(shù) cost 也應該越大。在數(shù)學上我們想使用一個函數(shù)來表示這種現(xiàn)象,可以使用如下這個:

      我們對上面這個函數(shù)做一定的解釋,為了更直觀的觀察上述兩個函數(shù),我們通過 Python 中的 Numpy 以及 Matplotlib 庫進行繪制。

      我們先繪制下 ,代碼如下:

      import numpy as npimport matplotlib.pyplot as plt
      def logp(x):    y = -np.log(x) return y
      plot_x = np.linspace(0.001, 1, 50) #取0.001避免除數(shù)為0
      plot_y = logp(plot_x)plt.plot(plot_x, plot_y)plt.show()

       如下圖4-9所示:

      圖4-9 損失函數(shù)if y=1

      當p=0的時候,損失函數(shù)的值趨近于正無窮,根據(jù) 說明y的預測值  偏向于0,但實際上我們的 y 真值為 1 。當 p 達到 1 的時候,y 的真值和預測值相同,我們能夠從圖中觀察到損失函數(shù)的值趨近于 0 代表沒有任何損失。

      我們再來繪制一下,代碼如下:

      import numpy as npimort matplotlib.pyplot as plt def logp2(x):    y = -np.log(1-x)    return y
      plot_x = np.linspace(0, 0.99, 50) #取0.99避免除數(shù)為0plot_y = logp2(plot_x)plt.plot(plot_x, plot_y)plt.show()

       效果如圖4-10所示:

      圖4-10 損失函數(shù) if y=0

      當p=1的時候,損失函數(shù)的值趨近于正無窮,根據(jù) 說明y的預測值  偏向于 1,但實際上我們的 y 真值為 0 。當 p 達到 0 的時候,y 的真值和預測值相同,我們能夠從圖中觀察到損失函數(shù)的值趨近于 0 代表沒有任何損失。

      我們再對這兩個函數(shù)稍微整理下,使之合成一個損失函數(shù):

      對這個函數(shù)稍微解釋下,當 y=1 的時候,后面的式子就變?yōu)榱?0 ,所以整個公式成為了;當 y=0 的時候前面的式子變?yōu)榱?0,整個公式就變?yōu)榱?/span>。

      最后就變?yōu)榱?,對m個樣本,求一組值使得損失函數(shù)最小。

      公式如下:

      (其中 = sigmoi;其中  代表了;恒等于1;為列向量)。

      當公式變?yōu)樯鲜龅臅r候,對于我們來說,只需要求解一組使得損失函數(shù)最小就可以了,那么對于如此復雜的損失函數(shù),我們一般使用的是梯度下降法進行求解。

      5、Python實現(xiàn)邏輯回歸

      結(jié)合之前講的理論,本小節(jié)開始動手實現(xiàn)一個邏輯回歸算法。首先我們定義一個類,名字為 LogisticRegressionSelf ,其中初始化一些變量:維度、截距、theta 值,代碼如下:

      class LogisticRegressionSelf:
          def __init__(self):        '''初始化Logistic regression模型'''        self.coef_ = None #維度        self.intercept_ = None #截距 self._theta = None

      接著我們實現(xiàn)下在損失函數(shù)中的  這個函數(shù),我們之前在

      Sigmoid 函數(shù)那個小節(jié)已經(jīng)實現(xiàn)過了,對于這個函數(shù)我們輸入的值為多元線性回歸中的(其中恒等于1),為了增加執(zhí)行效率,我們建議使用向量化來處理,而盡量避免使用 for 循環(huán),所以對于我們使用來代替,具體代碼如下: 

          def _sigmoid(x):        y = 1.0 / (1.0   np.exp(-x))        return y

      接著我們來實現(xiàn)損失函數(shù),

      代碼如下:

      #計算損失函數(shù)        def J(theta,X_b,y):            p_predcit = self._sigmoid(X_b.dot(theta))            try:                return -np.sum(y*np.log(p_predcit)   (1-y)*np.log(1-p_predcit)) / len(y)            except: return float('inf')

      然后我們需要實現(xiàn)下?lián)p失函數(shù)的導數(shù)。具體求導過程讀者可以自行百度,我們這邊直接給出結(jié)論,對于損失函數(shù)cost,得到的導數(shù)值為:  ,其中,之前提過考慮計算性能盡量避免使用 for 循環(huán)實現(xiàn)累加,所以我們使用向量化計算。

      完整代碼如下:

      import numpy as np

      class LogisticRegressionSelf:
      def __init__(self): '''初始化Logistic regression模型''' self.coef_ = None #維度 self.intercept_ = None #截距 self._theta = None
      #sigmoid函數(shù),私有化函數(shù) def _sigmoid(self,x): y = 1.0 / (1.0 np.exp(-x)) return y
      def fit(self,X_train,y_train,eta=0.01,n_iters=1e4): assert X_train.shape[0] == y_train.shape[0], '訓練數(shù)據(jù)集的長度需要和標簽長度保持一致'
      #計算損失函數(shù) def J(theta,X_b,y): p_predcit = self._sigmoid(X_b.dot(theta)) try: return -np.sum(y*np.log(p_predcit) (1-y)*np.log(1-p_predcit)) / len(y) except: return float('inf')
      #求sigmoid梯度的導數(shù) def dJ(theta,X_b,y): x = self._sigmoid(X_b.dot(theta)) return X_b.T.dot(x-y)/len(X_b)
      #模擬梯度下降 def gradient_descent(X_b,y,initial_theta,eta,n_iters=1e4,epsilon=1e-8): theta = initial_theta i_iter = 0 while i_iter < n_iters: gradient = dJ(theta,X_b,y) last_theta = theta theta = theta - eta * gradient i_iter = 1 if (abs(J(theta,X_b,y) - J(last_theta,X_b,y)) < epsilon): break return theta
      X_b = np.hstack([np.ones((len(X_train),1)),X_train]) initial_theta = np.zeros(X_b.shape[1]) #列向量 self._theta = gradient_descent(X_b,y_train,initial_theta,eta,n_iters) self.intercept_ = self._theta[0] #截距 self.coef_ = self._theta[1:] #維度        return self
      def predict_proba(self,X_predict): X_b = np.hstack([np.ones((len(X_predict), 1)), X_predict]) return self._sigmoid(X_b.dot(self._theta))
      def predict(self,X_predict): proba = self.predict_proba(X_predict) return np.array(proba > 0.5,dtype='int')

      小結(jié) 

      以上內(nèi)容主要講述了線性回歸模型和邏輯回歸模型,并做了相應的實現(xiàn)。其中線性回歸是邏輯回歸的基礎(chǔ),而邏輯回歸經(jīng)常被當做神經(jīng)網(wǎng)絡的神經(jīng)元,因此邏輯回歸又是神經(jīng)網(wǎng)絡的基礎(chǔ)。我們借邏輯回歸模型介紹了機器學習中離不開的最優(yōu)化方法,以及最常見的最優(yōu)化方法——梯度下降。了解本節(jié)內(nèi)容會對接下來第 5 章神經(jīng)網(wǎng)絡的學習有著很大的幫助。

      以上內(nèi)容主要講述了線性回歸模型和邏輯回歸模型,并做了相應的實現(xiàn)。其中線性回歸是邏輯回歸的基礎(chǔ),而邏輯回歸經(jīng)常被當做神經(jīng)網(wǎng)絡的神經(jīng)元,因此邏輯回歸又是神經(jīng)網(wǎng)絡的基礎(chǔ)。我們借邏輯回歸模型介紹了機器學習中離不開的最優(yōu)化方法,以及最常見的最優(yōu)化方法——梯度下降。了解本節(jié)內(nèi)容會對接下來第 5 章神經(jīng)網(wǎng)絡的學習有著很大的幫助。本文摘自《深度學習與圖像識別:原理與實踐》,經(jīng)出版方授權(quán)發(fā)布。 

        本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多