Tensorflow學(xué)習(xí)筆記(三)

經(jīng)過前兩節(jié)跳纳,已經(jīng)大致了解了tensorflow的基本思想和一些基礎(chǔ)的計算API,本節(jié)我們將以深度神經(jīng)網(wǎng)絡(luò)為例贪嫂,深度剖析tensorflow的使用技巧寺庄。

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

如果一個樣本包含n維,即{\bf x}=[x_1,\cdots,x_n],其標(biāo)簽為y斗塘,我們希望建立一個神經(jīng)網(wǎng)絡(luò)赢织,通過x來預(yù)測其標(biāo)簽y,以一個多層全連接的神經(jīng)網(wǎng)絡(luò)為例馍盟,其每層變換定義方式如下:
\begin{align} {\bf x}_{layer1}&=f_1({\bf w}_1{\bf x}+{\bf b}_1)\\ {\bf x}_{layer2}&=f_2({\bf w}_2{\bf x}_{layer1}+{\bf b}_2)\\ \vdots\\ {\bf x}_{layer(k)}&=f_2({\bf w}_k{\bf x}_{layer(k-1)}+{\bf b}_k) \end{align}
其中{\bf w}_i\in\mathrm{R}^{n_{i-1}\times n_i}是第i隱層的待學(xué)習(xí)的權(quán)重矩陣于置,其中n_i表示第i層輸出向量的維度,同時它又是第i+1層輸入向量的維度贞岭。特別地八毯,輸入樣本層的維度為n_0=n。由于線性分類器在面對一些復(fù)雜的分類任務(wù)時表達(dá)能力不夠瞄桨,所以神經(jīng)網(wǎng)絡(luò)引入了非線性變換f_i:\mathrm{R}^{n_i}\rightarrow\mathrm{R}^{n_i}(通常是元素級的操作,即對向量的每個元素取f_i函數(shù)值)话速,常使用的非線性變換包括sigmoid函數(shù)、tanh函數(shù)和relu函數(shù)芯侥。
于是可以撰寫如下代碼:

import tensorflow as tf
input = tf.constant([0.3,0.5,0.7,0.2])
w1 = tf.Variable(tf.random_normal(shape=[4,3], stddev=0.1),name='w1')
biases1 = tf.Variable(tf.random_normal(shape=[1,3], stddev=0.1),name='1')
w1 = tf.Variable(tf.random_normal(shape=[3,5], stddev=0.1),name='w1')
biases1 = tf.Variable(tf.random_normal(shape=[1,5], stddev=0.1),name='1')
x1 = tf.nn.relu(tf.matmul(x, w1)+biases1)
x2 = tf.nn.relu(tf.matmul(x1, w2)+biases2)

上面代碼中將得到x1是一個3維行向量泊交,x2時一個5維行向量,即通過兩層變換柱查,原來的輸入x從4維行向量變成了5維行向量活合。如果有多個輸入(即一個batch),則x為4\times batchsize維張量物赶,輸出x2則變?yōu)?img class="math-inline" src="https://math.jianshu.com/math?formula=5%5Ctimes%20batchsize" alt="5\times batchsize" mathimg="1">維張量(由于加法的向量列可以自動維度展開適應(yīng)白指,所以不用改代碼)。

損失函數(shù)

在上一步得到x2之后酵紫,我們得到了樣本x的一個新的表達(dá)告嘲,現(xiàn)在需要建立一個損失函數(shù)(loss function)來刻畫這個表達(dá)的合理性,loss函數(shù)是x2和樣本標(biāo)簽y的函數(shù)奖地,那么根據(jù)是分類任務(wù)還是回歸任務(wù)可以定義不同損失函數(shù):

  1. 分類任務(wù)的交叉熵?fù)p失函數(shù)
    對于分類任務(wù)來說橄唬,如果一個樣本屬于第k類(共m類),則其標(biāo)簽為{\bf y}={\bf e}_k\in\mathrm{R}^m参歹,為第k個元素為1而其余元素為0的單位向量仰楚。
    在定義交叉熵之前,需要將神經(jīng)網(wǎng)絡(luò)輸出的x2之后再加入稱為softmax的一層犬庇,其將x2轉(zhuǎn)為m維非負(fù)向量僧界,且所有元素相加為1,其本質(zhì)是將x2映射為其為m個類分別的概率臭挽。首先將x2采用線性變換映射為m維向量{\bf z}=[z_1,\cdots,z_m]捂襟,然后使用softmax函數(shù)得到概率分布
    {\bf x}_{soft}=\left[\frac{e^{z_1}}{\sum_{i=1}^n e^{z_i}},\cdots,\frac{e^{z_n}}{\sum_{i=1}^n e^{z_i}}\right].
    當(dāng)轉(zhuǎn)化為概率后,我們使用交叉熵來定義其損失函數(shù)欢峰≡岷桑可以證明最小化交叉熵等價于極大似然估計涨共。對于兩個分布p,q,其交叉熵定義為
    H(p,q)=\sum_{x}p(x)\log(\frac{1}{q(x)})=-\sum_{x}p(x)\log(q(x)).
    于是對于一個樣本的輸出{\bf x}_{soft}=[x^*_1,\cdots,x^*_m]和其向量化的標(biāo)簽{\bf y}=[y_1,\cdots,y_n](若第k類則y_k=1其余為0)宠漩,其交叉熵為
    cross\_entropy = -\sum_{i=0}^m y_i\log(x_i^*).
    于是在tensorflow中可以使用如下代碼計算交叉熵
