超详细推导逻辑回归公式与代码实现(二分类与多分类)

news2024/11/18 13:45:38

目录

  • 概述
  • 逻辑回归理论
  • 数学推导
    • 二类分类
    • 多分类
  • 代码实现
  • 备注

概述

本文使用梯度下降法对逻辑回归进行训练,使用类似于神经网络的方法进行前向传播与反向更新,使用数学公式详细推导前向传播与反向求导过程,包括二分类和多分类问题,最后用python代码实现鸢尾花分类(不使用算法库)

逻辑回归理论

逻辑回归使用了类似于线性回归的方法进行分类,常用于二类分类问题,该模型属于对数线性模型,公式为
P ( Y = 1 ∣ x ) = e x p ( w ⋅ x + b ) 1 + e x p ( w ⋅ x + b ) P(Y=1|x)=\frac{exp(w\cdot x+b)}{1+exp(w\cdot x+b)} P(Y=1∣x)=1+exp(wx+b)exp(wx+b)
P ( Y = 0 ∣ x ) = 1 1 + e x p ( w ⋅ x + b ) P(Y=0|x)=\frac{1}{1+exp(w\cdot x+b)} P(Y=0∣x)=1+exp(wx+b)1
Y=1代表属于该类别的概率,Y=0代表不属于该类别的概率,相当于属于另一类别的概率,二者和为1,服从概率分布。
由于 w ⋅ x + b w\cdot x+b wx+b输出的值范围在 ( − ∞ , + ∞ ) (-\infty, +\infty) (,+),无法直观的感受概率的大小,所以需要将其约束到一个 [ 0 , 1 ] [0,1] [0,1]之间的概率分布中。书中的公式为上面所示,在使用时通常使用sigmoid函数将其约束到一个概率分布中,其实目的是一样的,sigmoid函数公式为 y = 1 1 + e x p ( − x ) y=\frac{1}{1+exp(-x)} y=1+exp(x)1

函数图像为:
请添加图片描述

数学推导

二类分类

这里使用梯度下降法对参数w和b进行更新,所以需要对w和b进行求导计算。

  • 首先进行前向传播计算
    请添加图片描述

假设输入样本有四个特征: x = x 1 + x 2 + x 3 + x 4 x=x_1+x_2+x_3+x_4 x=x1+x2+x3+x4
经过w参数计算之后得到: z = w ⋅ x + b = w 1 x 1 + w 2 x 2 + w 3 x 3 + w 4 x 4 + b z=w\cdot x+b=w_1x_1+w_2x_2+w_3x_3+w_4x_4+b z=wx+b=w1x1+w2x2+w3x3+w4x4+b
之后再经过sigmoid函数得到预测概率: y ^ = s i g m o i d ( z ) = 1 1 + e x p ( − z ) \hat y=sigmoid(z)=\frac{1}{1+exp(-z)} y^=sigmoid(z)=1+exp(z)1
使用二元交叉熵函数求得损失值: − L ( y ^ , y ) = y ⋅ l o g y ^ + ( 1 − y ) ⋅ l o g ( 1 − y ^ ) -L(\hat y, y)=y\cdot log \hat y+(1-y)\cdot log(1-\hat y) L(y^,y)=ylogy^+(1y)log(1y^)
注:对于多个样本,直接取所有样本损失的平均值;

  • 反向传播
    反向传播时经过链式求导得到参数w和b的梯度,从而进行一步步更新

∂ L ∂ y ^ = − ( y y ^ − 1 − y 1 − y ^ ) = − ( y ( 1 − y ^ ) − y ^ ( 1 − y ) y ^ ( 1 − y ^ ) ) = − ( y − y y ^ − y ^ + y y ^ y ^ ( 1 − y ^ ) ) = y ^ − y y ^ ( 1 − y ^ ) \begin{align} \frac{\partial L}{\partial \hat y}&=-(\frac{y}{\hat y}-\frac{1-y}{1-\hat y})\\ &=-(\frac{y(1-\hat y)-\hat y(1-y)}{\hat y(1-\hat y)})\\ &=-(\frac{y-y\hat y-\hat y+y\hat y}{\hat y(1-\hat y)})\\ &=\frac{\hat y-y}{\hat y(1-\hat y)} \end{align} y^L=(y^y1y^1y)=(y^(1y^)y(1y^)y^(1y))=(y^(1y^)yyy^y^+yy^)=y^(1y^)y^y

