Pytorch_3.2_ 线性回归的从零开始实现

3.2 线性回归的从零开始实现

%matplotlib inline
import torch
from IPython import display
from matplotlib import pyplot as plt
import numpy as np
import random

3.2.1 生成数据集

num_inputs = 2
num_examples = 1000
true_w = [2,-3.4]
true_b = 4.2
features = torch.from_numpy(np.random.normal(0,1,(num_examples,num_inputs)))
labels = true_w[0] * features[:,0] + true_w[1] * features[:,1] + true_b
labels += torch.from_numpy(np.random.normal(0,0.01,size = labels.size()))
print(features[0],labels[0])
tensor([0.6324, 1.5551], dtype=torch.float64) tensor(0.2032, dtype=torch.float64)
def use_svg_display():
#     用矢量图显示
    display.set_matplotlib_formats('svg')
def set_figsize(figsize = (3.5,2.5)):
    use_svg_display()
    # 设置图的尺寸
    plt.rcParams['figure.figsize'] = figsize
set_figsize()
plt.scatter(features[:,1].numpy(),labels.numpy(),1)
<matplotlib.collections.PathCollection at 0x220da1a6ba8>

Pytorch_3.2_ 线性回归的从零开始实现

3.2.2 读取数据

读取小批量数据

def data_iter(batch_size, features, labels):
    num_examples = len(features)
    indices = list(range(num_examples))
    random.shuffle(indices)
    for i in range(0,num_examples,batch_size):
#         print(i)
        j = torch.LongTensor(indices[i:min(i +batch_size,num_examples)])
        yield features.index_select(0,j),labels.index_select(0,j)
batch_size = 10

for X,y in data_iter(batch_size,features,labels):
    print(X,y)
    break
    
tensor([[-1.3137, -1.6132],
        [ 0.1923, -0.4359],
        [-0.7929, -0.4088],
        [ 0.3640, -2.7373],
        [-0.6725,  0.1442],
        [ 0.5874, -0.3863],
        [ 2.2049,  1.3518],
        [-0.2108, -0.6305],
        [-0.2961, -0.4947],
        [ 0.7193,  2.7268]], dtype=torch.float64) tensor([ 7.0628,  6.0627,  3.9909, 14.2296,  2.3753,  6.6761,  4.0003,  5.9209,
         5.3056, -3.6368], dtype=torch.float64)

3.2.3 初始化模型参数

# 初始化 权重 和 偏差
w = torch.tensor(np.random.normal(0, 0.01, (num_inputs,1)),dtype = torch.float64)
b = torch.zeros(1, dtype = torch.float64)
w.requires_grad_(requires_grad = True)
b.requires_grad_(requires_grad = True)
tensor([0.], dtype=torch.float64, requires_grad=True)

3.2.4 定义模型

def linreg(X, w, b):
    return torch.mm(X, w) + b

3.2.5 定义损失函数

def squared_loss(y_hat, y):
    return (y_hat - y.view(y_hat.size())) ** 2 /2

3.2.6 定义优化算法

def sgd(params, lr, batch_size):
    for param in params:
        param.data -= lr * param.grad / batch_size

3.2.7 训练模型

lr = 0.03
num_epochs = 3
net = linreg
loss = squared_loss

for epoch in range(num_epochs):
    for X, y in data_iter(batch_size, features,labels):
#         print(X)
#         print(y)
#         print(w)
#         print(net(X, w, b))
        l = loss(net(X, w, b), y).sum() # l 是有关小批量X 和y 的 损失
        l.backward() # 求梯度
        sgd([w,b],lr, batch_size)
        # 梯度清零
        w.grad.data.zero_()
        b.grad.data.zero_()
    train_l = loss(net(features, w, b), labels)
    print('epoch %d, loss %f' % (epoch + 1, train_l.mean().item()))
epoch 1, loss 0.045305
epoch 2, loss 0.000189
epoch 3, loss 0.000052
print(true_w, '\n',w)
print(true_b, '\n',b)
[2, -3.4] 
 tensor([[ 1.9989],
        [-3.4000]], dtype=torch.float64, requires_grad=True)
4.2 
 tensor([4.1998], dtype=torch.float64, requires_grad=True)

【总结】
初步尝试了数据训练 反馈调节 训练后的参数 后续加强

上一篇:自动求梯度(pytorch版本)——2.20


下一篇:解释与注意:用于视觉问答的一场获得注意的两人游戏模型《Explanation vs Attention: A Two-Player Game to Obtain Attention for VQA》