pytorch簡單實例1---線性迴歸實例

在接觸pytorch中CNN的全連接層,卷積層,池化層的創建後,我們便可以使用特定的梯度下降算法,以及特定的損失函數來做簡單的線性迴歸了。

1.離散點的建立
因爲是做線性迴歸,所以我們需要人爲臆造一些符合某種線性關係的數據點

x_train = np.array([[.3], [1.2], [1.3], [2.], [3.2], [3.7], [4.], [4.9], [5.5], [6.], [6.7]], dtype=np.float32)
y_train = np.array([[.3], [1.], [2.1], [2.3], [3.], [2.9], [4.4], [5.], [5.5], [5.], [7.]], dtype=np.float32)
plt.figure()
plt.scatter(x_train, y_train)
plt.xlabel('x_train')
plt.ylabel('y_train')
plt.show()

在這裏插入圖片描述
2.創建線性迴歸的模型
就最常使用的方法是創建類屬性,繼承來自nn.Module的屬性

# 線性模型y=w*x+b,w和b的權值(weight)需要在創建時候給定,x爲輸入,在調用的時候輸入
class Linearmodel(nn.Module):

    def __init__(self, weight_w, weight_b):
        super(Linearmodel, self).__init__()

        self.model = nn.Sequential(
                                   nn.Linear(weight_w, weight_b),
                                   #CNN中的全連接層
                                   nn.Linear(weight_w, weight_b))
                                   #多創建一層,可以用於判斷層數與損失值的關係
        # self.model = nn.Sequential(
        #     nn.Linear(1, 1),  # 創建一個線性層,
        #     nn.ReLU(inplace=True),
        # )  # 調用一個激活函數,由於在第一象限,激活函數意義不大,只爲了更完整
        # 加上relu損失值更大

    def forward(self, x):
    #此部分尚未明確用意,但是參考許多文章,此函數不可省略
        out = self.model(x)
        return out

3.使用MSE損失和SGD的梯度優化方法來優化我們的模型

net = Linearmodel(weight_w, weight_b)  # 放入節點權值
criterion = nn.MSELoss()  # 指定損失函數,不能使用crossentropyloss,因爲這裏是1d
optimizer = torch.optim.SGD(net.parameters(), lr=learning_rate)  # 指定梯度優化方式

for i in range(num_epochs):
    inputs = var(torch.from_numpy(x_train))
    targets = var(torch.from_numpy(y_train))  # 使用var可以將來自numpy變換後的tensor自動變成我們所需的數值

    optimizer.zero_grad()  # 梯度初始化
    outputs = net(inputs)  # 將輸入值放入線性模型進行學習,得到輸出結果
    loss = criterion(outputs, targets)  # 計算損失值,輸出值與真實的目標值之間的差距
    loss.backward()  # 習慣將loss(損失值)的操作寫在一起
    optimizer.step()  # 開始梯度優化
    # net.eval()  # 保留已經運算的輸出結果
    if (i + 1) % 50 == 0:  # 便於查看計算過程
        print("訓練步驟:【{}/{}】,loss={}".format(i + 1, num_epochs, loss.item()))
#訓練結果
訓練步驟:【50/1000】,loss=4.736996650695801
訓練步驟:【100/1000】,loss=0.3275192975997925
訓練步驟:【150/1000】,loss=0.3081437647342682
訓練步驟:【200/1000】,loss=0.2996964454650879
訓練步驟:【250/1000】,loss=0.2921964228153229
訓練步驟:【300/1000】,loss=0.2855220139026642
訓練步驟:【350/1000】,loss=0.27957385778427124
訓練步驟:【400/1000】,loss=0.27426597476005554
訓練步驟:【450/1000】,loss=0.2695239186286926
訓練步驟:【500/1000】,loss=0.26528269052505493
訓練步驟:【550/1000】,loss=0.26148539781570435
訓練步驟:【600/1000】,loss=0.25808268785476685
訓練步驟:【650/1000】,loss=0.2550306022167206
訓練步驟:【700/1000】,loss=0.25229087471961975
訓練步驟:【750/1000】,loss=0.2498299479484558
訓練步驟:【800/1000】,loss=0.24761778116226196
訓練步驟:【850/1000】,loss=0.2456279695034027
訓練步驟:【900/1000】,loss=0.24383696913719177
訓練步驟:【950/1000】,loss=0.24222415685653687
訓練步驟:【1000/1000】,loss=0.24077099561691284

