逻辑回归揭秘: 从分类原理到机器学习实践

news2024/12/23 13:58:47

机器学习 第五课 逻辑回归

  • 概述
  • 逻辑回归应用领域
  • 逻辑回归 vs 线性回归
    • 基本定义
    • 输出类型
    • 函数关系
    • 误差计算
    • 使用场景
    • 数据分布
  • 逻辑回归的数学原理
    • Sigmoid 函数
    • 多数几率
    • 似然函数
    • 逻辑回归损失函数
  • 正则化
    • L1 正则化
    • L2 正则化
    • L1 vs L2 实例
  • 标准化
    • 为什么要标准化?
    • 如何进行标准化?
  • 梯度下降
    • 工作原理
    • 梯度下降的公式
    • 梯度下降的变种
    • 学习率
  • 前向传播 vs 反向传播
    • 前向传播
    • 反向传播
  • 手把手计算回归
    • 前向传播
    • 反向传播
    • 参数更新
  • 实战
    • 逻辑回归预测乳腺癌
    • 逻辑回归 鸢尾花
  • 手搓逻辑回归

概述

逻辑回归 (Logistic Regression) 尽管名字中带有 “回归” 两个字, 但主要是用来解决分类问题, 尤其是二分类问题. 逻辑回归的核心思想是: 通过将线性回归的输出传递给一个激活函数 (Activation Function) 比如 Sigmoid 函数) 将连续值转化为 0 到 1 之间的概率值, 在根据阈值 (Threshold) 对概率进行分类.

机器学习 逻辑回归

逻辑回归应用领域

逻辑回归 (Logistic Regression) 在许多领域有着广泛的应用, 包括但不限于:

  • 医学: 用于疾病预测
  • 金融: 信用评分, 评估某人违约的风险
  • 营销: 预测客户是否购买某个产品, 或是否点击某个广告
  • 社交网络: 预测用户相位, 例如是否接收好友请求或是否为垃圾信息

随着我们对数据的理解不断加深, 尤其是在设计分类任务时, 逻辑回归往往是我们首先尝试的算法. 相较于其他算法, 逻辑回归有着非常高的计算效率, 且背后的数学原理简单明了.

逻辑回归 vs 线性回归

在机器学习中, 线性回归 (Linear Regression) 和逻辑回归是最基础的算法. 尽管两个算法的名字十分相似, 但是工作原理和用途上有着很大的差异. 为了更深入的理解两者之间的差异, 我们从下面几个维度来展开讨论.

基本定义

  • 线性回归 (Linear Regression): 线性回归用于估计一个或多个自变量与因变量的线性关系, 用于回归任务
  • 逻辑回归 (Logistic Regression): 逻辑回归估算事件发生的概率, 用于分类任务

输出类型

  • 线性回归 (Linear Regression): 线性回归输出的是连续值, 范围是 − ∞ ∼ + ∞ -\infty\sim +\infty +
  • 逻辑回归 (Logistic Regression): 逻辑回归输出的是概率值, 范围是 0-1

函数关系

  • 线性回归 (Linear Regression): 线性回归关系是线性的, 使用恒等链接函数
  • 逻辑回归 (Logistic Regression): 逻辑回归关系是 S 形的 (Sigmoid) 函数

误差计算

  • 线性回归 (Linear Regression): 线性回归使用均方误差 (MSE) 来计算模型误差
  • 逻辑回归 (Logistic Regression): 逻辑回归使用对数损失函数 (Logarithmic Loss Function) 来计算模型误差

使用场景

  • 线性回归 (Linear Regression): 线性回归的目标是预测一个连续的值, 例如房价, 温度等
  • 逻辑回归 (Logistic Regression): 逻辑回归的目标是分类, 特别是二分类, 例如垃圾邮件检测, 疾病诊断等

数据分布

  • 线性回归 (Linear Regression): 要求自变量和因变量具有线性关系, 且误差应呈现正态分布 (Normal Distribution). 此外书籍中不能存在重共线性, 异方差性和自相关
  • 逻辑回归 (Logistic Regression): 不需要因变量和自变量之间存在线性关系, 每个自变量与 log(odds) 之间存在线性关系. 此外, 逻辑回归还假设观察值之间是独立的

逻辑回归的数学原理

在我们深入研究逻辑回归 (Logistic Regression) 之前, 理解其背后的数学原理至关重要. 通过理解原理, 我们可以更好的理解算法, 还可以帮助我们在实际应用中做出明智的决策.

Sigmoid 函数

逻辑回归的核心是 Sigmoid 函数, 也称为 Logistic 函数. 通过 Sigmoid 函数, 我们可以将任何实数映射到 0-1 之间.

Sigmoid 函数
sigmoid 公式:
S ( z ) = 1 1 + e − z S(z) = \frac{1}{1 + e^{-z}} S(z)=1+ez1

  • z 为输入的线性组合

z 的公式:
z = w 0 + w 1 x 1 + w 2 x 2 + w 3 x 3 + . . . + w n x n z = w_0 + w_1x_1 + w_2x_2 + w_3x_3 + ... + w_nx_n z=w0+w1x1+w2x2+w3x3+...+wnxn

  • 当 z 趋于正无穷时, S(z) 趋近于 1
  • 当 z 趋于负无穷时, S(z) 趋近于 0
  • 当 z=0 时, S(z) = 0.5

Sigmoid 的 S 形曲线非常适用于二分类问题, 因为 Sigmoid 可以产生的输出看做是属于某个类别的概率.

Sigmoid 函数在 Python 中的实现:

import numpy as np

def sigmoid(z):
    return 1 / (1 + np.exp(-z))

多数几率

逻辑回归涉及到一个重要的概念, 对数几率 (Log-Odds). 对数几率是事件发生概率与事件不发生概率之间的对数比率.

l o g i t ( p ) = l o g ( p 1 − p ) logit(p) = log(\frac{p}{1-p}) logit(p)=log(1pp)

其中, p 是事件发生的概率 (Probability). 我们的目标是建立解释变量和对数几率之间的关系.

似然函数

为了估计逻辑回归模型中的参数, 我们需要使用似然函数 (Likelihood Function). 给定一组参数, 依然函数描述了数据观测到的概率.

