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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用scipy实现简单神经网络

發布時間:2025/4/16 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用scipy实现简单神经网络 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 1、準備工作
      • (1) 導入必要的庫:
      • (2) 數據準備
    • 2、實現主要的函數
      • (1) `Logistic function`
      • (2) `Forward`函數
      • (3) 損失函數
      • (4) `mse_loss`
    • 3、訓練模型
    • 4、模型評估
    • 5、訓練結果可視化
    • 6、小結

1、準備工作

(1) 導入必要的庫:

  • numpy - 用于基本的數據操作
  • scipy.optimize 中導入 minimize函數,用于訓練模型
  • matplotlib 用于數據可視化
import numpy as np from scipy.optimize import minimize import matplotlib.pyplot as plt

(2) 數據準備

首先需要設置的參數:

  • N– 樣本個數
  • d– 輸入樣本的維度
  • num_hidden --隱函層的個數
N,d,num_hidden = 100,1,20

接著生成數據:

  • x– 區間 [?10,10][-10,10][?10,10] 上取 N 個點,這里我們的 N=100。另外將其設為列向量,即x.shape=(N,1)
  • y_true– Mexican Hat 函數
    y=sin?xxy=\frac{\sin x}{x} y=xsinx?
  • y– Mexican Hat函數的樣本點,這里我們使用了 [?0.05,0.05][-0.05,0.05][?0.05,0.05] 上的噪聲

數據生成完成后出圖看一下樣子:

x = np.linspace(-10,10,N).reshape(-1,1) y_true = np.sin(x)/x y = np.sin(x)/x + (np.random.rand(N,1)*0.1-0.05)plt.plot(x,y,'-b') plt.plot(x,y,'oy') plt.show()

2、實現主要的函數

(1) Logistic function

這里我們采用 Logistic function 作為激活函數,定義為:
y=11+e?xy = \frac{1}{1+\mathrm{e}^{-x}} y=1+e?x1?

(2) Forward函數

這里我們采用簡單的三層神經網絡,因此前饋函數的公式為:

Y^=(w?×1(2))Tf((w?×d(1))Txd×N(2)+b(1))+b(2)\hat{Y}=\left(\boldsymbol{w}_{\ell \times 1}^{(2)}\right)^{T} f\left(\left(\boldsymbol{w}_{\ell \times d}^{(1)}\right)^{T} \boldsymbol{x}_{d \times N}^{(2)}+\boldsymbol{b}^{(1)}\right)+b^{(2)} Y^=(w?×1(2)?)Tf((w?×d(1)?)Txd×N(2)?+b(1))+b(2)

這里需要特別說明一下,由于scipy.optimize只能優化第一個 positional argument,因此不能將每層的參數分開傳給loss。這里我們為了方便,就在把所有參數放在一個向量 θ\boldsymbol{\theta}θ 中,并且在forward函數中拆取各層參數。

(3) 損失函數

這里直接采用 MSE作為損失函數:

MSE=1N∥Y?Y^∥2MSE = \frac{1}{N} \|Y-\hat{Y}\|^2 MSE=N1?Y?Y^2

(4) mse_loss

這個函數有那么一點多余,不過在后面計算loss時會比較方便。

def logi_func(x):return 1/(1+np.exp(-x))def forward(x,theta,d,num_hidden):w1 = theta[:d*num_hidden].reshape(d,num_hidden)w2 = theta[d*num_hidden:d*num_hidden+num_hidden].reshape(num_hidden,1)b1 = theta[d*num_hidden+num_hidden:-1].reshape(num_hidden,1)b2 = theta[-1]return logi_func(x.dot(w1)+b1.T).dot(w2)+b2def nn_loss(theta,x,y,d,num_hidden):return ((forward(x,theta,d,num_hidden)-y)**2).mean()def mse_loss(y,y_pred):return ((y-y_pred)**2).mean()

寫完之后簡單測試一下,沒有什么問題:

theta = np.random.rand(d*num_hidden+num_hidden + num_hidden+1)forward(x, theta, d, num_hidden) print(nn_loss(theta,x,y,d,num_hidden)) 32.92328775623846

3、訓練模型

minimize函數的使用非常簡單,第一個參數為loss的函數名,第二個參數為網絡參數的初始值,第三個參數args是loss中第一個參數之外的所有參數組成的tuple。

minize這個函數默認的優化方法為BFGS,這個算法具有很好的收斂性,不過直接用于神經網絡的訓練時速度稍慢一點。

本次實驗在 MacBook Pro (m1) 上進行,運行時間3.7s,可見比梯度下降要慢很多(通常應該比簡單梯度精度要多,但在loss上體現并不見得明顯)。

res = minimize(nn_loss, theta, args=(x, y, d, num_hidden))

返回值res是優化結果的集合,其中參數的最優值在 res.x中,因此將該參數傳給forward即可算出擬合值。

y_pred = forward(x,res.x,d,num_hidden)

4、模型評估

MSE值為 0.00055,可見訓練效果還是不錯的:

print(mse_loss(y,y_pred)) 0.000552170732918358

5、訓練結果可視化

這里直接使用matploblib即可,用三種線型分別表示:函數真實值、樣本值、模型擬合值。

可以看到擬合效果是很不錯的。

plt.plot(x,y,'oy') plt.plot(x, y_true, '-r') plt.plot(x,y_pred,'-b')plt.legend(['y_samples', 'y_true', 'y_pred']) plt.show()

為了進一步驗證模型的泛化性能,我們在 [?5,5][-5,5][?5,5] 隨機采100個點,再看一下模型的預測效果。

可以看到在中間這一段的 MSE 僅有0.00033,可見這種單層神經網絡在函數擬合問題上的泛化性能還是很不錯的(注意到這里我們只用了20個隱含層節點)。

x_test = np.sort(np.random.rand(100,1)*10-5,axis=0) y_test_true = np.sin(x_test)/x_test y_test_pred = forward(x_test, res.x, d, num_hidden)plt.plot(x_test, y_test_true, 'oy') plt.plot(x_test, y_test_pred, '-b')plt.legend(['y_test_true', 'y_test_pred']) plt.title('mse={0}'.format(mse_loss(y_test_true,y_test_pred))) plt.show()

6、小結

  • 用 scipy.optimize.minimize 完全可以實現簡單的神經網絡
  • 本文構造的網絡僅有20個隱含層,但擬合效果和泛化性能均較好,可見單隱含層神經網絡在函數擬合上具有較好的性能
  • 實現細節的關鍵在于靈活調用miminize函數,尤其是對loss的傳參
  • 本文在實現forward時對參數的重構方式有點麻煩,其實還可以更為簡便,讀者可自行思考完成
  • 本文使用的算法效率并不高,可見針對具體的訓練問題仍需重視算法的選擇

總結

以上是生活随笔為你收集整理的使用scipy实现简单神经网络的全部內容,希望文章能夠幫你解決所遇到的問題。

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