pytorch學習筆記(一)之線性模型

pytorch學習筆記(一)之線性模型

2020.1.27筆記

  1. Grad在反向傳播過程中是累加的,意味着每一次運行反向傳播,梯度都會累加之前的梯度,一般在方向傳播之前把梯度清零。
  2. 不允許張量對張量求導,只允許標量對張量求導,求導結果是和自變量同行的張量。
  3. 可以用with torch.no_grad()將不想被追蹤的操作代碼塊包裹起來。
  4. Torch變量帶requires_grad的不能進行+=操作。x+=2。
  5. 批量大小和學習率的值是人爲設定的,不是通過模型訓練學出的,稱之爲超參數。
  6. Python super()函數用於調用父類(超類)的一個方法。
  7. a.numpy()將a轉換成numpy數據類型,torch.from_numpy()將numpy轉換爲tensor。
  8. torch.cuda.is_available()判斷是否支持gpu,a.cuda()就能夠將tensor a放到gpu上面。
  9. torch.autograd.Variable會被放入計算圖中,然後進行前向傳播和反向傳播,自動求導
    包含三個部分data,grad,grad_fn。from torch.autograd import Variable
    通過data可以去除variable裏面的tensor數值
    Grad_fn表示的是得到這個variable的操作
    Grad是這個variable反向傳播梯度
    求導y.backward(),對於標量求導裏面的參數可以不寫
    對於向量求導不能直接寫成y.backward()。需要傳入參數聲明。比如y.backward(torch.FloatTensor([1,1,1])),得到的就是每個分量的梯度。

