TensorFlow keras卷積神經(jīng)網(wǎng)絡(luò) 添加L2正則化方式
我就廢話不多說(shuō)了,大家還是直接看代碼吧!
model = keras.models.Sequential([ #卷積層1 keras.layers.Conv2D(32,kernel_size=5,strides=1,padding="same",data_format="channels_last",activation=tf.nn.relu,kernel_regularizer=keras.regularizers.l2(0.01)), #池化層1 keras.layers.MaxPool2D(pool_size=2,strides=2,padding="same"), #卷積層2 keras.layers.Conv2D(64,kernel_size=5,strides=1,padding="same",data_format="channels_last",activation=tf.nn.relu), #池化層2 keras.layers.MaxPool2D(pool_size=2,strides=2,padding="same"), #數(shù)據(jù)整理 keras.layers.Flatten(), #1024個(gè),全連接層 keras.layers.Dense(1024,activation=tf.nn.relu), #100個(gè),全連接層 keras.layers.Dense(100,activation=tf.nn.softmax) ])
import os os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' from tensorflow.python.keras.datasets import cifar100 from tensorflow.python import keras import tensorflow as tf class CNNMnist(object): model = keras.models.Sequential([ #卷積層1 keras.layers.Conv2D(32,kernel_size=5,strides=1,padding="same",data_format="channels_last",activation=tf.nn.relu,kernel_regularizer=keras.regularizers.l2(0.01)), #池化層1 keras.layers.MaxPool2D(pool_size=2,strides=2,padding="same"), #卷積層2 keras.layers.Conv2D(64,kernel_size=5,strides=1,padding="same",data_format="channels_last",activation=tf.nn.relu), #池化層2 keras.layers.MaxPool2D(pool_size=2,strides=2,padding="same"), #數(shù)據(jù)整理 keras.layers.Flatten(), #1024個(gè),全連接層 keras.layers.Dense(1024,activation=tf.nn.relu), #100個(gè),全連接層 keras.layers.Dense(100,activation=tf.nn.softmax) ]) def __init__(self): (self.x_train,self.y_train),(self.x_test,self.y_test) = cifar100.load_data() self.x_train = self.x_train/255.0 self.x_test = self.x_test/255.0 def compile(self): CNNMnist.model.compile(optimizer=keras.optimizers.Adam(),loss=keras.losses.sparse_categorical_crossentropy,metrics=["accuracy"]) def fit(self): CNNMnist.model.fit(self.x_train,self.y_train,epochs=1,batch_size=32) def evaluate(self): test_loss,test_acc = CNNMnist.model.evaluate(self.x_test,self.y_test) print(test_loss,test_acc) if __name__ == '__main__': cnn = CNNMnist() print(CNNMnist.model.summary()) cnn.compile() cnn.fit()
補(bǔ)充知識(shí):初步了解TensorFlow如何實(shí)現(xiàn)正則化
為了避免過(guò)擬合問(wèn)題,一個(gè)非常常用的方法是正則化(regularization),正則化的思想就是在損失函數(shù)中加入刻畫模型復(fù)雜程度的指標(biāo)。
假設(shè)用于刻畫模型在訓(xùn)練數(shù)據(jù)上表現(xiàn)的損失函數(shù)為J(θ),那么在優(yōu)化時(shí)不是直接優(yōu)化J(θ),而是優(yōu)化J(θ) + λR(w),其中R(w)刻畫的是模型的復(fù)雜程度,而λ表示模型復(fù)雜損失在總損失中的比例,需要注意的是,這里的θ表示的是一個(gè)神經(jīng)網(wǎng)絡(luò)中所有的參數(shù),它包括邊上的權(quán)重w和偏置項(xiàng)b,但一般來(lái)說(shuō)模型復(fù)雜度只由權(quán)重w決定。
常用的刻畫模型復(fù)雜度的函數(shù)R(w)有兩種,一種是L1正則化,計(jì)算公式是:

另一種是L2正則化,計(jì)算公式是:

TensorFlow可以優(yōu)化任意形式的損失函數(shù),所以TensorFlow自然也可以優(yōu)化帶正則化的損失函數(shù)。
L1正則化和L2正則化,在TensorFlow中分別以不同的函數(shù)實(shí)現(xiàn)它們,以下列代碼為示例:
#含有L1正則化的損失函數(shù): loss = tf.reduce_mean(tf.square(y_ - y)) + tf.contrib.layers.l1_regularizer(λ)(w) #含有L2正則化的損失函數(shù): loss = tf.reduce_mean(tf.square(y_ - y)) + tf.contrib.layers.l2_regularizer(λ)(w)
loss為定義的損失函數(shù),它由兩個(gè)部分組成,第一個(gè)部分是均方誤差損失函數(shù),它刻畫了模型在訓(xùn)練數(shù)據(jù)上的表現(xiàn),第二個(gè)部分就是正則化,它防止模型過(guò)度模擬訓(xùn)練數(shù)據(jù)中的隨機(jī)噪音;
λ表示了正則化項(xiàng)的權(quán)重,w為需要計(jì)算正則化損失的參數(shù)。
TensorFlow提供了tf.contrib.layers.l1_regularizer函數(shù)和tf.contrib.layers.l2_regularizer函數(shù)用來(lái)計(jì)算L1正則化和L2正則化,通過(guò)以下代碼給出使用兩個(gè)函數(shù)的樣例:
import tensorflow as tf weights = tf.constant([[1.0, -2.0], [-3.0, 4.0]]) with tf.Session() as sess: #計(jì)算結(jié)果為5.0 print(sess.run(tf.contrib.layers.l1_regularizer(0.5)(weights))) #計(jì)算結(jié)果為15 * 1/2 = 7.5,L2正則化乘以1/2可以方便求導(dǎo) print(sess.run(tf.contrib.layers.l2_regularizer(0.5)(weights)))
在簡(jiǎn)單的神經(jīng)網(wǎng)絡(luò)中,這樣的方式就可以很好地計(jì)算帶正則化的損失函數(shù)了,但當(dāng)神經(jīng)網(wǎng)絡(luò)的參數(shù)增多之后,這樣的方式首先可能導(dǎo)致?lián)p失函數(shù)loss的定義很長(zhǎng),可讀性差且容易出錯(cuò),更主要的是,當(dāng)網(wǎng)絡(luò)結(jié)構(gòu)復(fù)雜之后定義網(wǎng)絡(luò)結(jié)構(gòu)的部分和計(jì)算損失函數(shù)的部分可能不在同一個(gè)函數(shù)中,這樣通過(guò)變量這種方式計(jì)算損失函數(shù)就不方便了。
為了解決這個(gè)問(wèn)題,可以使用TensorFlow中提供的集合(collection)來(lái)維護(hù)需要計(jì)算的正則化損失,以下列代碼為示例給出通過(guò)集合計(jì)算一個(gè)5層神經(jīng)網(wǎng)絡(luò)帶L2正則化的損失函數(shù)的計(jì)算方法:
import tensorflow as tf
#獲取一層神經(jīng)網(wǎng)絡(luò)邊上的權(quán)重,并將這個(gè)權(quán)重的L2正則化損失加入名稱為losses的集合中
def get_weight(shape, r):
#生成一個(gè)變量
var = tf.Variable(tf.random_normal(shape, stddev=1, seed=1), dtype=tf.float32)
'''add_to_collection函數(shù)將這個(gè)新生成變量的L2正則化損失項(xiàng)加入集合
這個(gè)函數(shù)的第一個(gè)參數(shù)losses是集合的名字,第二個(gè)參數(shù)是要加入這個(gè)集合的內(nèi)容'''
tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(r)(var))
return var
x = tf.placeholder(tf.float32, shape=(None, 2))
y_ = tf.placeholder(tf.float32, shape=(None, 1))
#定義了每一層網(wǎng)絡(luò)中節(jié)點(diǎn)的個(gè)數(shù)
layer_dimension = [2, 10, 10, 10, 1]
#神經(jīng)網(wǎng)絡(luò)的層數(shù)
n_layers = len(layer_dimension)
#這個(gè)變量維護(hù)前向傳播時(shí)最深層的節(jié)點(diǎn),開始的時(shí)候就是輸入層
cur_layer = x
#in_dimension為當(dāng)前層的節(jié)點(diǎn)個(gè)數(shù)
in_dimension = layer_dimension[0]
#通過(guò)一個(gè)循環(huán)來(lái)生成5層全連接的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)
for i in range(1, n_layers):
#out_dimension為下一層的節(jié)點(diǎn)個(gè)數(shù)
out_dimension = layer_dimension[i]
#生成當(dāng)前層中權(quán)重的變量,并將這個(gè)變量的L2正則化損失加入losses集合
weight = get_weight([in_dimension, out_dimension], 0.001)
bias = tf.Variable(tf.fill([1, out_dimension], 0.1))
#使用ReLU激活函數(shù)
cur_layer = tf.nn.relu(tf.matmul(cur_layer, weight) + bias)
#進(jìn)入下一層之前將下一層的節(jié)點(diǎn)個(gè)數(shù)更新為當(dāng)前層節(jié)點(diǎn)個(gè)數(shù)
in_dimension = out_dimension
'''在定義神經(jīng)網(wǎng)絡(luò)前向傳播的同時(shí)已經(jīng)將所有的L2正則化損失加入了losses集合
這里只需要計(jì)算刻畫模型在訓(xùn)練數(shù)據(jù)上表現(xiàn)的損矣函數(shù)。'''
mse_loss = tf.reduce_mean(tf.square(y_ - cur_layer))
#將均方誤差損失函數(shù)加入損失集合
tf.add_to_collection('losses', mse_loss)
'''get_collection返回一個(gè)列表,這個(gè)列表包含所有這個(gè)集合中的元素
在這個(gè)樣例中這些元素就是損失函數(shù)的不同部分,將它們加起來(lái)就可以得到最終的損失函數(shù)。'''
loss = tf.add_n(tf.get_collection('losses'))
以上這篇TensorFlow keras卷積神經(jīng)網(wǎng)絡(luò) 添加L2正則化方式就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
python 讀取鼠標(biāo)點(diǎn)擊坐標(biāo)的實(shí)例
今天小編就為大家分享一篇python 讀取鼠標(biāo)點(diǎn)擊坐標(biāo)的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-12-12
python 實(shí)現(xiàn)docx與doc文件的互相轉(zhuǎn)換
這篇文章主要介紹了python 實(shí)現(xiàn)docx與doc文件的互相轉(zhuǎn)換操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-03-03
python機(jī)器人運(yùn)動(dòng)范圍問(wèn)題的解答
這篇文章主要為大家詳細(xì)解答了python機(jī)器人的運(yùn)動(dòng)范圍問(wèn)題,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-04-04
Python簡(jiǎn)單實(shí)現(xiàn)控制電腦的方法
這篇文章主要介紹了Python簡(jiǎn)單實(shí)現(xiàn)控制電腦的方法,涉及Python基于os及win32api等模塊調(diào)用系統(tǒng)命令操作電腦的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2018-01-01
解決TensorFlow模型恢復(fù)報(bào)錯(cuò)的問(wèn)題
今天小編就為大家分享一篇解決TensorFlow模型恢復(fù)報(bào)錯(cuò)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02
Python定時(shí)任務(wù)sched模塊用法示例
這篇文章主要介紹了Python定時(shí)任務(wù)sched模塊用法,結(jié)合實(shí)例形式分析了定時(shí)任務(wù)sched模塊的基本功能、參數(shù)含義、多線程定時(shí)任務(wù)等相關(guān)操作技巧,需要的朋友可以參考下2018-07-07
PyQt5 關(guān)于Qt Designer的初步應(yīng)用和打包過(guò)程詳解
Qt Designer中的操作方式十分靈活,其通過(guò)拖拽的方式放置控件可以隨時(shí)查看控件效果。這篇文章主要介紹了PyQt5 關(guān)于Qt Designer的初步應(yīng)用和打包,需要的朋友可以參考下2021-09-09