似然函数与概率:

  • 似然: 给定某一观测到数据集, 我们试图估计某一参数 (如硬币出现正面的概率) 的可能性.
  • 概率: 给定某一参数值 (例如一个硬币出现正反面的概率), 我们计算特定情况下观察到某一数据集的概率. 举个栗子: 抛硬币, 正反面出现的概率为 0.5, 我们可以计算连续抛投 5 词都是正面的概论, 即 P ( 5 正面 ∣ p ) = ( 0.5 ) 5 = 0.03125 P(5 正面 | p) = (0.5)^5 = 0.03125 P(5正面p)=(0.5)5=0.03125
  • 似然 vs 概率:
    • 函数角度: 似然是关于参数的函数, 给定观测到的数据; 概率是关于数据的函数, 给定固定的参数值
    • 归一化: 似然的总和并不一定为 1, 不是一个真正的概率分布; 概率所有可能的事件总和总是等于 1
    • 观点: 似然描述了给定已经发生的某事件下, 不同情景 (模型参数) 的可能; 概率描述了未来发生某件事情的可能性

似然函数公式:
L ( θ ∣ x ) = P ( X = x ∣ θ ) L(\theta|x) = P(X=x|\theta) L(θx)=P(X=xθ)

  • θ \theta θ: 模型参数
  • X X X: 随机变量
  • x x x: 观察到的数据
  • P ( X = x ∣ θ ) P(X=x|\theta) P(X=xθ): 在给定参数 θ \theta θ下观测到数据 x x x的概率

最大似然估计, 似然函数在统计学中一个主要应用是最大似然估计 (MLE). 目标是找到能使似然函数最大化的参数值. 公式:

θ ˆ = a r g    m a x    L ( θ ∣ x ) \^\theta = arg\; max\; L(\theta|x) θˆ=argmaxL(θx)

  • θ ˆ \^\theta θˆ为模型参数的最佳估计值

为什么要使用似然函数:

  • 似然函数为我们提供了一个框架来评估模型参数的不同可能值对观察数据的拟合程度. 最大似然函数估计为我们提供了一个一致性和渐进无偏的估计方法, 即样本量越大, MLE 会月接近真实参数值

逻辑回归损失函数

逻辑回归 (Logistic Regression) 用于解决二分类 (Binary Classification) 问题, 主要用于目标是预测给定输入的输出类别为 1 (True) 的概率. 为了衡量模型的预测值 ( y ˆ \^y yˆ Predict) 与实际类别标签之间的差异, 我们需要一个损失函数. 逻辑回归蚕蛹的损失函数通常被称为对数损失 (Log Loss) 或交叉熵损失 (Cross Entropy Loss).

对数损失函数:
J ( w , b ) = − y l o g ( y ˆ ) − ( 1 − y ) l o g ( 1 − y ˆ ) J(w, b) = -ylog(\^y)- (1-y)log(1-\^y) J(w,b)=ylog(yˆ)(1y)log(1yˆ)

  • y: 是类别标签 (0 或 1)
  • y ˆ \^y yˆ: 是模型预测值

对数损失函数考虑了模型预测值的概率和实际类别之间的所有可能的差异:

  • 当实际类别等于 1 时 (y=1): 损失函数就是 − l o g ( y ˆ ) -log(\^y) log(yˆ). 如果 y ˆ \^y yˆ 越接近 1, 那么损失值将越接近 0. 反之 y ˆ \^y yˆ 越接近 0, 损失值将越大
  • 当实际类别等于 1 时 (y=0): 损失函数就是 − l o g ( 1 − y ˆ ) -log(1-\^y) log(1yˆ). 如果 y ˆ \^y yˆ 越接近 0, 那么损失值将越接近 0. 反之 y ˆ \^y yˆ 越接近 1, 损失值将越大

注: 交叉熵损失和对数损失在二分类问题下是等价的.

正则化

正则化 (Regularization) 是机器学习中一个的一个重点. 正则化通过在模型损失函数中添加一定的 “惩罚” 项, 来限制模型的复杂度以提高模型的泛化能力 (Generalization Ability) 和避免过拟合 (Overfitting). 在逻辑回归中, 我们常常会用到 L1 和 L2 正则化来实现.

L1 正则化

L1 正则化 (Lasso 正则化):
J L 1 = J + λ ∑ i = 1 n ∣ w i ∣ J_{L1} = J + \lambda \sum\limits_{i=1}^{n}|w_i| JL1=J+λi=1nwi

  • J J J: 原始的损失函数
  • w i w_i wi: 模型参数
  • λ \lambda λ: 正则化参数

L1 正则化倾向于产生一些权重为 0 的特征 (Feature), 这意味着模型中某些特征可能完全被忽略, 从而实现了特征选择.

L2 正则化

L2 正则化 (Ridge 正则化):
J L 1 = J + λ ∑ i = 1 n w i 2 J_{L1} = J + \lambda \sum\limits_{i=1}^{n}w_i^2 JL1=J+λi=1nwi2

  • J J J: 原始的损失函数
  • w i w_i wi: 模型参数
  • λ \lambda λ: 正则化参数

与 L1 正则化不同, L2 正则化不会使权重完全为 0, 但它会尽量使它们小, 这有助于防止任何单一特征对预测结果产生过大的影响, 从而使模型更加稳健.

选择合适的正则化:

  • 选择 L1 或 L2 正则化 (或者它们的组合, Elastic Net) 取决于我们需要解决什么问题. 如果只有几个特征是重要的, 那么 L1 正则化可能更合适, 因为它会导致稀疏的模型. 而如果所有特征都有意义, 但我们希望模型不要过于以来任何单一特征, 那么 L2 正则可能是更好的选择.

L1 vs L2 实例

假设我们有一个拥有 10 个特征的数据集, 但是其中只有 3 个是真正有意义的, 及特征中含有许多冗余特征. 在这种情况下, 我们就需要用到 L1 正则化, 因为 L1 正则化可以帮我们将那些不重要的特征的权重将为 0.

先讲一下 sklearn 生成模拟数据的格式:

sklearn.datasets.make_classification(n_samples=100, n_features=20, *, n_informative=2, n_redundant=2, n_repeated=0, n_classes=2, n_clusters_per_class=2, weights=None, flip_y=0.01, class_sep=1.0, hypercube=True, shift=0.0, scale=1.0, shuffle=True, random_state=None)

参数:

  • n_samples: 生成的数据数量
  • n_features: 数据的特征个数
  • n_informative: 信息特征的个数 (最重要的特征)
  • n_redundant: 冗余特征的个数
  • random_state: 随机状态 (随机数种子)

例子:

"""
@Module Name: 逻辑回归 正则化.py
@Author: CSDN@我是小白呀
@Date: October 18, 2023

Description:
逻辑回归 正则化
"""
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import log_loss, accuracy_score

# 生成模拟数据, 长度1000, 特征10, 其中有用特征3, 冗余特征7
X, y = make_classification(n_samples=1000, n_features=10, n_informative=3, n_redundant=7, random_state=8)

# 输出数据维度
print("特征维度:", X.shape)  # (1000, 10)
print("标签维度:", y.shape)  # (1000, )

