005、线性回归

之——最基础的神经网络


目录

之——最基础的神经网络

杂谈

正文

1.手撕

2.torch模块化

补充


杂谈

        线性回归就是最简单的神经网络,多输入单输出,之所以叫回归正是因为如此,它更像是对于多个输入的一个结果预测,而不是像分类一样预测哪一个。

        详细的原理可以看看佬的:

4. 线性回归以及基础优化算法

         总结性的:

  1. 线性回归

    • 用途:线性回归用于建立输入特征(自变量)和输出目标(因变量)之间的线性关系。通常用于解决回归问题,即预测一个连续数值的输出。
    • 模型:线性回归模型假设自变量与因变量之间存在线性关系。模型通常表示为 Y = aX + b,其中 Y 是因变量,X 是自变量,a 是斜率,b 是截距。
    • 损失函数:线性回归通常使用均方误差(Mean Squared Error,MSE)作为损失函数,目标是最小化实际值与预测值之间的平方误差。
    • 输出:线性回归输出连续数值,可以是任何实数。
  2. Logistic回归

    • 用途:Logistic回归用于解决分类问题,其中目标是将输入特征映射到两个或多个类别中的一个。它通常用于二元分类,但也可以扩展到多类别分类。
    • 模型:Logistic回归使用 logistic 函数(也称为 sigmoid 函数)来建模概率。模型输出是介于0和1之间的概率值。
    • 损失函数:Logistic回归使用对数损失函数,通常称为交叉熵损失(Cross-Entropy Loss),以最小化实际类别和预测概率之间的差异。
    • 输出:Logistic回归输出表示输入属于每个类别的概率,可以进行阈值化来进行二元分类。
  3. 感知机

    • 用途:感知机是一个简单的二元分类算法,用于将输入特征分为两个类别。感知机可以看作是神经网络的早期形式。
    • 模型:感知机模型由权重和阈值组成,基于输入的线性组合来做出二元分类决策。如果线性组合大于阈值,则为一个类别,否则为另一个类别。
    • 损失函数:感知机使用误分类点到决策边界的距离作为损失函数,目标是最小化误分类点的数量。
    • 输出:感知机输出是二元的,表示输入属于两个类别之一。

区别:

  • 主要区别在于应用和问题类型。线性回归用于回归问题,Logistic回归用于分类问题,而感知机也用于分类问题但是限于二元分类。

  • 线性回归输出是连续值,而Logistic回归输出是表示概率的0到1之间的值。

  • 在损失函数上,线性回归使用均方误差,Logistic回归使用交叉熵损失,感知机使用误分类点到决策边界的距离。

  • 感知机是一个相对简单的模型,不能解决线性不可分的问题,而Logistic回归可以处理非线性关系,并且在实践中更常见。


正文

        主要是代码实现,坚持手打

1.手撕

#%%

 print("线性回归\n"
      "线性模型,可以看做单层的神经网络或者神经元,y=w1x1+w2x2+b\n"
      "神经网络最开始是从类人神经元开始的\n"
      "比较真实值和预测值来不断进化模型\n"
      "也就是建立所谓的损失函数")



#%%

print("基础优化方法\n"
      "最常见的就是梯度下降,沿反梯度可以最小化损失函数值\n"
      "小批量随机梯度下降,整个样本计算梯度计算太贵,所以一般都是随机采样小批量\n"
      "批量大小这种就是超参数batch size,决定了一次使用多少样本来进行拟合计算"
      "以及学习率")




#%%

print("线性回归从0开始"
      "复杂模型一般情况是没有显示解的,所以通过迭代拟合实现")

import random
import torch
from d2l import torch as d2l

def synthetic_data(w,b,numof_exam):
    x=torch.normal(0,1,(numof_exam,len(w)))
    y=torch.matmul(x,w)+b
    noise=torch.normal(0,0.01,y.shape)
    y+=noise
    return x,y.reshape((-1,1)) #-1自动行数,1列


true_w=torch.tensor([2.5,-3.6])
print(true_w)
true_b=1.1
print("start")
features,labels=synthetic_data(true_w,true_b,1000)
# print(features,labels)
print("第一个维度的特征和labels的图示")
d2l.plt.scatter(features[:,1].numpy(),labels.numpy(),1)

print("创建数据集迭代器")
def data_iter(batch_size,features,labels):
    numof_exam=len(features)
    indices=list(range(numof_exam))
    #打乱索引
    random.shuffle(indices)
    #每隔batchsize个取一次样
    for i in range(0,numof_exam,batch_size):
        batch_indices=torch.tensor(indices[i:min(i+batch_size,numof_exam)])
        yield features[batch_indices],labels[batch_indices] #yield每次暂停函数记录返回再继续执行,最后会返回一个结果列表


batch_size=10