import tensorflow as tf
## 該函數(shù)輸出softmax化后的概率向量
def soft_max(tensor):
    ##這一步將所有z_i同時減去最大的举反,方式指數(shù)運算溢出
    minus_maximum = tensor - tf.reduce_max(tensor)
    return tf.exp(minus_maximum)/tf.reduce_sum(tf.exp(minus_maximum))

def cross_entropy(_y, y):
     ##計算交叉熵: _y是softmax輸出層的向量,y是標(biāo)簽向量
     return -tf.reduce_sum(y*tf.log(tf.clip_by_value(_y, 1e-10, 1)))

z = tf.constant([1, 0.5, 2]) ##設(shè)z為神經(jīng)網(wǎng)絡(luò)softmax層的輸入
y = tf.constant([0,0,1]) ##設(shè)y為樣本對應(yīng)的標(biāo)簽向量扒吁,屬于第3類
tf.InteractiveSession()
print('softmax layer output is:', soft_max(w).eval())
print('cross entropy is:', cross_entropy(soft_max(w), y).eval())
----------
>>softmax layer output is: [0.2312239  0.14024438 0.6285317 ]
>>cross entropy is: 0.10.4643688

實際上照筑,在tensorflow中,這一類交叉熵以及softmax函數(shù)都不用自己寫瘦陈,有可供使用的api在tf.nn中凝危,只需要簡單的一行代碼

cross_entropy = tf.nn.softmax_cross_entropy_with_logits_v2(labels=y, logits=w)
  1. 回歸和自定義損失函數(shù)
    回歸常用最小均方誤差MSE = \frac{1}{n}\sum_{i=1}^n(y_i-y^{label}_i)^2,代碼也很簡單
mse = tf.reduce_mean(tf.square(y_ - y))

同樣我們還可以自定義其他的損失函數(shù)晨逝,比如我們希望當(dāng)y小于標(biāo)簽y_{\_}的時候懲罰為3*(y_{\_}-y)蛾默,y大于y\_懲罰為2*(y-y_{\_}),那么如下代碼可以實現(xiàn)該損失函數(shù)

v1 = tf.constant([2.0, 3, 4])  ##value
v2 = tf.constant([2.4, 2.5, 5]) ##label
loss = tf.reduce_sum(tf.where(tf.greater(v1, v2), (v1-v2)*2, (v2-v1)*3))
  1. 引入正則項Regularizer
    如果引入正則項\lambda\|w\|_2^2捉貌,其中w是訓(xùn)練參數(shù)支鸡,可以使用如下代碼
loss_with_regularizer=loss+tf.contrib.layers.l2_regularizer(lambda)(w)
  1. 使用collection來構(gòu)建帶正則項的損失函數(shù)
    在簡單的神經(jīng)網(wǎng)絡(luò)中,3中的方式就可以很好滴計算正則化的損失函數(shù)了趁窃,但是當(dāng)神經(jīng)網(wǎng)絡(luò)的層數(shù)增多時牧挣,每一層都會有一個w,這樣方式就可能導(dǎo)致loss的定義很長醒陆,可讀性差瀑构。更主要的是,當(dāng)網(wǎng)絡(luò)結(jié)構(gòu)復(fù)雜之后定義網(wǎng)絡(luò)結(jié)構(gòu)的部分和計算損失函數(shù)的的部分可能不在同一個函數(shù)中刨摩,這樣通過變量這種方式來計算損失函數(shù)就不方便了寺晌。為了解決這個問題,可以使用TensorFlow提供的集合(collection)澡刹。
import tensorflow as tf

def get_weight(shape, lambda):
    var = tf.Variable(tf.random_normal(shape), dtype=tf.float32)
    tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(lambda)(var))
    return var