∂ y ^ ∂ z = ∂ ( 1 + e − z ) − 1 ∂ z = e − z ( 1 + e − z ) 2 = 1 1 + e − z ⋅ e − z 1 + e − z = s i g m o i d ( z ) ⋅ ( 1 − s i g m o i d ( z ) ) = y ^ ⋅ ( 1 − y ^ ) \begin{align} \frac{\partial \hat y}{\partial z}&=\frac{\partial (1+e^{-z})^{-1}}{\partial z}\\ &=\frac{e^{-z}}{(1+e^{-z})^2}\\ &= \frac{1}{1+e^{-z}}\cdot \frac{e^{-z}}{1+e^{-z}}\\ &=sigmoid(z)\cdot (1-sigmoid(z))\\ &=\hat y\cdot (1-\hat y) \end{align} zy^=z(1+ez)1=(1+ez)2ez=1+ez11+ezez=sigmoid(z)(1sigmoid(z))=y^(1y^)

∂ z ∂ w = x , ∂ z ∂ b = 1 \frac{\partial z}{\partial w}=x, \frac{\partial z}{\partial b}=1 wz=x,bz=1

所以可以得到参数梯度为
∂ L ∂ w = ∂ L ∂ y ^ ∂ y ^ ∂ z ∂ z ∂ w = y ^ − y y ^ ( 1 − y ^ ) ⋅ y ^ ( 1 − y ^ ) ⋅ x = x ⋅ ( y ^ − y ) \frac{\partial L}{\partial w}=\frac{\partial L}{\partial \hat y}\frac{\partial \hat y}{\partial z}\frac{\partial z}{\partial w} =\frac{\hat y-y}{\hat y(1-\hat y)}\cdot \hat y (1-\hat y)\cdot x =x\cdot (\hat y-y) wL=y^Lzy^wz=y^(1y^)y^yy^(1y^)x=x(y^y)
∂ L ∂ b = ∂ L ∂ y ^ ∂ y ^ ∂ z ∂ z ∂ b = y ^ − y y ^ ( 1 − y ^ ) ⋅ y ^ ( 1 − y ^ ) ⋅ 1 = y ^ − y \frac{\partial L}{\partial b}=\frac{\partial L}{\partial \hat y}\frac{\partial \hat y}{\partial z}\frac{\partial z}{\partial b} =\frac{\hat y-y}{\hat y(1-\hat y)}\cdot \hat y (1-\hat y)\cdot 1 =\hat y-y bL=y^Lzy^bz=y^(1y^)y^yy^(1y^)1=y^y
最后进行梯度更新
w t = w t − 1 − l r ⋅ ∂ L ∂ w w_t = w_{t-1}-lr\cdot \frac{\partial L}{\partial w} wt=wt1lrwL
b t = b t − 1 − l r ⋅ ∂ L ∂ b b_t = b_{t-1}-lr\cdot \frac{\partial L}{\partial b} bt=bt1lrbL

多分类

多分类问题有一些方法sunshihanshu是使用多个二分类逻辑回归模型,有一些方法是最后使用softmax函数同时得到多个类别的概率,选取概率最大的类别作为预测类别,本文使用后一种方法,这里假设输出类别有三类。请添加图片描述

与二类分类问题的区别只有最后的概率归一化层和损失函数。

  • 首先进行前向传播计算

假设输入样本有四个特征: x = [ x 1 , x 2 , x 3 , x 4 ] x=[x_1,x_2,x_3,x_4] x=[x1,x2,x3,x4]

这里的w参数维度是(4, 3),会输出三个值,经过w参数计算之后得到:

w = [ w 11 w 21 w 31 w 12 w 22 w 32 w 13 w 23 w 33 w 14 w 24 w 34 ] w=\begin{bmatrix} w_{11} & w_{21} & w_{31} \\ w_{12} & w_{22} & w_{32} \\ w_{13} & w_{23} & w_{33} \\ w_{14} & w_{24} & w_{34} \\ \end{bmatrix} w= w11w12w13w14w21w22w23w24w31w32w33w34