2020.1.28筆記

  1. 優化算法:是一種調整模型參數更新的策略
    一階優化算法,使用各個參數的梯度值來更新參數,梯度下降。
    二階優化算法,使用了二階導數,hessian方法,來最小化或者最大化損失函數。
    torch.optim是一個實現各種優化算法的包。在調用時將需要優化的參數傳入,這些參數都必須是Variable,然後傳入一些基本的設定,比如學習率和動量等。
    優化之前,需要先將梯度歸0,optimizer.zeros(),然後通過loss.backward()自動求導得到每個參數的梯度,最後只需要optimizer.step()就可以通過梯度做一步參數更新。
  2. torch.save用於保存模型的結構和參數。保存方式兩種:
    保存整個模型的結構信息和參數信息,保存的對象是model
    保存模型的參數,保存的對象是模型的狀態。model.state_dict()。
    torch.save(model, ‘./model.pth’)
    torch.save(model.state_dict(), ‘./model_state.pth’)
    3.加載模型
    加載完整的模型結構和參數信息
    Load_model = torch.load('model.pth’),網絡較大的時候加載時間較長,同時存儲空間也比較大。
    加載模型參數信息,需要先導入模型的結構,然後
    model.load_state_dic(torch.load(‘model_state.pth’))導入。
    4.線性迴歸案例。
    給出一系列點,找到擬合的直線。model.eval()將模型變成測試模式,一些層如dropout和batchNormalization在訓練和測試的時候是不一樣的,因而需要通過這樣一個操作來轉換這些不一樣的層操作。
import torch
from torch import nn,optim
import numpy as np
import matplotlib.pyplot as plt
from torch.autograd import Variable
#線性迴歸,輸入數據(x1,y1),(x2,y2),...,(xn,yn)
x_train = np.array([[3.3],[4.4],[5.5],[6.71],[6.93],[4.168],
                    [9.779],[6.182],[7.59],[2.167],[7.042],
                    [10.791],[5.313],[7.997],[3.1]],dtype=np.float32)
y_train = np.array([[1.7],[2.76],[2.09],[3.19],[1.694],[1.573],
                    [3.366],[2.596],[2.53],[1.221],[2.827],
                    [3.465],[1.65],[2.904],[1.3]],dtype=np.float32)
#轉爲tensor
x_train = torch.from_numpy(x_train)
y_train = torch.from_numpy(y_train)

#定義線性迴歸網絡結構
class LinearRegression(nn.Module):
    def __init__(self):
        super(LinearRegression, self).__init__()
        self.linear = nn.Linear(1,1)

    def forward(self, x):
        out = self.linear(x)
        return out
#定義在gpu上的LinearRegression成員
if torch.cuda.is_available():
    model = LinearRegression().cuda()
else:
    model = LinearRegression()

#定義損失函數
criterion = nn.MSELoss()
#定義優化函數
optimizer = optim.SGD(model.parameters(), lr=1e-3)
num_epochs = 1000
for epoch in range(num_epochs):
    if torch.cuda.is_available():
        inputs = Variable(x_train).cuda()
        target = Variable(y_train).cuda()
    else:
        inputs = Variable(x_train)
        target = Variable(y_train)
    #forward
    out = model.forward(inputs)
    loss = criterion(out, target)
    #backward
    #梯度清0
    optimizer.zero_grad()
    #反向傳播
    loss.backward()
    #參數更新
    optimizer.step()
    if (epoch+1)%40 == 0:
        print('loss:', loss.data)
#將模型轉爲測試模式
model.eval()
#預測結果
predict = model.forward(Variable(x_train).cuda())
#轉成cpu,轉爲numpy
predict = predict.data.cpu().numpy()
plt.plot(x_train.numpy(), y_train.numpy(), 'ro', label='Original data')
plt.plot(x_train.numpy(), predict, label='Fitting Line')
plt.show()

在這裏插入圖片描述
在這裏插入圖片描述
2020.1.29筆記
多項式迴歸

  1. Torch.unsqueeze()對數據維度進行擴充
    a.unsqueeze(1)在第二維增加一個維度
    torch.squeeze()對數據進行降維,只有維度值爲1時纔會去掉改維度。
  2. tensor.size()
import torch
import numpy as np

test = torch.tensor([0,1,2])
print(test.size())
print(test[0], test[1], test[2])

test = torch.tensor([[0,1,2]])
print(test.size())
print(test[0])
print(test[0][0], test[0][1], test[0][2])
運行結果爲:
torch.Size([3])
tensor(0) tensor(1) tensor(2)
torch.Size([1, 3])
tensor([0, 1, 2])
tensor(0) tensor(1) tensor(2)

3.torch.mm()爲矩陣乘法
x.mm(w_target)
4.

import torch
import numpy as np
from torch import nn, optim
from torch.autograd import Variable
import matplotlib.pyplot as plt
#生成特徵點
def make_features(x):
    #在第二個維度添加一個維度
    #print("before x.size:", x.size())
    x = x.unsqueeze(1)
    #print("x:", x)
    #print("after x.size:", x.size())
    return torch.cat([x**i for i in range(1,4)], 1)

w_target = torch.FloatTensor([0.5, 3, 2.4]).unsqueeze(1)
#print('w_target: ', w_target)
b_target = torch.FloatTensor([0.9])

#將每次輸入一個x得到一個y的真實函數
def f(x):
    return x.mm(w_target) + b_target

#得到batch_size個訓練集
def get_batch(batch_size=32):
    #生成batch_size個隨機數
    random = torch.randn(batch_size)
    x = make_features(random)
    y = f(x)

    if torch.cuda.is_available():
        return Variable(x).cuda(), Variable(y).cuda()
    else:
        return Variable(x), Variable(y)

#定義多項式模型
class poly_model(nn.Module):
    def __init__(self):
        super(poly_model, self).__init__()
        #模型輸入爲3維,輸出是1維
        self.poly = nn.Linear(3,1)

    def forward(self, x):
        out = self.poly(x)
        return out

def main():
    if torch .cuda.is_available():
        model = poly_model().cuda()
    else:
        model = poly_model()

    criterion = nn.MSELoss()
    #使用隨機梯度下降來優化模型
    optimizer = optim.SGD(model.parameters(), lr=1e-3)

    #開始訓練模型
    epoch = 0
    while True:
        # 獲取數據集
        batch_x, batch_y = get_batch()

        #前向傳播
        output = model.forward(batch_x)
        #計算損失
        loss = criterion(output, batch_y)
        #打印損失值
        print_loss = loss.data
        #梯度清0
        optimizer.zero_grad()
        #反向傳播
        loss.backward()
        #更新參數
        optimizer.step()
        epoch += 1
        if print_loss < 1e-3:
            break
    print('loss: %.3f after batches: %d' %(print_loss, epoch))

    w_0, w_1, w_2 = model.poly.weight[0]
    w_0 = w_0.data.item()
    w_1 = w_1.data.item()
    w_2 = w_2.data.item()
    b_ = model.poly.bias[0].item()

    x = np.arange(-1,1,0.1)
    w0_truth = w_target[0].item()
    w1_truth = w_target[1].item()
    w2_truth = w_target[2].item()
    b_truth = b_target.item()
    y = w0_truth * x + w1_truth * x * x + w2_truth * x * x * x + b_truth

    y_ = w_0 * x + w_1 * x * x + w_2 * x * x * x + b_

    print('truth result:')
    print('w0:%.3f,w1:%.3f,w2:%.3f,b:%.3f' % (w0_truth, w1_truth, w2_truth, b_truth))
    print('train result:')
    print('w0:%.3f,w1:%.3f,w2:%.3f,b:%.3f' % (w_0, w_1, w_2, b_))
    plt.figure()
    plt.plot(x, y, 'ro')
    plt.plot(x, y_, 'b-')
    plt.legend(['actual curve', 'predict curve'])
    plt.show()


if __name__ == '__main__':
    main()

在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章