python損失函數(shù)學習的簡單介紹

從零開始用Python構(gòu)建神經(jīng)網(wǎng)絡(luò)

從零開始用Python構(gòu)建神經(jīng)網(wǎng)絡(luò)

創(chuàng)新互聯(lián)公司主營長白網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,重慶APP開發(fā)公司,長白h5成都小程序開發(fā)搭建,長白網(wǎng)站營銷推廣歡迎長白等地區(qū)企業(yè)咨詢

動機:為了更加深入的理解深度學習,我們將使用 python 語言從頭搭建一個神經(jīng)網(wǎng)絡(luò),而不是使用像 Tensorflow 那樣的封裝好的框架。我認為理解神經(jīng)網(wǎng)絡(luò)的內(nèi)部工作原理,對數(shù)據(jù)科學家來說至關(guān)重要。

這篇文章的內(nèi)容是我的所學,希望也能對你有所幫助。

神經(jīng)網(wǎng)絡(luò)是什么?

介紹神經(jīng)網(wǎng)絡(luò)的文章大多數(shù)都會將它和大腦進行類比。如果你沒有深入研究過大腦與神經(jīng)網(wǎng)絡(luò)的類比,那么將神經(jīng)網(wǎng)絡(luò)解釋為一種將給定輸入映射為期望輸出的數(shù)學關(guān)系會更容易理解。

神經(jīng)網(wǎng)絡(luò)包括以下組成部分

? 一個輸入層,x

? 任意數(shù)量的隱藏層

? 一個輸出層,?

? 每層之間有一組權(quán)值和偏置,W and b

? 為隱藏層選擇一種激活函數(shù),σ。在教程中我們使用 Sigmoid 激活函數(shù)

下圖展示了 2 層神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)(注意:我們在計算網(wǎng)絡(luò)層數(shù)時通常排除輸入層)

2 層神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)

用 Python 可以很容易的構(gòu)建神經(jīng)網(wǎng)絡(luò)類

訓練神經(jīng)網(wǎng)絡(luò)

這個網(wǎng)絡(luò)的輸出 ? 為:

你可能會注意到,在上面的等式中,輸出 ? 是 W 和 b 函數(shù)。

因此 W 和 b 的值影響預測的準確率. 所以根據(jù)輸入數(shù)據(jù)對 W 和 b 調(diào)優(yōu)的過程就被成為訓練神經(jīng)網(wǎng)絡(luò)。

每步訓練迭代包含以下兩個部分:

? 計算預測結(jié)果 ?,這一步稱為前向傳播

? 更新 W 和 b,,這一步成為反向傳播

下面的順序圖展示了這個過程:

前向傳播

正如我們在上圖中看到的,前向傳播只是簡單的計算。對于一個基本的 2 層網(wǎng)絡(luò)來說,它的輸出是這樣的:

我們在 NeuralNetwork 類中增加一個計算前向傳播的函數(shù)。為了簡單起見我們假設(shè)偏置 b 為0:

但是我們還需要一個方法來評估預測結(jié)果的好壞(即預測值和真實值的誤差)。這就要用到損失函數(shù)。

損失函數(shù)

常用的損失函數(shù)有很多種,根據(jù)模型的需求來選擇。在本教程中,我們使用誤差平方和作為損失函數(shù)。

誤差平方和是求每個預測值和真實值之間的誤差再求和,這個誤差是他們的差值求平方以便我們觀察誤差的絕對值。

訓練的目標是找到一組 W 和 b,使得損失函數(shù)最好小,也即預測值和真實值之間的距離最小。

反向傳播

我們已經(jīng)度量出了預測的誤差(損失),現(xiàn)在需要找到一種方法來傳播誤差,并以此更新權(quán)值和偏置。

