日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【TensorFlow】笔记2:深层神经网络

發布時間:2025/3/19 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【TensorFlow】笔记2:深层神经网络 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、深度學習 vs 深層神經網絡

深度學習:一類通過多層非線性變換對高復雜性數據建模算法的集合。

1、激活函數

線性模型的最大特點:任意線性模型的組合仍是線性模型,能夠解決的問題也是有限的,這就是線性模型最大的局限。

==》解決方法:激活函數實現去線性化
如果將前面提到的加權和節點后(注意:添加偏置項)通過一個非線性函數,那么神經網絡模型就是非線性的了。這個非線性函數就是激活函數(activation)

常用激活函數:

  • ReLU函數—— tf.nn.relu
  • sigmoid函數——tf.nn.sigmoid
  • tanh函數——tf.nn.tanh

    使用激活函數和偏置項的前向傳播。
# 前向傳播 a = tf.nn.relu(tf.matmul(x, w1) + biases1) y = tf.nn.relu(tf.matmul(a, w2) + biases2)

2、多層網絡解決異或運算

二、損失函數

1、經典損失函數

(1)分類問題

交叉熵:兩個概率分布之間的距離,廣泛用于分類問題中。交叉熵是信息論中概念,原本用于估算平均編碼的長度。

公式:
對于給定兩個概率分布 pppqqq,通過 qqq 來表示 ppp 的交叉熵為:
H(p,q)=?∑xp(x)logq(x)H(p,q)=-\sum_{x}p(x)log\ q(x)H(p,q)=?x?p(x)log?q(x)
注意:交叉熵不是對稱的,H(p,q)≠H(q,p)H(p,q)\neq H(q,p)H(p,q)??=H(q,p),交叉熵刻畫通過通過概率分布 qqq 來表示 ppp 的困難程度。所以, qqq 表示預測結果, ppp 表示ground-truth。
交叉熵刻畫的是兩個概率分布的距離,然而神經網絡的輸出不一定是一個概率分布(任意事件發生的概率都在0和1之間,且概率總和為1)。Softmax回歸是一個常用的將前向傳播結果變成概率分布的方法。

Softmax回歸本身可以作為一個學習算法來優化分類結果,但在tf中,Softmax回歸的參數被去掉了,只作為一個額外的處理層,將輸出變成一個概率分布
softmax(y)i=yi′=eyi∑j=1neyisoftmax(y)_i=y_i^\prime=\frac{e^{yi}}{\sum_{j=1}^{n}e^{yi}}softmax(y)i?=yi?=j=1n?eyieyi?

交叉熵代碼實現

cross_entropy = -tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y, 1e-10, 1.0)))

因為交叉熵一般與Softmax回歸一起使用,tf提供了 tf.nn.softmax_cross_entropy_with_logits 函數:

cross_entropy = tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y)

(2)回歸問題

回歸問題目標:具體數值的預測問題。

均方誤差(MSE, mean squared error)

公式:
MSE(y,y′)=∑i=1n(yi?yi′)2nMSE(y, y')=\frac{\sum_{i=1}^{n}(y_i-y_i')^2}{n}MSE(y,y)=ni=1n?(yi??yi?)2?
其中,yiy_iyi? 為一個 batch 中第 i 個數據的正確答案,yi′y_i'yi? 為預測值

tf 實現:

mse = tf.reduce_mean(tf.square(y_ - y))

2、自定義損失函數

為了讓神經網絡優化的結果更加接近實際問題,我們需要自定義損失函數。

