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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

【深度学习】(2) 数据加载,前向传播2,附python完整代码

發布時間:2023/11/27 生活经验 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【深度学习】(2) 数据加载,前向传播2,附python完整代码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

生成數據集:?tf.data.Dataset.from_tensor_slices(tensor變量)

創建一個數據集,其元素是給定張量的切片

生成迭代器:?next(iter())

next() 返回迭代器的下一個項目,iter()獲取可迭代對象的迭代器

# 返回2項數據,圖像x_test,目標y_test
db = tf.data.Dataset.from_tensor_slices((x_test,y_test))
# 迭代器得到的第0個元素是圖像,第1個元素是目標
next(iter(db))[0].shape  # TensorShape([32, 32, 3])
next(iter(db))[1].shape  # TensorShape([])

重新洗牌: .shuffle(buffer_size)

將序列的所有元素隨機排序,不打散x和y之間的相互對應關系。維持一個buffer_size大小的緩存,每次都會隨機在這個緩存區抽取一定數量的數據

調用函數: .map(func)

將func函數作用于dataset中的每一個元素

def preprocess(x,y):x = tf.cast(x, dtype=tf.float32)/255y = tf.cast(y, dtype=tf.int32)y = tf.one_hot(y,depth=10)return(x,y)
# 對Dataset中的數據進行函數所指定的預處理操作
db2 = db.map(preprocess)
# 生成迭代器
res = next(iter(db2))
# 查看數據
print(res[0].shape,res[1])

生成對列: .batch(batch_size)

tensor隊列生成器,作用是按照給定的tensor順序,把batch_size個tensor推送到文件隊列,作為訓練一個batch的數據,等待tensor出隊執行計算

#(5).batch 一次讀取讀取n張圖片
db3 = db2.batch(32) # 每次讀取32張圖片
res = next(iter(db3)) # 生成迭代器,每次取出32張
print(res[0].shape,res[1].shape) #res[0]代表圖像數據,res[1]代表目標
# (32, 32, 32, 3) (32, 10)

重復迭代: .repeat(count)

將數據重復count次,相當于我們訓練時的epoch

db = tf.data.Dataset.from_tensor_slices((x_test,y_test))
db = db.repeat(2) # 迭代兩次
db = db.repeat() # 永遠不會退出

實例展示

只需要對訓練數據y進行one-hot編碼,因為訓練集的y要和網絡輸出結果求損失。網絡輸出層得到的是每張圖片屬于每個分類的概率,是一個二維tensor,因此訓練集的y也需要是一個二維tensor,才能做比較。而在測試過程中。預測出的結果是一個值,該圖片屬于哪個,真實值y_test也是一個值,只需要比較兩個值是不是相同即可,不需要one-hot編碼。

#(1)加載數據集,(x,y)存放訓練數據,(x_test,y_test)存放測試數據
(x,y),(x_test,y_test) = datasets.fashion_mnist.load_data()
# 查看數據集信息
print('x-min:',x.min(),' x-max:',x.max(),' x-mean',x.mean())
print('x-shape:',x.shape,'\ny-shape:',y.shape)
print('x_test-shape:',x_test.shape,'\ny_test-shape:',y_test.shape)
print('y[:4]:',y[:4])  # 查看前4個y值#(2)定義預處理函數
y = tf.one_hot(y,depth=10)  # one-hot編碼,轉換成長度為10的向量,對應索引的值變為1def processing(x,y):x = tf.cast(x,tf.float32)/255.0  # x數據改變數據類型,并歸一化y = tf.cast(y,tf.int32)  # 對目標y改變數據類型return(x,y)#(3)生成訓練集的Dataset
ds = tf.data.Dataset.from_tensor_slices((x,y))
# 對訓練數據預處理
ds = ds.map(processing)
# 重新洗牌,每次迭代讀取100張圖片
ds = ds.shuffle(1000).batch(100)#(4)生成測試集的Dataset
ds_tes = tf.data.Dataset.from_tensor_slices((x_test,y_test))
# 測試數據預處理
ds_tes = ds_tes.map(processing)
# 洗牌、確定batch
ds_tes = ds_tes.shuffle(1000).batch(100)

