和鯨社區深度學習基礎訓練營2025年關卡2(1)純numpy

擬分3種實現方法:

1.純numpy

2.sklearn中的MLPClassifier

3.pytorch

題目:
在 MNIST 數據集上訓練 MLP 模型并比較不同的激活函數和優化算法

任務描述:

使用 MNIST 數據集中的前 20,000 個樣本訓練一個多層感知機 (MLP) 模型。你需要比較三種不同的激活函數(ReLU、Sigmoid、Tanh)和三種不同的優化算法(SGD、Momentum、Adam),以找到表現最好的組合。模型需要使用一層隱藏層,隱藏單元數量為 128。

要求:

加載并預處理數據,將每個圖像展平成 28x28 的向量,并進行標準化(除以 255)。
使用 one-hot 編碼將標簽進行轉換。
在訓練過程中,分別使用以下激活函數和優化算法:
激活函數:ReLU、Sigmoid、Tanh
優化算法:SGD、Momentum、Adam
對每種激活函數和優化算法組合,訓練模型 10000 個 epoch。
評估模型在驗證集上的準確率,并輸出最優的激活函數與優化算法組合。
輸入:

訓練數據:MNIST 數據集中的前 20,000 個樣本。
每個樣本是一個 28x28 的灰度圖像,標簽為 0-9 的分類。
輸出:

輸出最優激活函數與優化算法組合,以及在驗證集上的準確率。
要求:

不同激活函數與優化算法的組合實現。
對模型的正確率進行評估,并選擇最優方案。
提示:

你可以使用 OneHotEncoder 將標簽進行 one-hot 編碼。
在模型的反向傳播過程中,根據不同的優化算法更新權重。
激活函數可以用 ReLU、Sigmoid 和 Tanh,確保在前向傳播和反向傳播時分別計算激活值及其導數。

