本文目錄一覽:
怎樣用python構建一個卷積神經網路?
用keras框架較為方便
首先安裝anaconda,然後通過pip安裝keras
1、#導入各種用到的模塊組件
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
2、。#打亂數據
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,轉化一下,直接調用keras提供的這個函數
label = np_utils.to_categorical(label, 10)
###############
#開始建立CNN模型
###############
#生成一個model
model = Sequential()
3、#第一個卷積層,4個卷積核,每個卷積核大小5*5。1表示輸入的圖片的通道,灰度圖為1通道。
#border_mode可以是valid或者full,具體看這裡說明:
#激活函數用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表示輸入的特徵圖個數,等於上一層的卷積核個數
4、全連接層,先將前一層輸出的二維特徵圖flatten為一維的。
#Dense就是隱藏層。16就是上一層輸出的特徵圖個數。4是根據每個卷積層計算出來的:(28-5+1)得到24,(24-3+1)/2得到11,(11-3+1)/2得到4
#全連接有128個神經元節點,初始化方式為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里的參數loss就是損失函數(目標函數)
sgd = SGD(lr=0.05, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss=’categorical_crossentropy’, optimizer=sgd,metrics=[“accuracy”])
#調用fit方法,就是一個訓練過程. 訓練的epoch數設為10,batch_size為100.
#數據經過隨機打亂shuffle=True。verbose=1,訓練過程中輸出的信息,0、1、2三種方式都可以,無關緊要。show_accuracy=True,訓練時每一個epoch都輸出accuracy。
#validation_split=0.2,將20%的數據作為驗證集。
model.fit(data, label, batch_size=100, nb_epoch=10,shuffle=True,verbose=1,validation_split=0.2)
“””
#使用data augmentation的方法
#一些參數和調用的方法,請看文檔
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)] )
交叉熵損失函數是什麼?
平滑函數。
交叉熵損失函數,也稱為對數損失或者logistic損失。當模型產生了預測值之後,將對類別的預測概率與真實值(由0或1組成)進行不比較,計算所產生的損失,然後基於此損失設置對數形式的懲罰項。
在神經網路中,所使用的Softmax函數是連續可導函數,這使得可以計算出損失函數相對於神經網路中每個權重的導數(在《機器學習數學基礎》中有對此的完整推導過程和案例,這樣就可以相應地調整模型的權重以最小化損失函數。
擴展資料:
注意事項:
當預測類別為二分類時,交叉熵損失函數的計算公式如下圖,其中y是真實類別(值為0或1),p是預測類別的概率(值為0~1之間的小數)。
計算二分類的交叉熵損失函數的python代碼如下圖,其中esp是一個極小值,第五行代碼clip的目的是保證預測概率的值在0~1之間,輸出的損失值數組求和後,就是損失函數最後的返回值。
參考資料來源:百度百科-交叉熵
參考資料來源:百度百科-損失函數
生成對抗網路GAN的Loss
GAN同時要訓練一個生成網路(Generator)和一個判別網路(Discriminator),前者輸入一個noise變數 ,輸出一個偽圖片數據 ,後者輸入一個圖片(real image)以及偽圖片(fake image)數據 ,輸出一個表示該輸入是自然圖片或者偽造圖片的二分類置信度 ,理想情況下,判別器D需要儘可能準確的判斷輸入數據到底是一個真實的圖片還是某種偽造的圖片,而生成器G又需要盡最大可能去欺騙D,讓D把自己產生的偽造圖片全部判斷成真實的圖片。
根據上述訓練過程的描述,可以定義一個損失函數:
其中 , 分別是真實的圖片數據以及noise變數。
而優化目標則是:
參考資料
GAN損失函數理解
原始損失函數
首先假設D對樣本進行判別,1/0代表真/假。D的輸出數值越高,代表D越認為該樣本為正樣本。
GAN的訓練為先D後G。
G固定,訓練D時的損失函數為
第二項z來自隨機向量,G(z)為生成的圖像樣本,所以希望D能夠將其識別為假樣本,即D(G(z))儘可能接近0,1-D(G(z))儘可能接近1,即log(1-D(G(z)))儘可能大。
兩項都儘可能大,即整體儘可能大。所以D的損失函數V用max代表。
D固定,訓練G時的損失函數為
訓練G時候,希望D儘可能識別不出假樣本,即D(G(z))儘可能接近1。1-D(G(z))儘可能接近0,即log(1-D(G(z)))儘可能大,即整體儘可能小。所以G的損失函數V用max代表。
從零開始用Python構建神經網路
從零開始用Python構建神經網路
動機:為了更加深入的理解深度學習,我們將使用 python 語言從頭搭建一個神經網路,而不是使用像 Tensorflow 那樣的封裝好的框架。我認為理解神經網路的內部工作原理,對數據科學家來說至關重要。
這篇文章的內容是我的所學,希望也能對你有所幫助。
神經網路是什麼?
介紹神經網路的文章大多數都會將它和大腦進行類比。如果你沒有深入研究過大腦與神經網路的類比,那麼將神經網路解釋為一種將給定輸入映射為期望輸出的數學關係會更容易理解。
神經網路包括以下組成部分
? 一個輸入層,x
? 任意數量的隱藏層
? 一個輸出層,?
? 每層之間有一組權值和偏置,W and b
? 為隱藏層選擇一種激活函數,σ。在教程中我們使用 Sigmoid 激活函數
下圖展示了 2 層神經網路的結構(注意:我們在計算網路層數時通常排除輸入層)
2 層神經網路的結構
用 Python 可以很容易的構建神經網路類
訓練神經網路
這個網路的輸出 ? 為:
你可能會注意到,在上面的等式中,輸出 ? 是 W 和 b 函數。
因此 W 和 b 的值影響預測的準確率. 所以根據輸入數據對 W 和 b 調優的過程就被成為訓練神經網路。
每步訓練迭代包含以下兩個部分:
? 計算預測結果 ?,這一步稱為前向傳播
? 更新 W 和 b,,這一步成為反向傳播
下面的順序圖展示了這個過程:
前向傳播
正如我們在上圖中看到的,前向傳播只是簡單的計算。對於一個基本的 2 層網路來說,它的輸出是這樣的:
我們在 NeuralNetwork 類中增加一個計算前向傳播的函數。為了簡單起見我們假設偏置 b 為0:
但是我們還需要一個方法來評估預測結果的好壞(即預測值和真實值的誤差)。這就要用到損失函數。
損失函數
常用的損失函數有很多種,根據模型的需求來選擇。在本教程中,我們使用誤差平方和作為損失函數。
誤差平方和是求每個預測值和真實值之間的誤差再求和,這個誤差是他們的差值求平方以便我們觀察誤差的絕對值。
訓練的目標是找到一組 W 和 b,使得損失函數最好小,也即預測值和真實值之間的距離最小。
反向傳播
我們已經度量出了預測的誤差(損失),現在需要找到一種方法來傳播誤差,並以此更新權值和偏置。
為了知道如何適當的調整權值和偏置,我們需要知道損失函數對權值 W 和偏置 b 的導數。
回想微積分中的概念,函數的導數就是函數的斜率。
梯度下降法
如果我們已經求出了導數,我們就可以通過增加或減少導數值來更新權值 W 和偏置 b(參考上圖)。這種方式被稱為梯度下降法。
但是我們不能直接計算損失函數對權值和偏置的導數,因為在損失函數的等式中並沒有顯式的包含他們。因此,我們需要運用鏈式求導發在來幫助計算導數。
鏈式法則用於計算損失函數對 W 和 b 的導數。注意,為了簡單起見。我們只展示了假設網路只有 1 層的偏導數。
這雖然很簡陋,但是我們依然能得到想要的結果—損失函數對權值 W 的導數(斜率),因此我們可以相應的調整權值。
現在我們將反向傳播演算法的函數添加到 Python 代碼中
為了更深入的理解微積分原理和反向傳播中的鏈式求導法則,我強烈推薦 3Blue1Brown 的如下教程:
Youtube:
整合併完成一個實例
既然我們已經有了包括前向傳播和反向傳播的完整 Python 代碼,那麼就將其應用到一個例子上看看它是如何工作的吧。
神經網路可以通過學習得到函數的權重。而我們僅靠觀察是不太可能得到函數的權重的。
讓我們訓練神經網路進行 1500 次迭代,看看會發生什麼。 注意觀察下面每次迭代的損失函數,我們可以清楚地看到損失函數單調遞減到最小值。這與我們之前介紹的梯度下降法一致。
讓我們看看經過 1500 次迭代後的神經網路的最終預測結果:
經過 1500 次迭代訓練後的預測結果
我們成功了!我們應用前向和方向傳播演算法成功的訓練了神經網路並且預測結果收斂於真實值。
注意預測值和真實值之間存在細微的誤差是允許的。這樣可以防止模型過擬合併且使得神經網路對於未知數據有著更強的泛化能力。
下一步是什麼?
幸運的是我們的學習之旅還沒有結束,仍然有很多關於神經網路和深度學習的內容需要學習。例如:
? 除了 Sigmoid 以外,還可以用哪些激活函數
? 在訓練網路的時候應用學習率
? 在面對圖像分類任務的時候使用卷積神經網路
我很快會寫更多關於這個主題的內容,敬請期待!
最後的想法
我自己也從零開始寫了很多神經網路的代碼
雖然可以使用諸如 Tensorflow 和 Keras 這樣的深度學習框架方便的搭建深層網路而不需要完全理解其內部工作原理。但是我覺得對於有追求的數據科學家來說,理解內部原理是非常有益的。
這種練習對我自己來說已成成為重要的時間投入,希望也能對你有所幫助
原創文章,作者:AGDO,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/147670.html