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

歡迎訪問 生活随笔!

生活随笔

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

生活经验

深度学习--TensorFlow(7)拟合(过拟合处理)(数据增强、提前停止训练、dropout、正则化、标签平滑)

發布時間:2023/11/27 生活经验 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深度学习--TensorFlow(7)拟合(过拟合处理)(数据增强、提前停止训练、dropout、正则化、标签平滑) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

擬合

1、擬合情況

2、抵抗過擬合方法

過擬合處理(防止過擬合):

一、數據增強

1、設置圖像生成器

2、載入圖片

3、圖像轉三維數據

4、三維轉四維

5、生成圖片(用圖像生成器)

代碼

二、提前停止訓練(Early-Stopping)

1、設置回調函數(設置提前停止訓練)

2、訓練(應用回調函數)

代碼

三、Dropout

1、搭建神經網絡進行對比

1-1、普通神經網絡

1-2、dropout神經網絡

2、訓練

3、畫圖

代碼

四、正則化

1、L1正則化

2、L2正則化

步驟:

1、神經網絡中添加正則化操作

2、編譯

3、訓練

代碼

五、標簽平滑

1、在損失函數中定義平滑系數

2、編譯

3、訓練

代碼


擬合

1、擬合情況

擬合分為三種情況:欠擬合、正確擬合、過擬合

訓練集中:?

訓練集中,過擬合的效果最好。

測試集中:

不難看出,測試集中是正確擬合的效果最好。

總結:過擬合雖然在訓練集中的效果非常好,但是一旦到了測試集,效果就不如正確擬合好

????????模型復雜度在深度學習中主要指的是網絡的層數以及每層網絡神經元的各種,網絡的層

數越多越復雜,神經元的個數越多越復雜。

????????訓練集的誤差是隨著模型復雜度的提升而不斷降低的,測試集的誤差是隨著模型復雜度的提升而先下降后上升。

2、抵抗過擬合方法

增大數據集 提前停止(Early-Stopping) Dropout 正則化 標簽平滑(label Smoothing)

下面講解一些過擬合處理方法:

過擬合處理(防止過擬合):

一、數據增強

圖像領域數據增強常用方式:

1、旋轉/反射變換:隨機旋轉圖像一定的角度,改變圖像朝向。

2、翻轉變換:沿水平方向或豎直方向翻轉圖像。

3、縮放變換:按照一定的比例放大或縮小圖像。

4、平移變換:在圖像平面上對圖像以一定方式平移。

5、尺度變換:對圖像按照一定的尺度因子,進行放大或縮小。

6、對比度變換:在圖像的HSV色彩空間中,保持色調H不變,改變飽和度S和亮度V,對每個像素的S和V分量進行指數運算。

7、噪聲擾動:對圖像的每個RGB隨機噪聲擾動。(噪聲有:椒鹽噪聲、高斯噪聲)

8、顏色變換:對圖像的顏色進行一些有規律地調整。

?

步驟:

1、設置圖像生成器