# 分割数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)

# 使用L1正则化
l1_model = LogisticRegression(penalty='l1', solver='liblinear')
l1_model.fit(X_train, y_train)


# 使用L2正则化
l2_model = LogisticRegression(penalty='l2', solver='liblinear')
l2_model.fit(X_train, y_train)

# 对比权重
print("L1正则化的特征权重:\n{}".format(l1_model.coef_))
print("L2正则化的特征权重:\n{}".format(l2_model.coef_))

# 对比模型效果
l1_pred = l1_model.predict(X_test)
l2_pred = l2_model.predict(X_test)

print("L1 逻辑回归误差:", log_loss(y_test, l1_pred))
print("L2 逻辑回归误差:", log_loss(y_test, l2_pred))
print("L1 逻辑回归 acc:", accuracy_score(y_test, l1_pred))
print("L2 逻辑回归 acc:", accuracy_score(y_test, l2_pred))

输出结果:

特征维度: (1000, 10)
标签维度: (1000,)
L1正则化的特征权重:
[[ 0.          0.          0.         -0.66172034  0.          0.
   0.         -0.75254448 -0.27951727  0.41781586]]
L2正则化的特征权重:
[[-0.14042143 -0.21016038  0.12523401 -0.43610954  0.05762657  0.08849344
  -0.19145278 -0.51859205 -0.42032689  0.5046308 ]]
L1 逻辑回归误差: 9.901243835463227
L2 逻辑回归误差: 10.016373090112928
L1 逻辑回归 acc: 0.7133333333333334
L2 逻辑回归 acc: 0.71

标准化

标准化 (Standardization) 常用与预处理数据, 特别是在使用需要考虑特征尺度的机器学习算法, 例如: 支持向量机, 逻辑回归, K-近邻.

标准化

为什么要标准化?

机器学习算法对特征的尺度和分布较为敏感. 当特征的尺度 (范围) 相差很大时, 那些范围较大的特可能会主导算法的行为, 导致模型性能不佳.

如何进行标准化?

标准化的主要思想是对特征数据进行缩放, 使其均值为 0, 标准差为 1.

标准化公式:

z = x − μ σ z = \frac{x - \mu}{\sigma} z=σxμ

  • z z z: 原始特征值
  • μ \mu μ: 特征均值
  • σ \sigma σ: 特征标准差

sklearn 中进行标准化:

from sklearn.preprocessing import StandardScaler

# 原始数据
data = [[0, 1], [2, 3], [4, 5]]
print(data)

# 标准化
scaler = StandardScaler()
scaler.fit(data)
data = scaler.transform(data)
print(data)

输出结果:

[[0, 1], [2, 3], [4, 5]]
[[-1.22474487 -1.22474487]
 [ 0.          0.        ]
 [ 1.22474487  1.22474487]]

逻辑回归预测乳腺癌, 不进行标准化:

Classification Report:
               precision    recall  f1-score   support

           0       0.92      0.96      0.94        47
           1       0.97      0.94      0.95        67

    accuracy                           0.95       114
   macro avg       0.94      0.95      0.95       114
weighted avg       0.95      0.95      0.95       114

进行标准化:

Classification Report:
               precision    recall  f1-score   support

           0       0.96      0.96      0.96        47
           1       0.97      0.97      0.97        67

    accuracy                           0.96       114
   macro avg       0.96      0.96      0.96       114
weighted avg       0.96      0.96      0.96       114

梯度下降

梯度下降 (Gradient Descent) 是一个用于优化函数的迭代方法. 在机器学习 (Machine Learning) 和深度学习 (Deep Learning) 中, 我们常用梯度下降来最小化 (最大化) 损失函数, 进而找到模型的最优参数.

工作原理

梯度下降的核心思想很简单: 找到损失函数的斜率 (梯度), 然后沿着斜率的反方向更新模型的参数, 逐步减小损失.

在这里插入图片描述

梯度下降的公式

公式:
w n e x t = w − l r × ∂ l o s s ∂ w w_{next} = w - lr\times \frac{\partial loss}{\partial w} wnext=wlr×wloss

  • w n e x t w_{next} wnext: 是梯度下降过程中的下一个权重
  • lr: Learning Rate 学习率
  • ∂ l o s s ∂ w \frac{\partial loss}{\partial w} wloss: 误差函数的导数

下面我们来推导一下:
我们已知: M S E = 1 n ∑ i = 1 n ( y i − y ˆ i ) 2 y = w 0 + w 1 x 1 MSE = \frac{1}{n}\sum\limits_{i=1}^{n}(y_i - \^y_i)^2\\y = w_0 + w_1x_1 MSE=n1i=1n(yiyˆi)2y=w0+w1x1

在梯度下降中, 我们的目标是调整模型参数 (权重和偏置, w 和 b 或 w0) 以最小化损失函数, 所以我们需要对模型参数 (w 和 w0) 求偏导:

w1 (权重) 求导:
∂ M S E ∂ w 1 = 1 n ∑ i = 1 n ( w 0 + w 1 x 1 ) 2 d w = 2 n ∑ i = 1 n x ( w 0 + w 1 x 1 ) \frac{\partial MSE}{\partial w_1} = \frac{1}{n}\sum\limits_{i=1}^{n}(w_0 + w_1x_1)^2dw \\=\frac{2}{n}\sum\limits_{i=1}^{n}x(w_0 + w_1x_1) w1MSE=n1i=1n(w0+w1x1)2dw=n2i=1nx(w0+w1x1)

w0 (偏置) 求导:
∂ M S E ∂ w 0 = 1 n ∑ i = 1 n ( w 0 + w 1 x 1 ) 2 d w = 2 n ∑ i = 1 n ( w 0 + w 1 x 1 ) \frac{\partial MSE}{\partial w_0} = \frac{1}{n}\sum\limits_{i=1}^{n}(w_0 + w_1x_1)^2dw \\=\frac{2}{n}\sum\limits_{i=1}^{n}(w_0 + w_1x_1) w0MSE=n1i=1n(w0+w1x1)2dw=n2i=1n(w0+w1x1)

如果有 w2, w3 以此类推, 这边我就不写了.

计算新的权重, 将上面的导数代入梯度下降公式, 我们可以得到:
w 1 n e x t = w 1 − l r × ∂ l o s s ∂ w 1 = w 1 − l r × 2 n ∑ i = 1 n x ( w 0 + w 1 x 1 ) w_{1next} = w_1 - lr\times \frac{\partial loss}{\partial w_1} \\=w_1 - lr\times\frac{2}{n}\sum\limits_{i=1}^{n}x(w_0 + w_1x_1) w1next=w1lr×w1loss=w1lr×n2i=1nx(w0+w1x1)

