一、環境准備
PyTorch框架安裝,上篇隨筆提到了 如何安裝 ,這里不多說。
matplotlib模塊安裝,用於仿真繪圖。
一般搭建神經網絡還會用到numpy、pandas和sklearn模塊,pip安裝即可,這里我沒有用到。
import torch from torch.autograd import Variable import matplotlib.pyplot as plt
導入模塊
二、數據處理
根據實際預測需求確定輸入結點數和輸出結點數,我的代碼中inputnum、hiddennum、outputnum分別為(2,12,1)
神經網絡框架接受的輸入和輸出都是張量(tensor)形式,需要將多維度的數組或矩陣轉化到一個tensor中。如果不了解tensor,可以看:https://www.pytorch123.com/SecondSection/what_is_pytorch/
inputdata = torch.tensor(inputdata) outputdata = torch.tensor(outputdata)
還需要保證輸入(input)數據和目標(target)數據的維度相同,用torch.unsqueeze()來對輸入數據實現升維,torch.squeeze()來對預測值(predication)實現降維。
xtrain = torch.unsqueeze(torch.tensor(xtrain).float(), dim=1) #升維 xtest = torch.unsqueeze(torch.tensor(xtest).float(), dim=1)
這里 '.float()'的作用是使input和target數據類型一致,否則會報錯。可以聲明為其他類型,只要保持一致即可。
然后就是數據歸一化處理,數據歸一化處理主要包括數據同趨化處理(中心化處理)和無量綱化處理。不同評價指標往往具有不同的量綱和量綱單位,這樣的情況會影響到數據分析的結果,為了消除指標之間的量綱影響,需要進行數據標准化處理,以解決數據指標之間的可比性。具體的實現方法有很多種,可以自行查找。常用的處理方法:
建議只對input做歸一化處理,如果對target也做歸一化處理,就需要對預測值做反歸一化處理。
最后就是對數據做噪聲處理,這里我采用的方案是對target做手動添加噪聲。
ytrain = ytrain + 0.2*torch.rand(ytrain.size()) #加入噪聲提高魯棒性 ytest = ytest + 0.2*torch.rand(ytest.size())
加入噪聲可以認為是在增加網絡訓練的難度,可以達到一定的正則效果,常見的比如dropout,數據增強中給輸入數據加入噪聲。輸入層注入噪聲,其實可以看作是數據集增強的一種手段,本質是一種正則化。原因是神經網絡對於噪聲並不健壯,只好混入噪聲再進行訓練,提高魯棒性。輸出層注入噪聲,其實是對標簽噪聲建模。大部分數據集的label,總會有一定的錯誤率。
三、搭建神經網絡
用框架搭建神經網絡有兩種方法:
import torch import torch.nn.functional as F # 方法1,通過定義一個Net類來建立神經網絡 class Net(torch.nn.Module): def __init__(self, n_feature, n_hidden, n_output): super(Net, self).__init__() self.hidden = torch.nn.Linear(n_feature, n_hidden) self.predict = torch.nn.Linear(n_hidden, n_output) def forward(self, x): x = F.relu(self.hidden(x)) x = self.predict(x) return x net1 = Net(2, 12, 1)
第二種方案比第一種簡單許多,兩個網絡結構不同,但功能相似。
net1 = torch.nn.Sequential( torch.nn.Linear(2, 12), torch.nn.ReLU(), #激活函數 torch.nn.Linear(12, 1), torch.nn.Softplus() )
激活函數的選取一般是ReLU、Sigmoid和Softplus等,根據無限逼近原理,選取合適的激活函數和隱含層結點數就可以得到一個非線性函數。
其次,搭建完神經網絡可能需要保存網絡結構或參數,具體操作看這里 save()
四、訓練和測試數據
本例中6000組訓練集數據,2000組測試集數據。
optimizer = torch.optim.SGD(net1.parameters(), lr=0.5) #梯度下降方法 loss_function = torch.nn.MSELoss() #計算誤差方法 # 訓練部分 for i in range(500): prediction = net1(xtrain) prediction = prediction.squeeze(-1) loss = loss_function(prediction, ytrain) if loss.data <= 0.06: break optimizer.zero_grad() #消除梯度 loss.backward() #反向傳播 optimizer.step() #執行
lr是學習率,可以自己決定參數大小,也可以選用動態學習率。訓練終止條件可以設置也可以不設置。如果不了解代碼中的各個函數什么意思,推薦參考pytorch官方文檔。
# 首先搭建相同的神經網絡結構 net2 = torch.nn.Sequential( torch.nn.Linear(2, 12), torch.nn.ReLU(), torch.nn.Linear(12, 1), torch.nn.Softplus() ) # 載入神經網絡的模型參數 net2.load_state_dict(torch.load('net_params.pkl')) prediction = net2(xtest) prediction = prediction.squeeze(-1)
如果你之前保存了訓練出的參數,那么你需要調用參數文件,然后再進行預測。
五、預測數據處理
可以自己選取要觀測的數值,然后用matplotlib繪圖。
plt.title('net2') plt.scatter(ytest.data.numpy(), prediction.data.numpy()) plt.plot(ytest.data.numpy(), ytest.data.numpy(),'r--') plt.show()
最終結果如下:
可以看到,預測結果還是可信的。