逻辑回归dome演示

Posted Huterox

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了逻辑回归dome演示相关的知识,希望对你有一定的参考价值。

文章目录

前言

逻辑回归能干嘛

开始之前先明确逻辑回归能干嘛,首先这玩意使用的是梯度下降法来进行修正。整个过程,逻辑回归的过程类似一个小型神经网络。这玩意主要应用于二分类问题。

相关理论请参考:逻辑回归模型详解(Logistic Regression)
这里不做过多的理论探究。

评判标准

这里的话主要还是以实战为主,如何手撸一个超级简单的逻辑回归dome,演示神经网络的工作流程。
这个灵感还是来自与这个大哥:BoyC啊(老卷王:宁可累死也要卷死别人的老狠人!!!)

首先是损失函数。

长这样。

其中那个 y^ 是指你的预测值,y 是实际上的值。由于是一个二分类的问题,所以,在对0这个标签拟合计算损失的时候,损失值越接近1越好,拟合 1 标签的时候,越接近0 越好,所以总体的损失值,越接近0.5越好。
这个主要是他们那个理论推导来的,我这里直接说的结论。

然后是预测函数。

在咱们今天的这篇博文的话,我们做的是一个简单的二分类,是有十组数据,我们先看看最后的一个效果吧:

当然这里的话,我的损失计算也还是有点问题的,大体是这样的,你们后面可以考虑优化。

正向函数,在这里的话,叫做网络函数比较合适,是这样的。

def Net(X):
    X = X.T * W
    X = np.sum(X) +B
    X = sigmod(X)
    if(X>=1):
        X = X-0.0001
    elif(X<=0):
        X = X + 0.0001
    return X

这里还要对那个± 0.0001 是因为那个 这里的 sigmod 处理之后,如果某一个值非常接近1或者0的时候,就会被取成1或者0,但是这个是不允许的。只能这样先特殊处理了。
然后整个网络结构是长这个样子的。

所以你可以知道为什么那个Net函数这样的。

数据集

在我们的这个dome当中的话,我们的这个数据集是这样的。

X_train  = np.linspace(1,20,20).reshape((10,2))
classes = ["小猫","小狗"]
Labels = "小猫":0,"小狗":1
Y_train = np.array([Labels["小猫"],Labels["小狗"]])

训练策略

之后咱们来说说咱们的这个训练策略。
首先,咱们的这个数据是一行一行输入进去的,前5组属于0标签,后5组属于1标签。之后,为了模拟这个神经网络的batch_size
所以,我这里还干脆在每一轮训练的时候,每进去5组,5组计算完了之后,我再去进行梯度下降,更新权重,每一次计算,我先把所有的梯度加起来,然后后面求平均值然后去更新。(我们现在模拟的是非常简答的网络结构,对于复杂的,我们就需要单独记录梯度然后去更新,这样如果每进去一组我就更新梯度的话是会浪费很多时间的)

梯度更新

这里的话通过求导,我们最后可以发现这个
W1 的 梯度会等于 (当前预测值-实际值)* 当前对于的X1
然后,这里的话,我们既然使用了矩阵,那么我这里更新的时候,直接使用矩阵更新。

同样的,这个B 的话,就是直接 等于 (当前预测值-实际值)
由于我们 是 5 轮 更新一次嘛,所以都要先求个总和然后取平均值。

编码

前面都说的差不多了,那么我们就可以直接进行编码了。
这里由于使用的是梯度下降法,所以的话,我们这里的学习率就是Lr取0.00025
为什么取那么小,因为这个范围0-1本来就很小,参数变化很敏感,梯度下降嘛,容易出现那么几种情况,要么步子太大了过去了,要么就步子太小在局部出不来了,所以那个Lr其实是不太好设置的,在我们实际使用Pytroch的时候,其实我们使用的优化器的那个Lr是动态更新的。但是咱们这里模拟就不搞那么多花里胡哨的了。而且这个我们这里是100轮训练,那个Lr还是我自己调出来的,实际上做的时候,那个参数是作为超参数自适应的。

import numpy as np
import math
X_train  = np.linspace(1,20,20).reshape((10,2))
classes = ["小猫","小狗"]
Labels = "小猫":0,"小狗":1
Y_train = np.array([Labels["小猫"],Labels["小狗"]])

W = np.random.randint(0,1,(2,1))
#划分,2个特征决定0,1,一共十组,这十组前五组为0,后五组为1
#对1类的拟合,是越接近0越好,对于0类的拟合是越接近1越好,
# 对于损失函数,也就是说,总体的损失函数是越接近0.5越好

B = 0
m = 5
def sigmod(X):
    return 1/(1+np.exp(-X))

def com_grad(X,Y_,Y_T):
    #返回的是一个
    #   w1
    #      的向量
    #   w2
    W_ = (X.T)*(Y_ - Y_T)
    #计算梯度

    return W_

def Net(X):
    X = X.T * W
    X = np.sum(X) +B
    X = sigmod(X)
    if(X>=1):
        X = X-0.0001
    elif(X<=0):
        X = X + 0.0001
    return X

def loss(pred,Y_t):

    loss_ = -Y_t * math.log(pred) - (1-Y_t)*math.log(1-pred)
    return loss_

ecpho = 100
Lr = 0.000025
for e in range(ecpho):
    Y_T = None
    B_run = 0
    Pred_total = 0
    W_Z = np.zeros((2,1)) # m个运算之后的总的W
    Loss_Total = 0

    loss_y1_y2 = 0 #这个是针对那个不同的Y的损失
    for i in range(len(X_train)):
        X_ = X_train[i]
        pred = Net(X_)
        if((i+1)<=5):
            Y_T = Y_train[0]
        else:
            Y_T = Y_train[1]
        loss_now = loss(pred,Y_T)
        Loss_Total+=loss_now
        loss_y1_y2+= loss_now
        w_c = com_grad(X_,pred,Y_T)
        w_c = w_c.reshape(2,1)
        W_Z+=w_c
        B_run+=(pred-Y_T)
        Pred_total +=pred
        if((i+1)%m==0):
            W_Z = W_Z /m
            B = B_run/m
            W = W - W_Z*Lr
            print("第次训练对----标签拟合的平均损失为".format(e + 1,Y_T,loss_y1_y2 / m))
            #我们是每m次更新一次,所以更新完之后都要重新刷新
            B_run = 0
            loss_y1_y2 = 0
            W_Z = np.zeros([2, 1])  # m个运算之后的总的W
    print("第次训练的平均损失为".format(e+1,Loss_Total/10))



# 预测部分,在我们的那个数据里面,前面5个是标签1,后面是0,分别对应不同的类别
inx = 1
for i in X_train:
    P = Net(i)
    if(P<0.5):
        print("第组预测为:".format(inx,classes[0]))
    else:
        print("第组预测为:".format(inx, classes[1]))
    inx+=1

看大上面后面的写法,有没有发现和我先前写的那个HuClassfiy分类器有那么点类似。
最后效果是这样的

你改一下学习率,例如Lr=0.001

这玩意随缘,当然这个也是多方面因素决定的,有些情况下,有些参数的相关性本来就很差,很难拟合,所以出现这种效果是在所难免的。
在这了的话,我们还是两个特征决定一个类别。就比如那个数据集数子 1,2 共同决定他是0类别,对应的就是小猫。
当然上面那个dome还是有很多不足之处的。

以上是关于逻辑回归dome演示的主要内容,如果未能解决你的问题,请参考以下文章

机器学习P6 逻辑回归的 损失函数 以及 梯度下降

机器学习100天(十六):016 逻辑回归损失函数

机器学习100天(十六):016 逻辑回归损失函数

机器学习 | Logistic Regression(逻辑回归)中的损失函数

机器学习 | Logistic Regression(逻辑回归)中的损失函数

训练期间的sklearn逻辑回归损失值