深度學習_15_過擬合欠擬合

過擬合和欠擬合
在這里插入圖片描述
過擬合和欠擬合是訓練模型中常會發生的事,如所要識別手勢過于復雜,如五角星手勢,那就需要更改高級更復雜的模型去訓練,若用比較簡單模型去訓練,就會導致模型未能抓住手勢的全部特征,那簡單模型估計只能抓住五角星的其中一個角做特征,那么這個簡單模型很可能就會將三角形與五角星混淆,這就是所謂欠擬合

若用識別五角星的復雜模型去識別三角形也是不行的,模型會過擬合,即學習了過多不重要的部分,可能會把三角形每條邊所畫的時間也當作學習的內容,即便我們人知道什么時候畫哪條邊都無所謂。

過擬合和欠擬合的表現都是模型的識別精度不夠,所以要想判斷模型是過擬合還是欠擬合,除了理論還是要多調試

如:
在這里插入圖片描述
合適的模型應該是拋物線,上述左邊是欠擬合,右邊是過擬合

在這里插入圖片描述
訓練集和測試集

值得注意的是訓練集和測試集必須是分開的,訓練模型用訓練集,一定不能讓測試集污染模型

模型過擬的特征即對見過的數據集表現非常好,而對從未見過的模型表現非常差,若不把訓練,測試集完全分開,最后的模型過擬合將無法被發現

實例:

完整代碼:

import math
import torch
from torch import nn
from d2l import torch as d2l
import matplotlib.pyplot as plt# 生成隨機的數據集
max_degree = 20  # 多項式的最大階數
n_train, n_test = 100, 100  # 訓練和測試數據集大小
true_w = torch.zeros(max_degree)
true_w[0:4] = torch.Tensor([5, 1.2, -3.4, 5.6])# 生成特征
features = torch.randn((n_train + n_test, 1))
permutation_indices = torch.randperm(features.size(0))
# 使用隨機排列的索引來打亂features張量(原地修改)
features = features[permutation_indices]
poly_features = torch.pow(features, torch.arange(max_degree).reshape(1, -1))
for i in range(max_degree):poly_features[:, i] /= math.gamma(i + 1)# 生成標簽
labels = torch.matmul(poly_features, true_w)
labels += torch.normal(0, 0.1, size=labels.shape)# 以下是你原來的訓練函數,沒有修改
def evaluate_loss(net, data_iter, loss):metric = d2l.Accumulator(2)for X, y in data_iter:out = net(X)y = y.reshape(out.shape)l = loss(out, y)metric.add(l.sum(), l.numel())return metric[0] / metric[1]def train(train_features, test_features, train_labels, test_labels,num_epochs=400):loss = nn.MSELoss()input_shape = train_features.shape[-1]net = nn.Sequential(nn.Linear(input_shape, 1, bias=False))batch_size = min(10, train_labels.shape[0])train_iter = d2l.load_array((train_features, train_labels.reshape(-1, 1)),batch_size)test_iter = d2l.load_array((test_features, test_labels.reshape(-1, 1)),batch_size, is_train=False)trainer = torch.optim.SGD(net.parameters(), lr=0.01)# 用于存儲訓練和測試損失的列表train_losses = []test_losses = []for epoch in range(num_epochs):train_loss, train_acc = d2l.train_epoch_ch3(net, train_iter, loss, trainer)test_loss = evaluate_loss(net, test_iter, loss)# 將當前的損失值添加到列表中train_losses.append(train_loss)test_losses.append(test_loss)print(f"Epoch {epoch + 1}/{num_epochs}:")print(f"  訓練損失: {train_loss:.4f}, 測試損失: {test_loss:.4f}")print(net[0].weight)# 假設 train_losses 和 test_losses 是已經計算出的損失值列表plt.figure(figsize=(10, 6))plt.plot(train_losses, label='train', color='blue', linestyle='-', marker='.')plt.plot(test_losses, label='test', color='purple', linestyle='--', marker='.')plt.xlabel('epoch')plt.ylabel('loss')plt.title('Loss over Epochs')plt.legend()plt.grid(True)plt.ylim(0, 100)  # 設置y軸的范圍從0.01到100plt.show()# 選擇多項式特征中的前4個維度
train(poly_features[:n_train, :4], poly_features[n_train:, :4],labels[:n_train], labels[n_train:])

分部講解如下:

問題實例:
在這里插入圖片描述