比如商品銷量問題,如果預測值較大(大于真實銷量),商家損失生產商品的成本。如果預測值較小,損失商品的利潤。因為一般成本和利潤不相同,使用均方誤差不能夠很好地最大化利潤。比如成本是1元,利潤是10元,那么模型應該偏向預測值較大。下面的公式給出了預測值多于或少于真實值時有不同系數的損失函數,通過這個損失函數,模型可能最大化收益。
Loss(y,y′)=∑i=1nf(yi,yi′),f(x,y)={a(x?y),if?x>yb(y?x),if?x≤yLoss(y,y')=\sum_{i=1}^{n}f(y_i,y_i'),f(x,y)=\begin{cases} a(x-y), & \text{if $x>y$} \\ b(y-x), & \text{if $x\leq y$ } \end{cases} Loss(y,y)=i=1n?f(yi?,yi?),f(x,y)={a(x?y),b(y?x),?if?x>yif?xy??
注意:損失函數定義的是損失,所以要將利潤最大化,定義的損失函數應該刻畫成本或代價。

tf 實現

loss = tf.reduce_sum(tf.where(tf.greater(v1, v2), (v1 - v2) * a, (v2 - v1) * b))

整體代碼

import tensorflow as tf from numpy.random import RandomStatebatch_size = 8# 兩個輸入節點,一個輸出節點 x = tf.placeholder(tf.float32, shape=(None, 2), name='x-input') y_ = tf.placeholder(tf.float32, shape=(None, 1), name='y-input')w1 = tf.Variable(tf.random_normal([2, 1], stddev=1, seed=1)) y = tf.matmul(x, w1)# 定義預測多了的成本和預測少了的成本 loss_less = 10 loss_more = 1 loss = tf.reduce_mean(tf.where(tf.greater(y, y_), (y - y_) * loss_more, (y_ - y) * loss_less))train_step = tf.train.AdamOptimizer(0.001).minimize(loss)# 隨機數生成一個模擬數據集 rdm = RandomState(1) dataset_size = 128X = rdm.rand(dataset_size, 2) Y = [[x1 + x2 + rdm.rand()/10.0 - 0.05] for (x1, x2) in X]with tf.Session() as sess:init_op = tf.global_variables_initializer()sess.run(init_op)STEPS = 5000for i in range(STEPS):start = (i * batch_size) % dataset_sizeend = min(start + batch_size, dataset_size)sess.run(train_step, feed_dict={x: X[start: end], y_: Y[start: end]})print(sess.run(w1))

輸出

2019-03-09 15:21:02.100189: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA 2019-03-09 15:21:02.193850: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:897] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero 2019-03-09 15:21:02.194763: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1405] Found device 0 with properties: name: GeForce GTX 1060 major: 6 minor: 1 memoryClockRate(GHz): 1.6705 pciBusID: 0000:01:00.0 totalMemory: 5.94GiB freeMemory: 5.37GiB 2019-03-09 15:21:02.194798: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1484] Adding visible gpu devices: 0 2019-03-09 15:21:02.422253: I tensorflow/core/common_runtime/gpu/gpu_device.cc:965] Device interconnect StreamExecutor with strength 1 edge matrix: 2019-03-09 15:21:02.422279: I tensorflow/core/common_runtime/gpu/gpu_device.cc:971] 0 2019-03-09 15:21:02.422285: I tensorflow/core/common_runtime/gpu/gpu_device.cc:984] 0: N 2019-03-09 15:21:02.422603: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1097] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 5139 MB memory) -> physical GPU (device: 0, name: GeForce GTX 1060, pci bus id: 0000:01:00.0, compute capability: 6.1) [[1.0193471][1.0428091]]

三、神經網絡優化算法

關鍵:通過反向傳播算法(backpropagation)和梯度下降算法(Gradient Decent)調整神經網絡中的參數。梯度下降算法主要用于優化單個參數的取值,而反向傳播算法給出了一個高效的方式在所有參數上使用梯度下降算法。

1、優化過程

  • 前向傳播階段:通過前向傳播算法計算得到預測值,并計算損失函數。
  • 反向傳播階段:計算損失函數對每一個參數的梯度,再根據梯度和學習率使用梯度下降算法更新每一個參數。更新公式如下:
    θn+1=θn?η??θnJ(θn)\theta_{n+1}=\theta_n-\eta\frac{\partial}{\partial\theta_n}J(\theta_n)θn+1?=θn??η?θn???J(θn?)
    其中,θ\thetaθ 表示需要更新的參數,?\partial? 表示學習率,J(θn)J(\theta_n)J(θn?) 表示損失函數值