2. 前向傳播

在上一節中我們完成了對訓練數據的前向傳播操作,接下來加入測試數據從第(9)步開始。

上一節內容:【深度學習】(1) 前向傳播,附python完整代碼

# 前向傳播
import numpy as np
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import datasets # 數據集工具
import os  # 設置一下輸出框打印的內容
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' # '2'輸出欄只打印error信息,其他亂七八糟的信息不打印#(1)獲取mnist數據集
(x,y),(x_test,y_test) = datasets.mnist.load_data() #(2)轉換成tensor類型,x數據類型一般為float32,y存放的是圖片屬于哪種具體類型,屬于整型
x = tf.convert_to_tensor(x,dtype=tf.float32)/255.0
y = tf.convert_to_tensor(y,dtype=tf.int32)x_test = tf.convert_to_tensor(x_test,dtype=tf.float32)/255.0
y_test = tf.convert_to_tensor(y_test,dtype=tf.int32)#(3)查看數據內容
print('shape:',x.shape,y.shape,'\ndtype:',x.dtype,y.dtype)  #查看shape和數據類型
print('x的最小值:',tf.reduce_min(x),'\nx的最大值:',tf.reduce_max(x))  #查看x的數據范圍
print('y的最小值:',tf.reduce_min(y),'\ny的最大值:',tf.reduce_max(y))  #查看y的數據范圍#(4)預處理
y = tf.one_hot(y,depth=10) # 對訓練數據的目標集的數值編碼,變為長度為10的向量,對應索引的值變為1
lr = 1e-3 # 指定學習率#(5)指定一個選取數據的batch,一次取128個數據
train_db = tf.data.Dataset.from_tensor_slices((x,y)).batch(128)
test_db = tf.data.Dataset.from_tensor_slices((x_test,y_test)).batch(128)#(6)構建網絡
# 構建網絡,自定義中間層的神經元個數
# [b,784] => [b,256] => [b,128] => [b,10]# 第一個連接層的權重和偏置,都變成tf.Variable類型,這樣tf.GradientTape才能記錄梯度信息
w1 = tf.Variable(tf.random.truncated_normal([784,256], stddev=0.1)) # 截斷正態分布,標準差調小一點防止梯度爆炸
b1 = tf.Variable(tf.zeros([256])) #維度為[dim_out]
# 第二個連接層的權重和偏置
w2 = tf.Variable(tf.random.truncated_normal([256,128], stddev=0.1)) # 截斷正態分布,維度為[dim_in, dim_out]
b2 = tf.Variable(tf.zeros([128])) #維度為[dim_out]
# 第三個連接層的權重和偏置
w3 = tf.Variable(tf.random.truncated_normal([128,10], stddev=0.1)) # 截斷正態分布,維度為[dim_in, dim_out]
b3 = tf.Variable(tf.zeros([10])) #維度為[dim_out]#(7)前向傳播運算
for i in range(50):  #對整個數據集迭代10次# 對數據集的所有batch迭代一次# x為輸入的特征項,shape為[128,28,28],y為分類結果,shape為[128]for step,(x,y) in enumerate(train_db): # 返回下標和對應的值# 這里的x的shape為[b,28*28],從[b,w,h]變成[b,w*h]x = tf.reshape(x,[-1,28*28]) #對輸入特征項的維度變換,-1會自動計算bwith tf.GradientTape() as tape: # 自動求導計算梯度,只會跟蹤tf.Variable類型數據# ==1== 從輸入層到隱含層1的計算方法為:h1 = w1 @ x1 + b1   # [b,784] @ [784,256] + [b,256] = [b,256]h1 = x @ w1 + b1  # 相加時會自動廣播,改變b的shape,自動進行tf.broadcast_to(b1,[x.shape[0],256])# 激活函數,relu函數h1 = tf.nn.relu(h1)# ==2== 從隱含層1到隱含層2,[b,256] @ [256,128] + [b,128] = [b,128]h2 = h1 @ w2 + b2h2 = tf.nn.relu(h2)# ==3== 從隱含層2到輸出層,[b,128] @ [128,10] + [b,10] = [b,10]out = h2 @ w3 + b3 # shape為[b,10]#(8)計算誤差,輸出值out的shape為[b,10],onehot編碼后真實值y的shape為[b,10]# 計算均方差 mse = mean(sum((y-out)^2)loss_square = tf.square(y-out)  # shape為[b,10]loss = tf.reduce_mean(loss_square) # 得到一個標量# 梯度計算grads = tape.gradient(loss,[w1,b1,w2,b2,w3,b3])# 權重更新,lr為學習率,梯度每次下降多少# 注意:下面的方法,運算返回值是tf.tensor類型,在下一次運算會出現錯誤# w1 = w1 - lr * grads[0] # 返回的w1在grad的第0個元素# 因此需要原地更新函數,保證更新后的數據類型不變tf.Variablew1.assign_sub(lr * grads[0])b1.assign_sub(lr * grads[1])    w2.assign_sub(lr * grads[2])  b2.assign_sub(lr * grads[3]) w3.assign_sub(lr * grads[4])    b3.assign_sub(lr * grads[5]) if step % 100 == 0: #每100次顯示一次數據print(f"第{step+1}次迭代,loss為{np.float(loss)}") #loss是tensor變量# loss為nan,出現梯度爆炸的情況,初始化權重的時候變小一點#(9)網絡測試# total_correct統計預測對了的個數,total_num統計參與測試的個數total_correct, total_num = 0, 0# 對網絡測試,test必須要使用當前階段的權重w和偏置b,測試當前階段的計算精度for step,(x,y) in enumerate(test_db):x = tf.reshape(x,[-1,28*28])# 對測試數據進行前向傳播# 輸入層[b,784] => [b,256] => [b,128] => 輸出層[b,10]h1 = x @ w1 + b1 # 輸入特征和第一層權重做內積,結果加上偏置h1 = tf.nn.relu(h1) # 計算后的結果放入激活函數中計算,得到下一層的輸入# 隱含層1=>隱含層2h2 = tf.nn.relu(h1 @ w2 + b2)  # [b,256] => [b,128]# 隱含層2=>輸出層out = h2 @ w3 + b3  # [b,128] => 輸出層[b,10]#(10)輸出概率計算# 計算概率,out:shape為[b,10],屬于實數;prob:shape為[b,10],屬于[0,1]之間# 使用softmax()函數,使實數out映射到[0,1]的范圍prob = tf.nn.softmax(out,axis=1) # out是二維的,在第1個軸上映射,即把某張圖片屬于某個類的值變成概率# 概率最大的值所在的位置索引是預測結果,即屬于第幾個分類predict = tf.argmax(prob, axis=1,output_type=tf.int32) # 每張圖片的概率最大值所在位置,shape[b,10],10所在的維度# 測試集的y不需要轉換成one-hot,真實值y是一個數值,predict也是一個數值,兩兩相比較correct = tf.equal(predict, y) # 比較,返回布爾類型,相同為True,不同為Falsecorrect = tf.cast(correct,dtype=tf.int32) # 將布爾類型轉換為int32類型correct = tf.reduce_sum(correct) # 每次取出的batch中,有多少張圖片是預測對的# 1代表預測對了,0代表預測錯了total_correct += int(correct)  # 統計對的個數,correct是tensor類型total_num += x.shape[0]  # 統計一共有多少組參與測試,x.shape=[128,28*28],x.shape[0]有128張圖片# 數據集整體完成一次迭代后accuracy = total_correct / total_num # 計算每一輪循環的準確率print(f'accuracy={accuracy}')

迭代50輪,結果如下。優化方法,在下一節討論。

第50個循環
第1次迭代,loss為0.04710124433040619
第101次迭代,loss為0.05284833908081055
第201次迭代,loss為0.050228558480739594
第301次迭代,loss為0.052753616124391556
第401次迭代,loss為0.05572255700826645
accuracy=0.7847

總結

以上是生活随笔為你收集整理的【深度学习】(2) 数据加载,前向传播2,附python完整代码的全部內容,希望文章能夠幫你解決所遇到的問題。

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