# 1、設置圖像生成器
datagen = ImageDataGenerator(rotation_range = 40,            # 隨機旋轉度數width_shift_range = 0.2,        # 隨機水平平移height_shift_range = 0.2,       # 隨機豎直平移rescale = 1/255,                # 數據歸一化shear_range = 30,               # 隨機錯切變換zoom_range = 0.2,               # 隨機放大horizontal_flip = True,         # 水平翻轉brightness_range = (0.7,1.3),   # 亮度變化fill_mode = 'nearest',)         # 填充方式

2、載入圖片

# 2、載入圖片
img = load_img('Resource/test11.jpg')

3、圖像轉三維數據

# 3、圖像轉三維數據(array:3維(height,width,channel))
img = img_to_array(img)

4、三維轉四維

# 4、三維轉四維(然后再做數據增強)
# 在第 0 個位置增加一個維度
# 4 維(1,height,width,channel)
img = np.expand_dims(img,0)

5、生成圖片(用圖像生成器)

# 5、生成20張圖片
i = 0       # 生成的圖片都保存在 images 文件夾中,文件名前綴為 new_image,圖片格式為 jpeg
for batch in datagen.flow(img, batch_size=1, save_to_dir='images', save_prefix='new_image', save_format='jpeg'):i += 1if i==20:break

?得到這一系列的圖像。

代碼

# 圖像數據增強
# 注:需要提前有一個文件夾(比如這里設置文件夾名為images,則需要提前準備一個images文件夾)
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'from tensorflow.keras.preprocessing.image import ImageDataGenerator,img_to_array, load_img
import numpy as np# 1、設置圖像生成器
datagen = ImageDataGenerator(rotation_range = 40,            # 隨機旋轉度數width_shift_range = 0.2,        # 隨機水平平移height_shift_range = 0.2,       # 隨機豎直平移rescale = 1/255,                # 數據歸一化shear_range = 30,               # 隨機錯切變換zoom_range = 0.2,               # 隨機放大horizontal_flip = True,         # 水平翻轉brightness_range = (0.7,1.3),   # 亮度變化fill_mode = 'nearest',         # 填充方式
)# 2、載入圖片
img = load_img('Resource/test11.jpg')# 3、圖像轉三維數據(array:3維(height,width,channel))
img = img_to_array(img)# 4、三維轉四維(然后再做數據增強)
# 在第 0 個位置增加一個維度        4維:(1,height,width,channel)
img = np.expand_dims(img,0)# 5、生成20張圖片
i = 0       # 生成的圖片都保存在 images 文件夾中,文件名前綴為 new_image,圖片格式為 jpeg
for batch in datagen.flow(img, batch_size=1, save_to_dir='images', save_prefix='new_image', save_format='jpeg'):i += 1if i==20:break

二、提前停止訓練(Early-Stopping)

Early-Stopping 是一種提前結束訓練的策略用來防止過擬合。 ????????訓練效果不會隨著迭代次數的增加無限提高記錄到目前為止最好的測試集準確率 p,之后連續 m 個周期沒有超過最佳測試集準確率 p 時,則可以認為 p 不再提高了,此時便可以提前停止迭代(Early-Stopping)。

1、設置回調函數(設置提前停止訓練)

????????設置val_accuracy為監測對象,記錄每次的值,超過5次未超過之前的最佳值,則提前停止訓練(早退)。

# 6、設置回調函數(提前停止訓練)
early_stopping = EarlyStopping(monitor='val_accuracy', patience=5, verbose=1)
# monitor='val_accuracy':監控驗證集準確率
# patience=5:連續5個周期沒有超過最高的val_accuracy值,則提前停止訓練
# verbose=1:停止訓練時提示 early stopping

2、訓練(應用回調函數)

# 7、訓練(應用回調函數)
model.fit(train_data, train_label, epochs=100, batch_size=32, validation_data=(test_data, test_label),
callbacks=[early_stopping])
# 回調函數(提前停止訓練)

效果:

?

代碼

# 提前停止訓練(Early_Callback)
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'import tensorflow as tf
from tensorflow.keras.optimizers import SGD
from tensorflow.keras.callbacks import EarlyStopping# 1、載入數據集
mnist = tf.keras.datasets.mnist
(train_data, train_label), (test_data, test_label) = mnist.load_data()# 2、歸一化處理(有助于提升模型訓練速度)
train_data, test_data = train_data / 255.0, test_data / 255.0# 3、獨熱編碼
train_label = tf.keras.utils.to_categorical(train_label,num_classes=10)
test_label = tf.keras.utils.to_categorical(test_label,num_classes=10) # 模型定義# 4、搭建神經網絡
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),  #數據壓縮(三維->二維:(60000,28,28)->(60000,784)
tf.keras.layers.Dense(10, activation='softmax')
])# 5、設置優化器、損失函數、標簽
model.compile(optimizer=SGD(0.5), loss='mse', metrics=['accuracy'])
# EarlyStopping 是 Callbacks 的一種,callbacks用于指定在每個epoch或batch開始和結束的時候進行哪種特定操作# 6、設置回調函數(提前停止訓練)
early_stopping = EarlyStopping(monitor='val_accuracy', patience=5, verbose=1)
# monitor='val_accuracy':監控驗證集準確率
# patience=5:連續5個周期沒有超過最高的val_accuracy值,則提前停止訓練
# verbose=1:停止訓練時提示 early stopping# 7、訓練(應用回調函數)
model.fit(train_data, train_label, epochs=100, batch_size=32, validation_data=(test_data, test_label),
callbacks=[early_stopping])
# 回調函數(提前停止訓練)

三、Dropout

Dropout 也是一種用于抵抗過擬合的技術,它試圖改變網絡本身來對網絡進行優化 Dropout 通常是在神經網絡隱藏層的部分使用,使用的時候會臨時關閉掉一部分的神經 ,我們可以通過一個參數來控制神經元被關閉的概率每一次都隨機選擇部分的神經元參與訓練