x = tf.placeholder(tf.float32, shape=[None, 2])
y_ = tf.placeholder(tf.float32, shape=[None, 1])
batch_size = 8
layer_dimension = [2, 10, 10, 10, 1]
n_layers = len(layer_dimension)

cur_layer = x
in_dimension = layer_dimension[0]

for i in range(1, n_layers):
    out_dimension = layer_dimension[I]
    weight = get_weight([in_dimension, outdimension], 0.001)
    bias = tf.Variable(tf.constant(0.1, shape=[out_dimension]))
    cur_layer = tf.nn.relu(tf.matmul(cur_layer, weight) + bias)
    in_dimension = layer_dimension[I]

mes_loss= tf.reduce_mean(tf.square(y_-cur_layer))
tf.add_to_collection('losses', mes_loss)
loss = tf.add_n(tf.get_collection('losses'))

訓(xùn)練: 優(yōu)化算法

在前面已經(jīng)定義了網(wǎng)絡(luò)結(jié)構(gòu)和輸出的損失函數(shù)呻征,現(xiàn)在的目標(biāo)是希望通過迭代來逐漸更新參數(shù)來減小損失函數(shù)。在深度學(xué)習(xí)中最常用的優(yōu)化算法是隨機梯度下降(SGD)罢浇,但其有一些變種陆赋,比如說Nesterov和Momenta,另外步長的調(diào)節(jié)也有講究嚷闭,也有一些自適應(yīng)步長算法如ADAM和RMSProp算法攒岛。值得慶幸的是,常用的優(yōu)化器tensorflow都提供了api凌受,而且傳入損失函數(shù)能夠?qū)崿F(xiàn)自動求導(dǎo)(自動進(jìn)行反向傳播算法)阵子。本節(jié)先介紹如何使用內(nèi)置的優(yōu)化算法思杯,自定義的優(yōu)化算法(如果有空)將在后續(xù)研究介紹胜蛉。tf.train里面包括很多優(yōu)化器挠进,其中Optimizer是一個基類,在此之上定義了很多個優(yōu)化器

基類Optimizer (learning rate, ...params)
GradientDescentOptimizer
AdagradOptimizer
AdagradDAOptimizer
MomentumOptimizer
AdamOptimizer
FtrlOptimizer
RMSPropOptimizer

  • 定義衰減學(xué)習(xí)率
decayed_learning_rate =\
learning_rate*decay_rate^(global_step/deca_steps)

也可以使用tf.train自帶的指數(shù)衰減步長

global_step = tf.Variable(0, trainable=False)
learning_rate = tf.train.exponential_decay(0.1, global_step, 100, 0.96, staircase = True)
  • 進(jìn)行一次訓(xùn)練迭代
learning_step = tf.train.GradientDescentOptimizer(learning_rate)\
.minimize(...my loss..., global_step = global_step)

滑動平均模型

ExponentialMovingEverage誊册,通過引入影子變量领突,使得在開始的時候鼓勵模型更新,而在之后不鼓勵更新案怯,防止噪聲干擾君旦。具體應(yīng)用見下一節(jié)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末嘲碱,一起剝皮案震驚了整個濱河市金砍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌麦锯,老刑警劉巖恕稠,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異扶欣,居然都是意外死亡鹅巍,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進(jìn)店門料祠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來骆捧,“玉大人,你說我怎么就攤上這事髓绽×参” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵顺呕,是天一觀的道長接谨。 經(jīng)常有香客問我,道長塘匣,這世上最難降的妖魔是什么脓豪? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮忌卤,結(jié)果婚禮上扫夜,老公的妹妹穿的比我還像新娘。我一直安慰自己驰徊,他們只是感情好笤闯,可當(dāng)我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著棍厂,像睡著了一般颗味。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上牺弹,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天浦马,我揣著相機與錄音时呀,去河邊找鬼。 笑死晶默,一個胖子當(dāng)著我的面吹牛谨娜,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播磺陡,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼趴梢,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了币他?” 一聲冷哼從身側(cè)響起坞靶,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蝴悉,沒想到半個月后滩愁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡辫封,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年硝枉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片倦微。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡妻味,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出欣福,到底是詐尸還是另有隱情责球,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布拓劝,位于F島的核電站雏逾,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏郑临。R本人自食惡果不足惜栖博,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望厢洞。 院中可真熱鬧仇让,春花似錦、人聲如沸躺翻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽公你。三九已至踊淳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間陕靠,已是汗流浹背迂尝。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工脱茉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人雹舀。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓芦劣,卻偏偏與公主長得像粗俱,于是被迫代替她去往敵國和親说榆。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容