2、幾個概念

  • 學習率
  • 局部最優
  • 隨機梯度下降
  • mini-batch梯度下降:不會比單個數據慢太多,同時可以大大減小收斂所需的迭代次數,使得收斂到的結果更加接近梯度下降的效果。

3、神經網絡訓練模式

import tensorflow as tfbatch_size = nx = tf.placeholder(tf.float32, shape=(None, 2), name='x-input') y_ = tf.placeholder(tf.float32, shape=(None, 1), name='y-input')# 定義損失函數和優化算法 loss = ... train_step = tf.train.AdamOptimizer(0.001).minimize(loss)# 訓練神經網絡 with tf.Session() as sess:# 初始化參數...# 迭代參數更新for i in range(STEPS):current_X, current_Y = ...sess.run(train_step, feed_dict={x: current_X, y_: current_Y})

四、進一步優化

1、學習率設置

通過指數縮減的方法設置梯度下降算法中的學習率,在 tf 中使用 tf.train.exponential_decay 函數實現。先使用較大的學習率快速得到一個比較優的解,隨著迭代的繼續逐步減少學習率,使得模型在訓練后期更加穩定。它實現了以下代碼的功能:

decayed_learning_rate = learning_rate * decay_rate * decay_rate ^ (global_step / decay_steps)

其中,decayed_learning_rate 為每一輪優化時使用的學習率,learning_rate 為設定的初始學習率,decay_rate 為衰減系數,decay_steps 為衰減速度。

tf.train.exponential_decay 可以通過設置參數staircase 選擇不同的衰減方式,默認為 False,此時學習率衰減趨勢如下圖灰色曲線。當設置為 True 時,global_step/decay_steps 會被轉化成整數,使得學習率成為一個階梯函數,如黑色曲線。在這樣的設置下,decay_steps 通常代表完整使用一遍訓練數據所需要的迭代輪數,也就是總訓練數據/一個batch的樣本數。這樣可以使得總訓練數據中的每一個batch都使用相同的學習率,對模型產生相等的作用。當完整過完一遍訓練數據時,學習率就減少一次。

tf 實現

import tensorflow as tfglobal_step = tf.Variable(0)# 通過exponential_decay函數生成學習率 learning_rate = tf.train.exponential_decay(0.1, grobal_step, 100, 0.96, staircase=True)# 使用指數衰減的學習率。在minimize中傳入global_step參數,從而更新學習率 learning_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step)

2、過擬合問題

(1)正則化

正則化的思想是在損失函數中加入刻畫模型復雜程度的指標。所以一般優化的損失函數為 J(θ)+λR(w)J(\theta)+\lambda R(w)J(θ)+λR(w)。一般來說模型復雜度只由權重w決定,和偏置b無關。

常用正則化

  • L1正則化
    R(w)=∣∣w∣∣1=∑i∣wi∣R(w)=||w||_1=\sum_{i}|w_i|R(w)=w1?=i?wi?
  • L2正則化
    R(w)=∣∣w∣∣2=∑i∣wi2∣R(w)=||w||_2=\sum_{i}|w_i^2|R(w)=w2?=i?wi2?
  • 同時使用L1正則化和L2正則化
    R(w)=∣∣w∣∣2=∑iα∣wi∣+(2?α)wi2R(w)=||w||_2=\sum_{i}\alpha|w_i|+(2-\alpha)w_i^2R(w)=w2?=i?αwi?+(2?α)wi2?

L1正則化 會讓參數變得更稀疏,可達到類似特征選擇功能;而 L2正則 不會。其次,L1正則 的計算公式不可導,L2正則 可導。因為優化時需要計算損失函數的偏導數,所以對 L2正則 損失函數的優化要更加簡潔。優化 L1正則 更加復雜,而且優化方法也有很多種。