為了知道如何適當?shù)恼{(diào)整權(quán)值和偏置,我們需要知道損失函數(shù)對權(quán)值 W 和偏置 b 的導數(shù)。

回想微積分中的概念,函數(shù)的導數(shù)就是函數(shù)的斜率。

梯度下降法

如果我們已經(jīng)求出了導數(shù),我們就可以通過增加或減少導數(shù)值來更新權(quán)值 W 和偏置 b(參考上圖)。這種方式被稱為梯度下降法。

但是我們不能直接計算損失函數(shù)對權(quán)值和偏置的導數(shù),因為在損失函數(shù)的等式中并沒有顯式的包含他們。因此,我們需要運用鏈式求導發(fā)在來幫助計算導數(shù)。

鏈式法則用于計算損失函數(shù)對 W 和 b 的導數(shù)。注意,為了簡單起見。我們只展示了假設(shè)網(wǎng)絡(luò)只有 1 層的偏導數(shù)。

這雖然很簡陋,但是我們依然能得到想要的結(jié)果—損失函數(shù)對權(quán)值 W 的導數(shù)(斜率),因此我們可以相應的調(diào)整權(quán)值。

現(xiàn)在我們將反向傳播算法的函數(shù)添加到 Python 代碼中

為了更深入的理解微積分原理和反向傳播中的鏈式求導法則,我強烈推薦 3Blue1Brown 的如下教程:

Youtube:

整合并完成一個實例

既然我們已經(jīng)有了包括前向傳播和反向傳播的完整 Python 代碼,那么就將其應用到一個例子上看看它是如何工作的吧。

神經(jīng)網(wǎng)絡(luò)可以通過學習得到函數(shù)的權(quán)重。而我們僅靠觀察是不太可能得到函數(shù)的權(quán)重的。

讓我們訓練神經(jīng)網(wǎng)絡(luò)進行 1500 次迭代,看看會發(fā)生什么。 注意觀察下面每次迭代的損失函數(shù),我們可以清楚地看到損失函數(shù)單調(diào)遞減到最小值。這與我們之前介紹的梯度下降法一致。

讓我們看看經(jīng)過 1500 次迭代后的神經(jīng)網(wǎng)絡(luò)的最終預測結(jié)果:

經(jīng)過 1500 次迭代訓練后的預測結(jié)果

我們成功了!我們應用前向和方向傳播算法成功的訓練了神經(jīng)網(wǎng)絡(luò)并且預測結(jié)果收斂于真實值。

注意預測值和真實值之間存在細微的誤差是允許的。這樣可以防止模型過擬合并且使得神經(jīng)網(wǎng)絡(luò)對于未知數(shù)據(jù)有著更強的泛化能力。

下一步是什么?

幸運的是我們的學習之旅還沒有結(jié)束,仍然有很多關(guān)于神經(jīng)網(wǎng)絡(luò)和深度學習的內(nèi)容需要學習。例如:

? 除了 Sigmoid 以外,還可以用哪些激活函數(shù)

? 在訓練網(wǎng)絡(luò)的時候應用學習率

? 在面對圖像分類任務的時候使用卷積神經(jīng)網(wǎng)絡(luò)

我很快會寫更多關(guān)于這個主題的內(nèi)容,敬請期待!

最后的想法

我自己也從零開始寫了很多神經(jīng)網(wǎng)絡(luò)的代碼

雖然可以使用諸如 Tensorflow 和 Keras 這樣的深度學習框架方便的搭建深層網(wǎng)絡(luò)而不需要完全理解其內(nèi)部工作原理。但是我覺得對于有追求的數(shù)據(jù)科學家來說,理解內(nèi)部原理是非常有益的。

這種練習對我自己來說已成成為重要的時間投入,希望也能對你有所幫助

怎樣用python構(gòu)建一個卷積神經(jīng)網(wǎng)絡(luò)

用keras框架較為方便

首先安裝anaconda,然后通過pip安裝keras

以下轉(zhuǎn)自wphh的博客。

#coding:utf-8

'''

GPU?run?command:

THEANO_FLAGS=mode=FAST_RUN,device=gpu,floatX=float32?python?cnn.py

CPU?run?command:

python?cnn.py

2016.06.06更新:

這份代碼是keras開發(fā)初期寫的,當時keras還沒有現(xiàn)在這么流行,文檔也還沒那么豐富,所以我當時寫了一些簡單的教程。

現(xiàn)在keras的API也發(fā)生了一些的變化,建議及推薦直接上keras.io看更加詳細的教程。

'''

#導入各種用到的模塊組件

from?__future__?import?absolute_import

from?__future__?import?print_function

from?keras.preprocessing.image?import?ImageDataGenerator

from?keras.models?import?Sequential

from?keras.layers.core?import?Dense,?Dropout,?Activation,?Flatten

from?keras.layers.advanced_activations?import?PReLU

from?keras.layers.convolutional?import?Convolution2D,?MaxPooling2D

from?keras.optimizers?import?SGD,?Adadelta,?Adagrad

from?keras.utils?import?np_utils,?generic_utils

from?six.moves?import?range

from?data?import?load_data

import?random

import?numpy?as?np

np.random.seed(1024)??#?for?reproducibility

#加載數(shù)據(jù)

data,?label?=?load_data()

#打亂數(shù)據(jù)

index?=?[i?for?i?in?range(len(data))]

random.shuffle(index)

data?=?data[index]

label?=?label[index]

print(data.shape[0],?'?samples')

#label為0~9共10個類別,keras要求格式為binary?class?matrices,轉(zhuǎn)化一下,直接調(diào)用keras提供的這個函數(shù)

label?=?np_utils.to_categorical(label,?10)

###############

#開始建立CNN模型

###############

#生成一個model

model?=?Sequential()

#第一個卷積層,4個卷積核,每個卷積核大小5*5。1表示輸入的圖片的通道,灰度圖為1通道。

#border_mode可以是valid或者full,具體看這里說明:

#激活函數(shù)用tanh

#你還可以在model.add(Activation('tanh'))后加上dropout的技巧:?model.add(Dropout(0.5))

model.add(Convolution2D(4,?5,?5,?border_mode='valid',input_shape=(1,28,28)))?

model.add(Activation('tanh'))

#第二個卷積層,8個卷積核,每個卷積核大小3*3。4表示輸入的特征圖個數(shù),等于上一層的卷積核個數(shù)

#激活函數(shù)用tanh

#采用maxpooling,poolsize為(2,2)

model.add(Convolution2D(8,?3,?3,?border_mode='valid'))

model.add(Activation('tanh'))

model.add(MaxPooling2D(pool_size=(2,?2)))

#第三個卷積層,16個卷積核,每個卷積核大小3*3

#激活函數(shù)用tanh

#采用maxpooling,poolsize為(2,2)

model.add(Convolution2D(16,?3,?3,?border_mode='valid'))?

model.add(Activation('relu'))

model.add(MaxPooling2D(pool_size=(2,?2)))

#全連接層,先將前一層輸出的二維特征圖flatten為一維的。

#Dense就是隱藏層。16就是上一層輸出的特征圖個數(shù)。4是根據(jù)每個卷積層計算出來的:(28-5+1)得到24,(24-3+1)/2得到11,(11-3+1)/2得到4

#全連接有128個神經(jīng)元節(jié)點,初始化方式為normal

model.add(Flatten())

model.add(Dense(128,?init='normal'))

model.add(Activation('tanh'))

#Softmax分類,輸出是10類別

model.add(Dense(10,?init='normal'))

model.add(Activation('softmax'))

#############

#開始訓練模型

##############

#使用SGD?+?momentum

#model.compile里的參數(shù)loss就是損失函數(shù)(目標函數(shù))

sgd?=?SGD(lr=0.05,?decay=1e-6,?momentum=0.9,?nesterov=True)

model.compile(loss='categorical_crossentropy',?optimizer=sgd,metrics=["accuracy"])

#調(diào)用fit方法,就是一個訓練過程.?訓練的epoch數(shù)設(shè)為10,batch_size為100.

#數(shù)據(jù)經(jīng)過隨機打亂shuffle=True。verbose=1,訓練過程中輸出的信息,0、1、2三種方式都可以,無關(guān)緊要。show_accuracy=True,訓練時每一個epoch都輸出accuracy。

#validation_split=0.2,將20%的數(shù)據(jù)作為驗證集。

model.fit(data,?label,?batch_size=100,?nb_epoch=10,shuffle=True,verbose=1,validation_split=0.2)

"""

#使用data?augmentation的方法

#一些參數(shù)和調(diào)用的方法,請看文檔

datagen?=?ImageDataGenerator(

featurewise_center=True,?#?set?input?mean?to?0?over?the?dataset

samplewise_center=False,?#?set?each?sample?mean?to?0

featurewise_std_normalization=True,?#?divide?inputs?by?std?of?the?dataset

samplewise_std_normalization=False,?#?divide?each?input?by?its?std

zca_whitening=False,?#?apply?ZCA?whitening

rotation_range=20,?#?randomly?rotate?images?in?the?range?(degrees,?0?to?180)

width_shift_range=0.2,?#?randomly?shift?images?horizontally?(fraction?of?total?width)

height_shift_range=0.2,?#?randomly?shift?images?vertically?(fraction?of?total?height)

horizontal_flip=True,?#?randomly?flip?images

vertical_flip=False)?#?randomly?flip?images

#?compute?quantities?required?for?featurewise?normalization?

#?(std,?mean,?and?principal?components?if?ZCA?whitening?is?applied)

datagen.fit(data)

for?e?in?range(nb_epoch):

print('-'*40)

print('Epoch',?e)

print('-'*40)

print("Training...")

#?batch?train?with?realtime?data?augmentation

progbar?=?generic_utils.Progbar(data.shape[0])

for?X_batch,?Y_batch?in?datagen.flow(data,?label):

loss,accuracy?=?model.train(X_batch,?Y_batch,accuracy=True)

progbar.add(X_batch.shape[0],?values=[("train?loss",?loss),("accuracy:",?accuracy)]?)

"""

交叉熵損失函數(shù)是什么?

平滑函數(shù)。

交叉熵損失函數(shù),也稱為對數(shù)損失或者logistic損失。當模型產(chǎn)生了預測值之后,將對類別的預測概率與真實值(由0或1組成)進行不比較,計算所產(chǎn)生的損失,然后基于此損失設(shè)置對數(shù)形式的懲罰項。

在神經(jīng)網(wǎng)絡(luò)中,所使用的Softmax函數(shù)是連續(xù)可導函數(shù),這使得可以計算出損失函數(shù)相對于神經(jīng)網(wǎng)絡(luò)中每個權(quán)重的導數(shù)(在《機器學習數(shù)學基礎(chǔ)》中有對此的完整推導過程和案例,這樣就可以相應地調(diào)整模型的權(quán)重以最小化損失函數(shù)。

擴展資料:

注意事項:

當預測類別為二分類時,交叉熵損失函數(shù)的計算公式如下圖,其中y是真實類別(值為0或1),p是預測類別的概率(值為0~1之間的小數(shù))。

計算二分類的交叉熵損失函數(shù)的python代碼如下圖,其中esp是一個極小值,第五行代碼clip的目的是保證預測概率的值在0~1之間,輸出的損失值數(shù)組求和后,就是損失函數(shù)最后的返回值。

參考資料來源:百度百科-交叉熵

參考資料來源:百度百科-損失函數(shù)

python gradientboostingregressor可以做預測嗎

可以

最近項目中涉及基于Gradient Boosting Regression 算法擬合時間序列曲線的內(nèi)容,利用python機器學習包?scikit-learn 中的GradientBoostingRegressor完成

因此就學習了下Gradient Boosting算法,在這里分享下我的理解

Boosting 算法簡介

Boosting算法,我理解的就是兩個思想:

1)“三個臭皮匠頂個諸葛亮”,一堆弱分類器的組合就可以成為一個強分類器;

2)“知錯能改,善莫大焉”,不斷地在錯誤中學習,迭代來降低犯錯概率

