01.linear regression note

01.note

正文链接:https://jovian.ai/aakashns/02-linear-regression

一.不用pytorch的module模型手写简单的线性问题

1)输入train_data和test_data

#1.输入数据集
inputs = np.array([[73, 67, 43],
                   [91, 88, 64],
                   [87, 134, 58],
                   [102, 43, 37],
                   [69, 96, 70]], dtype='float32')

targets = np.array([[56, 70],
                    [81, 101],
                    [119, 133],
                    [22, 37],
                    [103, 119]], dtype='float32')
inputs = torch.from_numpy(inputs)
targets = torch.from_numpy(targets)

2)确定W和b的形状 初始化W和b

首先明确函数,该问题有两条函数:

注意:W的上标表示该W为第几条函数的W

确定形状:

矩阵和公式契合。

值得注意的是:在pytorch中,计算y(hat)的值并非是 y = wx+b 而是 y = x*w.t()+b,所以这里W的形状不是3,2,而是2,3,且w,b需要计算梯度

code:

w = torch.randn(2, 3, requires_grad=True)
b = torch.randn(2, requires_grad=True)

3).定义前馈函数

def module(x):
    return x@w.t()+b

4)定义Loss函数,采用均方差

def mse(t1, t2):
    diff = t1 - t2
    return torch.sum(diff * diff) / diff.numel()#numel返回torch对象里的元素个数,这里是10 target大小一致

5)train

for i in range(10000):
    preds = model(inputs)
    loss = mse(preds, targets)
    #pytorch框架自动计算loss中的梯度,并存储在w,b中
    loss.backward() 
    print(loss)

    with torch.no_grad():
        w -= w.grad * 1e-5
        b -= b.grad * 1e-5
        w.grad.zero_()
        b.grad.zero_()

里面值得注意的是:

 with torch.no_grad():

当我们不想进行梯度的计算时,加上这一行代码

loss变换结果:

tensor(26934.1621, grad_fn=<DivBackward0>)
tensor(18410.7305, grad_fn=<DivBackward0>)
tensor(12663.6895, grad_fn=<DivBackward0>)

.....

tensor(0.5032, grad_fn=<DivBackward0>)
tensor(0.5032, grad_fn=<DivBackward0>)
tensor(0.5032, grad_fn=<DivBackward0>)

全部代码:

import numpy as np
import torch

#1.输入数据集
inputs = np.array([[73, 67, 43],
                   [91, 88, 64],
                   [87, 134, 58],
                   [102, 43, 37],
                   [69, 96, 70]], dtype='float32')

targets = np.array([[56, 70],
                    [81, 101],
                    [119, 133],
                    [22, 37],
                    [103, 119]], dtype='float32')
inputs = torch.from_numpy(inputs)
targets = torch.from_numpy(targets)

#2.确定w,b矩阵
w = torch.randn(2, 3, requires_grad=True)
b = torch.randn(2, requires_grad=True)

#3.定义前馈函数
def model(x):
    return x@w.t() + b

#4.定义Loss function,MSE(均方差) numel()返回torch对象中元素的个数
def mse(t1, t2):
    diff = t1 - t2
    return torch.sum(diff * diff) / diff.numel()

for i in range(10000):
    preds = model(inputs)
    loss = mse(preds, targets)
    loss.backward()
    print(loss)

    with torch.no_grad():
        w -= w.grad * 1e-5
        b -= b.grad * 1e-5
        w.grad.zero_()
        b.grad.zero_()

二.引入pytorch框架的model与Dataset and DataLoader简化上述过程

import

import numpy as np
import torch
from torch.utils.data import TensorDataset
from torch.utils.data import DataLoader
import torch.nn as nn #构建model
import torch.nn.functional as F #构建loss function

1.数据划分

#1.数据划分
train_ds = TensorDataset(inputs,targets)
batch_size = 5
train_dl = DataLoader(train_ds, batch_size, shuffle=True) 

TensorDataset和DataLoader一般一起使用,用于将数据分块,batch_size是每块所含有的行数,shuffle参数是将数据打乱。

for xb, yb in train_dl:
    print(xb)
    print(yb)
    break