TF 實現
帶 L2 正則項的損失函數

w = tf.Variable(tf.random_normal([2, 1], stddev=1, seed=1) y = tf.matmul(x, w)# 損失函數包括:均方誤差損失函數 + 正則化項 ## lambda參數表示正則化的權重,w為需要計算正則化損失的參數 loss = tf.reduce_mean(tf.square(y_ - y)) + tf.contrib.layers.l2_regularizer(lambda)(w)
  • tf.contrib.layers.l2_regularizer:計算給定參數的L2正則化項的值;
  • tf.contrib.layers.l1_regularizer:計算L1正則化項的值。
weights = tf.constant([[1.0, -2.0], [-3.0, 4.0]]) with tf.Session() as sess:# 輸出為(|1|+|-2|+|3|+|-4|)*0.5=5. 其中0.5為正則項的權重print(sess.run(tf.contrib.layers.l1_regularizer(0.5)(weights))# 輸出為(1^2+(-2)^2+3^2+(-4)^2)/2*0.5=7.5。 其中0.5為正則項的權重print(sess.run(tf.contrib.layers.l2_regularizer(0.5)(weights))

當網絡結構復雜后,利用集合(collection)計算損失函數。eg:計算一個 5 層神經網絡帶 L2 正則化的損失函數計算方法。

import tensorflow as tf# 獲取一層神經網絡邊上的權重,并將這個權重的L2正則化損失加入“losses”的集合中 def get_weight(shape, lambda1):# 生成一個變量var = tf.Variable(tf.random_normal(shape), dtype=tf.float32)# add_to_collection函數將這個新生成變量的L2正則化損失項加入集合# 第一個參數:losses是集合的名字,第二個參數:要加入集合的內容tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(lambda1)(var))return varx = 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]# 通過一個循環來生成5層的FC層 for i in range(1, n_layers):# layer_dimension[i] 為下一層的節點個數out_dimension = layer_dimension[i]# 生成當前層中權重的變量,并將這個變量的L2正則化損失加入計算圖上的集合weight = get_weight([in_dimension, out_dimension], 0.001)bias = tf.Variable(tf.constant(0.1, shape=[out_dimension]))# ReLU activation functioncur_layer = tf.nn.relu(tf.matmul(cur_layer, weight) + bias)# 進入下一層之前將下一層的節點個數更新為當前層節點的個數in_dimension = layer_dimension[i]# 定義前向傳播的同時已經將所有的L2正則化損失加入圖上的集合 # 這里只需要計算刻畫模型在訓練數據上表現的損失函數 mse_loss = tf.reduce_mean(tf.square(y_ - cur_layer))# 將均方誤差損失加入到損失集合 tf.add_to_collection('losses', mse_loss)# get_collection 返回一個列表,該列表是所有這個集合中的元素。 # 在樣例中,這些元素就是損失函數的不同部分,將它們加起來就可以得到最終的損失函數 loss = tf.add_n(tf.get_collection('losses'))

3、滑動平均模型

作用:在使用隨機梯度下降算法訓練網絡時,可以使模型在測試數據上更健壯(robust)。

tf 的實現:tf.train.ExponentialMovingAverage

參數:

  • 衰減率(decay):該參數用于控制模型更新的速度。ExponentialMovingAverage 對每一個變量會維護一個影子變量(shadow_variable),這個影子變量的初始值就是相應變量的初始值,而每次運行變量更新時,影子變量的值會更新為:
    shadow_variable=decay×shadow_variable+(1?decay)×variableshadow\_variable=decay\times shadow\_variable + (1-decay)\times variableshadow_variable=decay×shadow_variable+(1?decay)×variable
    其中,shadow_variable為影子變量,variable為待更新的變量,decay為衰減率,衰減率越大模型越穩定。實際中,decay一般會設置非常接近1(eg: 0.999或0.9999)。

  • num_updates參數:為了在訓練的前期更新得更快,通過設置num_updates參數來動態設置decay的大小。若初始化時提供num_updates參數,則衰減率為:
    min{decay,1+num_updates10+1+num_updates}min\{decay,\frac{1+num\_updates}{10+1+num\_updates}\}min{decay,10+1+num_updates1+num_updates?}

TF實現

import tensorflow as tf# 定義一個變量用于計算滑動平均,初始值為實數型的0 v1 = tf.Variable(0, dtype=tf.float32) # step 變量模擬神經網絡中迭代的輪數,可以用于控制衰減率 step = tf.Variable(0, trainable = False)# 定義一個滑動平均的類。初始化:衰減率(0.99)和控制衰減率的變量 step ema = tf.train.ExponentialMovingAverage(0.99, step) # 定義一個更新變量滑動平均的操作。 # 這里需要給定一個列表,每次執行這個操作時,這個列表中的變量都會被更新 maintain_averages_op = ema.apply([v1]) with tf.Session() as sess:# 初始化所有變量init_op = tf.global_variables_initializer()sess.run(init_op)# 通過ema.average(v1)獲取滑動平均之后變量的取值。# 在初始化之后變量v1的值和v1的滑動平均都是0print(sess.run([v1, ema.average(v1)]))# output: [0.0, 0.0]# 更新變量v1的值到5sess.run(tf.assign(v1, 5))# 更新變量v1的值到5# 更新v1的滑動平均值。衰減率為min{0.99, (1+step)/(10+step)=0.1}=0.1,# 所以v1的滑動平均被更新為0.1*0+0.9*5=4.5sess.run(maintain_averages_op)print(sess.run([v1, ema.average(v1)]))# output: [5.0, 4.5]# 更新變量step的值到10000sess.run(tf.assign(step, 10000))# 更新變量v1的值到10sess.run(tf.assign(v1, 10))# 更新v1的滑動平均值。衰減率為min{0.99, (1+step)/(10+step)}=0.99,# 所以v1的滑動平均被更新為0.99*4.5+0.01*10=4.555sess.run(maintain_averages_op)print(sess.run([v1, ema.average(v1)]))# output: [10.0, 4.5549998]# 再次更新滑動平均值,得到的新滑動平均值為0.99*4.555+0.01*10 = 4.60945sess.run(maintain_averages_op)print(sess.run([v1, ema.average(v1)]))# Output: [10.0, 4.6094499]

輸出結果

2019-03-13 22:50:23.313337: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA 2019-03-13 22:50:23.444235: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:897] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero 2019-03-13 22:50:23.445227: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1405] Found device 0 with properties: name: GeForce GTX 1060 major: 6 minor: 1 memoryClockRate(GHz): 1.6705 pciBusID: 0000:01:00.0 totalMemory: 5.94GiB freeMemory: 5.38GiB 2019-03-13 22:50:23.445260: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1484] Adding visible gpu devices: 0 2019-03-13 22:50:24.216058: I tensorflow/core/common_runtime/gpu/gpu_device.cc:965] Device interconnect StreamExecutor with strength 1 edge matrix: 2019-03-13 22:50:24.216088: I tensorflow/core/common_runtime/gpu/gpu_device.cc:971] 0 2019-03-13 22:50:24.216096: I tensorflow/core/common_runtime/gpu/gpu_device.cc:984] 0: N 2019-03-13 22:50:24.216673: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1097] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 5150 MB memory) -> physical GPU (device: 0, name: GeForce GTX 1060, pci bus id: 0000:01:00.0, compute capability: 6.1) [0.0, 0.0] [5.0, 4.5] [10.0, 4.555] [10.0, 4.60945] [Finished in 4.9s]

總結

以上是生活随笔為你收集整理的【TensorFlow】笔记2:深层神经网络的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。