當然,要理解好Boosting的思想,首先還是從弱學習算法和強學習算法來引入:

1)強學習算法:存在一個多項式時間的學習算法以識別一組概念,且識別的正確率很高;

2)弱學習算法:識別一組概念的正確率僅比隨機猜測略好;

Kearns Valiant證明了弱學習算法與強學習算法的等價問題,如果兩者等價,只需找到一個比隨機猜測略好的學習算法,就可以將其提升為強學習算法。

那么是怎么實現(xiàn)“知錯就改”的呢?

Boosting算法,通過一系列的迭代來優(yōu)化分類結(jié)果,每迭代一次引入一個弱分類器,來克服現(xiàn)在已經(jīng)存在的弱分類器組合的shortcomings

在Adaboost算法中,這個shortcomings的表征就是權(quán)值高的樣本點

而在Gradient Boosting算法中,這個shortcomings的表征就是梯度

無論是Adaboost還是Gradient Boosting,都是通過這個shortcomings來告訴學習器怎么去提升模型,也就是“Boosting”這個名字的由來吧

Adaboost算法

Adaboost是由Freund 和 Schapire在1997年提出的,在整個訓練集上維護一個分布權(quán)值向量W,用賦予權(quán)重的訓練集通過弱分類算法產(chǎn)生分類假設(shè)(基學習器)y(x),然后計算錯誤率,用得到的錯誤率去更新分布權(quán)值向量w,對錯誤分類的樣本分配更大的權(quán)值,正確分類的樣本賦予更小的權(quán)值。每次更新后用相同的弱分類算法產(chǎn)生新的分類假設(shè),這些分類假設(shè)的序列構(gòu)成多分類器。對這些多分類器用加權(quán)的方法進行聯(lián)合,最后得到?jīng)Q策結(jié)果。