1、搭建神經網絡進行對比

1-1、普通神經網絡

# 4、搭建神經網絡(normal)
model = Sequential([
Flatten(input_shape=(28, 28)),
Dense(units=200,activation='tanh'),
Dense(units=100,activation='tanh'),
Dense(units=10,activation='softmax')
])

1-2、dropout神經網絡

# 4、搭建神經網絡(Dropout)
model_dropout = Sequential([
Flatten(input_shape=(28, 28)),
Dense(units=200,activation='tanh'),
Dropout(0.4),
Dense(units=100,activation='tanh'),
Dropout(0.4),
Dense(units=10,activation='softmax')
])

2、訓練

# 6、訓練
# 先訓練正常模型
history1 = model.fit(train_data, train_target, epochs=30, batch_size=32, validation_data=(test_data, test_target))# 再訓練Dropout模型
history2 = model_dropout.fit(train_data, train_target, epochs=30, batch_size=32, validation_data=(test_data, test_target))

3、畫圖

# 7、畫圖
# 畫出 model1 驗證集準確率曲線圖
plt.plot(np.arange(30), normal_history.history['val_accuracy'], c='b', label='normal')
plt.plot(np.arange(30), dropout_history.history['val_accuracy'], c='y', label='dropout')
#       橫坐標(0~30)     獲取訓練結果                               顏色    標簽
plt.legend()# x 坐標描述
plt.xlabel('epochs')
# y 坐標描述
plt.ylabel('accuracy')# 顯示圖像
plt.show()

normal:

?dropout:

????????可以發現dropout的測試集正確率甚至比正確率還要高,這是因為:模型在訓練的時候使用了dropout,但是在測試集的時候沒有使用dropout。

? ? ? ? 這里訓練的次數比較少,如果訓練更多的次數,那么dropout的測試集準確率將達到98.8%,比normal的測試集準確率還要高(98,2%)

代碼

# Dropout
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense,Dropout,Flatten
from tensorflow.keras.optimizers import SGD
import matplotlib.pyplot as plt
import numpy as np# 1、載入數據集
mnist = tf.keras.datasets.mnist
(train_data, train_target), (test_data, test_target) = mnist.load_data()# 2、歸一化處理(有助于提升模型訓練速度)
train_data, test_data = train_data / 255.0, test_data / 255.0# 3、獨熱編碼
train_target = tf.keras.utils.to_categorical(train_target,num_classes=10)
test_target = tf.keras.utils.to_categorical(test_target,num_classes=10) # 模型定義,model1 使用 Dropout
# Dropout(0.4)表示隱藏層 40%神經元不工作# 4、搭建神經網絡(normal)
model = Sequential([
Flatten(input_shape=(28, 28)),
Dense(units=200,activation='tanh'),
Dense(units=100,activation='tanh'),
Dense(units=10,activation='softmax')
])# 4、搭建神經網絡(Dropout)
model_dropout = Sequential([
Flatten(input_shape=(28, 28)),
Dense(units=200,activation='tanh'),
Dropout(0.4),
Dense(units=100,activation='tanh'),
Dropout(0.4),
Dense(units=10,activation='softmax')
])# 5、設置優化器、損失、標簽
model.compile(optimizer=SGD(0.2), loss='categorical_crossentropy', metrics=['accuracy'])
model_dropout.compile(optimizer=SGD(0.2), loss='categorical_crossentropy', metrics=['accuracy'])# 6、訓練
# 先訓練正常模型
normal_history = model.fit(train_data, train_target, epochs=30, batch_size=32, validation_data=(test_data, test_target))# 再訓練Dropout模型
dropout_history = model_dropout.fit(train_data, train_target, epochs=30, batch_size=32, validation_data=(test_data, test_target))# 7、畫圖
# 畫出 model1 驗證集準確率曲線圖
plt.plot(np.arange(30), normal_history.history['val_accuracy'], c='b', label='normal')
plt.plot(np.arange(30), dropout_history.history['val_accuracy'], c='y', label='dropout')
#       橫坐標(0~30)     獲取訓練結果                               顏色    標簽
plt.legend()# x 坐標描述
plt.xlabel('epochs')
# y 坐標描述
plt.ylabel('accuracy')# 顯示圖像
plt.show()

四、正則化

????????L1 和 L2 正則化的使用實際上就是在普通的代價函數(例如均方差代價函數或交叉熵代價函數)后面加上一個正則項最小化正則項的值,實際上就是讓w的值接近于0

