线性回归的简洁实现

1 导入实验所需要的包

import numpy as np
import torch
from torch import nn
from torch.utils import data
import matplotlib.pyplot as plt
#解决内核挂掉
import os
os.environ["KMP_DUPLICATE_LIB_OK"]  =  "TRUE"

 

2 生成数据集

  将根据带有噪声的线性模型构造一个人造数据集。任务是使用这个有限样本的数据集来恢复这个模型的参数。这里使用低维数据,这样可以很容易地将其可视化。

  在下面的代码中, 将生成一个包含 1000 个样本的数据集,每个样本包含从标准正态分布中采样的 2 个特征。合成数据集是一个矩阵 $\mathbf{X} \in \mathbb{R}^{1000 \times 2} $ 。
  使用线性模型参数 $ \mathbf{w}=[2,-3.4]^{\top}$ 、 $b=4.2$ 和噪声项 $\epsilon$  生成数据集及其标签:

    $\mathbf{y}=\mathbf{X} \mathbf{w}+b+\epsilon$

  可以将 $\epsilon$ 视为捕获特征和标签时的潜在观测误差。在这里认为标准假设成立,即 $\epsilon $ 服从均值为 $0$ 的正态分布。为了简化问题, 我们将标准差设 为 $0.01 $ 。下面的代码生成合成数据集。

def get_random_data(w,b,num_example):
    X = torch.normal(0,1,(num_example,len(w)))
    #X = torch.normal(0,1,(num_example,2))
    Y = torch.matmul(X,w)+b      #矩阵乘法,要求稍微低一点   
    Y += torch.normal(0,0.01,Y.shape)
    return X,Y.reshape(-1,1)

true_w = torch.tensor([2,-3.4])
true_b = 4.2
features ,labels = get_random_data(true_w,true_b,1000)

 

3 可视化初始数据

plt.rcParams['figure.figsize']=(12,4)
plt.subplot(1,2,1)
plt.scatter(features[:,0],labels,s=2)
plt.subplot(1,2,2)
plt.scatter(features[:,1],labels,s=2)

 

4 读取数据集

def load_array(data_arrays, batch_size, is_train=True): 
    """构造一个PyTorch数据迭代器。"""
    dataset = data.TensorDataset(*data_arrays)
    return data.DataLoader(dataset, batch_size, shuffle=is_train)

batch_size = 10
data_iter = load_array((features, labels), batch_size)
# next(iter(data_iter))

 

5 定义模型

#定义模型方法一:
# net = nn.Sequential(nn.Linear(2, 1))
# print(net[0])

#定义模型方法二:
# from collections import OrderedDict
# net = nn.Sequential(OrderedDict([('mylinear',nn.Linear(2, 1))]))
# print(net[0])

#定义模型方法三:
net = nn.Sequential()
net.add_module('mylinear',nn.Linear(2, 1))
print(net[0].weight)
print(net[0].bias)
print(net[0].weight.grad)

print("net[0] = ",net[0])

for index,param in enumerate(net.state_dict()):
    print("index = ",index)
    print("param = ",param)
    print("param_value = ",net.state_dict()[param])
    print('----------------')

Parameter containing: tensor([[-0.6449, -0.3191]], requires_grad=True) Parameter containing: tensor([0.1766], requires_grad=True) None net[0] = Linear(in_features=2, out_features=1, bias=True) index = 0 param = mylinear.weight param_value = tensor([[-0.6449, -0.3191]]) ---------------- index = 1 param = mylinear.bias param_value = tensor([0.1766]) ----------------

 

6 初始化模型参数

  正如我们在构造 nn.Linear 时指定输入和输出尺寸一样。

  现在我们直接访问参数以设定初始值。我们通过 net[0] 选择网络中的第一个图层,然后使用 weight.data 和 bias.data 方法访问参数。然后使用替换方法 normal_ 和 fill_ 来重写参数值。

from torch.nn import init
init.normal_(net[0].weight,mean=0,std=0.01)
init.constant_(net[0].bias,val = 0)

print(net[0].weight)
print(net[0].bias)
print(net[0].weight.grad)
Parameter containing:
tensor([[-0.0027, -0.0086]], requires_grad=True)
Parameter containing:
tensor([0.], requires_grad=True)
None

 

7 定义损失函数

loss = nn.MSELoss()

 

8 定义优化算法

optimizer = torch.optim.SGD(net.parameters(), lr=0.03)

 

9 训练

num_epochs = 3
for epoch in range(num_epochs):
    for X, y in data_iter:
        l = loss(net(X) ,y)
        optimizer.zero_grad()
        l.backward()
        optimizer.step()
    l = loss(net(features), labels)
    print(f'epoch {epoch + 1}, loss {l:f}')
epoch 1, loss 0.000228
epoch 2, loss 0.000102
epoch 3, loss 0.000103
posted @ 2021-10-20 13:47  图神经网络  阅读(98)  评论(0编辑  收藏  举报
Live2D