从零开始:神经网络(1)——神经元和梯度下降

 声明:本文章是根据网上资料,加上自己整理和理解而成,仅为记录自己学习的点点滴滴。可能有错误,欢迎大家指正。

一. 神经网络

1. 神经网络的发展

      先了解一下神经网络发展的历程。从单层神经网络(感知器)开始,到包含一个隐藏层的两层神经网络,再到多层的深度神经网络,一共有三次兴起过程。详见下图。

         随着神经网络的发展,其表示性能越来越强。从单层神经网络,到两层神经网络,再到多层神经网络,下图说明了,随着网络层数的增加,以及激活函数的调整,神经网络所能拟合的决策分界平面的能力。

  可以看出,随着层数增加,其非线性分界拟合能力不断增强。图中的分界线并不代表真实训练出的效果,更多的是示意效果。神经网络的研究与应用之所以能够不断地火热发展下去,与其强大的函数拟合能力是分不开关系的

2. 什么是神经网络

         神经网络是一种模拟人脑的神经网络以期能够实现类人工智能的机器学习技术。芬兰计算机科学家Teuvo Kohonen对神经网络定义为:“神经网络,是一种由具有自适应性简单单元构成的广泛并行互联的网络,它的组织结构能够模拟生物神经系统对真实世界所作出的交互反应。”

         下面是一个经典的神经网络。这是一个包含三个层次的神经网络。

  • 红色的是输入层(输入节点):从外部世界提供信息。在输入节点中,不进行任何的计算——仅向隐藏节点传递信息
  • 紫色的是中间层(也叫隐藏层或隐藏节点):隐藏层和外部世界没有直接联系(由此得名)。这些节点进行计算,并将信息从输入节点传递到输出节点。
  • 绿色的是输出层(输出节点):负责计算,并从网络向外部世界传递信息。

         输入层有3个输入单元,隐藏层有4个单元,输出层有2个单元。

 注意:

  1. 设计一个神经网络时,输入层与输出层的节点数往往是固定的,中间层则可以自由指定;
  2. 神经网络结构图中的拓扑与箭头代表着预测过程时数据的流向,跟训练时的数据流有一定的区别;
  3. 结构图里的关键不是圆圈(代表“神经元”),而是连接线(代表“神经元”之间的连接)。每个连接线对应一个不同的权重(其值称为权值),这是需要训练得到的。

3、什么是神经元

       上面说的“简单单元”,其实就是神经网络中的最基本元素——神经元(neuron)模型。在生物神经网络中,每个神经元与其它神经元,通过突触联接。神经元之间的“信息”传递,属于化学物质传递的。当它“兴奋(fire)”时,就会向与它相连的神经元发送化学物质(神经递质, neurotransmiter),从而改变这些神经元的电位;如果某些神经元的电位超过了一个“阈值(threshold)”,那么,它就会被“激活(activation)”,也就是“兴奋”起来,接着向其它神经元发送化学物质,犹如涟漪,就这样一层接着一层传播,如图所示。

      神经元模型是一个包含输入,输出与计算功能的模型。输入可以类比为神经元的树突,而输出(是否被激活)可以类比为神经元的轴突计算则可以类比为细胞核。如图所示。

然而,有的小伙伴还是感觉很抽象, 下面从一个逻辑与(AND)的例子形象说起。

(1)逻辑与(AND)

        在计算机中,存储的是0和1。计算机有很多对这种01操作的运算,其中有一种运算叫做逻辑与,在编程中运算符通常表示为&。两个数x_{1}x_{2}进行逻辑与运算的规则就是只要有一个数是0,那么整个运算就是0。我们将y=x_{1}&x_{2}的四种情况可以表示为如下所示。

x_{1}x_{2}y
000
100
010
111

          然后我们要解决的问题是,怎么让神经元根据这四组数据自己学习到这种规则。我们需要做的是让一个神经元根据这四个数据学习到逻辑与的规则。也就是说,将(x_{1}x_{2})视作一个坐标,将它描点在二维平面是这样的。

       我们让神经元能够学习到将(0,1)、(0,0)、(1,0)这些点分类为0,将(1,1)这个点分类为1。更直观的讲就是神经元得是像图中的这条直线一样,将四个点划分成两类。在直线左下是分类为0,直线右上分类为1。在人工智能范畴的的神经元它本质是一条直线,这条直线将数据划分为两类。与生物意义上的神经元可谓是千差万别。你可以理解为它是受到生物意义上的神经元启发,然后将它用来形象化数学公式。既然神经元它在数学意义上就是一条直线那么,怎么表示呢?