其結(jié)構(gòu)如下圖所示:

前一個學習器改變權(quán)重w,然后再經(jīng)過下一個學習器,最終所有的學習器共同組成最后的學習器。

如果一個樣本在前一個學習器中被誤分,那么它所對應的權(quán)重會被加重,相應地,被正確分類的樣本的權(quán)重會降低。

這里主要涉及到兩個權(quán)重的計算問題:

1)樣本的權(quán)值

1 沒有先驗知識的情況下,初始的分布應為等概分布,樣本數(shù)目為n,權(quán)值為1/n

2 每一次的迭代更新權(quán)值,提高分錯樣本的權(quán)重

2)弱學習器的權(quán)值

1 最后的強學習器是通過多個基學習器通過權(quán)值組合得到的。

2 通過權(quán)值體現(xiàn)不同基學習器的影響,正確率高的基學習器權(quán)重高。實際上是分類誤差的一個函數(shù)

Gradient Boosting

和Adaboost不同,Gradient Boosting 在迭代的時候選擇梯度下降的方向來保證最后的結(jié)果最好。

損失函數(shù)用來描述模型的“靠譜”程度,假設(shè)模型沒有過擬合,損失函數(shù)越大,模型的錯誤率越高

如果我們的模型能夠讓損失函數(shù)持續(xù)的下降,則說明我們的模型在不停的改進,而最好的方式就是讓損失函數(shù)在其梯度方向上下降。