產生高斯分布隨機數x并按上述式子生成訓練集和驗證集y,并對生成的y再添加一些雜音處理
注意:訓練集一定要打亂,不要排序,排序會讓訓練效果大打折扣,如果訓練數據是按照某種特定順序排列的,那么模型可能會學習到這種順序并在這個過程中引入偏差,導致模型在未見過的新數據上的泛化能力下降,打亂訓練集的目的通常是為了防止模型學習到訓練數據中的任何順序依賴性,這樣可以提高模型在隨機或未見過的新數據上的泛化能力。

# 生成隨機的數據集
max_degree = 20  # 多項式的最大階數
n_train, n_test = 100, 100  # 訓練和測試數據集大小
true_w = torch.zeros(max_degree)
true_w[0:4] = torch.Tensor([5, 1.2, -3.4, 5.6])# 生成特征
features = torch.randn((n_train + n_test, 1))
permutation_indices = torch.randperm(features.size(0))
# 使用隨機排列的索引來打亂features張量(原地修改)
features = features[permutation_indices]
poly_features = torch.pow(features, torch.arange(max_degree).reshape(1, -1))
for i in range(max_degree):poly_features[:, i] /= math.gamma(i + 1)# 生成標簽
labels = torch.matmul(poly_features, true_w)
labels += torch.normal(0, 0.1, size=labels.shape)

計算損失函數,并不會更新迭代模型,所以用他來測試模型測試集損失

def evaluate_loss(net, data_iter, loss):metric = d2l.Accumulator(2)for X, y in data_iter:out = net(X)y = y.reshape(out.shape)l = loss(out, y)metric.add(l.sum(), l.numel())return metric[0] / metric[1]

訓練函數,將X和對應y放在一起,即是進行模型迭代更新,又能計算模型訓練損失,測試損失并繪制相應圖形

def train(train_features, test_features, train_labels, test_labels,num_epochs=400):loss = nn.MSELoss()  # 默認取平均損失input_shape = train_features.shape[-1]  # 模型大小取train_features最后一項大小net = nn.Sequential(nn.Linear(input_shape, 1, bias=False))batch_size = min(10, train_labels.shape[0])  # 整體數據集分成<= 10批次train_iter = d2l.load_array((train_features, train_labels.reshape(-1, 1)),batch_size)test_iter = d2l.load_array((test_features, test_labels.reshape(-1, 1)),batch_size, is_train=False)trainer = torch.optim.SGD(net.parameters(), lr=0.01)  # 梯度下降算法# 用于存儲訓練和測試損失的列表train_losses = []test_losses = []for epoch in range(num_epochs):train_loss, train_acc = d2l.train_epoch_ch3(net, train_iter, loss, trainer)  # 訓練迭代模型test_loss = evaluate_loss(net, test_iter, loss)# 將當前的損失值添加到列表中train_losses.append(train_loss)test_losses.append(test_loss)print(f"Epoch {epoch + 1}/{num_epochs}:")print(f"  訓練損失: {train_loss:.4f}, 測試損失: {test_loss:.4f}")print(net[0].weight)  # 輸出訓練好的模型# 假設 train_losses 和 test_losses 是已經計算出的損失值列表plt.figure(figsize=(10, 6))plt.plot(train_losses, label='train', color='blue', linestyle='-', marker='.')plt.plot(test_losses, label='test', color='purple', linestyle='--', marker='.')plt.xlabel('epoch')plt.ylabel('loss')plt.title('Loss over Epochs')plt.legend()plt.grid(True)plt.ylim(0, 100)  # 設置y軸的范圍從0.01到100plt.show()

主函數

# 選擇多項式特征中的前4個維度
train(poly_features[:n_train, :4], poly_features[n_train:, :4],labels[:n_train], labels[n_train:])

利用上述實例驗證欠擬合和過擬合以及正常擬合

在這里插入圖片描述
上述函數對應真正的模型為:

true_w[0:4] = torch.Tensor([5, 1.2, -3.4, 5.6])

當然還有一些雜質,可忽略

那么可知預訓練模型取四個維度就能做到正常擬合,而取二十個維度就是過擬合,取四個以下維度就是欠擬合

過擬合即取二十維度效果:

在這里插入圖片描述
可以看出損失在下降到最低點的時候還會有上升
在這里插入圖片描述
這是因為學完主要四個維度后又將本應是0的維度也學習了,也就是學習了無用的雜質。
在這里插入圖片描述

欠擬合二維度模型效果:

在這里插入圖片描述
損失很大,這也是沒辦法,畢竟還有很多重要維度沒有學習上,本質上是模型過小

正常擬合四維度模型效果:

在這里插入圖片描述
正常擬合的模型在損失到達最低點后便不再上升,訓練出來的模型與真實數據也及其接近

在這里插入圖片描述
正常擬合才是我們訓練模型的期望狀態

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/711195.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/711195.shtml
英文地址,請注明出處:http://en.pswp.cn/news/711195.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[云原生] K8s之pod進階

一、pod的狀態說明 &#xff08;1&#xff09;Pod 一直處于Pending狀態 Pending狀態意味著Pod的YAML文件已經提交給Kubernetes&#xff0c;API對象已經被創建并保存在Etcd當中。但是&#xff0c;這個Pod里有些容器因為某種原因而不能被順利創建。比如&#xff0c;調度不成功(…

原神搶碼,米游社搶碼-首發

本文章僅供學習使用-侵權請聯系刪除_2023年3月14日08:17:06 本來在深淵12層打不過的我偶然在刷到了一個dy的直播間&#xff0c;看到主播在搶碼上號幫忙打深淵還號稱痛苦號打不滿不送原石的旗號我就決定掃碼試試&#xff0c;在直播間內使用了兩部手機互相掃碼在掃了一下午的碼后…

自動駕駛技術詳解

&#x1f3ac;個人簡介&#xff1a;一個全棧工程師的升級之路&#xff01; &#x1f4cb;個人專欄&#xff1a;自動駕駛技術 &#x1f380;CSDN主頁 發狂的小花 &#x1f304;人生秘訣&#xff1a;學習的本質就是極致重復! 目錄 一 自動駕駛視覺感知算法 1目標檢測 1.1 兩階…

代碼隨想錄算法訓練營第四五天 | dp[j] = min(dp[j], dp[j - coins[i]] + 1)

目錄 爬樓梯 &#xff08;進階&#xff09;零錢兌換完全平方數總結 LeetCode 70. 爬樓梯 &#xff08;進階&#xff09; LeetCode 322. 零錢兌換 LeetCode 279.完全平方數 爬樓梯 &#xff08;進階&#xff09; 好做 import java.util.*;public class Main{// dp[i] 爬到有…

css背景圖片屬性

基礎代碼&#xff1a; div {width: 200px;height: 200px;background: url(./css-logo.png); }<div></div> 1、background-repeat&#xff1a;默認是repeat 設置背景圖片在容器內是否平鋪。 background-repeat: repeat-y; background-repeat: repeat-x; background…

消息中間件之RocketMQ源碼分析(二十四)

事務消息 事務消息機制。 事務消息的發送和處理總結為四個過程: 1.生產者發送事務消息和執行本地事務 2.Broker存儲事務消息 3.Broker回查事務消息 4.Broker提交或回滾事務消息 生產者發送事務消息和執行本地事務。 發送過程分為兩個階段: 第一階段,發送事務消息 第二階段,發…

Spring Expression Language (SpEL)

Spring 表達語言&#xff08;SpEL&#xff09;&#xff0c;支持在運行時查詢和操作對象圖&#xff0c;可以用于數據綁定、屬性訪問、方法調用等。使用SpEL可以簡化代碼并提高應用程序的可維護性。 1 概覽 SpelExpressionParser是SpEL的一個核心組件&#xff0c;負責解析和編譯…

CentOS安裝編譯Python3.11.6

CentOs自帶python2版本太低&#xff0c;項目需要python3&#xff0c;于是自己安裝python 操作指南&#xff1a; 重新下載源代碼&#xff1a; # 刪除舊的 Python 源代碼文件&#xff08;如果有&#xff09; rm -rf Python-3.11.6.tar.xz # 下載 Python 3.11.6 的源代碼文件 wget…

Java泛型簡介

Java泛型簡介 Java泛型是在Java 5中引入的一個特性&#xff0c;它允許程序員在編譯時指定類、接口或方法能夠接受的類型。泛型的主要目的是提供編譯時類型安全檢查&#xff0c;避免在運行時因為類型轉換錯誤而導致的ClassCastException。 在沒有泛型之前&#xff0c;Java中的集…

如何利用動態靜態代理IP實現跨地域網絡營銷與市場研究