#结果是
tensor([[102.,  43.,  37.],
        [ 92.,  87.,  64.],
        [ 87., 134.,  58.],
        [ 69.,  96.,  70.],
        [101.,  44.,  37.]])
tensor([[ 22.,  37.],
        [ 82., 100.],
        [119., 133.],
        [103., 119.],
        [ 21.,  38.]])

若想从train_ds,或train_dl中各自取得trainset和testset,可以采取下面的方式,支持切片

x,y = train_ds[:,:]
print("x:",x)
print("y:",y)

#结果是:
x: tensor([[ 73.,  67.,  43.],
        [ 91.,  88.,  64.],
        [ 87., 134.,  58.],
        [102.,  43.,  37.],
        [ 69.,  96.,  70.]])
y: tensor([[ 56.,  70.],
        [ 81., 101.],
        [119., 133.],
        [ 22.,  37.],
        [103., 119.]])

2.使用model构建w b

#2.构建model
model = nn.Linear(3, 2)#传入w的形状后,其实bias的形状也就确定了,这里也是随机构成
print(model.weight)
print(model.bias)
#结果
tensor([[ 0.5272,  0.1223, -0.1660],
        [ 0.5324, -0.2326, -0.0065]], requires_grad=True)
Parameter containing:
tensor([-0.1113,  0.2527], requires_grad=True)

3.构建loss function

#3.构建loss function
loss_fn = F.mse_loss

当需要计算loss的时候,只需要传入input前馈后的值和标准值target, 该函数会自己用mse去计算loss.并将w的梯度计算存储在计算图内。

loss = loss_fn(model(inputs), targets)

4.构建optimizer(用于改变w,b的值),并设定学习率

opt = torch.optim.SGD(model.parameters(), lr=1e-5)

model.parameters()里面就是w与b。lr为学习率, w(new) = w(old) - lr*gradient.

5.训练

#5.训练
num_epochs=10000
for epoch in range(num_epochs):
    #x,y为train和target数据,每个数据块为5行
    for x,y in train_dl:
        #1.前馈
        pre = model(x)
        #2.计算loss
        loss = loss_fn(pre,y)
        print(loss)
        #3.计算梯度
        loss.backward()
        #4.优化w,b
        opt.step()
        #5.重置梯度
        opt.zero_grad()

loss变化为:

tensor(15312.8965, grad_fn=<MseLossBackward>)
tensor(10408.4082, grad_fn=<MseLossBackward>)
tensor(7102.2720, grad_fn=<MseLossBackward>)

。。。。

tensor(0.5017, grad_fn=<MseLossBackward>)
tensor(0.5017, grad_fn=<MseLossBackward>)
tensor(0.5017, grad_fn=<MseLossBackward>)

整体代码:

import numpy as np
import torch
from torch.utils.data import TensorDataset
from torch.utils.data import DataLoader
import torch.nn as nn
import torch.nn.functional as F
#1.预处理数据
inputs = np.array([[73, 67, 43],
                   [91, 88, 64],
                   [87, 134, 58],
                   [102, 43, 37],
                   [69, 96, 70]], dtype='float32')

targets = np.array([[56, 70],
                    [81, 101],
                    [119, 133],
                    [22, 37],
                    [103, 119]], dtype='float32')
inputs = torch.from_numpy(inputs)
targets = torch.from_numpy(targets)

train_ds = TensorDataset(inputs,targets)
batch_size = 5
train_dl = DataLoader(train_ds, batch_size, shuffle=True)

#2.构建model
model = nn.Linear(3, 2)
print(model.weight)
print(model.bias)

#3.构建loss function
loss_fn = F.mse_loss

#4.构建opimizer
opt = torch.optim.SGD(model.parameters(), lr=1e-5)

#5.训练
num_epochs=10000
for epoch in range(num_epochs):
    #x,y为train和target数据,每个数据块为5行
    for x,y in train_dl:
        #1.前馈
        pre = model(x)
        #2.计算loss
        loss = loss_fn(pre,y)
        print(loss)
        #3.计算梯度
        loss.backward()
        #4.优化w,b
        opt.step()
        #5.重置梯度
        opt.zero_grad()
posted @ 2021-01-29 20:35  lsxkugou  阅读(66)  评论(0编辑  收藏  举报