学计算机一个很重要的思维就是:任何一个系统都是由输入、输出、和处理组成

我们在了解神经元也是一样,在本文中的需求是知道一个坐标(x_{1}x_{2}),输出这个坐标的分类y。

我们按照计算机的输入输出思维整理下思路:

输入:x_{1}x_{2}

输出:y

处理:自己学习到从x_{1}x_{2}y的一种映射方法

我们知道输入输出,并且我们知道它是直线,那么我们就可以描述这个问题了。

我们继续看上面的图,在直线的右上方是x_{1}&x_{2}=1的情况,即分类为1的情况。在直线左下是x_{1}&x_{2}=0的情况。这个时候就可以用我们高中的知识来解决这个问题了。在高中我们知道一条直线可以表示为ax_{1}+bx_{2}+c=0。由于啊,在神经元里面大家喜欢把x_{1},x_{2}前面的系数a,b叫做权重(weight),把常数项c叫做偏置(bias)。因此一般大家把x前面系数命名为w,把常数项命名为b。这些都是约定俗成,所以大家记忆下就好。在本文中,用下面这个公式w_{1}*x_{1}+w_{2}*x_{2}+b=0表示图中的那条绿色的直线。

根据高中知识,一条直线将平面划分成两半,它可以用如下方式来描述所划分的两个半平面。

  • 左下:w_{1}*x_{1}+w_{2}*x_{2}+b<0,即当x_{1}x_{2}至少有一个是0 的时候。
  • 右上:w_{1}*x_{1}+w_{2}*x_{2}+b>0,即当x_{1}x_{2}都是1 的时候。

其实w_{1}*x_{1}+w_{2}*x_{2}+b=0,就是神经元,一个公式而已。是不是觉得神经元的神秘感顿时消失?大家平常看到的那种图只不过是受生物启发而画的,用图来描述这个公式而已。我们画个图来表示神经元,这种画图方法是受到生物启发。而求解图中的参数则从来都是数学家早就知道的方法(最小二乘法)

然后,前面提到过,神经元的形象化是受到生物启发。所以我们先介绍下怎么启发的。

生物意义上的神经元,有突触(输入),有轴突(输出),有细胞核(处理)。并且神经元传输的时候信号只有两个正离子和负离子。这和计算机1和0很类似。

总结下,神经元有突触(输入),有轴突(输出),有细胞核(处理)。如下图

咱们把上面这个神经元的数学表达式写一下对比下,w_{1}*x_{1}+w_{2}*x_{2}+b=0以后啊,大家见到神经元就用这种方式理解就可以

