本節利用pytorch中的模塊,生成一個更加簡潔的代碼來實現一樣的功能python
%matplotlib inline import torch from IPython import display from matplotlib import pyplot as plt import numpy as np import random
num_inputs =2 ## 特徵數量 num_examples=1000 # 樣本量 true_w=[2,-3.4] # 真實的權重係數 true_b=4.2 # 真實的偏置量 features = torch.randn(num_examples,num_inputs,dtype=torch.float32) # 生成隨機的特徵 labels = true_w[0]*features[:,0]+true_w[1]*features[:,1]+true_b # 生成隨機的標籤 labels += torch.tensor(np.random.normal(0,0.01,size=labels.size()),dtype=torch.float32) #在標籤上加上隨機噪聲項
pytotch 提供了data包來讀取數據。因爲data經常使用做變量名,咱們將data導入的data模塊用Data代替。在每一次的迭代中,咱們將隨機讀取包含10個樣本的小批量算法
import torch.utils.data as Data batch_size=10 dataset= Data.TensorDataset(features,labels) data_iter = Data.DataLoader(dataset,batch_size,shuffle=True) for X,y in data_iter: print(X,y) break
tensor([[ 1.9769, 1.5576], [-0.4743, 0.8653], [ 0.2641, 1.9682], [-2.3385, 0.3753], [ 0.3972, -0.6515], [ 1.1317, -0.2586], [ 1.6896, 1.0102], [-0.6803, 0.7734], [-0.3525, -0.7764], [ 0.3199, 0.9397]]) tensor([ 2.8727, 0.3198, -1.9711, -1.7576, 7.2187, 7.3517, 4.1360, 0.2171, 6.1193, 1.6434])
從上一節從零開始的實現中,咱們須要定義模型參數,並使用他們一步步描述模型是怎樣計算的。當模型結果變得複雜時,這些步驟變得更加繁瑣。其實pytorch提供了大量的預約義的層,這使我, 只須要關注使用哪些層來構造模型。下面介紹pytorch更加簡潔的定義線性迴歸。網絡
在實際使用中,經過會繼承torch.Module,撰寫本身的網絡/層。一個nn.Module實例應該包含一些曾以及返回輸出的前向傳播(forward)方法.數據結構
from torch import nn class LinearNet(nn.Module): def __init__(self,n_features): super(LinearNet,self).__init__() self.linear = nn.Linear(n_features,1) # 這裏的1是指out_features def forward(self,x): y = self.linear(x) return y net = LinearNet(num_inputs) # 輸入特維度爲2,輸出結果維度爲1 print(net)
LinearNet( (linear): Linear(in_features=2, out_features=1, bias=True) )
事實上,咱們還能夠用nn.Sequential來更加方便的搭建網絡,Sequential是一個有序的容器,網絡層將按照在傳入的Sequential的順序依次被添加到計算圖中。dom
# 寫法1 net= nn.Sequential(nn.Linear(num_inputs,1) # 此處還能夠傳入其餘的層 ) # 寫法2 net = nn.Sequential() net.add_module('linear',nn.Linear(num_inputs,1)) # net.add_module ..... # 寫法3 from collections import OrderedDict net = nn.Sequential( OrderedDict([ ('linear',nn.Linear(num_inputs,1)) # 其餘的層 ]) ) print(net) print(net[0])
Sequential( (linear): Linear(in_features=2, out_features=1, bias=True) ) Linear(in_features=2, out_features=1, bias=True)
for param in net.parameters(): print(param)
Parameter containing: tensor([[-0.4229, -0.0282]], requires_grad=True) Parameter containing: tensor([0.0852], requires_grad=True)
做爲一個單層神經網絡,線性迴歸輸出層中的神經元和輸入層中各輸入完成全鏈接,所以線性迴歸的輸出層有叫做全鏈接層函數
在使用net前,咱們須要初始化模型參數,如線性迴歸模型中的權重和誤差。pytorch在init模型中提供了多種參數初始化方法。這裏的init是initializer的縮寫形式。咱們經過init.normal_將權重參數每一個元素初始化爲隨機採樣的均值爲0,標準差爲0.01的正態分佈。誤差會初始化爲0工具
from torch.nn import init init.normal_(net[0].weight,mean=0,std=0.01) init.constant_(net[0].bias,val=0) # 該寫法與後面的三種寫法才能夠使用,若是使用一開始的寫法,net[0].weight 因改成net.linear.weight bias亦然。 #由於net[0]這樣的寫法只有當net是ModuleList或者Sequential實例時才能夠。 #
Parameter containing: tensor([0.], requires_grad=True)
# pytorch在nn模塊中提供了各類損失函數,這些損失函數能夠看作是一種特殊的層,pytorch也將這些損失函數實現爲nn.Module的子類。這裏咱們使用 # pytorch提供的均方偏差損失做爲模型的損失函數 loss = nn.MSELoss()
一樣咱們也無需本身實現小批量隨機梯度降低算法,torch.optim 模塊提供了不少經常使用的優化算法,SGD,Adam,RMSPorp等。下面咱們建立了一個用於優化net全部參數的優化器實例,並指定學習率爲0.03的小批量隨機梯度降低(SGD)爲優化算法。學習
import torch.optim as optim optimizer = optim.SGD(net.parameters(),lr=0.03) print(optimizer)
SGD ( Parameter Group 0 dampening: 0 lr: 0.03 momentum: 0 nesterov: False weight_decay: 0 )
咱們能夠爲不一樣的子網絡設置不一樣的學習率,這在finetune時常常用到。優化
optimizer = optim.SGD( [ {'params':net.subset1.parameters()}, # lr 默認用最外層的學習率 {'params':net.subset2.parameters(),'lr':0.01} ], lr= 0.03 )
在使用pytorch訓練模型時,咱們經過調用optim實例的step函數來迭代模型參數。按照小批量隨機梯度降低的定義,咱們在step函數中指明批量大小
從而而批量中中樣本梯度求平均ui
num_epochs =3 for epoch in range(1,num_epochs+1): for X,y in data_iter: output = net(X) l = loss(output,y.view(-1,1)) optimizer.zero_grad() # 梯度清零,等價於net.zero_grad() l.backward() optimizer.step() print('epoch %d loss: %f'%(epoch,l.item()))
epoch 1 loss: 0.000286 epoch 2 loss: 0.000199 epoch 3 loss: 0.000072
下面咱們分別比較學到的模型參數和真實的模型參數。咱們從net得到的須要的層,並訪問其權重(weight)和誤差(bias)。學到的參數和真實的參數很接近
dense=net[0] print(true_w,dense.weight) print(true_b,dense.bias)
[2, -3.4] Parameter containing: tensor([[ 2.0010, -3.3996]], requires_grad=True) 4.2 Parameter containing: tensor([4.2005], requires_grad=True)