同理:
w 0 n e x t = w 0 − l r × ∂ l o s s ∂ w 0 = w 1 − l r × 2 n ∑ i = 1 n ( w 0 + w 1 x 1 ) w_{0next} = w_0 - lr\times \frac{\partial loss}{\partial w_0} \\=w_1 - lr\times\frac{2}{n}\sum\limits_{i=1}^{n}(w_0 + w_1x_1) w0next=w0lr×w0loss=w1lr×n2i=1n(w0+w1x1)

在代码中:

# 计算w的导, w的导 = 2x(wx+b-y)
 w_gradient += (2 / N) * x * ((w_current * x + b_current) - y)

# 计算b的导, b的导 = 2(wx+b-y)
b_gradient += (2 / N) * ((w_current * x + b_current) - y)

梯度下降的变种

  • 批量梯度下降 (BGD, Batch Gradient Descent): 每次使用这个训练集来计算梯度
  • 随机梯度下降 (SGD, Stochastic Gradient Descent): 每次只使用一个样本来计算梯度
  • 小批量梯度下降 (Mini-Batch Gradient Descent): 使用一个小批量的样本来计算梯度

学习率

寻找山谷的最低点, 也就是我们的目标函数终点 (什么样的参数能使得目标函数达到极值点)

下山分几步走呢?

  1. 找到当前最合适的方向
  2. 走一小步
  3. 按照方向与步伐去更新我们的参数

学习率 (learning_rate): 对结果影响较大, 越小越好.

数据批次 (batch_size): 优先考虑内存和效率, 批次大小是次要的.

机器学习 学习率
选择适当的学习率非常重要:

  • 太小的学习率: 收敛速度慢
  • 太大的学习率: 会错过最小值, 或梯度爆炸

常见的操作有:

  • 学习率衰减或学习率退火 (Learning Rate Decay 或 Cosine Annealing), 即学习率随着迭代次数逐渐减小

前向传播 vs 反向传播

前向传播 (Forward Propagation) 和反向传播是深度学习 (Deep Learning) 中训练神经网络 (Neural Network) 的一个概念. 但是今天我乐意, 所以就来给大家讲一讲, 不喜欢欢迎来打我.

逻辑回归 (Logistic Regression) 可以被视为一个单层神经网络, 所以前向传播和反向传播的概念也适用.

前向传播

前向传播 (Forward Propagation) 是指从输入层传递到输出层的信息流. 在这个过程中我们计算每一层的输出值知道最后的预测值.

对于逻辑回归 (Logistic Regression) 而言, 逻辑回归的单层神经网络的前向传播可以描述为以下几步:

  1. 计算线性部分: 给定输入特征 X X X 和权重 w w w (以及偏置 b b b), 我们计算 z = w X + b z = wX + b z=wX+b
  2. 激活函数: 将上一步的结果 z z z 传递给 Sigmoid 激活函数, 得到预测值 y ˆ = σ ( z ) \^y = \sigma(z) yˆ=σ(z)

反向传播

反向传播 (Backward Propagation) 是通过计算损失函数对于每个参数梯度来更新模型的参数. 这些梯度可以告诉我们如何调整参数以最小化损失.

对于逻辑回归, 反向传播的过程可以描述为以下几步:

  1. 计算误差: 计算 y − y ˆ y - \^y yyˆ, 即真实值和预测值之间的差
  2. 计算梯度: 计算损失函数 L L L 相对于权重 w w w 和偏置 b b b 的梯度. 具体来说, 就是求对于权重 w w w 和偏置 b b b 的偏导. 计算梯度 (Gradient) 的目的是找到一个方向, 沿着方向调整参数使得损失减少
  3. 更新参数: 使用上一步计算所得的梯度来更新权重和偏置. 我们使用学习率 (Learning Rate) 来控制更新的步长

在神经网络中, 这个过程更加复杂, 因为我们需要从输出层开始, 一层一层的回到输入层, 计算每一层的梯度. 但基本思想是一样的, 即计算损失梯度, 并使用这些梯度来更新网络中的权重和偏置. 前向传播为我们提供了模型的预测值, 反向传播为我们提供了更新模型参数的方法, 从而改进模型的预测能力.

手把手计算回归

使用简单的线性回归模型 y = w x + b y=wx+b y=wx+b来拟合给定的数据.

数据:

x = [1, 2, 3, 4, 5]
y = [2, 4, 6, 8, 10]

模型初始参数:

  • w = 0
  • b = 0

目标: 最小化均方误差 (MSE)
1 n ∑ i = 1 n ( y − ( w x + b ) ) \frac{1}{n}\sum\limits_{i=1}^{n}(y - (wx + b)) n1i=1n(y(wx+b))

前向传播

前向传播计算:

对于 x 1 = 1 x_1 = 1 x1=1, 预测结果为:
y ˆ 1 = w × x 1 + b = 0 × 1 + 0 = 0 \^y_1 = w \times x_1 + b = 0 \times 1 + 0 = 0 yˆ1=w×x1+b=0×1+0=0
真实值 y 1 = 2 y_1 = 2 y1=2, 所以误差为 e 1 = y 1 − y ˆ 1 = 2 e_1 = y_1 - \^y_1 = 2 e1=y1yˆ1=2

以此类推:

  1. 对于 x 1 = 1 x_1 = 1 x1=1:
    • y ˆ 1 = w × x 1 + b = 0 \^y_1 = w \times x_1 + b = 0 yˆ1=w×x1+b=0
    • e 1 = y 1 − y ˆ 1 = 2 e_1 = y_1 - \^y_1 = 2 e1=y1yˆ1=2
  2. 对于 x 2 = 2 x_2 = 2 x2=2:
    • y ˆ 2 = w × x 2 + b = 0 \^y_2 = w \times x_2 + b = 0 yˆ2=w×x2+b=0
    • e 2 = y 2 − y ˆ 2 = 4 e_2 = y_2 - \^y_2 = 4 e2=y2yˆ2=4
  3. 对于 x 3 = 3 x_3 = 3 x3=3:
    • y ˆ 3 = w × x 3 + b = 0 \^y_3 = w \times x_3 + b = 0 yˆ3=w×x3+b=0
    • e 3 = y 3 − y ˆ 3 = 6 e_3 = y_3 - \^y_3 = 6 e3=y3yˆ3=6
  4. 对于 x 4 = 4 x_4 = 4 x4=4:
    • y ˆ 4 = w × x 4 + b = 0 \^y_4 = w \times x_4 + b = 0 yˆ4=w×x4+b=0
    • e 4 = y 4 − y ˆ 4 = 8 e_4 = y_4 - \^y_4 = 8 e4=y4yˆ4=8
  5. 对于 x 5 = 5 x_5 = 5 x5=5:
    • y ˆ 5 = w × x 5 + b = 0 \^y_5 = w \times x_5 + b = 0 yˆ5=w×x5+b=0
    • e 5 = y 5 − y ˆ 5 = 10 e_5 = y_5 - \^y_5 = 10 e5=y5yˆ5=10