(2)梯度下降(Gradient)

          现在问题来了,现在我们有三个参数w_{1},w_{2},b,我们怎么设置这三个参数呢?一个很直观的想法就是自己手动调。但是,通常我们要解决的问题比这个复杂的多,神经网络是由神经元连接而成。而一般神经网络都是有几百个神经元。手动调太麻烦。那怎么办?

          我们可以将神经元用公式表示为:f(x_{1}*x_{2})=w_{1}*x_{1}+w_{2}*x_{2}+b,其中未知参数是w_{1},w_{2},b。那么我们怎么衡量这些未知参数到底等于多少才是最优的呢?

          这就得想个办法去量化它对吧。在物理界有个东西叫做误差。我们神经元不就是一个函数么f(x_{1}*x_{2}),我们要做的是让这个函数尽可能的准确模拟逻辑与(&)这个功能。假设逻辑与(&)可以表示成一个函数g(x_{1}*x_{2})​。那么用物理界的术语,我可以称呼g(x_{1}*x_{2})真实值(参考量值)f(x_{1}*x_{2})测量值(也常被称作观测值/实际值)真实值和测量值之间的误差可以两者相减并平方来量化。(绝对误差 = | 测量值 -真实值 |

其实,本文中的g(x_{1}*x_{2})非常简单。就四个点而已。上一个表就可以改为:

x_{1}x_{2}g(x_{1}*x_{2})
000
100
010
111

这样我们就得到了神经元的误差函数,它的自变量是w_{1},w_{2},b。所以问题就转变为了求误差函数最小时,w_{1},w_{2},b的取值就是最优的参数。

注意了:误差函数(error) =代价函数(cost function) =目标函数(objective function) =损失函数(loss function),这三个词可以随意替换的。所以你们在其他地方看到这三个词就都替换成误差函数就可以,别被概念搞蒙了。
损失函数就是一个自变量为算法的参数,函数值为误差值的函数。梯度下降就是找让误差值最小时候这个算法对应的参数。

本文中误差函数可以这么写L(w_{1},w_{2},b)=(f(x_{1},x_{2})-g(x_{1},x_{2}))^{2}。但右边没有w_{1},w_{2},b​,我们可以将f(x_{1}*x_{2})=w_{1}*x_{1}+w_{2}*x_{2}+b​代入,展开后可以写成这个样子:

L(w_{1},w_{2},b)=(w_{1}*x_{1}+w_{2}*x_{2}+b-g(x_{1},x_{2}))^{2}

这时右边有了w_{1},w_{2},b。那怎么求L(w_{1},w_{2},b)的最小值点呢?我们如果是只看w_{1}的话,它是个过原点的二次函数。如果综合看w_{1},w_{2},它像口锅。如果看w_{1},w_{2},b的话,这个维度太高,我等人类想象不出来。

注意: 最小值点含有两个意思。一是:求自变量w_{1},w_{2},b的值,二是函数在这个自变量的值下取最小值。

再次强调:我们要求的是w_{1},w_{2},b​的值。因为神经元就是只有这三个未知量,我们不关心其他的。而且在本文中的L(w_{1},w_{2},b)的最小值很明显,它就是0。它是个完全平方嘛肯定>=0。

那怎么求这个误差函数的最小值点呢?

数学家想到了一个办法叫做梯度下降梯度下降是一个可以让计算机自动求一个函数最小值时,找到它的自变量值就可以了。注意梯度下降只关心自变量值,不关心函数值。这儿你迷糊也没关系,看到后面回头看这句话就懂了。反正梯度下降它做的事就是找自变量。

接下来咱们一起来学习下啥是梯度下降?啥是梯度?为何下降?梯度下降为了能求得最优参数

  1. 啥是梯度?梯度就是导数,大家见到“梯度”就把它替换成导数就可以。在多维情况下梯度也是导数只不过是个向量,这个向量每个元素是一个偏导数。
  2. 为何下降?因为在数学里面(因为神经网络优化本来就是数学问题),在数学里面优化一般只求最小值点。那么有些问题要求最大值点怎么办?答:“在前面加负号”。简单粗暴就解决了。好继续回答为何下降,因为是求最小值点,那么这个函数肯定就像一口锅,我们要找的就是锅底的那个点在哪,然后我们当然要下降才能找到最小值点啦
  3. 为何梯度下降能求最优参数?因为只有知道梯度下降怎么做的,才知道为何它能求最优参数。所以接下来要介绍的是,梯度下降如何实现利用负梯度进行下降的。

再次总结下,我们需要让计算机求的参数是w_{1},w_{2},b​. 我们先讲怎么怎使用梯度下降求最优的w_{1}​的吧。会求w_{1}其它的几个参数都是一样的求法。

那梯度下降怎么做到求最优的w_{1}呢?(最优指的是误差函数L(w_{1},w_{2},b)此时取最小)

采取的一个策略是猜。没错,就是猜。简单粗暴。不过它是理性的猜。说的好听点叫做理性的去估计。我们前面提到了误差函数关于w_{1}是一个二次函数,假设长下面这样。

但计算机不知道它长这样啦。它只能看到局部。首先一开始它随便猜,比如猜w_{1}=0.5吧。我们前面提到了计算机它只知道局部。为何呢?你想,我现在取值是w_{1}=0.5,我可以增大一点点或减小一点点w_{1},这样我当然只知道w_{1}=0.5​这周围的误差函数值啦。

现在按照你的直觉,猜一猜猜一猜,你觉得最优的w_{1}到底比0.5大还是比0.5小?

我想我们答案应该是一样的,肯定比0.5小。因为往右边走,即让w_{1}比0.5大的话,它的误差函数是增长的。也就是在w_{1}=0.5周围时候,w_{1}越大,误差越大。

其实梯度下降就是让计算机这么猜,因为计算机判断速度快嘛。猜个上万次就很容易猜到最优值。

回顾下我们怎么猜的?

我们是直觉上觉得,这个增大w_{1}误差函数是增加的。那这个怎么用理性思考呢?这个时候就可以用高中所学的判断函数单调性的方法了:求一阶导数啊。即:“一阶导数>0,函数单调递增,函数值随自变量的增大而增大”。

所以,我们只需要让计算机判断当前猜的这个点导数是大于0还是小于0. 该点一阶导数大于0的话,这个局部是单调递增的,增大w_{1}的值,误差函数值会增大。因此就得减小w_{1}的值;同理,如果一阶导数小于0 ,那么这个局部是单调递减的,我们增大w_{1}的值可以降低误差函数值。

总结规律:

导数>0, 减小w_{1}的值。     导数<0,增大w_{1}的值。

可以发现,w_{1}的变化与导数符号相反。因此下次要猜的w_{1}的值可以这么表示:下次要猜的w_{1}的值=本次猜的w_{1}的值-导数。有时候导数太大也可能会猜跳的太猛,我们在导数前面乘个小数防止猜的太猛。这个小数大家通常称呼它为学习率。(从这里可以看出学习率肯定小于1的)因此可以这么表示:

下次要猜的w_{1}的值=本次猜的w_{1}的值-学习率×导数。

学习率一般设置0.001,0.01,0.03等慢慢增大,如果计算机猜了很久没猜到证明得让它放开步子猜了,就增大它。

现在我们知道梯度下降干嘛了吧,它就是理性的猜最优值。那什么时候结束猜的过程呢?我们看下图,发现它最优值的那个地方导数也是0.那么我们只需要判断误差函数对w_{1}的导数是否接近0就可以。比如它绝对值小于0.01我们就认为已经到了最优点了。

误差函数是这个:L(w_{1},w_{2},b)=(w_{1}*x_{1}+w_{2}*x_{2}+b-g(x_{1},x_{2}))^{2}​. 对w_{1}求导,得到导函数L^{'}(w_{1},w_{2},b)=2*(w_{1}*x_{1}+w_{2}*x_{2}+b-g(x_{1},x_{2}))*x_{1}​.

现在总结下梯度下降(采用的是很常用的随机梯度下降)的步骤:

初始化w_{1}。(随便猜一个数),比如让w_{1}=0.5;// 注意了,同样数据反复输入进去训练的次数大家一般叫他epoch,// 大家都这么叫记住就可以,在英语里面epoch=times=次数循环多次(同样的数据重复训练)

②{遍历样本(逐个样本更新参数)

③{​ 将样本x_{1},x_{2},和标签g(w_{1},w_{2}),代入损失函数对w_{1}​的导函数,求得导数值;​

      下次要猜的w_{1}的值=本次猜的w_{1}的值-学习率*导数值;}

    }

然后我们就可以得到最优的w_{1}​了。

对于剩下的w_{2},b他们是一样的,都是利用让计算机猜。大家参考w_{1}怎么求的吧。

注意了,因为我们是二分类问题,虽然我们想让它直接输出0和1,但是很抱歉。它只能输出接近0和接近1的小数。为了方便编程,我们用-1代替0。也就是说只要神经元输出负数我们认为它就是输出0. 因为直接判断它是否接近0和是否接近1编程会更麻烦

注意了,因为我们是二分类问题,虽然我们想让它直接输出0和1,但是很抱歉。它只能输出接近0和接近1的小数。为了方便编程,我们用-1代替0。也就是说只要神经元输出负数我们认为它就是输出0. 因为直接判断它是否接近0和是否接近1编程会更麻烦

注意了,大家以后也会发现很多数据集二分类问题都会用1和-1而不用0.这是为了编程方便。我们只需要判断正负就可以知道是哪个分类。而不是需要判断是接近0还是接近1

好现在我们知道神经元的数学表达和怎么画它的形象化的图了。那么不如我们用编程也表达下它吧?

(3)实例演示

整体思路:

神经# 单层神经元 求f=x1&x2,f值的划分(即1划一组,0划一组) 
# 即求误差△=|测量值-参考值|=|w1*x1+w2*x2+b-g(x1,x2)|的值最小 
# 即求△的导数 ≈ 0,如对w1求导: 2*(w1*x1+w2*x2+b-g(x1,x2))*x1 ≈ 0

训练函数:

import numpy as np

# train :训练样本
# 输入 data  用于训练的数据样本,样本格式为[x1,x2,g(x1,x2)]
# 输入 epoch 数据训练的次数
# 输入 learn_rate # 设置学习率,防止猜的步子太大
# 输入 g_pred 预测值 g(x1,x2)
# 返回 weights 权重
# 返回 biases 偏置
def train(data, g_pred, n_epoch=1000, learn_rate=0.01):
    n_sample, n_feature = data.shape  # 获得样本的数量(行)和数据的特征(列)
    # 第一步: 初始化w和b的值,随便取w和b的值。
    weights = np.random.randn(n_feature)  # 随机设置权重,即初始化w,随便取w的值
    biases = np.random.randn()  # 初始化b,随便取b的值
    # 第二步 训练样本
    for _ in range(n_epoch):
        for i in range(n_sample):  # 逐个样本更新权重
            # 其中 i=[x1,x2,g(x1,x2)],为data数据中一行
            # 分别求w1、w2、b在(x1,x2,g(x1,x2))处的导函数值
            y_pred = np.dot(weights, data[i]) + biases  # 计算预测值,即 f=w*x+b的值
            d_weights = (y_pred - g_pred[i]) * 2 * data[i]  # 误差 =(测量值-预测值)^2,对误差取导数=2*(w*x+b-g(x1,x2))*w
            d_biases = (y_pred - g_pred) * 2
            loss = np.square(y_pred)  # 计算损失的平方
            # 设置猜数环节:下次猜的数 = 本次猜的数 - 学习率*导数值
            weights_next = weights - learn_rate * d_weights
            biases_next = biases - learn_rate
            # 更新各自参数
            weights = weights_next
            biases = biases_next
    return weights, biases

 定义神经元

# 定义 神经元
# 经过训练,我们期望它的返回值是x1&x2
# 即:返回值是 w1*x1+w2*x2 + b > 0? 1:0;
def f(data, weights, biases):
    c = 1 if np.dot(weights, data) + biases > 0 else 0
    return c

整体流程

import numpy as np
import matplotlib.pyplot as plt

data = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])  # x1,x2的四个元素
g_real = np.array([-1, -1, -1, -1])  # 四个真实值
weights, biases = train(data, g_real)  # 自定义的训练函数,让神经元自己根据四条数据学习逻辑与的规则
#打印相关值,看是否正确
print(weights, biases)
print("0&0", f(data[0], weights, biases))
print("0&1", f(data[1], weights, biases))
print("1&0", f(data[2], weights, biases))
print("1&1", f(data[3], weights, biases))