下面這個流程圖是Gradient Boosting的經(jīng)典圖了,數(shù)學推導并不復雜,只要理解了Boosting的思想,不難看懂

這里是直接對模型的函數(shù)進行更新,利用了參數(shù)可加性推廣到函數(shù)空間。

訓練F0-Fm一共m個基學習器,沿著梯度下降的方向不斷更新ρm和am

GradientBoostingRegressor實現(xiàn)

python中的scikit-learn包提供了很方便的GradientBoostingRegressor和GBDT的函數(shù)接口,可以很方便的調(diào)用函數(shù)就可以完成模型的訓練和預測

GradientBoostingRegressor函數(shù)的參數(shù)如下:

class sklearn.ensemble.GradientBoostingRegressor(loss='ls', learning_rate=0.1, n_estimators=100, subsample=1.0, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_depth=3, init=None, random_state=None, max_features=None, alpha=0.9, verbose=0, max_leaf_nodes=None, warm_start=False, presort='auto')[source]?

loss: 選擇損失函數(shù),默認值為ls(least squres)

learning_rate: 學習率,模型是0.1

n_estimators: 弱學習器的數(shù)目,默認值100

max_depth: 每一個學習器的最大深度,限制回歸樹的節(jié)點數(shù)目,默認為3

min_samples_split: 可以劃分為內(nèi)部節(jié)點的最小樣本數(shù),默認為2