z = x w + b = [ x 1 , x 2 , x 3 , x 4 ] [ w 11 w 21 w 31 w 12 w 22 w 32 w 13 w 22 w 33 w 14 w 23 w 34 ] + [ b 1 , b 2 , b 3 ] = [ z 1 , z 2 , z 3 ] z=xw+b=[x_1,x_2,x_3,x_4] \begin{bmatrix} w_{11} & w_{21} & w_{31} \\ w_{12} & w_{22} & w_{32} \\ w_{13} & w_{22} & w_{33} \\ w_{14} & w_{23} & w_{34} \\ \end{bmatrix}+[b_1 ,b_2,b_3]=[z_1, z_2,z_3] z=xw+b=[x1,x2,x3,x4] w11w12w13w14w21w22w22w23w31w32w33w34 +[b1,b2,b3]=[z1,z2,z3]
其中
z 1 = w 1 ⋅ x + b 1 = w 11 x 1 + w 12 x 2 + w 13 x 3 + w 14 x 4 + b 1 z_1=w_1\cdot x+b_1=w_{11}x_1+w_{12}x_2+w_{13}x_3+w_{14}x_4+b_1 z1=w1x+b1=w11x1+w12x2+w13x3+w14x4+b1
z 2 = w 2 ⋅ x + b 2 = w 21 x 1 + w 22 x 2 + w 23 x 3 + w 24 x 4 + b 2 z_2=w_2\cdot x+b_2=w_{21}x_1+w_{22}x_2+w_{23}x_3+w_{24}x_4+b_2 z2=w2x+b2=w21x1+w22x2+w23x3+w24x4+b2
z 3 = w 3 ⋅ x + b 3 = w 31 x 1 + w 32 x 2 + w 33 x 3 + w 34 x 4 + b 3 z_3=w_3\cdot x+b_3=w_{31}x_1+w_{32}x_2+w_{33}x_3+w_{34}x_4+b_3 z3=w3x+b3=w31x1+w32x2+w33x3+w34x4+b3

之后再经过softmax函数得到预测概率:
y ^ 1 = s o f t m a x ( z 1 ) = e x p ( z 1 ) ∑ e x p ( z i ) \hat y_1=softmax(z_1)=\frac{exp(z_1)}{\sum exp(z_i)} y^1=softmax(z1)=exp(zi)exp(z1)
y ^ 2 = s o f t m a x ( z 2 ) = e x p ( z 2 ) ∑ e x p ( z i ) \hat y_2=softmax(z_2)=\frac{exp(z_2)}{\sum exp(z_i)} y^2=softmax(z2)=exp(zi)exp(z2)
y ^ 3 = s o f t m a x ( z 3 ) = e x p ( z 3 ) ∑ e x p ( z i ) \hat y_3=softmax(z_3)=\frac{exp(z_3)}{\sum exp(z_i)} y^3=softmax(z3)=exp(zi)exp(z3)

使用多元交叉熵函数求得损失值: L ( y ^ , y ) = − ∑ y i ⋅ l o g y ^ i L(\hat y, y)=-\sum y_i\cdot log \hat y_i L(y^,y)=yilogy^i
注1:这里的 y i y_i yi代表是否属于第i个类别,例如某样本属于第二个类别,则 y = [ y 1 , y 2 , y 3 ] = [ 0 , 0 , 1 ] y=[y_1,y_2,y_3]=[0,0,1] y=[y1,y2,y3]=[0,0,1],则 L ( y ^ , y ) = − ∑ y i ⋅ l o g y ^ i = − ( 0 ⋅ l o g y ^ 1 + 0 ⋅ l o g y ^ 2 + 1 ⋅ l o g y ^ 3 ) L(\hat y, y)=-\sum y_i\cdot log \hat y_i=-(0\cdot log\hat y_1+0\cdot log\hat y_2+1\cdot log\hat y_3) L(y^,y)=yilogy^i=(0logy^1+0logy^2+1logy^3)
注2:对于多个样本,直接取所有样本损失的平均值;

  • 反向传播
    反向传播时经过链式求导得到参数w和b的梯度,从而进行一步步更新

∂ L ∂ y ^ = − y y ^ = [ − y 1 y ^ 1 , − y 2 y ^ 2 , − y 3 y ^ 3 ] \begin{align} \frac{\partial L}{\partial \hat y}&=-\frac{y}{\hat y}\\ &=[-\frac{y_1}{\hat y_1},-\frac{y_2}{\hat y_2},-\frac{y_3}{\hat y_3}] \end{align} y^L=y^y=[y^1y1,y^2y2,y^3y3]