反向传播

MSE 的偏导为:
∂ M S E ∂ w = − 2 n ∑ i = 1 n x ( y − ( w x + b ) ) \frac{\partial MSE}{\partial w} = -\frac{2}{n}\sum\limits_{i=1}^{n}x(y - (wx + b)) wMSE=n2i=1nx(y(wx+b))
∂ M S E ∂ b = − 2 n ∑ i = 1 n ( y − ( w x + b ) ) \frac{\partial MSE}{\partial b} =- \frac{2}{n}\sum\limits_{i=1}^{n}(y - (wx + b)) bMSE=n2i=1n(y(wx+b))

代入 x 1 = 1 x_1 = 1 x1=1 y 1 = 2 y_1 = 2 y1=2:

∂ M S E ∂ w = − 2 × 1 × 2 = − 4 \frac{\partial MSE}{\partial w} = -2 \times1 \times2 = -4 wMSE=2×1×2=4
∂ M S E ∂ b = = − 2 × 2 = − 4 \frac{\partial MSE}{\partial b} = = -2 \times2 = -4 bMSE==2×2=4

这是一个数据的梯度, 对于整个数据, 我们需要依次计算 x 1 x_1 x1 x 5 x_5 x5, 然后求平均:

∂ M S E ∂ w = − 2 5 × [ ( 1 × 2 ) + ( 2 × 4 ) + ( 3 × 6 ) + ( 4 × 8 ) + ( 5 × 10 ) ] = − 2 5 × 110 = − 44 \frac{\partial MSE}{\partial w} \\= \frac{-2}{5} \times[(1 \times 2) + (2 \times 4) + (3 \times 6) + (4 \times 8) + (5 \times 10)] \\= \frac{-2}{5} \times 110 \\= -44 wMSE=52×[(1×2)+(2×4)+(3×6)+(4×8)+(5×10)]=52×110=44

∂ M S E ∂ b = − 2 5 × ( 2 + 4 + 6 + 8 + 10 ) = − 2 5 × 30 = − 12 \frac{\partial MSE}{\partial b} \\= \frac{-2}{5} \times(2+4+6+8+10) \\= \frac{-2}{5} \times 30 \\= -12 bMSE=52×(2+4+6+8+10)=52×30=12

参数更新

参数更新公式:
w n e w = w o l d − L e a r n i n g R a t e × ∂ l o s s ∂ w w_{new} = w_{old} - LearningRate\times \frac{\partial loss}{\partial w} wnew=woldLearningRate×wloss

b n e w = b o l d − L e a r n i n g R a t e × ∂ l o s s ∂ b b_{new} = b_{old} - LearningRate\times \frac{\partial loss}{\partial b} bnew=boldLearningRate×bloss

代入 ∂ M S E ∂ w = − 44 \frac{\partial MSE}{\partial w} = -44 wMSE=44 ∂ M S E ∂ b = − 12 \frac{\partial MSE}{\partial b} = -12 bMSE=12:

w n e w = 0 − 0.01 × ∂ l o s s ∂ w = 0 − 0.01 × − 44 = 0.44 w_{new} = 0 - 0.01 \times \frac{\partial loss}{\partial w} = 0 - 0.01 \times -44 = 0.44 wnew=00.01×wloss=00.01×44=0.44

b n e w = 0 − 0.01 × ∂ l o s s ∂ b = 0 − 0.01 × − 12 = 0.12 b_{new} = 0 - 0.01 \times \frac{\partial loss}{\partial b} = 0 - 0.01 \times -12 = 0.12 bnew=00.01×bloss=00.01×12=0.12

这样我们就完成了一次迭代. 为了得到更准确的权重, 我们需要迭代多次对模型进行收敛. 经过多次得带, 我们会发现 w w w 趋近于 2, b b b 趋近于 0.

第 1 次迭代后: w=0.44, b=0.12
第 2 次迭代后: w=0.776, b=0.2112
第 3 次迭代后: w=1.032608, b=0.280416
第 4 次迭代后: w=1.22860928, b=0.3328512
第 5 次迭代后: w=1.3783441663999998, b=0.3724776192
第 6 次迭代后: w=1.4927597926399998, b=0.402327416832
第 7 次迭代后: w=1.5802129932492799, b=0.42471528093696004
第 8 次迭代后: w=1.6470832178782207, b=0.44140819572326406
第 9 次迭代后: w=1.6982404182016162, b=0.45375503873610556
第 10 次迭代后: w=1.7374022238730944, b=0.4627855128692865
第 11 次迭代后: w=1.7674066038488565, b=0.4692856691795151
第 12 次迭代后: w=1.7904200108513373, b=0.4738555595649934
第 13 次迭代后: w=1.8080962748901435, b=0.4769532477226133
第 14 次迭代后: w=1.8216978995509552, b=0.47892840627475247
第 15 次迭代后: w=1.83218865727326, b=0.4800479641762001
第 16 次迭代后: w=1.8403042748225709, b=0.48051568545628054
第 17 次迭代后: w=1.8466063932342285, b=0.4804871152578007
第 18 次迭代后: w=1.8515237598072303, b=0.48008098935859095
第 19 次迭代后: w=1.8553836732881241, b=0.47938794398298534
第 20 次迭代后: w=1.8584359885257578, b=0.4784771647060382
第 21 次迭代后: w=1.8608714411677287, b=0.47740146210037193
第 22 次迭代后: w=1.862835636384806, b=0.47620114638830074
第 23 次迭代后: w=1.8644397275968507, b=0.47490698527744635
第 24 次迭代后: w=1.8657685684088967, b=0.4735424619160864
第 25 次迭代后: w=1.8668869356439743, b=0.4721254985732309
第 26 次迭代后: w=1.8678442798879062, b=0.4706697724631278
第 27 次迭代后: w=1.8686783519647792, b=0.46918572022059085
第 28 次迭代后: w=1.8694179713192922, b=0.4676813046982923
第 29 次迭代后: w=1.8700851393471505, b=0.4661626003251689
第 30 次迭代后: w=1.8706966526712672, b=0.4646342399578365

实战

逻辑回归预测乳腺癌

