首页 > 其他分享 >线性回归-代码库

线性回归-代码库

时间:2024-08-27 22:47:28浏览次数:6  
标签:torch features 代码 labels print 线性 net true 回归

import torch
import os
import numpy as np
import random 

def synthetic_data(w, b, num_examples):
    '''
    产生data
    '''
    features = torch.normal(0,1,(num_examples,len(w)))
    labels = torch.matmul(features, w) + b
    labels += torch.normal(0,0.001,labels.shape)  # 添加噪声
    return features, labels

def data_iterator(batch_size,features, labels):
    '''
    数据生成器,生成批量数据
    '''
    n = len(labels)
    indices = np.arange(n)
    random.shuffle(indices)  # 数据shuffle
    
    for i in range(0,n,batch_size):
        indices_index = indices[i:min(i+batch_size, n)]  # 防止数据出界
        yield features[indices_index], labels[indices_index]

def linear_reg(X,w,b):
    '''
    定义模型输出
    '''
    return torch.matmul(X, w) + b

def mse(y_hat, y_pred):
    '''
    评价标准
    '''
    return (y_hat - y_pred.reshape(y_hat.shape))**2 * 0.5 / len(y_hat) # y_hat与y_pred 维度一定要一致

def SGD(params, lr, batch_size):
    with torch.no_grad():
        for param in params:
            param -= (lr * param.grad)
            param.grad.zero_()  # 梯度清0

def fit(num_epoch, features, labels, batch_size, lr, net, criterion, w, b):
    for i in range(num_epoch):
        for feature,label  in data_iterator(batch_size, features, labels):
            y_pred = net(feature, w,b)
            loss = criterion(y_pred, label)
            loss.sum().backward()
            SGD([w,b],lr, batch_size)

        with torch.no_grad():
            loss = criterion(net(features, w, b), labels).sum()
            print('i=',i,'loss:= ',loss, 'w:= ',w, 'b:= ',b)

# -----------------------------  1. 使用dataloader 载入数据-----------------------------
'''
总结: 如上为手动实现线性回归的完整过程。
接下来:沿着如下线索构建网络
  1. 使用dataloader载入数据 --> 使用 pytorch定义的MSE损失函数 --> 使用 系统自带的优化器 --> 自定义网络 逐个部件将 其替换为由nn.module 构建的网络 
  2. 分支 
    (a). 构建网络 使用nn.parameter vs 不实用nn.parameter
'''

from torch import nn 
from torch.utils import data

def data_iter_sys(features, labels,v_batch_size, is_train=True):
    '''
    1. TensorDataset 可以用来对 tensor 进行打包,包装成数据集,被 DataLoader 类使用
    2. * 表示解包操作
    3. DataLoader返回打散之后小批量数据 返回的是一个生成器
    '''
    dataset = data.TensorDataset(*(features, labels))
    return data.DataLoader(dataset,batch_size=v_batch_size, shuffle=is_train)

def fit_dataloader(num_epoch, dataloader, features, labels, batch_size, lr, net, criterion, w, b):
    for i in range(num_epoch):
        for feature,label  in dataloader:
            y_pred = net(feature, w,b)
            loss = criterion(y_pred, label)
            loss.sum().backward()
            SGD([w,b],lr, batch_size)

        with torch.no_grad():
            loss = criterion(net(features, w, b), labels).sum()
            print('i=',i,'loss:= ',loss, 'w:= ',w, 'b:= ',b)


def fit_optimizer(num_epoch, dataloader, features, labels, batch_size, lr, net, criterion, params, optimizer):
    for i in range(num_epoch):
        for feature,label  in dataloader:
            y_pred = net(feature, params[0], params[1])
            loss = criterion(y_pred, label)
            loss.sum().backward()

            optimizer.step()
            optimizer.zero_grad()
            
        with torch.no_grad():
            loss = criterion(net(features, params[0], params[1]), labels).sum()
            print('i=',i,'loss:= ',loss, 'w:= ',params[0], 'b:= ',params[1])

# -----------------------------  2. 自定义网络-----------------------------
class Liner_net(nn.Module):
    def __init__(self, dim):
        super(Liner_net, self).__init__()
        self.weight = torch.randn(dim, requires_grad=True)
        self.bias = torch.randn(1, requires_grad=True)
    
    def forward(self, X):
        return torch.matmul(X, self.weight)+self.bias

class Liner_net_1(nn.Module):
    def __init__(self, dim):
        super(Liner_net_1, self).__init__()
        self.weight = nn.Parameter(torch.randn(dim))
        self.bias = nn.Parameter(torch.randn(1))
    
    def forward(self, X):
        return torch.matmul(X, self.weight)+self.bias

class Liner_net_2(nn.Module):
    def __init__(self, dim):
        super(Liner_net_2, self).__init__()
        self.hidden = nn.Linear(in_features=dim, out_features=1,bias=True)
    
    def forward(self, X):
        return self.hidden(X)