对于softmax的反向传播比较特殊,由于输入包含多个参数 ( z 1 , z 2 , z 3 ) (z_1,z_2,z_3) (z1,z2,z3),对不同的z求导的结果不同。对于 y i y_i yi z j z_j zj,需要分为 i = j i=j i=j i ≠ j i\ne j i=j两种情况。
i = j i=j i=j时:
∂ y ^ i ∂ z j = ∂ y ^ i ∂ z i = e z i ∑ e z i − e z i e z i ( ∑ e z i ) 2 = e z i ( ∑ e z i − e z i ) ( ∑ e z i ) 2 = e z i ∑ e z i ∑ e z i − e z i ∑ e z i = s o f t m a x ( z i ) ⋅ ( 1 − s o f t m a x ( z i ) ) = y ^ i ⋅ ( 1 − y ^ i ) \begin{align} \frac{\partial \hat y_i}{\partial z_j}&=\frac{\partial \hat y_i}{\partial z_i}\\ &=\frac{e^{z_i}\sum e^{z_i}-e^{z_i}e^{z_i}}{(\sum e^{z_i})^2}\\ &=\frac{e^{z_i}(\sum e^{z_i}-e^{z_i})}{(\sum e^{z_i})^2}\\ &=\frac{e^{z_i}}{\sum e^{z_i}}\frac{\sum e^{z_i}-e^{z_i}}{\sum e^{z_i}}\\ &=softmax(z_i)\cdot (1-softmax(z_i))\\ &=\hat y_i\cdot (1-\hat y_i) \end{align} zjy^i=ziy^i=(ezi)2eziezieziezi=(ezi)2ezi(eziezi)=ezieziezieziezi=softmax(zi)(1softmax(zi))=y^i(1y^i)

i ≠ j i\ne j i=j时:
∂ y ^ i ∂ z j = − e z i e z j ( ∑ e z i ) 2 = − s o f t m a x ( z i ) ⋅ s o f t m a x ( z j ) = − y ^ i ⋅ y ^ j \begin{align} \frac{\partial \hat y_i}{\partial z_j}&=\frac{-e^{z_i}e^{z_j}}{(\sum e^{z_i})^2}\\ &=-softmax(z_i)\cdot softmax(z_j)\\ &=-\hat y_i\cdot\hat y_j \end{align} zjy^i=(ezi)2eziezj=softmax(zi)softmax(zj)=y^iy^j

合并起来得到:
∂ y ^ ∂ z = [ ∂ y ^ 1 ∂ z 1 ∂ y ^ 1 ∂ z 2 ∂ y ^ 1 ∂ z 3 ∂ y ^ 2 ∂ z 1 ∂ y ^ 2 ∂ z 2 ∂ y ^ 2 ∂ z 3 ∂ y ^ 3 ∂ z 1 ∂ y ^ 3 ∂ z 2 ∂ y ^ 3 ∂ z 3 ] = [ y ^ 1 ⋅ ( 1 − y ^ 1 ) − y ^ 1 ⋅ y ^ 2 − y ^ 1 ⋅ y ^ 3 − y ^ 2 ⋅ y ^ 1 y ^ 2 ⋅ ( 1 − y ^ 2 ) − y ^ 2 ⋅ y ^ 3 − y ^ 3 ⋅ y ^ 1 − y ^ 3 ⋅ y ^ 2 y ^ 3 ⋅ ( 1 − y ^ 3 ) ] \begin{align} \frac{\partial \hat y}{\partial z}= {\Large\begin{bmatrix} \frac{\partial \hat y_1}{\partial z_1} & \frac{\partial \hat y_1}{\partial z_2} & \frac{\partial \hat y_1}{\partial z_3} \\ \\ \frac{\partial \hat y_2}{\partial z_1} & \frac{\partial \hat y_2}{\partial z_2} & \frac{\partial \hat y_2}{\partial z_3} \\ \\ \frac{\partial \hat y_3}{\partial z_1} & \frac{\partial \hat y_3}{\partial z_2} & \frac{\partial \hat y_3}{\partial z_3} \\ \end{bmatrix}}= \begin{bmatrix} \hat y_1\cdot (1-\hat y_1) & -\hat y_1\cdot \hat y_2 & -\hat y_1\cdot \hat y_3 \\ \\ -\hat y_2\cdot \hat y_1 & \hat y_2\cdot (1-\hat y_2) & -\hat y_2\cdot \hat y_3 \\ \\ -\hat y_3\cdot \hat y_1 & -\hat y_3\cdot \hat y_2 & \hat y_3\cdot (1-\hat y_3) \\ \end{bmatrix} \end{align} zy^= z1y^1z1y^2z1y^3z2y^1z2y^2z2y^3z3y^1z3y^2z3y^3 = y^1(1y^1)y^2y^1y^3y^1y^1y^2y^2(1y^2)y^3y^2y^1y^3y^2y^3y^3(1y^3)

∂ L ∂ z = [ − y 1 ⋅ ( 1 − y ^ 1 ) y 1 ⋅ y ^ 2 y 1 ⋅ y ^ 3 y 2 ⋅ y ^ 1 − y 2 ⋅ ( 1 − y ^ 2 ) y 2 ⋅ y ^ 3 y 3 ⋅ y ^ 1 y 3 ⋅ y ^ 2 − y 3 ⋅ ( 1 − y ^ 3 ) ] \begin{align} \frac{\partial L}{\partial z}= \begin{bmatrix} -y_1\cdot (1-\hat y_1) & y_1\cdot \hat y_2 & y_1\cdot \hat y_3 \\ \\ y_2\cdot \hat y_1 & - y_2\cdot (1-\hat y_2) & y_2\cdot \hat y_3 \\ \\ y_3\cdot \hat y_1 & y_3\cdot \hat y_2 & - y_3\cdot (1-\hat y_3) \\ \end{bmatrix} \end{align} zL= y1(1y^1)y2y^1y3y^1y1y^2y2(1y^2)y3y^2y1y^3y2y^3y3(1y^3)

之后
∂ z ∂ w = [ x 1 x 1 x 1 x 2 x 2 x 2 x 3 x 3 x 3 x 4 x 4 x 4 ] \frac{\partial z}{\partial w}= \begin{bmatrix} x_1 & x_1 & x_1 \\ x_2 & x_2 & x_2 \\ x_3 & x_3 & x_3 \\ x_4 & x_4 & x_4 \\ \end{bmatrix} wz= x1x2x3x4x1x2x3x4x1x2x3x4
∂ z ∂ b = [ 1 , 1 , 1 ] \frac{\partial z}{\partial b}=[1, 1, 1] bz=[1,1,1]

所以最后得到梯度
∂ L ∂ w = ∂ L ∂ z ∂ z ∂ w = [ x 1 x 1 x 1 x 2 x 2 x 2 x 3 x 3 x 3 x 4 x 4 x 4 ] [ − y 1 ⋅ ( 1 − y ^ 1 ) y 1 ⋅ y ^ 2 y 1 ⋅ y ^ 3 y 2 ⋅ y ^ 1 − y 2 ⋅ ( 1 − y ^ 2 ) y 2 ⋅ y ^ 3 y 3 ⋅ y ^ 1 y 3 ⋅ y ^ 2 − y 3 ⋅ ( 1 − y ^ 3 ) ] \begin{align}\frac{\partial L}{\partial w}&=\frac{\partial L}{\partial z}\frac{\partial z}{\partial w}\\ &=\begin{bmatrix} x_1 & x_1 & x_1 \\ x_2 & x_2 & x_2 \\ x_3 & x_3 & x_3 \\ x_4 & x_4 & x_4 \\ \end{bmatrix} \begin{bmatrix} -y_1\cdot (1-\hat y_1) & y_1\cdot \hat y_2 & y_1\cdot \hat y_3 \\ \\ y_2\cdot \hat y_1 & - y_2\cdot (1-\hat y_2) & y_2\cdot \hat y_3 \\ \\ y_3\cdot \hat y_1 & y_3\cdot \hat y_2 & - y_3\cdot (1-\hat y_3) \\ \end{bmatrix} \end{align} wL=zLwz= x1x2x3x4x1x2x3x4x1x2x3x4 y1(1y^1)y2y^1y3y^1y1y^2y2(1y^2)y3y^2y1y^3y2y^3y3(1y^3)

∂ L ∂ b = ∂ L ∂ z ∂ z ∂ b = [ 1 , 1 , 1 ] [ − y 1 ⋅ ( 1 − y ^ 1 ) y 1 ⋅ y ^ 2 y 1 ⋅ y ^ 3 y 2 ⋅ y ^ 1 − y 2 ⋅ ( 1 − y ^ 2 ) y 2 ⋅ y ^ 3 y 3 ⋅ y ^ 1 y 3 ⋅ y ^ 2 − y 3 ⋅ ( 1 − y ^ 3 ) ] \begin{align}\frac{\partial L}{\partial b}&=\frac{\partial L}{\partial z}\frac{\partial z}{\partial b}\\ &=[1,1,1] \begin{bmatrix} -y_1\cdot (1-\hat y_1) & y_1\cdot \hat y_2 & y_1\cdot \hat y_3 \\ \\ y_2\cdot \hat y_1 & - y_2\cdot (1-\hat y_2) & y_2\cdot \hat y_3 \\ \\ y_3\cdot \hat y_1 & y_3\cdot \hat y_2 & - y_3\cdot (1-\hat y_3) \\ \end{bmatrix} \end{align} bL=zLbz=[1,1,1] y1(1y^1)y2y^1y3y^1y1y^2y2(1y^2)y3y^2y1y^3y2y^3y3(1y^3)

最后进行梯度更新
w t = w t − 1 − l r ⋅ ∂ L ∂ w w_t = w_{t-1}-lr\cdot \frac{\partial L}{\partial w} wt=wt1lrwL
b t = b t − 1 − l r ⋅ ∂ L ∂ b b_t = b_{t-1}-lr\cdot \frac{\partial L}{\partial b} bt=bt1lrbL

代码实现

这里自定义了一个逻辑回归模型类,使用numpy数组指定了w和b参数,自定义softmax和sigmoid函数,计算反向求导公式并更新,代码严格按照上文公式进行计算。


from sklearn.datasets import load_iris
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split

class Logistic_Regression:
    def __init__(self, optimizer='GD', lr=0.001, max_iterations=1000):
        self.optimizer = optimizer
        self.lr = lr
        self.max_iterations = max_iterations

    def fit(self, input, label, input_test, label_test, n_target=2):
        self.n_target = n_target
        # 多分类,使用softmax
        if self.n_target > 2:
            self.weights = np.random.normal(0, 0.1, (input.shape[1], self.n_target))
            self.bias = np.zeros(self.n_target)

            # 梯度下降法求解
            if self.optimizer == 'GD':
                for iteration in range(self.max_iterations):
                    pred = np.dot(input, self.weights) + self.bias
                    pred = self.softmax(pred)
                    accuracy = self.accuracy(pred, label)
                    loss = self.cross_entropy_multi(pred, label)
                    print(f'{iteration}, accuracy: {accuracy}, loss:{loss}')

                    label_expand = np.array([[0] * l + [1] + [0] * (self.n_target - 1 - l) for l in label])
                    softmax_grad = []
                    for sample in range(label_expand.shape[0]):
                        softmax_grad.append([[-label_expand[sample][i]*(1-pred[sample][j]) if i == j else label_expand[sample][i]*pred[sample][j] for j in range(self.n_target)] for i in range(self.n_target)])
                    softmax_grad = np.array(softmax_grad)
                    input_repeat = np.expand_dims(input, axis=-1).repeat(3, axis=-1)

                    w_grad = np.matmul(input_repeat, softmax_grad).mean(axis=0)
                    bias_grad = (softmax_grad.sum(axis=0)).mean(axis=0)

                    self.weights -= self.lr * w_grad
                    self.bias -= self.lr * bias_grad

                    if (iteration + 1) % 500 == 0:
                        self.test(input_test, label_test)
                        print(f'{iteration + 1}, accuracy: {accuracy}')
        # 二分类,使用sigmoid
        else:
            self.weights = np.random.normal(0, 0.1, (input.shape[1]))
            self.bias = 0

            # 梯度下降法求解
            if self.optimizer == 'GD':
                for iteration in range(self.max_iterations):
                    pred = np.dot(input, self.weights) + self.bias
                    pred = self.sigmoid(pred)  # pred预测的值代表标签为1的概率
                    pred_class = (pred > 0.5) + 0
                    accuracy = self.accuracy(pred_class, label)
                    loss = self.cross_entropy_binary(pred, label)
                    print(f'{iteration}, accuracy: {accuracy}, loss:{loss}')

                    w_grad = (1 / input.shape[0]) * np.matmul(input.T, pred - label)
                    bias_grad = (pred - label).mean()

                    self.weights -= self.lr * w_grad
                    self.bias -= self.lr * bias_grad

                    if (iteration + 1) % 10 == 0:
                        self.test(input_test, label_test)
                        print(f'{iteration + 1}, accuracy: {accuracy}')
        return

    def test(self, input_test, label_test):
        pred = np.dot(input_test, self.weights) + self.bias
        if self.n_target > 2:
            pred = self.softmax(pred)
        else:
            pred = self.sigmoid(pred)  # pred预测的值代表标签为1的概率
            pred = (pred > 0.5) + 0
        accuracy = self.accuracy(pred, label_test)
        return accuracy

    def softmax(self, x):
        return np.exp(x) / np.expand_dims(np.exp(x).sum(axis=1), axis=-1)

    def sigmoid(self, x):
        return 1 / (1 + np.exp(-x))

    def cross_entropy_multi(self, pred, label):
        loss = pred[range(pred.shape[0]), label] * np.log(pred[range(pred.shape[0]), label])
        return -loss.mean()

    def cross_entropy_binary(self, pred, label):
        loss = label * np.log(pred) + (1 - label) * np.log(1 - pred)
        return -loss.mean()

    def accuracy(self, pred, label):
        if len(pred.shape) != 1:
            pred = np.argmax(pred, axis=-1)
        return sum(pred == label) / pred.shape[0]


