深度學習 pytorch實戰 神經網絡關係擬合

Pytorch是最近興起的新的深度學習框架,不同於tensorflow的先構建計算圖再進行運算,它是動態構建計算圖,因此更為通俗易懂。

本文主要使用Pytorch來完成對三次函數的擬合任務,並比較集中不同的激活函數對預測結果的影響。

手動構造的三次函數如下(為了模擬真實場景,函數中加入了一些隨機噪聲)

深度學習 pytorch實戰 神經網絡關係擬合

x^3-x^2

在Pytorch中,為了完成模型的搭建,我們需要創建一個繼承torch.nn.Module的類,類中我們需要實現forward函數和init函數。

代碼如下:

<code>import torchimport torch.nn.functional as Ffrom torch.autograd import Variableimport matplotlib.pyplot as pltx = torch.unsqueeze(torch.linspace(-1, 1, 300), dim=1)  y = x.pow(3) - x.pow(2) + 0.2*torch.rand(x.size())plt.scatter(x.data.numpy(), y.data.numpy())plt.show()class Net(torch.nn.Module):  # 繼承 torch 的 Module        def __init__(self, n_feature, n_hidden1, n_hidden2, n_output):                super(Net, self).__init__()     # 繼承 __init__ 功能        # 定義每層用什麼樣的形式                             self.hidden1 = torch.nn.Linear(n_feature, n_hidden1)   # 隱藏層線性輸出                             self.hidden2 = torch.nn.Linear(n_hidden1, n_hidden2)  # 隱藏層線性輸出                             self.predict = torch.nn.Linear(n_hidden2, n_output)   # 輸出層線性輸出                    def forward(self, x):   # 這同時也是 Module 中的 forward 功能               # 正向傳播輸入值, 神經網絡分析出輸出值                x = F.relu(self.hidden1(x))      # 激勵函數(隱藏層的線性值)                x = F.relu(self.hidden2(x))  # 激勵函數(隱藏層的線性值)                x = self.predict(x)             # 輸出值        return x                net = Net(n_feature=1, n_hidden1=10, n_hidden2=10, n_output=1)#創建一個類的對象optimizer = torch.optim.SGD(net.parameters(), lr=0.2)  # 傳入 net 的所有參數, 創建一個SGD優化器loss_func = torch.nn.MSELoss()  # 定義損失函數plt.ion()  # 畫圖plt.show()for t in range(300):#總共進行300代的優化    prediction = net(x)  # 餵給 net 訓練數據 x, 輸出預測值        loss = loss_func(prediction, y)  # 計算兩者的誤差        optimizer.zero_grad()  # 清空上一步的殘餘更新參數值        loss.backward()  # 誤差反向傳播, 計算參數更新值        optimizer.step()  # 將參數更新值施加到 net 的 parameters 上    if t % 5 == 0:  #每5步更新一次圖像        plt.cla()        plt.scatter(x.data.numpy(), y.data.numpy())        plt.plot(x.data.numpy(), prediction.data.numpy(), 'r-', lw=5)        plt.text(0.5, 0, 'Loss=%.4f' % loss.data.numpy(), fontdict={'size': 20, 'color': 'red'})        plt.pause(0.1)/<code>


比較一下使用不同激活函數的擬合效果:

RELU函數


深度學習 pytorch實戰 神經網絡關係擬合

RELU

softplus函數:


深度學習 pytorch實戰 神經網絡關係擬合

softplus

tanh函數:


深度學習 pytorch實戰 神經網絡關係擬合

tanh

對比三個激活函數的擬合效果,我們可以發現,經過relu函數擬合的曲線帶有明顯的“稜角”,這也是有relu函數自身不可導的特性所致。但是這種稜角特性在加深網絡後就變得不再明顯。同時,relu函數也是預測結果最好的激活函數,這符合我們的預期。


分享到:


相關文章: