DeepLeaning入門——簡單案例資料擬合
在深度學習環境安裝一文中,我們已經搭建了擼程式碼的基本環境。現在就可以來正式寫程式碼了,雞凍!我們今天的目的是模擬一些資料(線性),並通過調整引數(斜率k和b)找到和這些資料最匹配的函式。中間會穿插一些關於運算概念的解釋
大概長這樣

首先是引入pytorch,以及包含的 variable
(所有程式碼都在jupyter notebook中完成)
import torch from torch.autograd import Variable 複製程式碼
這個 variable
是用來幹什麼的呢? 它其實是一個 自動微分變數
,簡單來說,他是將張量的運算“流程化”,在使用自動微分變數進行運算時,其實上是在構建一個計算圖。 比如, 我們定義了兩個py變數,並把他們打印出來看
//定義一個tensor x = torch.tensor([[1.,2.],[3.,4.]]) //定一個variable y = Variable(x,requires_grad = True); print('x',x); print('y',y); 複製程式碼

requires_grad = True
的含義是讓這個微分變數
可反向傳播
tensor
的方法 variable
幾乎都能用,而 variable
有很多它自己獨特的方法,比如 反向傳播(backward)
,對輸入量求 梯度值(grad())
等等。別急,它們具體是什麼含義我們稍後揭曉
知道了什麼是自動微分變數之後,我們開始進入正題。
讓我們再定一個variable變數, torch.linspace(0, 10)
是建立在閾值為[0, 10]上均等劃分出一個100維的向量,結果如圖所示
x = Variable(torch.linspace(0, 10),requires_grad = True) print(x) 複製程式碼

然後我們對這個變數進行幾步運算,得到一個變數z
y = x + 2# y是一個100維的自動微分變數,值為x的每項+2 z = torch.mean(y*y) # torch.mean()的含義是求均值,z為一個數值(或者理解為0維的張量) print(z) 複製程式碼

backward()
方法進行反向傳播,從而獲取到x的變化梯度。
z.backward() #反向傳播操作 x.grad#獲取x反傳後的梯度值 print(x.grad) 複製程式碼

到這一步你就會發現,這樣的操作並沒有什麼實際的意義。所有的操作都只是為了解釋這些基本概念
好了真實案例開搞
首先我們模擬一些離散的點。使用randn方法生成[0-1]區間內正態分佈的隨機點,它接收一個生成數量的引數
# 橫座標, 100維張量,分為100份 x = Variable(torch.linspace(0, 100).type(torch.FloatTensor)); # 我們現在要設定y,先生成一些隨機分佈的數 rand = Variable(torch.randn(100) * 10); y = x + rand 複製程式碼
設定完了之後我們把這些點畫出來,這裡就用到了一個第三方的庫 matplotlib.pyplot
,官方文件在這裡,上篇文章也帶大家安裝過。這裡直接引入,並畫圖
# 引入繪相簿 import matplotlib.pyplot as plt # 畫圖操作,'ro'代表繪製離散的點 plt.plot(x.data.tolist(),y.data.tolist(), 'ro' ) 複製程式碼
繪圖結果如下

然後就開始去計算我們要求的函式的引數。這個圖形是線性的,沒有扭來扭去的波段,我們就可以將它設為一個一次函式 y = k * x + b
的形式,k和b就是我們最後要訓練得到的引數
先隨機生成k和b這兩個引數,再設定學習率。
學習率的設定一般都在0.0001,如果太大會導致無法得到精確的結果,而太小又需要數量更多的運算過程。
# 先隨機生成這個引數 k = Variable(torch.rand(1), requires_grad = True) b = Variable(torch.rand(1), requires_grad = True) # 設定一個學習率 learning_rate = 0.0001;#學習率 複製程式碼
現在開始訓練
#這裡的a和b都是一個1維的自動微分變數 for i in range(1000): # 為了之後的計算,k.expand_as(x) 方法將a的維度擴充套件到和x一致,x是100維,k就會也變成一個100維張量 predictions = k.expand_as(x)*x+b.expand_as(x) # 損失函式定義方法: 我們要使預測出來的y值到真實y值的距離最小 loss = torch.mean((predictions - y) ** 2)# **2代表平方 # 使用loss進行反向傳播 # loss在逐漸減小 loss.backward() #獲得k和b的變化梯度 # 根據變化梯度和學習率獲取到新的a b值 k.data.add_(-learning_rate * a.grad.data) b.data.add_(-learning_rate * b.grad.data) # 梯度記得清空 k.grad.data.zero_() b.grad.data.zero_() 複製程式碼
經過訓練步驟後我們就獲得了新的k和b,那麼我們就可以畫出這條一次函數了. 這時候我們需要引入計算包numby,將tensor轉為可以繪圖的資料
# 設定繪圖畫布大小 plt.figure(figsize = (10, 7)) #為了對比把離散點也畫上 plt.plot(x.data.numpy(),y.data.numpy(), 'ro') # 繪製函式 plt.plot(x.data.numpy(), a.data.numpy() * x.data.numpy() + b.data.numpy()) 複製程式碼

大功告成
over ~~
下回我會寫一篇真正的神經網路訓練過程,更復雜也更有趣~ 敬請期待
參考資料 ofollow,noindex">火炬上的深度學習-集智AI學園 pytorch官網 matplotlib繪相簿官網