for x,y in data_iter(batch_size,features,labels):
    print("其中一个batch的样本和标签")
    print(x,y)
    break


#%%

#初始化待训练模型参数
print("初始化待训练模型参数")
w=torch.normal(0,0.01,(2,1),requires_grad=True)
print(w)
b=torch.zeros(1,requires_grad=True)
print(b)

#线性模型
def lin_model(X,w,b):
    return torch.matmul(X,w)+b

#损失函数
def squared_loss(y_pre,y):
    return (y.reshape(y_pre.shape)-y_pre)**2/2

#小批量梯度下降,优化算法
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.02
num_epochs=3
net=lin_model
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)

    #每一个epoch的训练损失
    print('with torch.no_grad():用于将计算图的梯度传播简化,隔绝不需要的部分,'
          '可以理解为全体的detach')
    with torch.no_grad():
        train_l=loss(net(features,w,b),labels)
        print(f'epoch{epoch+1},loss{train_l.mean()}')

print(w,b)

2.torch模块化

        torch上场的简化版本

#%%###############################################################################
#torch上场

import numpy as np
import torch
from torch.utils import data #data module
from d2l import torch as d2l

true_w=torch.tensor([2.5,-3.6])
print(true_w)
true_b=1.1
print("1、生成数据集")
features,labels=synthetic_data(true_w,true_b,1000)

#dataloder 的使用,是针对dataset、dataframe类型的数据,生成迭代器
print("2、加载数据集生成批量迭代器")
def load_array(data_arrays,batch_size,is_train=True):
    dataset=data.TensorDataset(*data_arrays)#转化为dataset
    return data.DataLoader(dataset,batch_size,is_train)

batch_size=10
data_iter_new=load_array([features,labels],batch_size)
print(data_iter_new)

print("批量迭代器的调用实例")
next(iter(data_iter_new))


print('3、模型结构构建')
from torch import nn

#线性层,输入2输出1,Sequential是网络构建容器,可以理解为转载各个层的list
net=nn.Sequential(nn.Linear(2,1))

print('4、初始化模型参数')
net[0].weight.data.normal_(0,0.01)
net[0].bias.data.fill_(0)

print('5、定义损失函数')
loss=nn.MSELoss()

print('6、定义优化算法')
trainer=torch.optim.SGD(net.parameters(),lr=0.03)

print('7、开始训练')
num_epochs=3
for epoch in range(num_epochs):
    for x,y in data_iter_new:
        l=loss(net(x),y)
        trainer.zero_grad()
        l.backward() #损失的梯度计算之前默认会求sum
        trainer.step() #模型参数更新
    l=loss(net(features),labels)
    print(f'epoch{epoch+1},loss{l:f}')

print(net[0].weight.data,net[0].bias.data)\


print("提到的优化方法有"
      "优化算法的选择"
      "学习率的动态调整"
      "收敛的判断  ")

补充

        之后会在softmax回归谈到logistic回归,就不多加以赘述。

        线性回归在机器学习中具有重要地位,它是一种基本且经典的监督学习算法,通常用于解决回归问题。以下是线性回归在机器学习中的地位和关键特点:

  1. 基础模型: 线性回归是机器学习中最基础的模型之一。它建立了自变量(特征)与因变量(目标)之间的线性关系,通过拟合一条直线(对于简单线性回归)或一个超平面(对于多元线性回归)来进行预测。因此,它为理解和入门机器学习提供了良好的起点。

  2. 可解释性: 线性回归具有很高的可解释性,因为它的模型参数表示自变量与因变量之间的线性关系。这使得我们可以直观地理解不同特征对目标的影响程度,以及预测结果如何受到不同特征的影响。

  3. 广泛应用: 线性回归广泛应用于各种领域,包括经济学、社会科学、自然科学、工程学以及医学等。它可以用于预测房价、股市趋势、销售量、疾病发病率等各种连续性的数值预测问题。

  4. 基准模型: 线性回归常常被用作其他复杂模型的基准,用于比较新模型的性能。如果一个更复杂的模型不能显著优于线性回归,那么采用线性回归可能更为合适,因为它具有较低的计算复杂性和过拟合的风险。

  5. 拓展和改进: 虽然线性回归本身是一种简单的模型,但已经有很多拓展和改进的方法,如岭回归、Lasso回归、弹性网络等,用于应对线性关系假设的不足。这些方法允许在线性框架内进行正则化,以提高模型的性能和泛化能力。

  6. 机器学习教育: 线性回归通常是机器学习课程的一部分,因为它可以帮助学生理解基本的机器学习概念,如目标函数、损失函数、优化算法等。它也有助于培养数据分析和建模的思维方式。

        尽管线性回归在处理复杂问题时可能过于简单,但它仍然是机器学习的重要组成部分,有助于建立坚实的基础知识,为进一步学习更高级的模型和技术奠定基础。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Here-We-Are

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值