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

目录

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

概述

本文使用梯度下降法对逻辑回归进行训练,使用类似于神经网络的方法进行前向传播与反向更新,使用数学公式详细推导前向传播与反向求导过程,包括二分类和多分类问题,最后用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.mfbz.cn/a/47452.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OS1_进程与线程的管理

序言 1.OS以进程、线程的方式在CPU中执行静态保存在外存(内存)中的程序,进程的构成与状态转化,特别是进程的切换; 2.当有多个进程处于就绪态,有哪些常见的挑选以执行方式; 3.并发执行(乱序发射)的进程,共享…

c# Outlook检索设定问题

基于c# 设定outlook约会予定,时间格式是YYYY-MM-DD HH:mm 的情报。 问题发生: 根据开始时间(2023/01/01 7:00)条件查询该时间是否存在outlook信息时,明明存在一条数据,就是查询不出来数据 c#代码 Strin…

20.1:ABC对应123问题

规定1和A对应、2和B对应、3和C对应…26和Z对应 那么一个数字字符串比如"111”就可以转化为: “AAA”、“KA"和"AK” 给定一个只有数字字符组成的字符串str,返回有多少种转化结果 一:暴力方法 public static int number(String str) {…

使用nginx和ffmpeg搭建HTTP FLV流媒体服务器(摄像头RTSP视频流->RTMP->http-flv)

名词解释 RTSP (Real-Time Streaming Protocol) 是一种网络协议,用于控制实时流媒体的传输。它是一种应用层协议,通常用于在客户端和流媒体服务器之间建立和控制媒体流的传输。RTSP允许客户端向服务器发送请求,如…

4. 方法(函数)

文章目录 4.1. 什么是方法的返回值?返回值在类的方法里的作用是什么?4.2. 为什么 Java 中只有值传递? 4.1. 什么是方法的返回值?返回值在类的方法里的作用是什么? 方法的返回值是指我们获取到的某个方法体中的代码执行后产生的结果!(前提…

机器学习02-再识K邻近算法(自定义数据集训练及测试)

定义: 如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。简单的说就是根据你的“邻居”来推断出你的类别。 用个成语就是物以类聚 思想: 如果一个样本在特征空间中的K个最…

视频内存过大如何压缩变小?这个压缩方法了解一下

在日常生活中,不管是日常随手拍的视频还是在工作中遇到的视频文件,在编辑处理的时候,如果视频的内存过大,不仅会占用很大的内存,在传送的时候也会花费很长时间,这时候将视频给压缩一下就可以很好的解决这一…

使用ComPDFKit PDF SDK 构建iOS PDF阅读器

在当今以移动为先的世界中,为企业和开发人员创建一个iOS应用程序是必不可少的。随着对PDF文档处理需求的增加,使用ComPDFKit这个强大的PDF软件开发工具包(SDK)来构建iOS PDF阅读器和编辑器可以让最终用户轻松查看和编辑PDF文档。 …

Elasticsearch监控工具Cerebro安装

Elasticsearch监控工具Cerebro安装 1、在windwos下的安装 1.1 下载安装包 https://github.com/lmenezes/cerebro/releases/download/v0.9.4/cerebro-0.9.4.zip 1.2 解压 1.3 修改配置文件 如果需要修改相关信息,编辑C:\zsxsoftware\cerebro-0.9.4\conf\applica…

mybatis日志工厂

前言: 如果一个数据库操作,出现异常,我们需要排错,日志就是最好的助手 官方给我们提供了logImpl:指定 MyBatis 所用日志的具体实现,未指定时将自动查找。 默认工厂: 在配置文件里添加&#xf…

桥梁安全监测系统中数据采集上传用 什么?

背景 2023年7月6日凌晨时分,G5012恩广高速达万段230公里加80米处6号大桥部分桥面发生垮塌,导致造成2车受损后自燃,3人受轻伤。目前,四川省公安厅交通警察总队高速公路五支队十四大队民警已对现场进行双向管制。 作为世界第一桥梁…

msvcp140.dll丢失怎么办?(详细解决方法)

1.msvcp140.dll有什么用? 运行C程序:msvcp140.dll文件包含了许多C程序所需的函数和资源,使得C程序能够在计算机上正确运行。 提供运行时库:msvcp140.dll文件包含了C程序在运行时所需的库文件,如输入/输出操作、内存管…

pdf合并大小不一样怎么办?有这几个方法就够了

pdf合并大小不一样怎么办?在日常工作和生活中,我们经常需要处理PDF文件。在将多个PDF文件合并成一个时,由于这些文件的大小和格式可能不同,可能会遇到一些问题。但不用担心,接下来将介绍几种方法来解决这个问题。 方法…

小程序轮播图的两种后台方式(JSP)--【浅入深出系列009】

微信目录集链接在此: 详细解析黑马微信小程序视频–【思维导图知识范围】难度★✰✰✰✰ 不会导入/打开小程序的看这里:参考 让别人的小程序长成自己的样子-更换window上下颜色–【浅入深出系列001】 文章目录 本系列校训学习资源的选择啥是轮播图轮播…

【广州华锐互动】VR模拟灭火逃生体验系统

VR模拟灭火逃生体验系统由广州华锐互动开发,是一种基于虚拟现实技术的应急演练与培训系统,可以真实模拟消防逃生场景,让体验者在沉浸式的虚拟环境中,根据正确的消防逃生方法提示,进行自救演练。这种科学普及方法是更加…

NLP实战8:图解 Transformer笔记

目录 1.Transformer宏观结构 2.Transformer结构细节 2.1输入 2.2编码部分 2.3解码部分 2.4多头注意力机制 2.5线性层和softmax 2.6 损失函数 3.参考代码 🍨 本文为[🔗365天深度学习训练营]内部限免文章(版权归 *K同学啊* 所有&#…

【云原生】Docker网络及Cgroup资源控制

一、Docker网络 1.docker网络实现原理 Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。…

QT--day3(定时器事件、对话框)

头文件代码&#xff1a; #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimerEvent> //定时器事件处理时间头文件 #include <QTime> //时间类 #include <QtTextToSpeech> #include <QPushButton> #include <QLabel&g…

分布式文件存储与数据缓存 FastDFS

一、FastDFS概述 1.1 什么是分布式文件系统 单机时代 初创时期由于时间紧迫&#xff0c;在各种资源有限的情况下&#xff0c;通常就直接在项目目录下建立静态文件夹&#xff0c;用于用户存放项目中的文件资源。如果按不同类型再细分&#xff0c;可以在项目目录下再建立不同的…

已实现商业化却仍陷亏损泥潭,瑕瑜错陈的觅瑞集团求上市

撰稿|行星 来源|贝多财经 7月25日&#xff0c;Mirxes Holding Company Limited-B&#xff08;以下简称“觅瑞集团”&#xff09;向港交所递交上市申请材料&#xff0c;计划在港交所主板上市&#xff0c;中金公司和建银国际为其联席保荐人。 据招股书介绍&#xff0c;成立于2…
最新文章