线性神经网络--线性回归实现实例

线性回归初级实现

torch.normal(A, B ,size(C, D), requires_grad=True)
A表示均值,B表示标准差 ,C代表生成的数据行数,D表示列数,requires_grad=True表示对导数开始记录,可以忽略。

import math

import torch
import os
from IPython import display
from d2l import torch as d2l
import pandas as pd

import numpy as np
import matplotlib.pyplot as plt
from pylab import *
import matplotlib.gridspec as gridspec

import  random

#生成数据
def synthetic_data(w, b, num_Lines):
    '''生成方差0,标准差1,行数num_Lines,列数len(w) '''
    x = torch.normal(0, 1, (num_Lines,len(w)))
    '''生存 y = Xw + b + 噪声'''
    y = torch.matmul(x, w) + b
    y += torch.normal(0, 0.01, y.shape)
    return  x, y.reshape((-1,1))

#查看生成的数据
def scan_generateData():
    #给定W,B初始化值
    true_w = torch.tensor([2,-3.4])
    true_b = 4.2
    #生成x,y 数据
    features, labels = synthetic_data(true_w,true_b,1000)

    print('features:', features[0], '\nlabel:', labels[0])
    # 显示数据
    d2l.set_figsize()
    d2l.plt.scatter(features[:,(1)].detach().numpy(), labels.detach().numpy(),1)
    plt.show()

#小批量遍历数据
def data_iter(batch_size, features, labels):
    num_examples = len(features)
    indices = list(range(num_examples))
    #这些样本是随机read的,没有特定的顺序
    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]

# 遍历小批量数据,并print
def scan_iterData():
    batch_size = 10
    # 给定W,B初始化值
    true_w = torch.tensor([2,-3.4])
    true_b = 4.2
    features, labels = synthetic_data(true_w,true_b,1000)

    #遍历生成的数据,batch size
    for x , y in data_iter(batch_size,features,labels):
        print(x,'\n', y)
        break

#define model
def linreg(x,w,b):
    return  torch.matmul(x,w) +b

#define loss function 平⽅损失函数
def squared_loss(y_hat, y):
    return (y_hat - y.reshape(y_hat.shape))**2 / 2

#参数:模型参数集合、学习速率、批量⼤小。每⼀步更新的⼤小由学习速率learnRate决定。
def sgd(params, learnRate , batch_size):
    '''小批量随机梯度下降'''
    with torch.no_grad():
        for param in params:
            param -= learnRate * param.grad / batch_size #批量⼤小(batch_size)来归⼀化步⻓
            param.grad.zero_()

if __name__ == '__main__':
    #均值为0、标准差为0.01的正态分布中采样随机数来初始化权重,并将偏置初始化为0
    w = torch.normal(0,0.01, size = (2,1), requires_grad=True)
    b = torch.zeros(1, requires_grad=True)

    #目的是构筑一个真值x,y
    true_w = torch.tensor([2,-3.4])
    true_b = 4.2
    features, labels = synthetic_data(true_w,true_b,1000)

    batch_size = 10
    learnRate = 0.03
    num_epochs = 100 #1000个点,batch_size = 10 
    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) # `X`和`y`的⼩批量损失
            # 因为`l`形状是(`batch_size`, 1),⽽不是⼀个标量。`l`中的所有元素被加到⼀起,
            # 并以此计算关于[`w`, `b`]的梯度
            l.sum().backward()
            # 使⽤参数的梯度更新参数
            sgd([w,b],learnRate,batch_size)
        with torch.no_grad():
            train_l = loss(net(features,w,b),labels)
            print(f'epoch {epoch + 1}, loss {float (train_l.mean()):f}')
        print(f'w 的估计误差: {true_w - w.reshape(true_w.shape)}')
        print(f'b的估计误差: {true_b - b}')

线性回归版本简化

import torch
from d2l import torch as d2l
from torch.utils import data
# nn 是神经⽹络的缩写
from torch import nn

# data_arrays: features 和 labels 作为API的参数传递,
# 并在实例化数据迭代器对象时指定 batch_size,迭代器的时候一次读取
# is_train 表⽰是否希望数据迭代器对象在每个迭代周期内打乱数据
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)

if __name__ == '__main__':
    #生成数据集
    true_w = torch.tensor([3, -5.4])
    true_b = 4.2
    features, labels = d2l.synthetic_data(true_w, true_b, 1000)
    #读取数据集
    batch_size = 10
    data_iter = load_array((features, labels), batch_size)

    #print(f'data: {next(iter(data_iter))}')

    #定义⼀个模型变量net,它是⼀个 Sequential 类的实例。Sequential 类为串联在⼀起的多个层定义了⼀个容器。
    #全连接层在 Linear 类中定义,⼀个指定输⼊特征形状,即 2,第⼆个指定输出特征形状,输出特征形状为单个标量,因此为 1
    net = nn.Sequential(nn.Linear(2, 1))

    # 线性回归,net[0]表示第一层:每个权重参数应该从均值为0、标准差为0.01的正态分布中随机采样,偏置参数将初始化为零
    net[0].weight.data.normal_(0, 0.01) #权重
    net[0].bias.data.fill_(0) #偏置

    #均⽅误差
    loss = nn.MSELoss()

    #定义优化算法:小批量随机梯度下降
    trainer = torch.optim.SGD(net.parameters(), lr=0.03)

    #训练
    num_epochs = 3
    for epoch in range(num_epochs):
        for X, y in data_iter:
            l = loss(net(X), y)
            trainer.zero_grad()
            l.backward() #梯度求解
            trainer.step()
        l = loss(net(features), labels)
        print(f'epoch {epoch + 1}, loss {l:f}')

    w = net[0].weight.data
    print('w的估计误差:', true_w - w.reshape(true_w.shape))
    b = net[0].bias.data
    print('b的估计误差:', true_b - b)

备注:

TensorDataset:
可用来对tensor进行打包,好比python中的zip功能。它通过每一个tensor的第一个维度进行索引。
因此,该类中的 tensor 第一维度必须相等。
    net = nn.Sequential(
        nn.Linear(1024, 512), #1024x512
        nn.ReLU(inplace=True), #线性整流函数
        nn.Linear(512, 256),
        nn.ReLU(inplace=True),
        nn.Linear(256, 6),
    )
    net[4].weight.data = torch.zeros(6, 256)
    net[4].bias.data = torch.ones(6)
    t = torch.randn(32, 1024) # 32x1024
    print(net(t).size()) 
   
   
   
  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值