4.對於已經優化的模型我們作出迴歸線

predicted = net(var(torch.from_numpy(x_train))).data.numpy()#作出線性模型的圖像所需的預測數據
plt.scatter(x_train, y_train)
#plt.plot(x_train, y_train, 'rx')
plt.plot(x_train, predicted, label='predict')
plt.legend()
plt.show()

結果圖如下
在這裏插入圖片描述

完整代碼如下

#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
@author: 1234
@file: linear_practice.py
@time: 2020/06/27
@desc:
    格式化代碼 :Ctrl + Alt + L 
    運行代碼 : Ctrl + Shift + F10
    註釋代碼/取消註釋 : Ctrl + /
"""
import torch
import numpy as np
import matplotlib.pyplot as plt
import torch.nn as nn
from torch.autograd import Variable as var

weight_w = 1
weight_b = 1  # 線性模型的權值
learning_rate = 0.001  # 學習率
num_epochs = 1000# 訓練次數

x_train = np.array([[.3], [1.2], [1.3], [2.], [3.2], [3.7], [4.], [4.9], [5.5], [6.], [6.7]], dtype=np.float32)
y_train = np.array([[.3], [1.], [2.1], [2.3], [3.], [2.9], [4.4], [5.], [5.5], [5.], [7.]], dtype=np.float32)
plt.figure()
plt.scatter(x_train, y_train)
plt.xlabel('x_train')
plt.ylabel('y_train')
plt.show()


# 線性模型y=w*x+b,w和b的權值(weight)需要在創建時候給定,x爲輸入,在調用的時候輸入
class Linearmodel(nn.Module):

    def __init__(self, weight_w, weight_b):
        super(Linearmodel, self).__init__()

        self.model = nn.Sequential(
                                   nn.Linear(weight_w, weight_b),#CNN中的全連接層
                                   nn.Linear(weight_w, weight_b))#多創建一層,可以用於判斷層數與損失值的關係
        # self.model = nn.Sequential(
        #     nn.Linear(1, 1),  # 創建一個線性層,
        #     nn.ReLU(inplace=True),
        # )  # 調用一個激活函數,由於在第一象限,激活函數意義不大,只爲了更完整
        # 加上relu損失值更大

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


net = Linearmodel(weight_w, weight_b)  # 放入節點權值
criterion = nn.MSELoss()  # 指定損失函數,不能使用crossentropyloss,因爲這裏是1d
optimizer = torch.optim.SGD(net.parameters(), lr=learning_rate)  # 指定梯度優化方式

for i in range(num_epochs):
    inputs = var(torch.from_numpy(x_train))
    targets = var(torch.from_numpy(y_train))  # 使用var可以將來自numpy變換後的tensor自動變成我們所需的數值

    optimizer.zero_grad()  # 梯度初始化
    outputs = net(inputs)  # 將輸入值放入線性模型進行學習,得到輸出結果
    loss = criterion(outputs, targets)  # 計算損失值,輸出值與真實的目標值之間的差距
    loss.backward()  # 習慣將loss(損失值)的操作寫在一起
    optimizer.step()  # 開始梯度優化
    # net.eval()  # 保留已經運算的輸出結果
    if (i + 1) % 50 == 0:  # 便於查看計算過程
        print("訓練步驟:【{}/{}】,loss={}".format(i + 1, num_epochs, loss.item()))


predicted = net(var(torch.from_numpy(x_train))).data.numpy()#作出線性模型的圖像所需的預測數據
plt.plot(x_train, y_train, 'rx')
plt.plot(x_train, predicted, label='predict')
plt.legend()
plt.show()

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