"""
@Module Name: 逻辑回归 乳腺癌.py
@Author: CSDN@我是小白呀
@Date: October 19, 2023

Description:
逻辑回归 乳腺癌
"""
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report

# 加载数据
data = load_breast_cancer()
X = data.data
y = data.target

# 调试输出数据基本信息
print("输出特征:", X[:5])
print("输出标签:", y[:5])

# 分割数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

# 标准化
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

# 训练
clf = LogisticRegression(random_state=42)
clf.fit(X_train, y_train)

# 预测
y_pred = clf.predict(X_test)

# 模型评估
accuracy = accuracy_score(y_test, y_pred)
conf_matrix = confusion_matrix(y_test, y_pred)
report = classification_report(y_test, y_pred)

print("acc:", accuracy)
print("\n混淆矩阵:\n", conf_matrix)
print("\nClassification Report:\n", report)

输出结果:

输出特征: [[1.799e+01 1.038e+01 1.228e+02 1.001e+03 1.184e-01 2.776e-01 3.001e-01
  1.471e-01 2.419e-01 7.871e-02 1.095e+00 9.053e-01 8.589e+00 1.534e+02
  6.399e-03 4.904e-02 5.373e-02 1.587e-02 3.003e-02 6.193e-03 2.538e+01
  1.733e+01 1.846e+02 2.019e+03 1.622e-01 6.656e-01 7.119e-01 2.654e-01
  4.601e-01 1.189e-01]
 [2.057e+01 1.777e+01 1.329e+02 1.326e+03 8.474e-02 7.864e-02 8.690e-02
  7.017e-02 1.812e-01 5.667e-02 5.435e-01 7.339e-01 3.398e+00 7.408e+01
  5.225e-03 1.308e-02 1.860e-02 1.340e-02 1.389e-02 3.532e-03 2.499e+01
  2.341e+01 1.588e+02 1.956e+03 1.238e-01 1.866e-01 2.416e-01 1.860e-01
  2.750e-01 8.902e-02]
 [1.969e+01 2.125e+01 1.300e+02 1.203e+03 1.096e-01 1.599e-01 1.974e-01
  1.279e-01 2.069e-01 5.999e-02 7.456e-01 7.869e-01 4.585e+00 9.403e+01
  6.150e-03 4.006e-02 3.832e-02 2.058e-02 2.250e-02 4.571e-03 2.357e+01
  2.553e+01 1.525e+02 1.709e+03 1.444e-01 4.245e-01 4.504e-01 2.430e-01
  3.613e-01 8.758e-02]
 [1.142e+01 2.038e+01 7.758e+01 3.861e+02 1.425e-01 2.839e-01 2.414e-01
  1.052e-01 2.597e-01 9.744e-02 4.956e-01 1.156e+00 3.445e+00 2.723e+01
  9.110e-03 7.458e-02 5.661e-02 1.867e-02 5.963e-02 9.208e-03 1.491e+01
  2.650e+01 9.887e+01 5.677e+02 2.098e-01 8.663e-01 6.869e-01 2.575e-01
  6.638e-01 1.730e-01]
 [2.029e+01 1.434e+01 1.351e+02 1.297e+03 1.003e-01 1.328e-01 1.980e-01
  1.043e-01 1.809e-01 5.883e-02 7.572e-01 7.813e-01 5.438e+00 9.444e+01
  1.149e-02 2.461e-02 5.688e-02 1.885e-02 1.756e-02 5.115e-03 2.254e+01
  1.667e+01 1.522e+02 1.575e+03 1.374e-01 2.050e-01 4.000e-01 1.625e-01
  2.364e-01 7.678e-02]]
输出标签: [0 0 0 0 0]
acc: 0.9649122807017544

混淆矩阵:
 [[45  2]
 [ 2 65]]

Classification Report:
               precision    recall  f1-score   support

           0       0.96      0.96      0.96        47
           1       0.97      0.97      0.97        67

    accuracy                           0.96       114
   macro avg       0.96      0.96      0.96       114
weighted avg       0.96      0.96      0.96       114

逻辑回归 鸢尾花

"""
@Module Name: 逻辑回归 鸢尾花.py
@Author: CSDN@我是小白呀
@Date: October 19, 2023

Description:
逻辑回归 鸢尾花
"""
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report

# 加载数据
data = load_iris()
X = data.data
y = data.target

# 调试输出数据基本信息
print("输出特征:", X[:5])
print("输出标签:", y[:5])

# 分割数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

# 标准化
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

# 训练
clf = LogisticRegression(random_state=42)
clf.fit(X_train, y_train)

# 预测
y_pred = clf.predict(X_test)

# 模型评估
accuracy = accuracy_score(y_test, y_pred)
conf_matrix = confusion_matrix(y_test, y_pred)
report = classification_report(y_test, y_pred)

print("acc:", accuracy)
print("\n混淆矩阵:\n", conf_matrix)
print("\nClassification Report:\n", report)

输出结果:

输出特征: [[5.1 3.5 1.4 0.2]
 [4.9 3.  1.4 0.2]
 [4.7 3.2 1.3 0.2]
 [4.6 3.1 1.5 0.2]
 [5.  3.6 1.4 0.2]]
输出标签: [0 0 0 0 0]
acc: 1.0

混淆矩阵:
 [[11  0  0]
 [ 0 13  0]
 [ 0  0  6]]

Classification Report:
               precision    recall  f1-score   support

           0       1.00      1.00      1.00        11
           1       1.00      1.00      1.00        13
           2       1.00      1.00      1.00         6

    accuracy                           1.00        30
   macro avg       1.00      1.00      1.00        30
weighted avg       1.00      1.00      1.00        30

手搓逻辑回归

"""
@Module Name: 手把手教你实现逻辑回归.py
@Author: CSDN@我是小白呀
@Date: October 19, 2023

Description:
手把手教你实现逻辑回归
"""
class LogisticRegression:
    def __init__(self, learning_rate=0.01, num_iterations=1000):
        """
        初始化参数
        :param learning_rate: 学习率
        :param num_iterations: 迭代次数
        """
        self.learning_rate = learning_rate
        self.num_iterations = num_iterations
        self.weights = None
        self.bias = 0

    def _sigmoid(self, z):
        """
        sigmoid 激活函数
        :param z: 值
        :return: 0-1概率
        """
        return 1 / (1 + self._exp(-z))

    def _exp(self, value):
        # 实现指数函数, 为了防止溢出
        if value.any() < -100:
            return 0.0
        else:
            return 2.718281828459045 ** value

    def fit(self, X, y):
        """
        训练模型
        :param X: 特征
        :param y: 标签
        :return:
        """
        num_samples, num_features = X.shape
        self.weights = [0] * num_features

        for _ in range(self.num_iterations):
            model_output = self._predict(X)

            # 计算梯度
            d_weights = (1 / num_samples) * (X.T.dot(model_output - y))
            d_bias = (1 / num_samples) * sum(model_output - y)

            # 更新权重和偏置
            self.weights -= self.learning_rate * d_weights
            self.bias -= self.learning_rate * d_bias

    def predict(self, X):
        """
        预测
        :param X: 特征
        :return: 预测值
        """
        linear_model_output = X.dot(self.weights) + self.bias
        return [1 if i > 0.5 else 0 for i in self._sigmoid(linear_model_output)]

    def _predict(self, X):
        linear_model_output = X.dot(self.weights) + self.bias
        return self._sigmoid(linear_model_output)

