基于神经网络多层感知器的波士顿房价数据集回归问题
目錄
- 1. 作者介紹
- 2. 神經網絡多層感知器
- 2.1 前向傳播與反向傳播
- 2.2損失函數
- 2.3激活函數
- 3. 實驗過程
- 3.1波士頓房價數據集
- 3.2實驗代碼
- 3.3運行結果
1. 作者介紹
鄧越,男,西安工程大學電子信息學院,2021級研究生
研究方向:機器視覺與人工智能
電子郵件:2570878225@qq.com
吳燕子,女,西安工程大學電子信息學院,2021級研究生,張宏偉人工智能課題組
研究方向:模式識別與人工智能
電子郵件:1219428323@qq.com
2. 神經網絡多層感知器
多層感知器(Multi-Layer Perceptron,MLP)也叫人工神經網絡(Artificial Neural Network,ANN),神經網絡通常包含一個輸入層, 一個輸出層以及若干隱藏層, 輸入層只接收輸入信息, 通常為數據樣本的特征向量, 經過隱藏分層和輸出層的處理, 由輸出層輸出結果. 隱藏層的層數和節點數可以根據實際情況進行調整. 神經網絡能夠通過學習得到輸入與輸出的映射關系, 整個訓練過程就是不斷更新權重以及偏置值, 使得模型預測越來越準確. 通常每個層之間可以加入激活函數引入非線性因素。
2.1 前向傳播與反向傳播
下式表示了神經網絡的前向傳播過程,其中,σ為激活函數,可以看出每個神經元的值由上一層的神經元的值與連接權重、偏置值以及激活函數共同決定。
神經網絡的反向傳播過程,是根據前向傳播計算樣本輸出結果,利用計算結果計算各層梯度,然后根據輸出結果及梯度更新權重系數及偏置。
2.2損失函數
損失函數用來評價模型的預測值和真實值不一樣的程度,損失函數越好,通常模型的性能越好。不同的模型用的損失函數一般也不一樣。
2.3激活函數
在人工神經網絡中, 激活函數用于表示上層神經元輸出與下層輸入的非線性映射函數, 其主要作用就是增強神經網絡的非線性建模能力. 如無特殊說明激活函數一般是非線性函數. 如果不用激活函數, 每一層的輸出都是上一層輸入的線性函數, 無論神經網絡有多少層, 最終的輸出都是初始輸入的線性變換, 無法擬合現實中很多非線性問題. 引入激活函數后, 使得神經網絡可以逼近任何非線性函數, 理論上可以擬合任意分布的數據。
常用的激活函數如圖所示:
3. 實驗過程
3.1波士頓房價數據集
波士頓房價數據集是一個回歸問題。每個類的觀察值數量是均等的,共有 506 個觀察,13 個輸入變量和1個輸出變量。每條數據包含房屋以及房屋周圍的詳細信息。其中包含城鎮犯罪率,一氧化氮濃度,住宅平均房間數,到中心區域的加權距離以及自住房平均房價等等。
3.2實驗代碼
1.模塊導入
import torch import torch.nn as nn # 搭建神經網絡 from torch.optim import SGD # 優化器SGD import torch.utils.data as Data # 數據預處理from skimage.metrics import mean_squared_error from sklearn.metrics import r2_score # 使用r2_score對模型評估from sklearn.datasets import load_boston # 導入波士頓房價數據 from sklearn.preprocessing import StandardScaler # 數據標準化 from sklearn.model_selection import train_test_split # 導入數據集劃分模塊import numpy as npimport matplotlib.pyplot as plt import matplotlib.pyplot as plt22.數據預處理
需要將從sklearn導入的數據集中的數據進行劃分,分為訓練集和測試集,然后對數據進行標準化,因為需要將數據傳入pytorch 創建的網絡中,因此還要將數據從numpy轉化為torch張量。
3.定義網絡模型
定義了一個包含一個輸入層、兩個隱藏層和一個輸出層的多層感知器,在每個隱藏層之后連接了relu激活函數。
4.網絡配置
配置DataLoader進行數據加載,設置batch_size大小為32;定義優化器為SGD優化器并設置學習率為0.001,定義了損失函數為均方差損失函數。
5.訓練
迭代100次對網絡進行訓練。
6.測試及可視化
y_predict = mlp_1(test_xt).reshape(-1) # 預測# 網絡輸出有張量轉為numpy y_predict = y_predict.detach().numpy() test_yt = test_yt.detach().numpy()# 與驗證值作比較 error = mean_squared_error(test_yt, y_predict).round(5) # 平方差 score = r2_score(test_yt, y_predict).round(5) # 相關系數# 繪制真實值和預測值的對比圖 fig = plt.figure(figsize=(13, 7)) plt.rcParams['font.family'] = "sans-serif" plt.rcParams['font.sans-serif'] = "SimHei" plt.rcParams['axes.unicode_minus'] = False # 繪圖 plt.plot(range(test_yt.shape[0]), test_yt, color='red', linewidth=1, linestyle='-') plt.plot(range(test_yt.shape[0]), y_predict, color='blue', linewidth=1, linestyle='dashdot') plt.legend(['真實值', '預測值']) plt.title("波士頓房價預測", fontsize=20) error = "標準差d=" + str(error)+"\n"+"相關指數R^2="+str(score) plt.xlabel(error, size=18, color="black") plt.grid() plt.show()plt2.rcParams['font.family'] = "sans-serif" plt2.rcParams['font.sans-serif'] = "SimHei" plt2.title('波士頓房價預測', fontsize=20) xx = np.arange(0, 40) yy = xx plt2.xlabel('* truth *', fontsize=14) plt2.ylabel('* predict *', fontsize=14) plt2.plot(xx, yy) plt2.scatter(test_yt, y_predict, color='red') plt2.grid() plt2.show()完整代碼
import torch import torch.nn as nn # 搭建神經網絡 from torch.optim import SGD # 優化器SGD import torch.utils.data as Data # 數據預處理from skimage.metrics import mean_squared_error from sklearn.metrics import r2_score # 使用r2_score對模型評估from sklearn.datasets import load_boston # 導入波士頓房價數據 from sklearn.preprocessing import StandardScaler # 數據標準化 from sklearn.model_selection import train_test_split # 導入數據集劃分模塊import numpy as npimport matplotlib.pyplot as plt import matplotlib.pyplot as plt2 # 讀入數據 boston_X, boston_y = load_boston(return_X_y=True) x_train, x_test, y_train, y_test = train_test_split(boston_X, boston_y, test_size=0.3, random_state=0)# 標準化數據 ss = StandardScaler(copy=True, with_mean=True, with_std=True) xs_train = ss.fit_transform(x_train) sst = StandardScaler(copy=True, with_mean=True, with_std=True) xs_test = sst.fit_transform(x_test)# 將數據轉化為張量 test_xt = torch.from_numpy(xs_test.astype(np.float32)).cpu() test_yt = torch.from_numpy(y_test.astype(np.float32)).cpu() train_xt = torch.from_numpy(xs_train.astype(np.float32)).cpu() train_yt = torch.from_numpy(y_train.astype(np.float32)).cpu()# 定義網絡模型 class MLPmodel(nn.Module):def __init__(self):super(MLPmodel, self).__init__()# First hidden layerself.h1 = nn.Linear(in_features=13, out_features=30, bias=True)self.a1 = nn.ReLU()# Second hidden layerself.h2 = nn.Linear(in_features=30, out_features=10)self.a2 = nn.ReLU()# regression predict layerself.regression = nn.Linear(in_features=10, out_features=1)def forward(self, x):x = self.h1(x)x = self.a1(x)x = self.h2(x)x = self.a2(x)output = self.regression(x)return outputdevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')# 制作訓練用數據,即關聯數據,將輸房價特征數據train_xt與房價數據train_y關聯 train_data = Data.TensorDataset(train_xt, train_yt)# 定義一個數據加載器,用于批量加載訓練用數據, 讓數據分批次進入神經網絡 train_loader = Data.DataLoader(dataset=train_data,batch_size=32,shuffle=True,num_workers=0)mlp_1 = MLPmodel().cpu() print(mlp_1)optimizer = SGD(mlp_1.parameters(), lr=0.001) # 定義優化器 define Optimizer loss_function = nn.MSELoss() # 定義損失函數loss functiontrain_loss_all = [] # 存放每次迭代的誤差數據,便于可視化訓練過程# Train for epoch in range(100): # 迭代總輪數# 對每個批次進行迭代計算for step, (b_x, b_y) in enumerate(train_loader):output = mlp_1(b_x).flatten()train_loss = loss_function(output, b_y) # 誤差計算optimizer.zero_grad() # 梯度置位,或稱梯度清零train_loss.backward() # 反向傳播,計算梯度optimizer.step() # 梯度優化train_loss_all.append(train_loss.item())print("train epoch %d, loss %s:" % (epoch + 1, train_loss.item()))# 可視化訓練過程(非動態) plt.figure() plt.plot(train_loss_all, "g-") plt.title("MLPmodel1: Train loss per iteration") plt.show()y_predict = mlp_1(test_xt).reshape(-1) # 預測# 網絡輸出有張量轉為numpy y_predict = y_predict.detach().numpy() test_yt = test_yt.detach().numpy()# 與驗證值作比較 error = mean_squared_error(test_yt, y_predict).round(5) # 平方差 score = r2_score(test_yt, y_predict).round(5) # 相關系數# 繪制真實值和預測值的對比圖 fig = plt.figure(figsize=(13, 7)) plt.rcParams['font.family'] = "sans-serif" plt.rcParams['font.sans-serif'] = "SimHei" plt.rcParams['axes.unicode_minus'] = False # 繪圖 plt.plot(range(test_yt.shape[0]), test_yt, color='red', linewidth=1, linestyle='-') plt.plot(range(test_yt.shape[0]), y_predict, color='blue', linewidth=1, linestyle='dashdot') plt.legend(['真實值', '預測值']) plt.title("波士頓房價預測", fontsize=20) error = "標準差d=" + str(error)+"\n"+"相關指數R^2="+str(score) plt.xlabel(error, size=18, color="black") plt.grid() plt.show()plt2.rcParams['font.family'] = "sans-serif" plt2.rcParams['font.sans-serif'] = "SimHei" plt2.title('波士頓房價預測', fontsize=20) xx = np.arange(0, 40) yy = xx plt2.xlabel('* truth *', fontsize=14) plt2.ylabel('* predict *', fontsize=14) plt2.plot(xx, yy) plt2.scatter(test_yt, y_predict, color='red') plt2.grid() plt2.show()3.3運行結果
訓練過程損失值曲線變化曲線如圖:
計算測試集上的預測值與真實值標準差和r2相關指數并繪制,如圖:
總結
以上是生活随笔為你收集整理的基于神经网络多层感知器的波士顿房价数据集回归问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vim 函数列表插件
- 下一篇: Git 忽略一些文件的提交