# 绘制训练后的图像
x1 = data[:, 0]  # 提取第1列的值
x2 = -(weights[0] * x1 + biases) / weights[1]
plt.plot(x1, x2, 'r', label='Decision Boundary')
n_sample, n_feature = data.shape  # 获得样本的数量(行)和数据的特征(列)
for i in range(data.shape[0]):

    if f(data[i], weights, biases) == 0:
        plt.plot(data[i, 0], data[i, 1], 'bo')
    else:
        plt.plot(data[i, 0], data[i, 1], 'ro')

plt.legend()
plt.show()

运行的结果:

参考:易懂的神经网络理论到实践(1):单个神经元+随机梯度下降学习逻辑与规则 - 知乎 (zhihu.com)

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

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

相关文章

349. 两个数组的交集

349. 两个数组的交集 力扣题目链接(opens new window) 题意&#xff1a;给定两个数组&#xff0c;编写一个函数来计算它们的交集。 说明&#xff1a; 输出结果中的每个元素一定是唯一的。 我们可以不考虑输出结果的顺序。 对于看某个元素是否出现在一个集合中的 &#xff0c;…

STM32利用标准库的方式输出PWM(proteus仿真)

首先打开proteus仿真软件&#xff0c;绘制电路图&#xff1a; 其中示波器的添加很简单的&#xff0c;看图&#xff1a; 再来看看咱们最后程序的效果&#xff1a; 下面就是程序代码了&#xff0c;新建两个文件PWM.c和PWM.h文件&#xff0c;所属关系如图&#xff1a; 整个的编程思…