import numpy as np
from sklearn.preprocessing import OneHotEncoder
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
np.random.seed(999)def load_data(path="mnist.npz"):# np.load加載數據文件f = np.load(path)# 提取訓練集和測試集的圖片和標簽數據X_train, y_train = f['x_train'], f['y_train']X_test, y_test = f['x_test'], f['y_test']f.close()  # 關閉文件# 返回訓練集和測試集return (X_train, y_train), (X_test, y_test)# 加載MNIST數據集
(X_train, y_train), (X_test, y_test) = load_data()X_train=X_train[:2000]
y_train=y_train[:2000]
X_test=X_test[:1000]
y_test=y_test[:1000]
# 數據預處理
X_train = X_train.reshape((-1,  28 * 28)).astype('float32') / 255
X_test = X_test.reshape((-1,  28 * 28)).astype('float32') / 255# 標簽進行獨熱編碼
def one_hot_encoding(labels, num_classes):encoded = np.zeros((len(labels),  num_classes))for i, label in enumerate(labels):encoded[i][label] = 1return encodedy_train = one_hot_encoding(y_train, 10)
y_test = one_hot_encoding(y_test, 10)# MLP類的實現
class MLP:def __init__(self, input_size, hidden_size, output_size, activation='relu'):# 初始化權重(Xavier初始化適應Sigmoid/Tanh)self.W1 = np.random.randn(input_size, hidden_size) * np.sqrt(2 / input_size)self.b1 = np.zeros((1, hidden_size))self.W2 = np.random.randn(hidden_size, output_size) * np.sqrt(2 / hidden_size)self.b2 = np.zeros((1, output_size))self.activation = activation  # 支持relu/sigmoid/tanhself.losses = []  # 記錄訓練損失# Adam專用初始化self.t = 0  # 時間步計數器[1,2]self.m_W1, self.v_W1 = None, None  # 一階/二階矩(權重1)self.m_b1, self.v_b1 = None, None  # 一階/二階矩(偏置1)self.m_W2, self.v_W2 = None, None  # 一階/二階矩(權重2)self.m_b2, self.v_b2 = None, None  # 一階/二階矩(偏置2)# Adam超參數(可調整)self.beta1 = 0.9    # 一階矩衰減率self.beta2 = 0.999  # 二階矩衰減率self.epsilon = 1e-8 # 防除零常數def _activate(self, x):"""激活函數及其導數"""if self.activation == 'relu':return np.maximum(0, x), np.where(x > 0, 1, 0)  # 函數值 + 導數elif self.activation == 'sigmoid':s = 1 / (1 + np.exp(-x))return s, s * (1 - s)elif self.activation == 'tanh':t = np.tanh(x)return t, 1 - t**2def forward(self, X):"""前向傳播"""self.z1 = np.dot(X, self.W1) + self.b1self.a1, self.da1 = self._activate(self.z1)  # 隱藏層激活值及導數self.z2 = np.dot(self.a1, self.W2) + self.b2self.a2 = np.exp(self.z2) / np.sum(np.exp(self.z2), axis=1, keepdims=True)  # Softmax輸出return self.a2def compute_loss(self, y_pred, y_true):"""交叉熵損失"""return -np.mean(y_true * np.log(y_pred + 1e-8))def backward(self, X, y_true, y_pred):"""反向傳播"""m = X.shape[0]# 輸出層梯度 (dL/dz2)error_output = y_pred - y_truedW2 = np.dot(self.a1.T, error_output) / mdb2 = np.sum(error_output, axis=0, keepdims=True) / m# 隱藏層梯度 (dL/dz1)error_hidden = np.dot(error_output, self.W2.T) * self.da1dW1 = np.dot(X.T, error_hidden) / mdb1 = np.sum(error_hidden, axis=0, keepdims=True) / mreturn dW1, db1, dW2, db2def update_params(self, dW1, db1, dW2, db2, lr=0.01, optimizer='sgd', momentum=0.9):"""參數更新(支持SGD/Momentum/Adam)"""if optimizer == 'sgd':self.W1 -= lr * dW1self.b1 -= lr * db1self.W2 -= lr * dW2self.b2 -= lr * db2elif optimizer == 'momentum':# 初始化動量緩存if not hasattr(self, 'v_dW1'):self.v_dW1, self.v_db1 = np.zeros_like(dW1), np.zeros_like(db1)self.v_dW2, self.v_db2 = np.zeros_like(dW2), np.zeros_like(db2)# 更新動量self.v_dW1 = momentum * self.v_dW1 + lr * dW1self.v_db1 = momentum * self.v_db1 + lr * db1self.v_dW2 = momentum * self.v_dW2 + lr * dW2self.v_db2 = momentum * self.v_db2 + lr * db2# 應用更新self.W1 -= self.v_dW1self.b1 -= self.v_db1self.W2 -= self.v_dW2self.b2 -= self.v_db2# Adam實現elif optimizer == 'adam':# 首次調用時初始化矩估計if self.m_W1 is None:self.m_W1, self.v_W1 = np.zeros_like(dW1), np.zeros_like(dW1)self.m_b1, self.v_b1 = np.zeros_like(db1), np.zeros_like(db1)self.m_W2, self.v_W2 = np.zeros_like(dW2), np.zeros_like(dW2)self.m_b2, self.v_b2 = np.zeros_like(db2), np.zeros_like(db2)self.t += 1  # 更新時間步# 更新W1/b1的矩估計self.m_W1 = self.beta1*self.m_W1 + (1-self.beta1)*dW1self.v_W1 = self.beta2*self.v_W1 + (1-self.beta2)*(dW1**2)self.m_b1 = self.beta1*self.m_b1 + (1-self.beta1)*db1self.v_b1 = self.beta2*self.v_b1 + (1-self.beta2)*(db1**2)# 更新W2/b2的矩估計self.m_W2 = self.beta1*self.m_W2 + (1-self.beta1)*dW2self.v_W2 = self.beta2*self.v_W2 + (1-self.beta2)*(dW2**2)self.m_b2 = self.beta1*self.m_b2 + (1-self.beta1)*db2self.v_b2 = self.beta2*self.v_b2 + (1-self.beta2)*(db2**2)# 偏差校正m_W1_hat = self.m_W1 / (1 - self.beta1**self.t)v_W1_hat = self.v_W1 / (1 - self.beta2**self.t)m_b1_hat = self.m_b1 / (1 - self.beta1**self.t)v_b1_hat = self.v_b1 / (1 - self.beta2**self.t)m_W2_hat = self.m_W2 / (1 - self.beta1**self.t)v_W2_hat = self.v_W2 / (1 - self.beta2**self.t)m_b2_hat = self.m_b2 / (1 - self.beta1**self.t)v_b2_hat = self.v_b2 / (1 - self.beta2**self.t)# 參數更新self.W1 -= lr * m_W1_hat / (np.sqrt(v_W1_hat) + self.epsilon)self.b1 -= lr * m_b1_hat / (np.sqrt(v_b1_hat) + self.epsilon)self.W2 -= lr * m_W2_hat / (np.sqrt(v_W2_hat) + self.epsilon)self.b2 -= lr * m_b2_hat / (np.sqrt(v_b2_hat) + self.epsilon)def train(self, X, y, epochs=1000, lr=0.01, optimizer='sgd'):for epoch in range(epochs):y_pred = self.forward(X)loss = self.compute_loss(y_pred, y)self.losses.append(loss)dW1, db1, dW2, db2 = self.backward(X, y, y_pred)self.update_params(dW1, db1, dW2, db2, lr, optimizer)#if epoch % 100 == 0:#print(f"Epoch {epoch}: Loss={loss:.4f}")def predict(self, X):return np.argmax(self.forward(X), axis=1)# 創建MLP模型
input_size = 28 * 28
hidden_size = 128
output_size = 10# 訓練模型
lr = 0.001
epochs = 1000# 訓練和評估模型
best_accuracy = 0  # 保存最佳模型的準確率
best_model = None  # 保存最佳模型
best_activation = None  # 保存最佳的激活函數
best_optimizer = None  # 保存最佳的優化器for activation in ['relu', 'sigmoid', 'tanh']:  # 激活函數分別為ReLU、Sigmoid、Tanhfor optimizer in ['sgd', 'momentum', 'adam']:  # 優化器分別為SGD、Momentum和Adamprint(f"\nTraining with {activation} activation and {optimizer} optimizer")mlp = MLP(input_size=input_size, hidden_size=hidden_size, output_size=output_size, activation=activation)mlp.train(X_train, y_train, epochs=epochs, lr=lr, optimizer=optimizer)# 評估準確率y_pred = mlp.predict(X_test)accuracy = np.mean(np.argmax(y_test, axis=1) == y_pred)print(f"測試集準確率: {accuracy * 100:.2f}%")# 保存最佳模型if accuracy > best_accuracy:best_accuracy = accuracy # 保存最佳模型的準確率best_model = None  # 保存最佳模型best_activation = activation  # 保存最佳的激活函數best_optimizer = optimizer # 保存最佳的優化器print(f"\nBest model with activation '{best_activation}' and optimizer '{best_optimizer}'")
print(f"Validation Accuracy: {best_accuracy * 100:.2f}%")

