Tensorflow2.1基礎知識---緩解過擬合

  1. 欠擬合和過擬合
    過擬合和欠擬合是導致模型泛化能力不高的兩種原因,都是模型學習能力與數據複雜度之間失配的 結果。

    1. 欠擬合:是在模型學習能力較弱,而數據複雜度較高的情況出現,此時模型由於學習能力不足,無 法學習到數據集中的“一般規律”,因而導致泛化能力弱。
    2. 過擬合:是在模型學習能力過強的情況中出現,此時的模型學習能力太強,以至於將訓練單個樣本 自身的特定都能捕捉到,並將其認爲是“一般規律”,因而導致模型泛化能力下降
    3. 各自優缺點
      欠擬合在訓練集和測試集上的性能都較差,而過擬合往往能較好地學習訓練集數據地性質,而在測試集上地性能較差。
      在這裏插入圖片描述
  2. 欠擬合和過擬合解決辦法

    1. 欠擬合的解決辦法:
    	a. 增加輸入特徵項
    	b. 增減網絡
    	c. 減少正則化參數
    2. 過擬合解決辦法:
    	a. 數據清洗
    	b. 增大訓練集
    	c. 採用正則化
    	d. 增大正則化參數
    
  3. 正則化緩解過擬合
    正則化在損失函數中引入模型複雜度指標,利用給w加權值,弱化了訓練數據的噪聲(一般不正則化b)
    在這裏插入圖片描述
    正則化的選擇:
    1. L1正則化大概率會使很多參數變爲0,因此該方法可通過稀疏參數,即減少參數的數量,降低複雜度
    2. L2正則化會使參數很接近零但不爲零,因此該方法可通過減小參數值的大小降低複雜度

  4. 案例:

    	#導入所需模塊
    	import tensorflow as tf
    	from matplotlib import pyplot as plt
    	import numpy as np
    	import pandas as pd
    	
    	#讀入數據/標籤 生成x_train y_train
    	df = pd.read_csv('dot.csv')
    	x_data = np.array(df[['x1','x2']])
    	y_data = np.array(df['y_c'])
    	
    	x_train = np.vstack(x_data).reshape(-1,2)
    	y_train = np.vstack(y_data).reshape(-1,1)
    	
    	Y_c = [['red' if y else 'blue'] for y in y_train]
    	
    	#轉換x的數據類型,否則後面矩陣相乘時會因數據類型問題報錯
    	x_train = tf.cast(x_train,tf.float32)
    	y_train = tf.cast(y_train,tf.float32)
    	
    	#from_tensor_slices函數切分傳入張量的第一個維度,生成相應的數據集,使輸入特徵和標籤值一一對應
    	train_db = tf.data.Dataset.from_tensor_slices((x_train,y_train)).batch(32)
    	
    	#生成神經網絡參數,輸入層爲兩個神經單元,隱藏層爲11個神經元,1層隱藏層,輸出層爲1個神經元
    	w1 = tf.Variable(tf.random.normal([2,11]),dtype=tf.float32)
    	b1 = tf.Variable(tf.constant(0.01, shape=[11]))
    	w2 = tf.Variable(tf.random.normal([11,1]),dtype=tf.float32)
    	b2 = tf.Variable(tf.constant(0.01, shape=[1]))
    	
    	lr = 0.01 #學習率
    	epoch = 400 #循環次數
    	
    	#訓練部分
    	for epoch in range(epoch):
    	    for step,(x_train,y_train) in enumerate(train_db):
    	        with tf.GradientTape() as tape:  #記錄梯度信息
    	            
    	            h1 = tf.matmul(x_train,w1) + b1  #記錄神經網絡乘加運算
    	            h1 = tf.nn.relu(h1)
    	            y = tf.matmul(h1,w2) + b2
    	            
    	            #採用均方誤差損失函數mse = mean(sum(y-out)^2)
    	            loss_mse = tf.reduce_mean(tf.square(y_train - y))
    	            
    	            #添加l2正則化
    	            loss_regularization = []
    	            #tf.nn.l2_loss(w) = sum(w ** 2) / 2
    	            loss_regularization.append(tf.nn.l2_loss(w1))
    	            loss_regularization.append(tf.nn.l2_loss(w2))
    	            loss_regularization = tf.reduce_sum(loss_regularization)
    	            loss = loss_mse + 0.03 * loss_regularization  #REGULARIZER = 0.03
    	        #計算loss對各個參數的梯度
    	        variables = [w1,b1,w2,b2]
    	        grads = tape.gradient(loss,variables)
    	        
    	        #實現梯度更新
    	        #w1 = w1 - lr * w1_grad   tape.gradient是自動求導結果與[w1,b1,w2,b2] 索引爲0,1,2,3
    	        w1.assign_sub(lr * grads[0])
    	        b1.assign_sub(lr * grads[1])
    	        w2.assign_sub(lr * grads[2])
    	        b2.assign_sub(lr * grads[3])
    	    
    	    #每20個epoch,打印loss信息
    	    if epoch % 20 == 0:
    	        print('epoch:',epoch,'loss:',float(loss))
    	        
    	#預測部分
    	print("**************predict*************")
    	#xx在 -3到3之間步長爲0.01,yy在-3到3之間步長0.01,生成間隔數值點
    	xx,yy = np.mgrid[-3:3:.1,-3:3:.1]
    	
    	#將xx,yy拉直,併合並配對爲二維張量,生成二維座標點
    	grid = np.c_[xx.ravel(),yy.ravel()]
    	grid = tf.cast(grid,tf.float32)
    	#將網絡座標點喂入神經網絡,進行預測,probs爲輸出
    	probs = []
    	for x_test in grid:
    	    #使用訓練好的參數進行預測
    	    h1 = tf.matmul([x_test],w1) + b1
    	    h1 = tf.nn.relu(h1)
    	    y = tf.matmul(h1,w2) + b2 #y爲預測結果
    	    probs.append(y)
    	
    	#取第0列給x1,取第一列給x2
    	x1 = x_data[:,0]
    	x2 = x_data[:,1]
    	#probs的shape調整成xx的樣子
    	probs = np.array(probs).reshape(xx.shape)
    	#畫座標爲x1,x2的散點圖,顏色爲color   squeeze去掉維度是1的維度,相當於[['red'],['blue']],內層括號變爲['red','blue']
    	plt.scatter(x1,x2,color = np.squeeze(Y_c))
    	#把座標xx yy和對應的值probs放入contour函數,給probs值爲0.5的所有點上色  plt點show後 顯示的是紅藍點的分界線
    	plt.contour(xx,yy,probs,levels=[.5])
    	plt.show()
    
    
  5. 正則化和沒有正則化的效果對比
    在這裏插入圖片描述

下面的是筆者的微信公衆號,歡迎關注,會持續更新c++、python、tensorflow、機器學習、深度學習等系列文章

                    在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章