Redis 内存的优化

目录 前言 Redis 的内存碎片问题 判断Redis 内存碎片 如何清理内存碎片&#xff1f; 前言 我想讲一下怎么提高Redis 内存的利用率&#xff0c;redis 的数据是保存在内存中。对内存的利用率低&#xff0c;意味着存的数据很少&#xff0c;并不意味着就没有内存了&#xff0c…

如何在Mapbox GL中处理大的GEOJSON文件

Mapbox GL可以将 GeoJSON 数据由客户端(Web 浏览器或移动设备)即时转换为 Mapbox 矢量切片进行显示和处理。本文的目的是教大家如何有效加载和渲染大型 GeoJSON 源,并优化渲染显示速度,增强用户体验,减少客户端卡顿问题。本文以Mapbox 为例,至于其它框架原理大致相同,可…

中国联通云联网在多元行业应用中的核心地位与价值体现

在全球化浪潮与数字化转型的时代背景下&#xff0c;中国联通积极响应市场需求&#xff0c;推出以云联网为核心的全球化智能组网解决方案&#xff0c;突破地理限制&#xff0c;为各行业提供高效、安全、灵活的网络服务。该方案不仅涵盖传统的通信连接&#xff0c;更是深入到能源…

复盘-excel

excel-选列没有用&#xff0c;选小标题才可以 将簇状柱形图放置在一个新表上##### excel: 添加数据模型时&#xff0c;要通过套用表格格式与外部断开连接 透视分析2010年人数未解决(第四套&#xff09; 通过日期显示星期几 判断星期几 因为前面已经通过星期六&#xff0c…