運行結果如下:

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

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

相關文章

Sequential Thinking:AI深度思考的新范式及其與CoT、ReAct的對比分析

引言:AI深度思考的演進與Sequential Thinking的崛起在人工智能技術快速發展的今天,AI模型的思考能力正經歷著從簡單應答到深度推理的革命性轉變。這一演進過程不僅反映了技術本身的進步,更體現了人類對機器智能認知邊界的持續探索。早期的大語…

云原生詳解:構建現代化應用的未來

引言 在數字化轉型的浪潮中,"云原生"已成為技術領域最熱門的話題之一。從初創公司到全球500強企業,都在積極探索云原生技術以提升業務敏捷性和創新能力。本文將全面解析云原生的概念、核心技術、優勢以及實踐路徑,幫助您深入理解這一改變IT格局的技術范式。 什么…

SSE事件流簡單示例

文章目錄1、推送-SseEmitter2、接收-EventSourceListenerSSE(Server-Sent Events,服務器推送事件)是一種基于HTTP的服務器向客戶端實時推送數據的技術標準。1、推送-SseEmitter SseEmitter用于實現服務器向客戶端單向、長連接的實時數據推送…

Elasticsearch RESTful API入門:基礎搜索與查詢DSL

Elasticsearch RESTful API入門:基礎搜索與查詢DSL 本文為Elasticsearch初學者詳細解析RESTful API的核心操作與查詢DSL語法,包含大量實戰示例及最佳實踐。 一、Elasticsearch與RESTful API簡介 Elasticsearch(ES)作為分布式搜索…

(六)復習(OutBox Message)

文章目錄 項目地址一、OutBox Message1.1 OutBox表配置1. OutBoxMessage類2. OutboxMessage表配置3. 給每個模塊生成outboxmessage表1.2 發布OutBox Message1. 修改Intercepotor2. 配置Quartz3. 創建Quatz方法發布領域事件4. 創建Quatz定時任務5. 注冊Quatz服務和配置6. 流程梳…

STM32-ADC內部溫度

