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

歡迎訪問 生活随笔!

生活随笔

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

生活经验

【深度学习】(7) 交叉验证、正则化,自定义网络案例:图片分类,附python完整代码

發布時間:2023/11/27 生活经验 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【深度学习】(7) 交叉验证、正则化,自定义网络案例:图片分类,附python完整代码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

各位同學好,今天和大家分享一下TensorFlow2.0深度學習中的交叉驗證法正則化方法,最后展示一下自定義網絡的小案例。


1. 交叉驗證

交叉驗證主要防止模型過于復雜而引起的過擬合找到使模型泛化能力最優的參數。我們將數據劃分為訓練集、驗證集、測試集。訓練集用于輸入網絡模型作為樣本進行學習。驗證集是在迭代過程中對模型進行評估,尋找最優解。測試集是在整個網絡訓練完成后進行評估。

K折交叉驗證,就是將訓練集數據等比例劃分成K份,以其中的1份作為驗證數據其他的K-1份數據作為訓練數據。每次迭代從都是從K個部分選取一份不同的數據部分作為測試數據,剩下的K-1個當作訓練數據,最后把得到的K個實驗結果進行平分。

?

?


劃分方法?

(1)構造數據集時劃分

首先導入訓練集(x,y)和測試集(x_test, y_test),K折交叉驗證是對測試集的劃分,指定迭代500次,每次迭代都從訓練集中選出一部分作為驗證數據ds_val,剩下的作為訓練數據ds_train。使用tf.random.shuffle() 隨機打亂索引順序,不影響x和y之間的對應關系。tf.gather()根據索引來選取值。

# 以手寫數字為例,獲取訓練集和測試集
(x,y),(x_test,y_test) = datasets.mnist.load_data()# 預處理函數
def processing(x,y): # 從[0,255]=>[-1,1]x = 2 * tf.cast(x, dtype=tf.float32) / 255.0 - 1y = tf.cast(y, dtype=tf.int32)return(x,y)# 交叉驗證K=500
for epoch in range(500):idx = tf.range(60000) # 假設training數據一共有60k張圖象,生成索引idx = tf.random.shuffle(idx) # 隨機打亂索引# 利用隨機打散的索引來收集數據,不改變xy之間的關聯x_train, y_train = tf.gather(x, idx[:50000]), tf.gather(y, idx[:50000])x_val, y_val = tf.ga,ther(x, idx[-10000:]), tf.gather(y, idx[-10000:])# 構建訓練集ds_train = tf.data.Dataset.from_tensor_slices((x_train, y_train))  # 自動將輸入的xy轉變成tenosr類型ds_train = ds_train.map(processing).shuffle(10000).batch(128) # 對數據集中的所有數據使用預處理函數# 構建驗證集ds_val = tf.data.Dataset.from_tensor_slices((x_val, y_val))  ds_val = ds_test.map(processing).batch(128) # 每次迭代取128組數據,驗證不需要打亂數據

(2)使用訓練函數fit()中的參數劃分

如果嫌使用上面的方法構造數據集太麻煩的話,可以在模型訓練函數fit()中指定劃分方式validation_split=0.1,每次迭代取0.1倍的訓練數據作為驗證集,剩下的作為訓練集。ds_train_val?要求是沒有被劃分過的訓練集數據。這樣的話就不需要再指定validation_data驗證集數據了,在劃分時自動生成。

# ds_train_val指沒有劃分過的train和val數據集,validation_split=0.1動態切割,0.1比例的數據分給val
network.fit(ds_train_val, epochs=6, validation_split=0.1, validation_freq=2)
# 不需要再指定validation_data,已經在被包含在validation_split中了

在模型迭代過程中使用驗證集來查看什么時候模型效果最優,找到最優的就跳出循環。驗證集在挑選模型參數的時候,先保存誤差極小值對應的權重,如果后面檢測到的誤差都大于它,就使用當前這個權重。

?


2. 正則化

當采用比較復雜的模型,去擬合數據時,很容易出現過擬合現象,這會導致模型的泛化能力下降,對模型添加正則化項可以限制模型的復雜度,使得模型在復雜度和性能達到平衡。

原理:?【通俗易懂】機器學習中 L1 和 L2 正則化的直觀解釋

?

L1正則化是在原來的損失函數基礎上加上權重參數的絕對值。L1可以產生0解,L1獲得稀疏解。

L2正則化是在原來的損失函數基礎上加上權重參數的平方和。L2可以產生趨近0的解,L2獲得非零稠密解。


在構建網絡層時指定正則化參數kernel_regularizer,使用二范數的方法keras.regularizers.l2,懲罰系數0.01。

# 使用二范數正則化,loss = loss + 0.001*regularizer,指定正則化的權重
model = keras.Sequential([keras.layers.Dense(16, kernel_regularizer=keras.regularizers.l2(0.001), activation=tf.nn.relu),keras.layers.Dense(16, kernel_regularizer=keras.regularizers.l2(0.001), activation=tf.nn.relu),keras.layers.Dense(1, activation=tf.nn.sigmoid)])

3. 自定義網絡

3.1 數據獲取

