基于线性回归的单层神经网络的实验

  • Post author:
  • Post category:其他


目的:预测房价

使用工具为miniconda,jupyter notebook

实验需要用到的模块

预设的函数表达式 y=x1

w1+x2

w2+…+xn*wn+b+c

其中y为实际房价,xi为房价影响因素,wi为权重,b和c均为参数

%matplotlib inline
import random
import torch

首先人工制造数据集

def synthetic_data(w,b,num_examples):
    x=torch.normal(0,1,(num_examples,len(w)))//normal为正态分布函数,均值为0方差为1,大小为(num_examples,len(w))
    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])//设置实际的w
true_b = 4.2//设置实际的b
features,labels = synthetic_data(true_w,true_b,1000)//开始生成1000个样本数据,其中features代指样本的实际特征,比如房屋大小,卧室数量,labels代表的是每个样本房屋的预测价格
其实这一函数是为了通过设定的函数的计算结果来视为实际的结果,再通过计算结果来对模型进行调整,最后通过对模型的w和b的训练,由于真实的w和b都是我们自己设定的,通过计算偏差值大小来判断模型的好坏程度

批量获取数据

def data_iter(batch_size,features,labels):
    num_examples = len(features)//获取样本数据的长度
    indices =list(range(num_examples))//获取索引,将索引设置list形式
    random.shuffle(indices)//打乱数据元素
    for i in range(0,num_examples,batch_size):
        batch_indices = torch.tensor(indices[i:min(i+batch_size,num_examples)])
        yield features[batch_indices],labels[batch_indices]
batch_size = 10
for x,y in data_iter(batch_size,features,labels):
    print(x,'\n',y)
    break
执行结果
tensor([[ 1.2838,  0.9067],
        [-1.0581, -0.0623],
        [-0.5936,  0.7942],
        [-0.3193, -0.9345],
        [-1.2520,  0.9346],
        [ 0.6596,  0.0682],
        [ 1.3233, -0.0881],
        [ 1.5563, -1.1190],
        [ 0.3354,  0.8223],
        [ 0.0585,  0.4161]]) 
 tensor([[ 3.6689],
        [ 2.2965],
        [ 0.3161],
        [ 6.7445],
        [-1.4739],
        [ 5.3039],
        [ 7.1427],
        [11.1118],
        [ 2.0775],
        [ 2.9013]])
随机设置w和b,同时requires_grad=True表示获取梯度
w= torch.normal(0,0.01,size=(2,1),requires_grad=True)
b = torch.zeros(1,requires_grad=True)
获取预测的y值
def linreg(x,w,b):
    return torch.matmul(x,w)+b
获取平方差误差
def squared_loss(y_hat,y):
    return(y_hat-y.reshape(y_hat.shape))**2/2
对w和b进行梯度更新-梯度调整函数
def sgd(params,lr,batch_size):
    with torch.no_grad():
        for param in params:
            param-=lr*param.grad/batch_size
            param.grad.zero_()
执行函数
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):
       l=loss(net(x,w,b),y)
       l.sum().backward()
       sgd([w,b],lr,batch_size)
关键步骤
  l=loss(net(x,w,b),y)
       l.sum().backward()
       sgd([w,b],lr,batch_size)
因为l是 w,b的函数,故会产生w和b的梯度,通过w.grad和b.grad访问梯度



版权声明:本文为weixin_44050588原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。