在通道16無引腳(測量溫度不準確)跟ADC代碼差不多;不需要使能引腳時鐘;將內部溫度測量打開/*** brief 啟用或禁用溫度傳感器和內部參考電壓功能* param NewState: 新的功能狀態,取值為ENABLE或DISABLE* retval 無* no…

「Linux命令基礎」文本模式系統關閉與重啟

關機重啟基本命令 直接拔掉計算機電源可能損壞內部元件;Linux系統通過命令關閉計算機則是安全流程,讓所有程序有機會保存數據、釋放資源。 關機命令:shutdown Linux系統提供了多種用于關閉或重啟系統的命令,其中 shutdown 是最常用的一種,它可以安全地通知用戶系統即將…

射頻信號(大寬高比)時頻圖目標檢測anchors配置

一、大寬高比目標YOLO檢測參數設置 這是yolov7的一個label的txt文件: 1 0.500 0.201 1.000 0.091 2 0.500 0.402 1.000 0.150 3 0.500 0.604 1.000 0.093 0 0.500 0.804 1.000 0.217 對應的樣本: 長寬比分別是:1/0.09110.98, 1/0.1506.67…

OpenStack 鑒權服務介紹.md

引言 OpenStack是一個開源的云計算管理平臺,其中的Keystone組件承擔了身份認證和授權的關鍵任務。Keystone的主要功能包括管理用戶及其權限、維護OpenStack Services的Endpoint,以及實現認證(Authentication)和鑒權(Au…

Linux_3:進程間通信

IPC1.什么是IPC?Inter Process Communication2.進程間通信常用的幾種方式1,管道通信:有名管道,無名管道2,信號- 系統開銷小3,消息隊列-內核的鏈表4,信號量-計數器5,共享內存6&#x…

【Springboot】Bean解釋

在 Spring Boot 中,Bean 就像是你餐廳里的一名員工。比如,你有一名服務員(Service)、一名廚師(Chef)和一名收銀員(Cashier)。這些員工都是餐廳正常運轉所必需的,他們各自…

axios的post請求,數據為什么要用qs處理?什么時候不用?

為什么使用 qs 處理 POST 數據axios 的 POST 請求默認將 JavaScript 對象序列化為 JSON 格式(Content-Type: application/json)。但某些后端接口(尤其是傳統表單提交)要求數據以 application/x-www-form-urlencoded 格式傳輸&…

【unitrix】 4.21 類型級二進制數基本結構體(types.rs)

一、源碼 這段代碼定義了一個類型級數值系統的 Rust 實現,主要用于在編譯時表示和操作各種數值類型。 use crate::sealed::Sealed; use crate::number::{NonZero, TypedInt, Unsigned, Primitive}; // // 特殊浮點值枚舉 ///// 特殊浮點值(NaN/∞&#x…

UI前端與數字孿生結合實踐案例:智慧零售的庫存管理優化系統

hello寶子們...我們是艾斯視覺擅長ui設計和前端數字孿生、大數據、三維建模、三維動畫10年經驗!希望我的分享能幫助到您!如需幫助可以評論關注私信我們一起探討!致敬感謝感恩!一、引言:數字孿生重構零售庫存的 “人 - 貨 - 場” 協同在零售行業利潤率持續承壓的背景…

【Freertos實戰】零基礎制作基于stm32的物聯網溫濕度檢測(教程非常簡易)持續更新中.........

本次記錄采用Freertos的第二個DIY作品,基于Onenet的物聯網溫濕度檢測系統,此次代碼依然是全部開源。通過網盤分享的文件:物聯網溫濕度檢測.rar 鏈接: https://pan.baidu.com/s/1uj9UURVtGE6ZB6OsL2W8lw?pwdqm2e 提取碼: qm2e 大家也可以看看…

Matplotlib-多圖布局與網格顯示

Matplotlib-多圖布局與網格顯示一、多圖布局的核心組件二、基礎布局:plt.subplots()快速創建網格1. 均等分網格2. 不等分網格(指定比例)三、進階布局:GridSpec實現復雜嵌套1. 跨行列布局2. 嵌套GridSpec四、實用技巧:布…

GitHub上優秀的開源播放器項目介紹及優劣對比

ExoPlayer 項目地址:https://github.com/google/ExoPlayer 特點: 由Google開發,支持廣泛的視頻格式和流媒體傳輸協議,如DASH、HLS、SmoothStreaming。 提供靈活的媒體源架構和高級特性,如動態自適應流播放。 開發者可以輕松擴展和定制播放器組件,適應特定需求。 優點: 功…

react打包發到線上報錯Minified React error #130

開發過程中遇到一個問題,記錄一下 本地打包發布正常,發測試環境正常,可是通過Jenkins打包發布線上報錯 報錯信息 index-67fbbd81.js:39 Error: Minified React error #130; visit https://reactjs.org/docs/error-decoder.html?invariant130…

微服務項目遠程調用時的負載均衡是如何實現的?

負載均衡概述 負載均衡是微服務架構中的核心組件,用于將請求合理分配到多個服務實例上,提高系統的可用性和性能。負載均衡的分類 負載均衡大致可以分為兩類 1. 服務端負載均衡 實現位置:獨立部署的負載均衡服務器(位于客戶端和服務…

【中文核心期刊推薦】中國農業科技導報

《中國農業科技導報》是中國科技核心期刊,也是北京大學圖書館“中文核心期刊要目總覽”收錄的期刊。它是由中國農村技術開發中心主辦,全面為科教興農服務的綜合性農業學術期刊。《中國農業科技導報》是中國農業科學院生物技術研究所承辦的&a…