【AcWing】蓝桥杯集训每日一题Day1|二分|差分|503.借教室(C++)

503. 借教室 503. 借教室 - AcWing题库难度&#xff1a;简单时/空限制&#xff1a;1s / 128MB总通过数&#xff1a;8052总尝试数&#xff1a;26311来源&#xff1a;NOIP2012提高组算法标签二分差分 题目内容 在大学期间&#xff0c;经常需要租借教室。 大到院系举办活动&…

Linux上安装torch-geometric(pyg)1.7.2踩坑记录

重点&#xff1a;1.一定要在创建虚拟环境的时候设置好python版本。2.一定要先确定使用1.X还是2.X的pyg库&#xff0c;二者不兼容。3.一定要将cuda、torch、pyg之间的版本对应好。所以&#xff0c;先确定pyg版本&#xff0c;再确定torch和cuda的版本。 结论&#xff1a;如果在u…

【解读】OWASP大语言模型应用程序十大风险

OWASP大型语言模型应用程序前十名项目旨在教育开发人员、设计师、架构师、经理和组织在部署和管理大型语言模型&#xff08;LLM&#xff09;时的潜在安全风险。该项目提供了LLM应用程序中常见的十大最关键漏洞的列表&#xff0c;强调了它们的潜在影响、易利用性和在现实应用程序…

基本计算器II

文章目录 题目解析算法解析算法模拟第一步 第二步第三步第四步第五步第六步最后一步 代码 题目解析 题目链接 我们先来看一下题目这个题目的意思很明确就是给你一个算数式让你计算结果并返回并且给了很多辅助条件来帮助你。 算法解析 那么我们来看看这个题目有哪些做法&…

Qt 定时器事件

文章目录 1 定时器事件1.1 界面布局1.2 关联信号槽1.3 重写timerEvent1.4 实现槽函数 启动定时器 2 定时器类 项目完整的源代码 QT中使用定时器&#xff0c;有两种方式&#xff1a; 定时器类&#xff1a;QTimer定时器事件&#xff1a;QEvent::Timer&#xff0c;对应的子类是QTi…

SQL中常见的DDL操作及示例,数据库操作及表操作

目录 一、数据库操作 1、创建数据库 2、查看所有数据库 3、使用数据库 4、删除数据库 二、表操作&#xff1a; 1、创建表 2、查看表结构 3、修改表结构 3.1 添加列 3.2 修改列数据类型 3.3 修改列名 3.4 删除列 3.5 修改表名 3.6 删除表 注意&#xff1a; 在数…

云计算项目十一:构建完整的日志分析平台

检查k8s集群环境&#xff0c;master主机操作&#xff0c;确定是ready 启动harbor [rootharbor ~]# cd /usr/local/harbor [rootharbor harbor]# /usr/local/bin/docker-compose up -d 检查head插件是否启动&#xff0c;如果没有&#xff0c;需要启动 [rootes-0001 ~]# system…

OpenCV学习笔记(四)——对视频的读取操作

目录 读取视频内容 将彩色视频转换为灰色视频 读取视频内容 读取视频文件通常分为读取文件、验证是否打开成功打开文件、逐帧读取视频文件、释放资源和关闭窗口 &#xff08;1&#xff09;读取文件 在OpenCV中&#xff0c;通常使用VedioCapture来读取视频流&#xff0c;Vedi…

linux多线程编程使用互斥量的原理分析和应用实例

目录 概述 1 保护对共享变量的访问&#xff1a;互斥量 1.1 认识互斥量 1.2 互斥锁API 1.2.1 互斥锁初始化函数 1.2.2 互斥锁函数 1.2.3 互斥锁变体函数 1.3 互斥锁使用方法 1.4 互斥锁死锁 2 互斥量的应用介绍 2.1 创建与销毁 2.1.1 创建互斥量 2.1.2 销毁互斥量 …

UnicodeDecodeError: ‘gbk‘和Error: Command ‘pip install ‘pycocotools>=2.0

今天重新弄YOLOv5的时候发现不能用了&#xff0c;刚开始给我报这个错误 subprocess.CalledProcessError: Command ‘pip install ‘pycocotools&#xff1e;2.0‘‘ returned non-zero exit statu 说这个包安装不了 根据他的指令pip install ‘pycocotools&#xff1e;2.0这个根…

FPGA的时钟资源

目录 简介 Clock Region详解 MRCC和SRCC的区别 BUFGs 时钟资源总结 简介 7系列FPGA的时钟结构图&#xff1a; Clock Region&#xff1a;时钟区域&#xff0c;下图中有6个时钟区域&#xff0c;用不同的颜色加以区分出来 Clock Backbone&#xff1a;从名字也能看出来&#x…

【数据结构】万字长文图解+代码实现AVL树

目录 一、概念 二、图解 1.图解插入 2.图解右单旋 3.图解左单旋 4.图解右左双旋 5.图解左右双旋 6.验证是否是AVL树 三、代码实现 一、概念 AVL树是一种高度平衡的二叉搜索树&#xff0c;得名于其发明者的名字&#xff08;G. M. Adelson-Velskii和E. M. Landis&#xff0…

ELK-介绍及Elasticsearch集群搭建

ELK是三个开源软件的缩写&#xff0c;分别为Elasticsearch、Logstash、kibana它们都是开源软件。后来新增了一个FileBeat&#xff0c;它是一个轻量及的日志收集处理工具&#xff0c;因为Logstash由java程序开发&#xff0c;比较消耗内存资源&#xff0c;后来将Logstash使用go语…

微信小程序如何实现下拉刷新

1.首先在你需要实现下拉刷新页面的json文件中写入"enablePullDownRefresh": true。 2.在js文件的onPullDownRefresh() 事件中实现下拉刷新。 实现代码 onPullDownRefresh() {console.log(开始下拉刷新)wx.showNavigationBarLoading()//在标题栏中显示加载图标this.d…