if __name__ == '__main__':
    iris = load_iris()

    X = iris.data
    y = iris.target
    print(X.data.shape)
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.15, random_state=420)
    # 一共150个样本,分别是50个类别1、50个类别2、50个类别3,若想测试二分类可以取前100个样本
    # X_train, X_test, y_train, y_test = train_test_split(X[:100], y[:100], test_size=0.15, random_state=420)
    LR = Logistic_Regression(optimizer='GD', lr=0.5, max_iterations=5000)
    LR.fit(X_train, y_train, X_test, y_test, n_target=3)

备注

本文公式是自己推导的,公式是一个一个敲的,若有错误请指出,我会尽快修改,完整文件可在github查看。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/799859.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

农业管理3d可视化管理大屏展示为乡村新基建加速

随着科技的不断发展,智慧农业已经成为当今社会农业发展的一个重要趋势。而数字孪生技术作为一种新兴的技术手段,正在逐渐应用到智慧农业领域中。 数字孪生公司深圳华锐视点基于数字孪生为核心技术打造的智慧大脑为乡村新基建加速,让乡村更“聪…

Python入门【推导式创建序列、字典推导式、集合推导式】(九)

👏作者简介:大家好,我是爱敲代码的小王,CSDN博客博主,Python小白 📕系列专栏:python入门到实战、Python爬虫开发、Python办公自动化、Python数据分析、Python前后端开发 📧如果文章知识点有错误…

239.滑动窗口最大值