首先導入我們需要的庫文件,從系統中導入圖片數據,劃分測試集和訓練集。

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import datasets, layers, optimizers, Sequential, metrics
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' # 輸出框只輸出有意義的信息#(1)數據獲取
(x,y),(x_test,y_test) = datasets.cifar10.load_data() #獲取圖像分類數據
# 查看數據信息
print(f'x.shape: {x.shape}, y.shape: {y.shape}')  #查看訓練集的維度信息
print(f'x_test.shape: {x_test.shape}, y_test.shape: {y_test.shape}')  #測試集未讀信息
print(f'y[:5]: {y[:5]}')  #查看訓練集目標的前5項
# 繪圖展示
import matplotlib.pyplot as plt
for i in range(10): # 展示前10張圖片plt.subplot(2,5,i+1)  # 2行5列第i+1個位置plt.imshow(x[i])plt.xticks([]) # 不顯示x和y軸坐標刻度plt.yticks([])# 輸入的圖像形狀
# x.shape: (50000, 32, 32, 3), y.shape: (50000, 1)
# x_test.shape: (10000, 32, 32, 3), y_test.shape: (10000, 1)

需要訓練的圖片如下,圖片本身不清晰,這里只說一下基本的自定義網絡的構造,最多只有80%準確率,模型優化到卷積神經網絡章節再談。

?


3.2 數據預處理

由于導入的目標值y的shape時二維[50k,1],需要將axis=1的軸壓縮掉,變成一個一維的向量[50k],使用tf.squeeze()壓縮指定軸,對目標值one-hot編碼對應索引的值變為1,其他索引對應的值變為0,shape變為[b,10]。把特征值x的范圍映射到[-1,1]之間。

#(2)數據預處理
# 定義預處理函數
def processing(x,y): # 由于目標數據是而二維的,把shape=1的軸刪除,從向量變成標量y = tf.squeeze(y)  # 默認壓縮所有維度為1的軸,shape為[50k]y = tf.one_hot(y, depth=10) # one-hot編碼,分成10個類別,shape為[50k,10],對應下標所在的值為1# 每個像素值的范圍在[-1,1]之間,從[0,255]=>[-1,1]x = 2 * tf.cast(x, dtype=tf.float32) / 255.0 - 1y = tf.cast(y, dtype=tf.int32)return(x,y)# 構建訓練集數據集
ds_train = tf.data.Dataset.from_tensor_slices((x, y))  # 自動將輸入的xy轉變成tenosr類型
ds_train = ds_train.map(processing).batch(128).shuffle(10000)  # 對數據集中的所有數據使用預處理函數# 構建測試集數據集
ds_test = tf.data.Dataset.from_tensor_slices((x_test, y_test))  
ds_test = ds_test.map(processing).batch(128) # 每次迭代取128組數據,測試不需要打亂數據# 構造迭代器,查看數據集是否正確
sample = next(iter(ds_train))  # 每次運行從訓練數據集中取出一組xy
print('x_batch.shape', sample[0].shape, 'y_batch.shape', sample[1].shape)
# x_batch.shape (128, 32, 32, 3)   y_batch.shape (128, 10)

3.3 自定義網絡

#(3)構造網絡
class MyDense(layers.Layer): #必須繼承layers.Layer層,放到sequential容器中# 代替layers.Dense層def __init__(self, input_dim, output_dim):super(MyDense, self).__init__()   # 調用母類初始化,必須# 自己發揮'w''b'指定名字沒什么用,創建shape為[input_dim, output_dim的權重# 使用add_variable創建變量        self.kernel = self.add_variable('w',[input_dim, output_dim])self.bias = self.add_variable('b', [output_dim])# call方法,training來指示現在是訓練還是測試         def call(self, inputs, training=None):x = inputs @ self.kernel + self.biasreturn x# 自定義網絡層
class MyNetwork(keras.Model):  # 必須繼承keras.Model大類,才能使用complie、fit等功能def __init__(self):super(MyNetwork, self).__init__()  # 調用父類Mymodel# 新建五個層次self.fc1 = MyDense(32*32*3, 256)  #input_dim=784,output_dim=256self.fc2 = MyDense(256, 128)self.fc3 = MyDense(128, 64)self.fc4 = MyDense(64, 32)        self.fc5 = MyDense(32, 10)def call(self, inputs, training=None):# 前向傳播,可以接收四維的tensorx = tf.reshape(inputs, [-1,32*32*3]) # 改變輸入特征的形狀x = self.fc1(x) #第一層[b,32*32*3]==>[b,256]x = tf.nn.relu(x) #激活函數x = self.fc2(x)x = tf.nn.relu(x)x = self.fc3(x)x = tf.nn.relu(x)x = self.fc4(x)x = tf.nn.relu(x)x = self.fc5(x)  #logits層return x

3.4 網絡配置

#(4)網絡配置
network = MyNetwork()       
network.compile(optimizer = optimizers.Adam(lr=0.001),  # 指定優化器loss = tf.losses.CategoricalCrossentropy(from_logits=True), #交叉熵損失metrics = ['accuracy'])  # 測試指標     #(5)網絡訓練,輸入訓練數據,循環5次,驗證集為ds_test,每一次大循環做一次測試
network.fit(ds_train, epochs=5, validation_data=ds_test, validation_freq=1)# 循環5次后的結果為
Epoch 5/5
391/391 [==============================] - 3s 8ms/step - loss: 1.2197 - accuracy: 0.5707 - val_loss: 1.3929 - val_accuracy: 0.5182

優化方法到卷積神經網絡再展示

總結

以上是生活随笔為你收集整理的【深度学习】(7) 交叉验证、正则化,自定义网络案例:图片分类,附python完整代码的全部內容,希望文章能夠幫你解決所遇到的問題。

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