1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        梯度下降—Python實現(xiàn)

        共 9350字,需瀏覽 19分鐘

         ·

        2022-06-13 13:07

        點擊上方小白學視覺”,選擇加"星標"或“置頂

        重磅干貨,第一時間送達



          磐創(chuàng)AI分享  

        作者 | Vagif Aliyev 

        編譯 | VK 

        來源 | Towards Data Science

        梯度下降是數(shù)據(jù)科學的基礎,無論是深度學習還是機器學習。對梯度下降原理的深入了解一定會對你今后的工作有所幫助。

        你將真正了解這些超參數(shù)的作用、在背后發(fā)生的情況以及如何處理使用此算法可能遇到的問題,而不是玩弄超參數(shù)并希望獲得最佳結(jié)果。

        然而,梯度下降并不局限于一種算法。另外兩種流行的梯度下降(隨機和小批量梯度下降)建立在主要算法的基礎上,你可能會看到比普通批量梯度下降更多的算法。因此,我們也必須對這些算法有一個堅實的了解,因為它們有一些額外的超參數(shù),當我們的算法沒有達到我們期望的性能時,我們需要理解和分析這些超參數(shù)。

        雖然理論對于深入理解手頭的算法至關(guān)重要,但梯度下降的實際編碼及其不同的“變體”可能是一項困難的任務。為了完成這項任務,本文的格式如下:

        1. 簡要概述每種算法的作用。

        2. 算法的代碼

        3. 對規(guī)范不明確部分的進一步解釋

        我們將使用著名的波士頓住房數(shù)據(jù)集,它是預先內(nèi)置在scikit learn中的。我們還將從頭開始構(gòu)建一個線性模型



        好的,首先讓我們做一些基本的導入。我不打算在這里做EDA,因為這不是我們文章的真正目的。不過,我會把一些事情說明白。

        import numpy as np
        import pandas as pd 
        import plotly.express as px
        from sklearn.datasets import load_boston
        from sklearn.metrics import mean_squared_error

        好的,為了讓我們看到數(shù)據(jù)是什么樣子,我將把數(shù)據(jù)轉(zhuǎn)換成一個數(shù)據(jù)幀并顯示輸出。

        data = load_boston()

        df = pd.DataFrame(data['data'],columns=data['feature_names'])
        df.insert(13,'target',data['target'])
        df.head(5)

        好吧,這里沒什么特別的,我敢肯定你之前已經(jīng)類似實現(xiàn)過了。

        現(xiàn)在,我們將定義我們的特征(X)和目標(y)。我們還將定義我們的參數(shù)向量,將其命名為thetas,并將它們初始化為零。

        X,y = df.drop('target',axis=1),df['target']

        thetas = np.zeros(X.shape[1])

        成本函數(shù)

        回想一下,成本函數(shù)是衡量模型性能的東西,也是梯度下降的目標。我們將使用的代價函數(shù)稱為均方誤差。公式如下:

        好吧,我們把它寫出來:

        def cost_function(X,Y,B):
            predictions = np.dot(X,B.T)
            
            cost = (1/len(Y)) * np.sum((predictions - Y) ** 2)
            return cost

        在這里,我們將輸入、標簽和參數(shù)作為輸入,并使用線性模型進行預測,得到成本,然后返回。如果第二行讓你困惑,回想一下線性回歸公式:

        所以,我們基本上是得到每個特征和它們相應權(quán)重之間的點積。如果你還不確定我在說什么,看看這個視頻:https://www.youtube.com/watch?v=kHwlB_j7Hkc


        很好,現(xiàn)在讓我們測試一下我們的成本函數(shù),看看它是否真的有效。為了做到這一點,我們將使用scikit learn的均方誤差,得到結(jié)果,并將其與我們的算法進行比較。

        mean_squared_error(np.dot(X,thetas.T),y)

        OUT: 592.14691169960474

        cost_function(X,y,thetas)

        OUT: 592.14691169960474

        太棒了,我們的成本函數(shù)起作用了!

        特征縮放

        特征縮放是線性模型(線性回歸、KNN、SVM)的重要預處理技術(shù)。本質(zhì)上,特征被縮小到更小的范圍,并且特征也在一定的范圍內(nèi)。可以這樣考慮特征縮放:

        1. 你有一座很大的建筑物

        2. 你希望保持建筑的形狀,但希望將其調(diào)整為較小的比例

        特征縮放通常用于以下場景:

        1. 如果一個算法使用歐幾里德距離,那么由于歐幾里德距離對較大的量值敏感,因此需要對特征進行縮放

        2. 特征縮放還可以用于數(shù)據(jù)標準化

        3. 特征縮放還可以提高算法的速度

        雖然有許多不同的特征縮放方法,但我們將使用以下公式構(gòu)建MinMaxScaler的自定義實現(xiàn):

        由于上述原因,我們將使用縮放。

        現(xiàn)在,對于python實現(xiàn):

        X_norm = (X - X.min()) / (X.max() - X.min())
        X = X_norm

        這里沒什么特別的,我們只是把公式翻譯成代碼?,F(xiàn)在,節(jié)目真正開始了:梯度下降!


        梯度下降

        具體地說,梯度下降是一種優(yōu)化算法,它通過迭代遍歷數(shù)據(jù)并獲得偏導數(shù)來尋求函數(shù)的最小值(在我們的例子中是MSE)。

        如果這有點復雜,試著把梯度下降想象成是一個人站在山頂上,他們試著以最快的速度從山上爬下來,沿著山的負方向不斷地“走”,直到到達底部。

        現(xiàn)在,梯度下降有不同的版本,但是你會遇到最多的是:

        1. 批量梯度下降

        2. 隨機梯度下降法

        3. 小批量梯度下降

        現(xiàn)在我們將按順序討論、實現(xiàn)和分析每一項,所以讓我們開始吧!

        批量梯度下降

        批量梯度下降可能是你遇到的第一種梯度下降類型?,F(xiàn)在,我在這篇文章中并不是很理論化(你可以參考我以前的文章:https://medium.com/@vagifaliyev/gradient-descent-clearly-explained-in-python-part-1-the-troubling-theory-49a7fa2c4c06),但實際上它計算的是整個(批處理)數(shù)據(jù)集上系數(shù)的偏導數(shù)。你可能已經(jīng)猜到這樣做很慢了。

        我們的數(shù)據(jù)集很小,所以我們可以像這樣實現(xiàn)批量梯度下降:

        def batch_gradient_descent(X,Y,theta,alpha,iters):
            cost_history = [0] * iters  # 初始化歷史損失列表
            for i in range(iters):         
                prediction = np.dot(X,theta.T)                  
                theta = theta - (alpha/len(Y)) * np.dot(prediction - Y,X)   
                cost_history[i] = cost_function(X,Y,theta)               
            return theta,cost_history

        要澄清一些術(shù)語:

        alpha:這是指學習率。

        iters:迭代運行的數(shù)量。


        太好了,現(xiàn)在讓我們看看結(jié)果吧!

        batch_theta,batch_history=batch_gradient_descent(X,y,theta,0.05,500)

        好吧,不是很快,但也不是很慢。讓我們用我們新的和改進的參數(shù)來可視化和成本:

        cost_function(X,y,batch_theta)

        OUT: 27.537447130784262

        哇,從592到27!這只是一個梯度下降的力量的一瞥!讓我們對迭代次數(shù)的成本函數(shù)進行可視化:

        fig = px.line(batch_history,x=range(5000),y=batch_history,labels={'x':'no. of iterations','y':'cost function'})
        fig.show()

        好的,看看這個圖表,我們在大約100次迭代之后達到了一個大的下降,從那里開始,它一直在逐漸減少。

        所以,批量梯度下降到此結(jié)束:

        優(yōu)點

        1. 有效且曲線平滑

        2. 最準確,最有可能達到全局最低值

        缺點

        1. 對于大型數(shù)據(jù)集可能會很慢

        2. 計算成本高


        隨機梯度下降法

        這里,不是計算整個訓練集的偏導數(shù),而是只計算一個隨機樣本(隨機意義上的隨機)。

        這是很好的,因為計算只需要在一個訓練示例上進行,而不是在整個訓練集上進行,這使得計算速度更快,而且對于大型數(shù)據(jù)集來說非常理想。

        然而,由于其隨機性,隨機梯度下降并不像批量梯度下降那樣具有平滑的曲線,雖然它可以返回良好的參數(shù),但不能保證達到全局最小值。

        學習率調(diào)整

        解決隨機梯度下降問題的一種方法是學習率調(diào)整。

        基本上,這會逐漸降低學習率。因此,學習率一開始很大(這有助于避免局部極小值),當學習率接近全局最小值時,學習率逐漸降低。但是,你必須小心:

        1. 如果學習速率降低得太快,那么算法可能會陷入局部極小,或者在達到最小值的一半時停滯不前。

        2. 如果學習速率降低太慢,可能會在很長一段時間內(nèi)跳轉(zhuǎn)到最小值附近,仍然無法得到最佳參數(shù)


        現(xiàn)在,我們將使用簡易的學習率調(diào)整策略實現(xiàn)隨機梯度下降:

        t0,t1 = 5,50 # 學習率超參數(shù)

        def learning_schedule(t):
            return t0/(t+t1)
            
        def stochastic_gradient_descent(X,y,thetas,n_epochs=30):
            c_hist = [0] * n_epochs # 歷史成本
            for epoch in range(n_epochs):
                for i in range(len(y)):
                    random_index = np.random.randint(len(Y))
                    xi = X[random_index:random_index+1]
                    yi = y[random_index:random_index+1]
                    
                    prediction = xi.dot(thetas)
                    
                    gradient = 2 * xi.T.dot(prediction-yi)
                    eta = learning_schedule(epoch * len(Y) + i)
                    thetas = thetas - eta * gradient
                    c_hist[epoch] = cost_function(xi,yi,thetas)
            return thetas,c_hist

        現(xiàn)在運行函數(shù):

        sdg_thetas,sgd_cost_hist = stochastic_gradient_descent(X,Y,theta)

        好吧,太好了,這樣就行了!現(xiàn)在讓我們看看結(jié)果:

        cost_function(X,y,sdg_thetas)

        OUT:
        29.833230764634493

        哇!我們從592到29,但是請注意:我們只進行了30次迭代。批量梯度下降,500次迭代后得到27次!這只是對隨機梯度下降的非凡力量的一瞥。

        讓我們用一個圖再次將其可視化:

        由于這是一個小數(shù)據(jù)集,批量梯度下降就足夠了,但這只是顯示了隨機梯度下降的力量。

        優(yōu)點:

        1. 與批量梯度下降相比更快

        2. 更好地處理更大的數(shù)據(jù)集

        缺點:

        1. 在某個最小值上很難跳出

        2. 并不總是有一個清晰的圖,可以在一個最小值附近反彈,但永遠不會達到最佳的最小值


        小批量梯度下降

        好了,快到了,還有一個要通過!現(xiàn)在,在小批量梯度下降中,我們不再計算整個訓練集或隨機樣本的偏導數(shù),而是在整個訓練集的小子集上計算。

        這給了我們比批量梯度下降更快的速度,因為它不像隨機梯度下降那樣隨機,所以我們更接近于最小值。然而,它很容易陷入局部極小值。

        同樣,為了解決陷入局部最小值的問題,我們將在實現(xiàn)中使用簡易的學習率調(diào)整。

        np.random.seed(42# 所以我們得到相同的結(jié)果

        t0, t1 = 2001000
        def learning_schedule(t):
            return t0 / (t + t1)
            
        def mini_batch_gradient_descent(X,y,thetas,n_iters=100,batch_size=20):
            t = 0
            c_hist = [0] * n_iters
            for epoch in range(n_iters):
                shuffled_indices = np.random.permutation(len(y))
                X_shuffled = X_scaled[shuffled_indices]
                y_shuffled = y[shuffled_indices]
                
                for i in range(0,len(Y),batch_size):
                    t+=1
                    xi = X_shuffled[i:i+batch_size]
                    yi = y_shuffled[i:i+batch_size]
                    
                    gradient = 2/batch_size * xi.T.dot(xi.dot(thetas) - yi)
                    eta = learning_schedule(t)
                    thetas = thetas - eta * gradient
                    c_hist[epoch] = cost_function(xi,yi,thetas)
            return thetas,c_hist

        讓我們運行并獲得結(jié)果:

        mini_batch_gd_thetas,mini_batch_gd_cost = mini_batch_gradient_descent(X,y,theta)

        以及新參數(shù)下的成本函數(shù):

        cost_function(X,Y,mini_batch_gd_thetas)

        OUT: 27.509689139167012

        又一次真的很棒。我們運行了1/5的迭代,我們得到了一個更好的分數(shù)!

        讓我們再畫出函數(shù):


        好了,我的梯度下降系列到此結(jié)束!感謝閱讀!

        好消息! 

        小白學視覺知識星球

        開始面向外開放啦??????




        下載1:OpenCV-Contrib擴展模塊中文版教程
        在「小白學視覺」公眾號后臺回復:擴展模塊中文教程,即可下載全網(wǎng)第一份OpenCV擴展模塊教程中文版,涵蓋擴展模塊安裝、SFM算法、立體視覺、目標跟蹤、生物視覺、超分辨率處理等二十多章內(nèi)容。

        下載2:Python視覺實戰(zhàn)項目52講
        小白學視覺公眾號后臺回復:Python視覺實戰(zhàn)項目即可下載包括圖像分割、口罩檢測、車道線檢測、車輛計數(shù)、添加眼線、車牌識別、字符識別、情緒檢測、文本內(nèi)容提取、面部識別等31個視覺實戰(zhàn)項目,助力快速學校計算機視覺。

        下載3:OpenCV實戰(zhàn)項目20講
        小白學視覺公眾號后臺回復:OpenCV實戰(zhàn)項目20講,即可下載含有20個基于OpenCV實現(xiàn)20個實戰(zhàn)項目,實現(xiàn)OpenCV學習進階。

        交流群


        歡迎加入公眾號讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器自動駕駛、計算攝影、檢測、分割、識別、醫(yī)學影像、GAN、算法競賽等微信群(以后會逐漸細分),請掃描下面微信號加群,備注:”昵稱+學校/公司+研究方向“,例如:”張三 + 上海交大 + 視覺SLAM“。請按照格式備注,否則不予通過。添加成功后會根據(jù)研究方向邀請進入相關(guān)微信群。請勿在群內(nèi)發(fā)送廣告,否則會請出群,謝謝理解~


        瀏覽 44
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            屁股撅高bl玉势 岛国a级毛片 | 国产屁屁影院 | 亚洲无码免费网站 | 一女两男做爰3p文 | 国产麻豆传媒视频 | 天天色艹 | 少妇交换做爰3在线看 | 小舞3d被吸乳羞羞在线观看 | 高清无码在线一区 | 美女干b视频 |