leetcode原题链接 题目描述: 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 示例1: 输入:nums [1,…

【UniApp开发小程序】悬浮按钮+出售闲置商品+商品分类选择【基于若依管理系统开发】

文章目录 界面效果界面实现悬浮按钮实现商品分类选择界面使元素均匀分布 闲置商品描述信息填写界面价格校验 界面效果 【悬浮按钮】 【闲置商品描述信息填写界面】 【商品分类选择界面】 【分类选择完成】 界面实现 悬浮按钮实现 悬浮按钮漂浮于页面之上,等页面…

使用langchain与你自己的数据对话(三):检索(Retrieval)

之前我已经完成了使用langchain与你自己的数据对话的前两篇博客,还没有阅读这两篇博客的朋友可以先阅读一下: 使用langchain与你自己的数据对话(一):文档加载与切割使用langchain与你自己的数据对话(二):向量存储与嵌入 今天我们…

【C语言】文件操作(二)

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃 目录 📌补充1.sprintf2.…

hive 全量表、增量表、快照表、切片表和拉链表

全量表:记录每天的所有的最新状态的数据,增量表:记录每天的新增数据,增量数据是上次导出之后的新数据。快照表:按日分区,记录截止数据日期的全量数据切片表:切片表根据基础表,往往只…

如何利用tf.keras 实现深度学习?

tf.keras是TensorFlow 2.0的高阶API接口,为TensorFlow的代码提供了新的风格和设计模式,大大提升了TF代码的简洁性和复用性,官方也推荐使用tf.keras来进行模型设计和开发。 常用模块 tf.keras中常用模块如下表所示: 常用方法 深度…

智慧环保:创造绿色未来

随着全球环境问题的日益严重,智慧环保成为推动绿色发展的关键。智慧环保利用先进的技术手段和智能化设备,致力于解决环境问题,保护生态环境,实现可持续发展。它融合了物联网、人工智能、大数据等技术,将科技的力量与环…

C#实现计算题验证码

开发环境:C#,VS2019,.NET Core 3.1,ASP.NET Core API 1、建立一个验证码控制器 新建两个方法Create和Check,Create用于创建验证码,Check用于验证它是否有效。 声明一个静态类变量存放列表,列…

公众号运营:公众号互选广告操作流程指南

什么是公众号互选广告平台? 公众号互选平台,是广告主和流量主双向互选、自由达成内容合作的交易 平台,广告创意呈现在公众号文章内容中。 收入模式:按合作文章收费,合作价格由流量主自主决定。 操作配合:提…

1334179-85-9,BTTAA,是各种化学生物学实验中生物偶联所需

资料编辑|陕西新研博美生物科技有限公司小编MISSwu​ BTTAA试剂 | 基础知识概述(部分): 中文名称:2-[4-({双[(1-叔丁基-1H-1,2,3-三唑-4-基)甲基]氨基}甲基)-1H-1,2,3-三唑-1-基]乙酸 英文名称:BTTAA CAS号:1334179-8…

Vue2 第一节 通用概念和前置知识

本篇将记录自己学习Vue的知识点总结 学习资源: B站 :尚硅谷Vue2.0Vue3.0全套教程 有个博主将这个视频总结成了笔记,之后的博客也会参考这个笔记 (126条消息) 【2022.3】尚硅谷Vue.js从入门到精通基础笔记(理论实操知识点速查&…

Android 之 Paint API —— PathEffect (路径效果)

本节引言: 本节继续来学习Paint的API——PathEffect(路径效果),我们把画笔的sytle设置为Stroke,可以 绘制一个个由线构成的图形,而这些线偶尔会显得单调是吧,比如你想把这些先改成虚线,又 或者想让路径的转…

我们聊聊性能测试的理解误区

有同学私信我,和他聊了聊关于性能测试的一些话题,发现他对性能测试的理解走入了一些误区。 在一些技术交流群,同样遇到过很多同学由于对性能测试理解上的误区导致的各种问题,比如: 注册用户数并发数,然后服…

Top命令

Top top - 12:46:01 up 2 days, 11:10, 3 users, load average: 0.56, 0.59, 0.45系统基本信息:显示了系统运行时间、登录用户数和平均负载(load average)情况。平均负载是系统在特定时间范围内的平均活跃进程数,可以用来衡量系…

自动驾驶之轨迹规划8——Apollo参考线和轨迹

1. abstract 本文主要讲解routing和planning模块中的reference line,我之前一直搞不明白这个reference line是如何生成的,有什么作用,和routing以及planning的关系。现在有了一些心得打算梳理一下: 决策规划模块负责生成车辆的行…

Go基础—反射,性能和灵活性的双刃剑

Go基础—反射,性能和灵活性的双刃剑 1 简介2 结构体成员赋值对比3 结构体成员搜索并赋值对比4 调用函数对比5 基准测试结果对比 1 简介 现在的一些流行设计思想需要建立在反射基础上,如控制反转(Inversion Of Control,IOC&#x…

7.27 Qt

制作简易小闹钟 Timer.pro QT core gui texttospeechgreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c11# The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (the exact warnings # dep…

替换字母题解

样例输入1: 5 4 abcab样例输出1: 1样例输入2: 5 3 abcab样例输出2: 2思路分析: 看到这种题,先想到 O ( 26 n ) O(26\times n) O(26n)的时间复杂度,枚举把字符串都变成每一个字母所需要的最…