if __name__ == '__main__':
    from sklearn.datasets import load_breast_cancer
    from sklearn.model_selection import train_test_split
    from sklearn.preprocessing import StandardScaler
    from sklearn.metrics import accuracy_score, confusion_matrix, classification_report

    # 加载数据
    data = load_breast_cancer()
    X = data.data
    y = data.target

    # 调试输出数据基本信息
    print("输出特征:", X[:5])
    print("输出标签:", y[:5])

    # 分割数据集
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

    # 标准化
    scaler = StandardScaler()
    X_train = scaler.fit_transform(X_train)
    X_test = scaler.transform(X_test)

    # 训练
    clf = LogisticRegression()
    clf.fit(X_train, y_train)

    # 预测
    y_pred = clf.predict(X_test)

    # 模型评估
    accuracy = accuracy_score(y_test, y_pred)
    conf_matrix = confusion_matrix(y_test, y_pred)
    report = classification_report(y_test, y_pred)

    print("acc:", accuracy)
    print("\n混淆矩阵:\n", conf_matrix)
    print("\nClassification Report:\n", report)

输出结果:

输出特征: [[1.799e+01 1.038e+01 1.228e+02 1.001e+03 1.184e-01 2.776e-01 3.001e-01
  1.471e-01 2.419e-01 7.871e-02 1.095e+00 9.053e-01 8.589e+00 1.534e+02
  6.399e-03 4.904e-02 5.373e-02 1.587e-02 3.003e-02 6.193e-03 2.538e+01
  1.733e+01 1.846e+02 2.019e+03 1.622e-01 6.656e-01 7.119e-01 2.654e-01
  4.601e-01 1.189e-01]
 [2.057e+01 1.777e+01 1.329e+02 1.326e+03 8.474e-02 7.864e-02 8.690e-02
  7.017e-02 1.812e-01 5.667e-02 5.435e-01 7.339e-01 3.398e+00 7.408e+01
  5.225e-03 1.308e-02 1.860e-02 1.340e-02 1.389e-02 3.532e-03 2.499e+01
  2.341e+01 1.588e+02 1.956e+03 1.238e-01 1.866e-01 2.416e-01 1.860e-01
  2.750e-01 8.902e-02]
 [1.969e+01 2.125e+01 1.300e+02 1.203e+03 1.096e-01 1.599e-01 1.974e-01
  1.279e-01 2.069e-01 5.999e-02 7.456e-01 7.869e-01 4.585e+00 9.403e+01
  6.150e-03 4.006e-02 3.832e-02 2.058e-02 2.250e-02 4.571e-03 2.357e+01
  2.553e+01 1.525e+02 1.709e+03 1.444e-01 4.245e-01 4.504e-01 2.430e-01
  3.613e-01 8.758e-02]
 [1.142e+01 2.038e+01 7.758e+01 3.861e+02 1.425e-01 2.839e-01 2.414e-01
  1.052e-01 2.597e-01 9.744e-02 4.956e-01 1.156e+00 3.445e+00 2.723e+01
  9.110e-03 7.458e-02 5.661e-02 1.867e-02 5.963e-02 9.208e-03 1.491e+01
  2.650e+01 9.887e+01 5.677e+02 2.098e-01 8.663e-01 6.869e-01 2.575e-01
  6.638e-01 1.730e-01]
 [2.029e+01 1.434e+01 1.351e+02 1.297e+03 1.003e-01 1.328e-01 1.980e-01
  1.043e-01 1.809e-01 5.883e-02 7.572e-01 7.813e-01 5.438e+00 9.444e+01
  1.149e-02 2.461e-02 5.688e-02 1.885e-02 1.756e-02 5.115e-03 2.254e+01
  1.667e+01 1.522e+02 1.575e+03 1.374e-01 2.050e-01 4.000e-01 1.625e-01
  2.364e-01 7.678e-02]]
输出标签: [0 0 0 0 0]
acc: 0.9649122807017544

混淆矩阵:
 [[45  2]
 [ 2 65]]

Classification Report:
               precision    recall  f1-score   support

           0       0.96      0.96      0.96        47
           1       0.97      0.97      0.97        67

    accuracy                           0.96       114
   macro avg       0.96      0.96      0.96       114
weighted avg       0.96      0.96      0.96       114

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

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

相关文章

【Vue】前端解决跨域问题——反向代理

在 axios 请求路径只需填写资源路径&#xff1a; axios.get(/users).then(res > {console.log(res) })此时相当于向自己发送请求&#xff0c;会报 404。 然后在 vue.config,js 中配置反向代理&#xff1a; const { defineConfig } require(vue/cli-service) module.expo…

智安网络|从区块链到社交网络:解析去中心化的意义与应用

在当今数字化的世界中&#xff0c;一个越来越常见的概念是“去中心化”。从区块链技术到金融系统&#xff0c;从社交网络到数据存储&#xff0c;去中心化被认为是一种前所未有的方式来重新定义和改变传统的中心化结构。那么&#xff0c;去中心化到底是什么&#xff1f; 首先&a…

ThreadX任务栈大小确定及其溢出检测方法详解

在使用ThreadX实时操作系统&#xff08;RTOS&#xff09;进行嵌入式系统开发时&#xff0c;合理确定任务栈的大小及进行溢出检测是非常重要的。本篇博客将介绍如何确定ThreadX任务栈大小以及常用的溢出检测方法&#xff0c;并提供相应的代码示例。 一、确定ThreadX任务栈大小 …

基于springboot实现滴答拍摄影项目【项目源码+论文说明】计算机毕业设计

摘要 拍摄能让人放开自我、因看到不同的美景都想留下美好的记忆&#xff0c;有些人喜欢拍摄静物来表现宁静的氛围&#xff0c;通过小品类的照片&#xff0c;传达内心的情绪。而我更喜欢另一种方式&#xff0c;就是用长时间曝光把波动的海水或湖水雾化&#xff0c;拍摄出来的作…