1、L1正則化

????????L1 正則項會使得神經網絡中的很多權值參數變為 0,如果神經網絡中很多的權值都是 0 的 話那么可以認為網絡的復雜度降低了,擬合能力也降低了,因此不容易出現過擬合的情況。

加上了L1正則項的交叉熵:

2、L2正則化

????????L2正則項會使得神經網絡的權值衰減,權值參數變為接近于 0 的值,注意這里的接近于 0 不是等于零,L2 正則化很少會使權值參數等于 0。

當w變得很小之后,wx+b的計算會變成一個接近0的值:

? ? ? ? ?正則化使得神經網絡中增加了很多線性特征,減少了很多非線性特征,網絡復雜度降低,所以不容易出現過擬合

步驟:

1、神經網絡中添加正則化操作

設置L2正則化,正則化系數:0.0003。?

# 4、神經網絡(正則化:正則化系數:0.0003)
model_l2 = Sequential([
Flatten(input_shape=(28, 28)),
Dense(units=200,activation='tanh',kernel_regularizer=l2(0.0003)),
Dense(units=100,activation='tanh',kernel_regularizer=l2(0.0003)),
Dense(units=10,activation='softmax',kernel_regularizer=l2(0.0003))
])

2、編譯

# 5、設置優化器、損失函數、標簽
model_l2.compile(optimizer=SGD(0.2), loss='categorical_crossentropy', metrics=['accuracy'])
model.compile(optimizer=SGD(0.2), loss='categorical_crossentropy', metrics=['accuracy'])
# categorical_crossentropy:交叉熵損失函數

3、訓練

# 6、訓練
# 先訓練 model_l2
history_l2 = model_l2.fit(train_data, train_target, epochs=30, batch_size=32, validation_data=(test_data,test_target))
# 再訓練 model
history = model.fit(train_data, train_target, epochs=30, batch_size=32, validation_data=(test_data,test_target))

效果:

正常:

L2正則化:

代碼

# L2正則化
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense,Dropout,Flatten
from tensorflow.keras.optimizers import SGD
import matplotlib.pyplot as plt
import numpy as np
# 使用 l1 或 l2 正則化
from tensorflow.keras.regularizers import l1,l2# 1、載入數據
mnist = tf.keras.datasets.mnist
(train_data, train_target), (test_data, test_target) = mnist.load_data()# 2、歸一化處理(有助于提升模型訓練速度)
train_data, test_data = train_data / 255.0, test_data / 255.0# 3、獨熱編碼
train_target = tf.keras.utils.to_categorical(train_target,num_classes=10)
test_target = tf.keras.utils.to_categorical(test_target,num_classes=10) # 模型定義,model_l2 使用 l2 正則化 # l2(0.0003)表示使用 l2 正則化,正則化系數為 0.0003# 4、神經網絡(正則化:正則化系數:0.0003)
model_l2 = Sequential([
Flatten(input_shape=(28, 28)),
Dense(units=200,activation='tanh',kernel_regularizer=l2(0.0003)),
Dense(units=100,activation='tanh',kernel_regularizer=l2(0.0003)),
Dense(units=10,activation='softmax',kernel_regularizer=l2(0.0003))
])# 神經網絡(正常,無正則化)
model = Sequential([
Flatten(input_shape=(28, 28)),
Dense(units=200,activation='tanh'),
Dense(units=100,activation='tanh'),
Dense(units=10,activation='softmax')
])# 5、設置優化器、損失函數、標簽
model_l2.compile(optimizer=SGD(0.2), loss='categorical_crossentropy', metrics=['accuracy'])
model.compile(optimizer=SGD(0.2), loss='categorical_crossentropy', metrics=['accuracy'])
# categorical_crossentropy:交叉熵損失函數# 6、訓練
# 先訓練 model_l2
history_l2 = model_l2.fit(train_data, train_target, epochs=30, batch_size=32, validation_data=(test_data,test_target))
# 再訓練 model
history = model.fit(train_data, train_target, epochs=30, batch_size=32, validation_data=(test_data,test_target))# 7、畫圖
plt.plot(np.arange(30),history_l2.history['val_accuracy'], c='b',label='L2 Regularization') # 畫出 model 驗證集準確率曲線圖
plt.plot(np.arange(30),history.history['val_accuracy'], c='y',label='FC') # 圖例
plt.legend()# x 坐標描述
plt.xlabel('epochs')
# y 坐標描述
plt.ylabel('accuracy')
# 顯示圖像
plt.show()