min_samples_leaf: 葉節(jié)點所需的最小樣本數(shù),默認為1

……

可以參考

官方文檔里帶了一個很好的例子,以500個弱學習器,最小平方誤差的梯度提升模型,做波士頓房價預測,代碼和結(jié)果如下:

1 import numpy as np 2 import matplotlib.pyplot as plt 3 ?4 from sklearn import ensemble 5 from sklearn import datasets 6 from sklearn.utils import shuffle 7 from sklearn.metrics import mean_squared_error 8 ?9 ###############################################################################10 # Load data11 boston = datasets.load_boston()12 X, y = shuffle(boston.data, boston.target, random_state=13)13 X = X.astype(np.float32)14 offset = int(X.shape[0] * 0.9)15 X_train, y_train = X[:offset], y[:offset]16 X_test, y_test = X[offset:], y[offset:]17 18 ###############################################################################19 # Fit regression model20 params = {'n_estimators': 500, 'max_depth': 4, 'min_samples_split': 1,21 ? ? ? ? ? 'learning_rate': 0.01, 'loss': 'ls'}22 clf = ensemble.GradientBoostingRegressor(**params)23 24 clf.fit(X_train, y_train)25 mse = mean_squared_error(y_test, clf.predict(X_test))26 print("MSE: %.4f" % mse)27 28 ###############################################################################29 # Plot training deviance30 31 # compute test set deviance32 test_score = np.zeros((params['n_estimators'],), dtype=np.float64)33 34 for i, y_pred in enumerate(clf.staged_predict(X_test)):35 ? ? test_score[i] = clf.loss_(y_test, y_pred)36 37 plt.figure(figsize=(12, 6))38 plt.subplot(1, 2, 1)39 plt.title('Deviance')40 plt.plot(np.arange(params['n_estimators']) + 1, clf.train_score_, 'b-',41 ? ? ? ? ?label='Training Set Deviance')42 plt.plot(np.arange(params['n_estimators']) + 1, test_score, 'r-',43 ? ? ? ? ?label='Test Set Deviance')44 plt.legend(loc='upper right')45 plt.xlabel('Boosting Iterations')46 plt.ylabel('Deviance')47 48 ###############################################################################49 # Plot feature importance50 feature_importance = clf.feature_importances_51 # make importances relative to max importance52 feature_importance = 100.0 * (feature_importance / feature_importance.max())53 sorted_idx = np.argsort(feature_importance)54 pos = np.arange(sorted_idx.shape[0]) + .555 plt.subplot(1, 2, 2)56 plt.barh(pos, feature_importance[sorted_idx], align='center')57 plt.yticks(pos, boston.feature_names[sorted_idx])58 plt.xlabel('Relative Importance')59 plt.title('Variable Importance')60 plt.show()

可以發(fā)現(xiàn),如果要用Gradient Boosting 算法的話,在sklearn包里調(diào)用還是非常方便的,幾行代碼即可完成,大部分的工作應該是在特征提取上。

感覺目前做數(shù)據(jù)挖掘的工作,特征設(shè)計是最重要的,據(jù)說現(xiàn)在kaggle競賽基本是GBDT的天下,優(yōu)劣其實還是特征上,感覺做項目也是,不斷的在研究數(shù)據(jù)中培養(yǎng)對數(shù)據(jù)的敏感度。

文章名稱:python損失函數(shù)學習的簡單介紹
文章位置:http://muchs.cn/article8/hgsdop.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化、網(wǎng)站收錄、軟件開發(fā)、網(wǎng)站營銷面包屑導航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

h5響應式網(wǎng)站建設(shè)