動態代理IP和靜態代理IP都可以在跨地域網絡營銷與市場研究中發揮關鍵作用&#xff0c;具體實現方式如下&#xff1a; ### 動態代理IP的應用&#xff1a; 1. 跨地域營銷活動測試&#xff1a; - 在進行網絡營銷時&#xff0c;尤其是要驗證廣告投放、SEO效果或A/B測試不同地區用戶…

Ubuntu系統使用Docker搭建Jupyter Notebook并實現無公網ip遠程連接

文章目錄 1. 選擇與拉取鏡像2. 創建容器3. 訪問Jupyter工作臺4. 遠程訪問Jupyter工作臺4.1 內網穿透工具安裝4.2 創建遠程連接公網地址4.3 使用固定二級子域名地址遠程訪問 本文主要介紹如何在Ubuntu系統中使用Docker本地部署Jupyter Notebook&#xff0c;并結合cpolar內網穿透…

C語言系列(所需基礎:大學C語言及格)-4-轉義字符/注釋/選擇語句

文章目錄 一、轉義字符二、注釋三、選擇語句 一、轉義字符 加上\會講原來的字符改變意思&#xff0c;即進行轉義 例如\t會使t變成\t用于表示轉義字符&#xff0c;使得t轉義成水平制表符 其他轉義字符&#xff1a; 三字母詞&#xff08;展示\&#xff1f;的用處&#xff09;…

C#面:接口是一種引用類型,不可以聲明公有的域或私有的成員變量,但是可以聲明什么呢?

可以聲明&#xff1a;方法&#xff0c;屬性&#xff0c;索引器&#xff0c;事件。 接口的主要作用是定義一套規范&#xff0c;使得不同的類可以按照相同的規范進行交互。通過實現接口&#xff0c;類可以具備多態性&#xff0c;即可以以接口類型來引用對象&#xff0c;并調用接…

k8s-001-Centos7內核升級

1. 查看內核 [rootlocalhost ~]# uname -a 2. 執行的命令(安裝最新版內核): 下載: rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org 安裝: rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm &#xff08; 查看最新版內核&…

杭州默安-安全技術實習生-一面

1.自我介紹 略 2.專業主修的課程 略 3.xss漏洞的類型&#xff0c;原理及防御 原理&#xff0c;服務器對用戶的輸入過濾不嚴格&#xff0c;將用戶的輸入當作Javascript代碼執行并返回給客戶端。 防御&#xff0c;輸入和url參數過濾&#xff0c;HTML實體編碼轉義特殊字符。…

力扣hot100題解(python版33-35題)

33、排序鏈表 給你鏈表的頭結點 head &#xff0c;請將其按 升序 排列并返回 排序后的鏈表 。 示例 1&#xff1a; 輸入&#xff1a;head [4,2,1,3] 輸出&#xff1a;[1,2,3,4]示例 2&#xff1a; 輸入&#xff1a;head [-1,5,3,4,0] 輸出&#xff1a;[-1,0,3,4,5]示例 3&a…

kafka架構詳解

文章目錄 概述kafaka架構Kafka的設計時什么樣的Zookeeper 在 Kafka 中的作用知道 概述 Apache Kafka 是分布式發布 - 訂閱消息系統&#xff0c;在 kafka 官網上對 kafka 的定義&#xff1a;一個分布式發布 - 訂閱消息傳遞系統。 Kafka 最初由 LinkedIn 公司開發&#xff0c;Li…

mysql 中 auto_increment 自增約束的用法和配置

自增約束 int字段 特殊約束條件&#xff0c;用于為表中寫入新的記錄生成唯一的值&#xff0c;一個表中只能有一個自增約束字段 格式 字段 數據類型 auto_increment 創建帶有自增約束的表 create table student_game_auto ( id int unique auto_increment, name char(5),…

螞蟻集團推動編制的全球首個隱私計算一體機國際標準發布

近日&#xff0c;IEEE 標準協會&#xff08;IEEE-SA&#xff09;正式發布并推行了由我國企業主導的全球首個隱私計算一體機國際標準《隱私計算一體機技術要求》&#xff08;IEEE 3156-2023&#xff09;。IEEE-SA是權威國際標準制定機構&#xff0c;該標準的成功發布意味著中國的…

numpy常見操作

返回各維度元組print(img.shape)返回大小img.size返回各維度數據類型print(img.dtype) 數據類型變int8maskmask.astype(np.int8) 注意int32可變float64 但float64變int32會把小數截斷 string_可變float64 NumPy常見操作&#xff1a; import numpy as np 創建一個一維數組 ar…