五、標簽平滑

標簽平滑(LSR):也稱為標簽平滑正則化。?

????????我們在做分類模型的時候通常會把標簽變成獨熱編碼(one-hot),但是變成獨熱編碼的標簽在模型訓練時會使得模型變得“極度自信”,容易產生過擬合

例:

????????這個數字你能說它 100%就是 6 嗎,不一定吧,它也有點像 2,說不定還是 1 或者 7 只不 過手滑了。所以讓模型非常自信的認為圖中的數字就是 6,獨熱編碼(0,0,0,0,0,0,1,0,0,0),不 一定是合適的。可能把它的標簽改成(0,0.02,0.2,0.01,0.01,0.01,0.7,0.03,0.01,0.01)會比較好 一點。 ????????在 MNIST 數據集里面實際上確實有一些數字會寫得比較奇怪,讓人也很難分辨,其它數 據集也會有類似的問題,所以讓模型“過度自信”就不一定是好事了。

?

1、在損失函數中定義平滑系數

# 定義交叉熵函數(設置平滑系數)
loss = CategoricalCrossentropy(label_smoothing=0)
loss_smooth = CategoricalCrossentropy(label_smoothing=0.1)
# label_smoothing:平滑系數

2、編譯

# 編譯
model.compile(optimizer=SGD(0.2), loss=loss, metrics=['accuracy'])
model_smooth.compile(optimizer=SGD(0.2), loss=loss_smooth, metrics=['accuracy'])

3、訓練

# 6、訓練
# 先訓練 model
history = model.fit(train_data, train_target, epochs=12, batch_size=32, validation_data=(test_data,test_target))
# 再訓練 model_smooth
history_smooth = model_smooth.fit(train_data, train_target, epochs=12, batch_size=32, validation_data=(test_data,test_target))

效果:?

?

代碼

# 標簽平滑
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense,Dropout,Flatten
from tensorflow.keras.optimizers import SGD
from tensorflow.keras.losses import CategoricalCrossentropy
import matplotlib.pyplot as plt
import numpy as np# 1、載入數據
mnist = tf.keras.datasets.mnist
(train_data, train_target), (test_data, test_target) = mnist.load_data()# 2、歸一化處理(有助于提升模型訓練速度)
train_data, test_data = train_data / 255.0, test_data / 255.0# 3、獨熱編碼
train_target = tf.keras.utils.to_categorical(train_target,num_classes=10)
test_target = tf.keras.utils.to_categorical(test_target,num_classes=10) # 模型定義,model 不用 label smoothing# 4、神經網絡(普通)
model = Sequential([Flatten(input_shape=(28, 28)),Dense(units=200,activation='tanh'),Dense(units=100,activation='tanh'),Dense(units=10,activation='softmax')
])# 神經網絡(標簽平滑)
model_smooth = Sequential([
Flatten(input_shape=(28, 28)),
Dense(units=200,activation='tanh'),
Dense(units=100,activation='tanh'),
Dense(units=10,activation='softmax')
])# 5、編譯
# 定義交叉熵函數(設置平滑系數)
loss = CategoricalCrossentropy(label_smoothing=0)
loss_smooth = CategoricalCrossentropy(label_smoothing=0.1)
# label_smoothing:平滑系數
# 編譯
model.compile(optimizer=SGD(0.2), loss=loss, metrics=['accuracy'])
model_smooth.compile(optimizer=SGD(0.2), loss=loss_smooth, metrics=['accuracy'])# 6、訓練
# 先訓練 model
history = model.fit(train_data, train_target, epochs=12, batch_size=32, validation_data=(test_data,test_target))
# 再訓練 model_smooth
history_smooth = model_smooth.fit(train_data, train_target, epochs=12, batch_size=32, validation_data=(test_data,test_target))# 7、畫圖
plt.plot(np.arange(12),history.history['val_accuracy'],c='b',label='without LSR') # 畫出 model_smooth 驗證集準確率曲線圖
plt.plot(np.arange(12),history_smooth.history['val_accuracy'],c='y',label='LSR') # 圖例
plt.legend()
# x 坐標描述
plt.xlabel('epochs')
# y 坐標描述
plt.ylabel('accuracy')
# 顯示圖像
plt.show()

總結

以上是生活随笔為你收集整理的深度学习--TensorFlow(7)拟合(过拟合处理)(数据增强、提前停止训练、dropout、正则化、标签平滑)的全部內容,希望文章能夠幫你解決所遇到的問題。

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