Linux Docker图形化工具Portainer如何进行远程访问

文章目录 前言1. 部署Portainer2. 本地访问Portainer3. Linux 安装cpolar4. 配置Portainer 公网访问地址5. 公网远程访问Portainer6. 固定Portainer公网地址 前言 Portainer 是一个轻量级的容器管理工具&#xff0c;可以通过 Web 界面对 Docker 容器进行管理和监控。它提供了可…

【合宙Air700E/780E短信转发】短信转发移动联通 不要钉钉不要微信,转发自建服务器-傻瓜式搭建

官方提供的教程介绍了通过钉钉、微信等工具接收短信验证码的方法&#xff0c;但最终实现的目的是获取验证码&#xff0c;而不是通过工具间接获得。 因此&#xff0c;我们可以直接调用API接口来获取验证码&#xff0c;从而达到更快、更便捷地获得验证码的目的。 所以做了一个服…

uniapp开发微信小程序,webview内嵌h5,h5打开pdf地址,解决方案

根据公司要求&#xff0c;让我写一个h5&#xff0c;后续会嵌入到合作公司的微信小程序的webview中&#xff0c;如果是自己公司微信小程序&#xff0c;可以采取先下载下来pdf&#xff0c;然后通过wx.openDocument&#xff0c;进行单纯的预览操作&#xff0c;这个可以根据这个老哥…

chromium arm64 新版

chrome官方并没有对外公布arm64的正式版本但debian已经适配&#xff0c;以下链接提取自debian可直接一条命令安装&#xff1a;sudo dpkg -i *.deb即可 https://www.aliyundrive.com/s/vVCpzTyFjH6

CV、MV基础知识(持续补充ing)

文章目录 全局自注意机制Permutation InvariantMLP扩展比AP、mAP、FLOPs、FPS、Top1、mIoUAP (平均精度)&#xff1a;mAP (平均精度均值)&#xff1a;FLOPs (浮点运算数)&#xff1a;FPS (每秒帧数)&#xff1a;Top1 (前1精度)&#xff1a;mIoU (平均交并比)&#xff1a; Preci…

虚幻引擎:代理

一、代理类型 1.单薄代理 特点&#xff1a;允许有返回值&#xff0c;允许有参数&#xff0c;只可以一对一的传递消息就算绑定多个&#xff0c;但是总会被最后一个覆盖 2.多播代理 特点&#xff1a;不允许有返回值&#xff0c;允许有参数允许一对多传递消息 3.动态代理 …

25 个超棒的 Python 脚本合集

Python是一种功能强大且灵活的编程语言&#xff0c;拥有广泛的应用领域。下面是一个详细介绍25个超棒的Python脚本合集&#xff1a; 1. 网络爬虫&#xff1a;使用Python可以轻松编写网络爬虫&#xff0c;从网页中提取数据并保存为结构化的格式。 2. 数据清洗和预处理&#xf…

GEE:对二值图层进行腐蚀和/或膨胀操作

作者:CSDN @ _养乐多_ 腐蚀和膨胀 是数学形态学图像处理中的两个基本操作,用于修改和分析二值图像(包含只有两个像素值的图像,通常是黑和白)。这些操作可用于处理遥感图像、地理信息系统(GIS)中的栅格数据以及其他领域的图像处理。 腐蚀(Erosion):腐蚀是一种用于缩小…

北京筑龙助力中粮集团MRO集采顺利完成

近日&#xff0c;中粮集团MRO集采项目在中粮E采供应链采购平台顺利完成。作为中粮集团3年一次的集中采购类项目&#xff0c;本次采购创新采用清单式采购&#xff0c;涵盖中粮集团全集团的物资类集中采购&#xff0c;采购物料清单总量达10w&#xff0c;涉及供应商近千家&#xf…

科技成果验收测试有什么作用?需要提供哪些材料?

科技成果验收测试是指对科技成果进行系统全面的评估和检验&#xff0c;以确保其技术的稳定性、可行性和可靠性&#xff0c;以及达到预期效果和质量指标。它在新产品研发、项目推进和市场推广等方面起着重要作用。 一、科技成果验收测试的作用   1、有助于评估科技成果的可行…

人物百度百科词条创建教程分享,建议收藏

如何在互联网上树立个人品牌&#xff0c;展示自己的专业度和影响力&#xff1f;百度百科词条给大家提供了一个绝佳的展示平台。本文伯乐网络传媒将为您揭秘人物百度百科词条创建的全过程&#xff0c;助您轻松打造专属的数字名片。 一、了解百度百科词条 百度百科是全球最大的中…

vue3.0+wangEditor使用

第一步&#xff1a;安装 npm install wangeditor/editor --save第二步&#xff1a; 新建一个文件&#xff0c;命名是WangEditor.vue,代码截图如下&#xff1a; 3、第三步&#xff1a;引用 结束&#xff0c;记录一下&#xff0c;方便后续查询

一次清理全屋地面,一键清洁烘干无异味,KEEWOO启为C260 Pro洗地机上手

放长假的时候&#xff0c;我一般都会抽出两天时间好好打扫家里的卫生&#xff0c;虽说如今市面上有很多自动化的清洁工具&#xff0c;比如扫地机、擦窗机之类的&#xff0c;但是它们的清洁效果往往并不理想&#xff0c;尽管自动化程度很高&#xff0c;但是适用的地面类型有限&a…

Unity Meta Quest 开发导论:开发现状与主流 SDK

文章目录 &#x1f4d5;开发平台分类&#x1f4d5;Quest 一体机开发分类&#x1f4d5;Quest 一体机开发主流 SDK&#x1f4d5;Quest PCVR 开发主流 SDK&#x1f4d5;新手入门开发的 SDK 推荐 推荐一个高质量知识星球 XR 社区&#xff1a;SEED XR社区。包含教程答疑、及时交流、…

【GCN】Semi-Supervised Classification with Graph Convolutional Networks

GCN代码详细解读 如何运行代码详解utils.py GCN的不足[6]Reference 基于谱分解的经典方法代表之一&#xff1a;GCN, ICLR2017 Paper Code(pytorch) 如何运行 先看整个代码文件的结构&#xff08;运行过的&#xff09;&#xff1a; 运行的话&#xff1a; 首先一键安装需要的库…

VS2019编译一个带qrc项目时出现的问题

问题 跑中科大付老师的一个参数化的代码&#xff0c;原来的项目可能是用VS2015写的&#xff0c;编译的时候报错 严重性 代码 说明 项目 文件 行 禁止显示状态 错误 MSB8066 “surfacemeshprocessing.qrc”的自定义生成已退出&#xff0c;代码为 3。 Surface_Mesh C:\Program …