def fit_net_selfdefine(num_epoch, dataloader, features, labels, batch_size, lr, net, criterion, params, optimizer):
    for i in range(num_epoch):
        for feature,label in dataloader:
            y_pred = net(feature).reshape(label.shape)  # 当 y_pred 是32*1,label是32 那么此时求出的loss是不对的
            loss = criterion(y_pred, label)
            loss.sum().backward()

            optimizer.step()
            optimizer.zero_grad()
            
        with torch.no_grad():
            loss = criterion(net(features), labels).sum()
            print('i=',i,'loss:= ',loss, 'w:= ',params[0], 'b:= ',params[1])

# -----------------------------  全局配置 ---------------------------- 
num_epoch = 100
num_examples = 2000
batch_size = 32
lr = 0.001
net = linear_reg
criterion = mse

if __name__=='__main__':
    # 0. 生成数据
    w_true = torch.tensor([3,-2,4,1], dtype=torch.float)
    b_true = torch.tensor([0.5])
    features, labels = synthetic_data( w_true, b_true, num_examples)    

    w = torch.randn(w_true.shape, requires_grad=True)
    b = torch.randn(1, requires_grad=True)
    # 1. 手动实现线性回归
    '''
    # 模型训练
    fit(num_epoch, features, labels, batch_size, lr, net, criterion, w, b)
    print(10*'*','运行结果',10*'*')
    print('[w_true,w]',[w_true, w])
    print('[b_true,b]',[b_true, b])
    '''
    
    # 2. 使用dataloader 替换自定义数据生成器
    '''
    print(10*'*','2. 使用自定义数据生成器', 10*'*')
    num_epoch = 50
    dataloader = data_iter_sys(features, labels, batch_size)
    fit_dataloader(num_epoch,dataloader,features, labels, batch_size, lr, net, criterion, w, b)
    print(10*'*','运行结果',10*'*')
    print('[w_true,w]',[w_true, w])
    print('[b_true,b]',[b_true, b])
    ''' 
    # 3. 使用自定义损失函数
    ''' 
    print(10*'*','3. 使用自定义损失函数', 10*'*')
    criterion = nn.MSELoss()
    fit(num_epoch, features, labels, batch_size, lr, net, criterion, w, b)
    print(10*'*','运行结果',10*'*')
    print('[w_true,w]',[w_true, w])
    print('[b_true,b]',[b_true, b])
    '''
    # 4. 自定义优化器
    ''' 
    print(10*'*','4. 自定义优化器', 10*'*')
    w = torch.randn(w_true.shape, requires_grad=True)
    b = torch.randn(1, requires_grad=True)
    print([w,b])
    optimizer = torch.optim.SGD([w,b],lr=lr) 
    criterion = mse  # or criterion = nn.MSELoss() 
    dataloader = data_iter_sys(features, labels, batch_size) # 不能使用 dataloader = data_iterator(batch_size,features, labels) why?
    fit_optimizer(num_epoch, dataloader, features, labels, batch_size, lr, net, criterion, [w,b], optimizer)
    print(10*'*','运行结果',10*'*')
    print('[w_true,w]',[w_true, w])
    print('[b_true,b]',[b_true, b])
    '''
    
    # 5. 自定义网络
    ''' 
    print(10*'*','5. 自定义优化器-不使用parameter or parameter', 10*'*')
    criterion = nn.MSELoss()   # or criterion = nn.MSELoss() 
    num_epoch = 100
    #net = Liner_net(w.shape[0])   # 使用tensor定义net
    net = Liner_net_1(w.shape[0])  # 使用parameter定义net
    optimizer = torch.optim.SGD([net.weight,net.bias],lr=lr) 
    dataloader = data_iter_sys(features, labels, batch_size) # 不能使用 dataloader = data_iterator(batch_size,features, labels) why?
    fit_net_selfdefine(num_epoch, dataloader, features, labels, batch_size, lr, net, criterion, [net.weight,net.bias], optimizer)
    print(10*'*','运行结果',10*'*')
    print('[w_true,w]',[w_true, net.weight.data])
    print('[b_true,b]',[b_true, net.bias.data])
    '''
   # 6. 使用nn.linear 
    ''' 
    print(10*'*','6. 自定义网络 使用Sequential ', 10*'*')
    criterion = nn.MSELoss()   # or criterion = nn.MSELoss() 
    num_epoch = 100
    net = nn.Sequential(nn.Linear(in_features=w.shape[0], out_features=1,bias=True))
    net[0].weight.data = torch.randn(w.shape[0], 1, dtype=torch.float).T # 一定要定义成矩阵而不是向量
    net[0].bias.data = torch.randn(1)
    optimizer = torch.optim.SGD([net[0].weight,net[0].bias],lr=lr) 
    dataloader = data_iter_sys(features, labels, batch_size) # 不能使用 dataloader = data_iterator(batch_size,features, labels) why?
    fit_net_selfdefine(num_epoch, dataloader, features, labels, batch_size, lr, net, criterion, [net[0].weight,net[0].bias], optimizer)
    print(10*'*','运行结果',10*'*')
    print('[w_true,w]',[w_true, net[0].weight.data])
    print('[b_true,b]',[b_true, net[0].bias.data])
    '''
   # 7. 自定义网络 使用nn.linear 
    print(10*'*','7. 自定义网络 使用nn.linear', 10*'*')
    criterion = nn.MSELoss()   # or criterion = nn.MSELoss() 
    num_epoch = 100
    net = Liner_net_2(w.shape[0])
    params = [net.hidden.weight,net.hidden.bias]
    optimizer = torch.optim.SGD(params,lr=lr) 
    dataloader = data_iter_sys(features, labels, batch_size) # 不能使用 dataloader = data_iterator(batch_size,features, labels) why?
    fit_net_selfdefine(num_epoch, dataloader, features, labels, batch_size, lr, net, criterion, params, optimizer)
    print(10*'*','运行结果',10*'*')
    print('[w_true,w]',[w_true, params[0].data])
    print('[b_true,b]',[b_true, params[1].data])
    ```

标签:torch,features,代码,labels,print,线性,net,true,回归
From: https://www.cnblogs.com/douniwanli/p/18381800

相关文章

  • 八行代码解决字母异位词分组(49)
    leetcode题目链接 这道题利用hash表特性可以很轻松的解决。首先我们只需要给所有的字母异位词排序,那样的所有的字母异位词就会变成同一个词,拿这个词当键,插入hash表,而所有的字母异位词当值,这样打印出hash表所有的词就是最后的结果。代码如下classSolution{ public: v......
  • IDA反汇编STM32代码学习记录
    首先,使用IDA反汇编STM32代码应该打开的是bin文件,而不是.hex或.axf文件,只有bin文件是和下载到flash内的数据一致的。具体参见:三种文件的区别那么,怎么生成bin文件呢,在有工程的情况下,在MDK中是在user的afterbuild后添加命令:fromelf--bin-o./Output/@L.bin./Output/@L.axf@L代......
  • 打造敏捷开发环境:JNPF低代码平台的实践与探索
    在数字化转型的浪潮中,企业对软件开发的敏捷性和效率提出了更高的要求。传统的软件开发模式通常耗时长、成本高昂,难以迅速适应市场变化。低代码平台的出现,为解决这一问题提供了新的视角。本文将探讨如何运用JNPF低代码平台构建敏捷开发环境,并分享在实践中的探索与经验。敏......
  • 你是如何写分批处理数据的代码的
    分批处理代码框架这个分批处理框架可以应用于多种需要处理大量数据,但每次只能处理一部分数据的场景。这种框架有助于管理内存使用、优化处理时间,并避免在单个操作中处理所有数据可能导致的性能问题或超时。以下是一些具体的应用场景:数据库批量插入:当您需要将大量数据插入......
  • 有趣的C++模板代码
    1#include<iostream>2template<typename...Ts>3structCNAny{4staticboolDo(inti){5return(Ts::Do(i)||...);6}7};89template<typename...Ts>10structCNAll{11staticboolDo(inti){......
  • [图文直播]基于Mermaid代码借助draw.io绘制依赖关系图
    安装draw.io开源仓库地址:GitHub-jgraph/drawio-desktop:Officialelectronbuildofdraw.io安装包地址Releases·jgraph/drawio-desktop·GitHub安装、具体实现......
  • c/c++代码流程图生成
    以下介绍2款皆免费1.cxx2flow【github项目】c/c++函数解析为dot然后通过Graphviz渲染项目有附带gui程序可直接生成流程图,但是显示效果缩放不太行,建议解析生成dot后喂给其他基于Graphviz的渲染服务,使用过vscode上面的graphviz-interactive-preview,效果还行,也有在线网页渲染......
  • VScode+QT 无法自动补全代码的解决方法
    问题:没有添加包含的头文件路径,即include文件夹所在位置第一步找到库路径并复制(在qt安装路径中)第二步打开vscode环境配置文件,添加库路径最终效果头文件红色波浪线消失了,并且代码可以完美补全!注意事项请根据自己的来修改。记得把路径的\更换成\\或者用/表示记得在incl......
  • 逻辑回归算法 0基础小白也能懂
    逻辑回归算法0基础小白也能懂(附代码)原文链接啥是逻辑回归算法逻辑回归(LogisticRegression)是一种广泛用于分类任务的统计模型,特别适用于二元分类问题。尽管名称中带有“回归”,但逻辑回归主要用于分类。逻辑回归算法包含以下几个关键部分:线性回归与分类,Sigmoid函数与决策边......
  • 「代码随想录算法训练营」第四十八天 | 图论 part6
    目录108.冗余连接109.冗余连接II108.冗余连接题目链接:https://kamacoder.com/problempage.php?pid=1181文章讲解:https://www.programmercarl.com/kamacoder/0108.冗余连接.html题目状态:看题解思路:构建并查集,然后通过并查集来判断节点,若当前这对节点(s,t)在同一个集合......