机器学习——人工神经网络之BP算法编程(python二分类数据集:马疝病数据集)

目录

一、理论知识回顾

1、神经网络模型

2、明确任务以及参数

1)待估参数:

2)超参数:

3)任务

3、神经网络数学模型定义

1)激活函数

​

2)各层权重、阈值定义

3)各层输入输出定义

4、优化问题的目标函数与迭代公式

1)目标函数

2)待估参数的优化迭代公式

二、python编程

1、编程步骤

2、数据准备、数据处理、数据划分

1)数据下载

2)关键代码

3、初始化待估参数

1)关键代码

2)np.random.randint(a,b,(m,n))函数

3)astype(np.float64)

4、创建激活函数

5、参数迭代更新

1)关键代码

2)dot、multiply

3)难点

6、测试模型

7、主函数运行

三、总结

1、几个循环

2、问题集锦

1)若是有多个输出怎么办?

2)BP算法为什么叫做后向传播?

四、完整代码


坚持嗑完这篇文章一定会明白神经网络BP算法的精髓所在的,以及各层之间误差的互相影响以及传播

一、理论知识回顾

参考文章:

《机器学习——人工神经网络之发展历史(神经元数学模型、感知器算法)》

《机器学习——人工神经网络之多层神经网络(多层与三层)》

《机器学习——人工神经网络之后向传播算法(BP算法)》

《机器学习——人工神经网络之参数设置(BP算法)》

1、神经网络模型

一个神经元即一个感知机模型,由多个神经元相互连接形成的网络,即神经网络。

这里我们只讨论单隐层前馈神经网络,其连接形式入下:

2、明确任务以及参数

1)待估参数:

每个神经元的阈值b或者value,以及神经元之间的连接权重weight。

2)超参数:

超参数就是求解不出来,需要用户自己定义的参数,如在神经网络中,超参数有:

神经网络隐层的层数,一般只考虑隐层的层数,因为输入层和输出层一般默认为一层

每一层神经网络的神经元个数:神经元的个数直接影响着待估参数的个数,假设隐层第m层有k个神经元,第m+1层有l个神经元,那么这两层之间的权重系数weight的个数为k*l个,一般组成(k,l)矩阵的形式;每一层的阈值或者叫做偏置的个数和神经元个数相同

神经网络:可能这个听起来比较抽象,但是这就是需要自己进行定义的,具体见代码,主要是指定神经网络层数,每层神经元的个数,确定待估参数的初始值就基本上将神经网络给定义好了

3)任务

通过训练样本将定义的神经网络模型进行不断的优化,将待测参数进行不断的迭代,直到满足条件为止(条件理论上是目标函数E对所有的待测参数的偏导为0,但是计算机没有绝对的0值,因此一般通过迭代次数和偏导的最小值来作为迭代的终止条件)

3、神经网络数学模型定义

对于该模型有如下定义:

训练集:D={(x1, y1), (x2, y2), ......, (xm, ym)},x具有d个属性值,y具有k个可能取值

则我们的神经网络(单隐层前馈神经网络)应该是具有d个输入神经元,q个隐层神经元,k个输出层神经元的神经网络 ,我们默认输入层只是数据的输入,不对数据做处理,即输入层没有阈值。

1)激活函数

2)各层权重、阈值定义

输出层第j个神经元的阈值为:θj

隐层第h个神经元的阈值为:γh(γ是Gamma)

输入层第i个神经元与隐层第h个神经元的连接权重为:vih

隐层第h个神经元与输出层第j个神经元的连接权重为:ωhj

3)各层输入输出定义

输入层的输入和输出一样,就是样本数据

隐层第h个神经元的输入

隐层第h个神经元的输出

输出层第j个神经元的输入

输出层的输出跟隐层的输出类似

4、优化问题的目标函数与迭代公式

1)目标函数

对参数进行估计,需要有优化方向,我们继续使用欧式距离,或者均方误差来作为优化目标:

2)待估参数的优化迭代公式

我们使用梯度下降的策略对参数进行迭代优化,所以任意一个参数的变化大小为(θ代表任意参数):

下面根据这个更新公式,我们来求各个参数的更新公式:

对数几率函数的导数如下:

输出层第j个神经元的阈值θj:

 隐层第h个神经元的阈值γh:

 

 

输入层第i个神经元与隐层第h个神经元的连接权重vih : 

 

隐层第h个神经元与输出层第j个神经元的连接权重ωhj: 

 

现在四个参数的更新规则都计算出来了,我们可以开始编码实现了。 

现在有一个问题:在二分类任务中,输出层神经元有几个?

                             一个:如果只有1个,那么输出0表示反例,1表示正例

                             二个:那么输出(1,0)表示反例,(0,1)表示正例

以下实例我们使用第一种:即输出层的神经元只有一个

二、python编程

1、编程步骤

数据准备(通过读取数据文件获取)

数据处理(读取的数据是字符串形式,需要将其转换为浮点数或者整型)

数据划分(将特征和标签分割开)

初始化待估参数(通过自定义超参数每层神经元的个数来进行初始化待估参数)——这里不需要定义层数,因为这里只有一个隐层

参数迭代更新(用初始化的待估参数去对样本数据进行逐一训练,并且不断地迭代更新,最后得到最优的待估参数)——这里和上一步其实就基本上将整个神经网络的框架已经搭建好了

测试模型(利用上面得到的参数,对测试样本集进行测试,查看准确率)

2、数据准备、数据处理、数据划分

1)数据下载

我们使用一个二分类数据集:马疝病数据集

UCI下载地址为:http://archive.ics.uci.edu/ml/datasets/Horse+Colic

或者:

以下是用户《9527----到》提供的,可见文章:《基于tensorflow的logistics回归--数据集为 horseColicTest and horseColicTraining.txt(文章底部附数据集链接)》文末

测试集

https://pan.baidu.com/s/1h1t0LLxZlESPPdfn1zxTXQ

训练集

https://pan.baidu.com/s/1IVO2opIQ0e66_AEchw_X4Q

2)关键代码

#创建加载数据读取数据以及划分数据集的函数,返回数据特征集以及数据标签集
def loaddataset(filename):fp = open(filename)#(299,22)# 存放数据dataset = []# 存放标签labelset = []for i in fp.readlines():#按照行来进行读取,每次读取一行,一行的数据作为一个元素存放在了类别中a = i.strip().split()#去掉每一行数据的空格以及按照默认的分隔符进行划分# 每个数据行的最后一个是标签dataset.append([float(j) for j in a[:len(a) - 1]])#读取每一行中除最后一个元素的前面的元素,并且将其转换为浮点数labelset.append(int(float(a[-1])))#读取每一行的最后一个数据作为标签数据return dataset, labelset#dataset是(299,21)的列表,labelset是(299,1)的列表

3、初始化待估参数

1)关键代码

# x为输入层神经元个数,y为隐层神经元个数,z输出层神经元个数
#创建的是参数初始化函数,参数有各层间的权重weight和阈值即偏置value就是b
#本例的x,y=len(dataset[0])=22,z=1
def parameter_initialization(x, y, z):# 隐层阈值value1 = np.random.randint(-5, 5, (1, y)).astype(np.float64)#随机生成(-5,5)之间的整数组成(1,y)的数组,然后再将其转为浮点数显示# 输出层阈值value2 = np.random.randint(-5, 5, (1, z)).astype(np.float64)# 输入层与隐层的连接权重weight1 = np.random.randint(-5, 5, (x, y)).astype(np.float64)# 隐层与输出层的连接权重weight2 = np.random.randint(-5, 5, (y, z)).astype(np.float64)return weight1, weight2, value1, value2'''
weight1:输入层与隐层的连接权重
weight2:隐层与输出层的连接权重
value1:隐层阈值
value2:输出层阈值
权重和阈值的个数和神经网络的隐层层数有关,若隐层为n,则权重和阈值的个数为n+1
'''

2)np.random.randint(a,b,(m,n))函数

np.random.randint(a,b,(m,n))
#在指定的范围内随机生成整数
#a,区间上限,b,区间下限,size=(m,n),a<b
#表示生成(m,n)的数组,数组元素为(a,b)间的整数
import numpy as np
a = np.random.randint(-5,5,size=(2,4))
print(a)
print(type(a))[[-1  3 -5  3][-3  1 -4  4]]
<class 'numpy.ndarray'>

3)astype(np.float64)

将元素转化为指定的类型进行显示

import numpy as np
a = np.random.randint(-5,5,size=(2,4)).astype(np.float64)
print(a)
print(type(a))[[-1. -2. -3.  3.][ 3. -2. -2. -3.]]
<class 'numpy.ndarray'>

4、创建激活函数

#创建激活函数sigmoid
def sigmoid(z):return 1 / (1 + np.exp(-z))

5、参数迭代更新

这里是对所有的样本逐一进行训练一轮的函数,即对整个训练样本进行了一次迭代,若要循环迭代,则需要在外层再套一层循环,来表示迭代的次数,本例将其直接放在了主函数中进行迭代的不断循环

1)关键代码

#创建训练样本的函数,返回训练完成后的参数weight和value,这里的函数是经过一次迭代后的参数,即所有的样本经过一次训练后的参数
#具体参数的值可以通过设置迭代次数和允许误差来进行确定
def trainning(dataset, labelset, weight1, weight2, value1, value2):# x为步长x = 0.01#学习率for i in range(len(dataset)):#依次读取数据特征集中的元素,一个元素即为一个样本所含有的所有特征数据# 输入数据#(1,21)inputset = np.mat(dataset[i]).astype(np.float64)#每次输入一个样本,将样本的特征转化为矩阵,以浮点数显示# 数据标签#(1,1)outputset = np.mat(labelset[i]).astype(np.float64)#输入样本所对应的标签# 隐层输入,隐层的输入是由输入层的权重决定的,wx#input1:(1,21).(21,21)=(1,21)input1 = np.dot(inputset, weight1).astype(np.float64)# 隐层输出,由隐层的输入和阈值以及激活函数决定的,这里的阈值也可以放在输入进行计算#sigmoid((1,21)-(1,21))=(1,21)output2 = sigmoid(input1 - value1).astype(np.float64)# 输出层输入,由隐层的输出#(1,21).(21,1)=(1,1)input2 = np.dot(output2, weight2).astype(np.float64)# 输出层输出,由输出层的输入和阈值以及激活函数决定的,这里的阈值也可以放在输出层输入进行计算# (1,1).(1,1)=(1,1)output3 = sigmoid(input2 - value2).astype(np.float64)# 更新公式由矩阵运算表示#a:(1,1)a = np.multiply(output3, 1 - output3)#输出层激活函数求导后的式子,multiply对应元素相乘,dot矩阵运算#g:(1,1)g = np.multiply(a, outputset - output3)#outputset - output3:实际标签和预测标签差#weight2:(21,1),np.transpose(weight2):(1,21),b:(1,21)b = np.dot(g, np.transpose(weight2))#(1,21)c = np.multiply(output2, 1 - output2)#隐层输出激活函数求导后的式子,multiply对应元素相乘,dot矩阵运算#(1,21)e = np.multiply(b, c)value1_change = -x * e#(1,21)value2_change = -x * g#(1,1)weight1_change = x * np.dot(np.transpose(inputset), e)#(21,21)weight2_change = x * np.dot(np.transpose(output2), g)#(21,1)# 更新参数,权重与阈值的迭代公式value1 += value1_changevalue2 += value2_changeweight1 += weight1_changeweight2 += weight2_changereturn weight1, weight2, value1, value2

2)dot、multiply

dot:两个矩阵按照行列相乘组成新的矩阵

multiply:两个矩阵和得到结果的矩阵的维度是一样的,对应位置的元素进行相乘得到新矩阵对应位置的元素值

3)难点

这一部分最大的难点就是在于读懂相关数学表达式的含义。建议将前面的理论部分之《待估参数的优化迭代公式》自己推导一遍,然后弄清楚这一部分中参数的维数,基本上就可以读懂了,代码中注释已经将所有参数的维数变化进行了标注。

6、测试模型

将最后得到的待估参数的值作为最终的神经网络的参数,对测试样本进行测试

#创建测试样本数据的函数
def testing(dataset1, labelset1, weight1, weight2, value1, value2):# 记录预测正确的个数rightcount = 0for i in range(len(dataset1)):# 计算每一个样例的标签通过上面创建的神经网络模型后的预测值inputset = np.mat(dataset1[i]).astype(np.float64)outputset = np.mat(labelset1[i]).astype(np.float64)output2 = sigmoid(np.dot(inputset, weight1) - value1)output3 = sigmoid(np.dot(output2, weight2) - value2)# 确定其预测标签if output3 > 0.5:flag = 1else:flag = 0if labelset1[i] == flag:rightcount += 1# 输出预测结果print("预测为%d   实际为%d" % (flag, labelset1[i]))# 返回正确率return rightcount / len(dataset1)

7、主函数运行

def main():#读取训练样本数据并且进行样本划分dataset, labelset = loaddataset('./horseColicTraining.txt')#读取测试样本数据并且进行样本划分dataset1, labelset1 = loaddataset('./horseColicTest.txt')#得到初始化的待估参数的值weight1, weight2, value1, value2 = parameter_initialization(len(dataset[0]), len(dataset[0]), 1)#迭代次数为1500次,迭代次数一般越大准确率越高,但是其运行时间也会增加for i in range(1500):#获得对所有训练样本训练迭代一次后的待估参数weight1, weight2, value1, value2 = trainning(dataset, labelset, weight1, weight2, value1, value2)#对测试样本进行测试,并且得到正确率rate = testing(dataset1, labelset1, weight1, weight2, value1, value2)print("正确率为%f" % (rate))
if __name__ == '__main__':main()

三、总结

1、几个循环

在本例中(单隐层),可以分为以下几个循环:

***通过行来遍历每一个样本的特征集和标签

    for i in range(len(dataset)):#依次读取数据特征集中的元素,一个元素即为一个样本所含有的所有特征数据

***迭代次数的循环,通过迭代次数来控制迭代的终止条件,当然也可以用while循环来进行迭代,用误差来控制迭代的终止

    for i in range(1500):#获得对所有训练样本训练迭代一次后的待估参数weight1, weight2, value1, value2 = trainning(dataset, labelset, weight1, weight2, value1, value2)

若是多隐层的话,还多一层循环:

***通过循环来遍历所有的隐层,一般遍历只是为了获得每一隐层的神经元的个数,因此只需要通过字典定义好每一隐层的神经元个数,然后通过遍历的方式获得神经元个数即可(注意神经元个数和权重、阈值个数的关系)。或者如果隐层的层数比较少,可以通过多添加几组待测参数即可,设有k层:

def parameter_initialization(x1,x2,...,xi,..., xk):# 隐层阈值value1 = np.random.randint(-5, 5, (x1, x2)).astype(np.float64)#随机生成(-5,5)之间的整数组成(1,y)的数组,然后再将其转为浮点数显示# 输出层阈值value2 = np.random.randint(-5, 5, (x1, x3)).astype(np.float64).........valuei = np.random.randint(-5, 5, (x1, xi)).astype(np.float64).........valuek = np.random.randint(-5, 5, (x1, xk+1)).astype(np.float64)# 输入层与隐层的连接权重weight1 = np.random.randint(-5, 5, (x1, x2)).astype(np.float64)# 隐层与输出层的连接权重weight2 = np.random.randint(-5, 5, (x2, x3)).astype(np.float64)........weighti = np.random.randint(-5, 5, (xi,xi+1)).astype(np.float64)........return weight1, weight2,...,weighti,...,weightk, value1, value2,...,valuei,...,valuek

2、问题集锦

1)若是有多个输出怎么办?

若是有多个输出的话,只需要在主函数中修改输出层的神经元个数即可,神经元个数等于输出的个数,设有i个输出,输出的增多也意味着输出的归类判断会更加的复杂

    weight1, weight2, value1, value2 = parameter_initialization(len(dataset[0]), len(dataset[0]), i)

2)BP算法为什么叫做后向传播?

因为从目标函数对待测参数求偏导可以看出,目标函数对越往前的神经网络的参数进行求导,其要经过的层数就会越多,即要想求得目标函数对前面的参数的偏导,就必须先知道该层神经网络后面的层数中目标函数对待测参数的偏导,因为链式法则。而且在求对阈值的偏导的时候,我们需要注意的是,对该层阈值的偏导,受下一层所有神经元的影响,如下图就知道,每一层的神经元都互相有关系,所有每一层的神经元的阈值的偏导也和相邻层神经元有关

四、完整代码

#导入模块
import numpy as np#创建加载数据读取数据以及划分数据集的函数,返回数据特征集以及数据标签集
def loaddataset(filename):fp = open(filename)#(299,22)# 存放数据dataset = []# 存放标签labelset = []for i in fp.readlines():#按照行来进行读取,每次读取一行,一行的数据作为一个元素存放在了类别中a = i.strip().split()#去掉每一行数据的空格以及按照默认的分隔符进行划分# 每个数据行的最后一个是标签dataset.append([float(j) for j in a[:len(a) - 1]])#读取每一行中除最后一个元素的前面的元素,并且将其转换为浮点数labelset.append(int(float(a[-1])))#读取每一行的最后一个数据作为标签数据return dataset, labelset#dataset是(299,21)的列表,labelset是(299,1)的列表# x为输入层神经元个数,y为隐层神经元个数,z输出层神经元个数
#创建的是参数初始化函数,参数有各层间的权重weight和阈值即偏置value就是b
#本例的x,y=len(dataset[0])=22,z=1
def parameter_initialization(x, y, z):# 隐层阈值value1 = np.random.randint(-5, 5, (1, y)).astype(np.float64)#随机生成(-5,5)之间的整数组成(1,y)的数组,然后再将其转为浮点数显示# 输出层阈值value2 = np.random.randint(-5, 5, (1, z)).astype(np.float64)# 输入层与隐层的连接权重weight1 = np.random.randint(-5, 5, (x, y)).astype(np.float64)# 隐层与输出层的连接权重weight2 = np.random.randint(-5, 5, (y, z)).astype(np.float64)return weight1, weight2, value1, value2#创建激活函数sigmoid
def sigmoid(z):return 1 / (1 + np.exp(-z))'''
weight1:输入层与隐层的连接权重
weight2:隐层与输出层的连接权重
value1:隐层阈值
value2:输出层阈值
权重和阈值的个数和神经网络的隐层层数有关,若隐层为n,则权重和阈值的个数为n+1
'''#创建训练样本的函数,返回训练完成后的参数weight和value,这里的函数是经过一次迭代后的参数,即所有的样本经过一次训练后的参数
#具体参数的值可以通过设置迭代次数和允许误差来进行确定
def trainning(dataset, labelset, weight1, weight2, value1, value2):# x为步长x = 0.01#学习率for i in range(len(dataset)):#依次读取数据特征集中的元素,一个元素即为一个样本所含有的所有特征数据# 输入数据#(1,21)inputset = np.mat(dataset[i]).astype(np.float64)#每次输入一个样本,将样本的特征转化为矩阵,以浮点数显示# 数据标签#(1,1)outputset = np.mat(labelset[i]).astype(np.float64)#输入样本所对应的标签# 隐层输入,隐层的输入是由输入层的权重决定的,wx#input1:(1,21).(21,21)=(1,21)input1 = np.dot(inputset, weight1).astype(np.float64)# 隐层输出,由隐层的输入和阈值以及激活函数决定的,这里的阈值也可以放在输入进行计算#sigmoid((1,21)-(1,21))=(1,21)output2 = sigmoid(input1 - value1).astype(np.float64)# 输出层输入,由隐层的输出#(1,21).(21,1)=(1,1)input2 = np.dot(output2, weight2).astype(np.float64)# 输出层输出,由输出层的输入和阈值以及激活函数决定的,这里的阈值也可以放在输出层输入进行计算# (1,1).(1,1)=(1,1)output3 = sigmoid(input2 - value2).astype(np.float64)# 更新公式由矩阵运算表示#a:(1,1)a = np.multiply(output3, 1 - output3)#输出层激活函数求导后的式子,multiply对应元素相乘,dot矩阵运算#g:(1,1)g = np.multiply(a, outputset - output3)#outputset - output3:实际标签和预测标签差#weight2:(21,1),np.transpose(weight2):(1,21),b:(1,21)b = np.dot(g, np.transpose(weight2))#(1,21)c = np.multiply(output2, 1 - output2)#隐层输出激活函数求导后的式子,multiply对应元素相乘,dot矩阵运算#(1,21)e = np.multiply(b, c)value1_change = -x * e#(1,21)value2_change = -x * g#(1,1)weight1_change = x * np.dot(np.transpose(inputset), e)#(21,21)weight2_change = x * np.dot(np.transpose(output2), g)#(21,1)# 更新参数,权重与阈值的迭代公式value1 += value1_changevalue2 += value2_changeweight1 += weight1_changeweight2 += weight2_changereturn weight1, weight2, value1, value2#创建测试样本数据的函数
def testing(dataset1, labelset1, weight1, weight2, value1, value2):# 记录预测正确的个数rightcount = 0for i in range(len(dataset1)):# 计算每一个样例的标签通过上面创建的神经网络模型后的预测值inputset = np.mat(dataset1[i]).astype(np.float64)outputset = np.mat(labelset1[i]).astype(np.float64)output2 = sigmoid(np.dot(inputset, weight1) - value1)output3 = sigmoid(np.dot(output2, weight2) - value2)# 确定其预测标签if output3 > 0.5:flag = 1else:flag = 0if labelset1[i] == flag:rightcount += 1# 输出预测结果print("预测为%d   实际为%d" % (flag, labelset1[i]))# 返回正确率return rightcount / len(dataset1)def main():#读取训练样本数据并且进行样本划分dataset, labelset = loaddataset('./horseColicTraining.txt')#读取测试样本数据并且进行样本划分dataset1, labelset1 = loaddataset('./horseColicTest.txt')#得到初始化的待估参数的值weight1, weight2, value1, value2 = parameter_initialization(len(dataset[0]), len(dataset[0]), 1)#迭代次数为1500次,迭代次数一般越大准确率越高,但是其运行时间也会增加for i in range(1500):#获得对所有训练样本训练迭代一次后的待估参数weight1, weight2, value1, value2 = trainning(dataset, labelset, weight1, weight2, value1, value2)#对测试样本进行测试,并且得到正确率rate = testing(dataset1, labelset1, weight1, weight2, value1, value2)print("正确率为%f" % (rate))if __name__ == '__main__':main()

参考:《机器学习 BP神经网络(Python实现)》写的很详细

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

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

相关文章

Halcon例程(基于多个标定图的单目相机标定)详解—— Camera_calibration_multi_image.hdev

一、前言 在我的工业相机专栏里已经将相机标定涉及到的理论部分讲解完毕&#xff0c;为什么要标定以及标定要求出什么参数呢&#xff0c;用一个Halcon 例程来帮助理解。 这个例程是比较经典的标定程序&#xff0c;基本将标定过程讲的比较清楚&#xff0c;用的标定图像是系统自…

SkipList 跳表

为什么选择跳表 目前经常使用的平衡数据结构有&#xff1a;B树&#xff0c;红黑树&#xff0c;AVL树&#xff0c;Splay Tree, Treep等。 想象一下&#xff0c;给你一张草稿纸&#xff0c;一只笔&#xff0c;一个编辑器&#xff0c;你能立即实现一颗红黑树&#xff0c;或者AVL树…

Redis failover过程

在Leader触发failover之前&#xff0c;首先wait数秒(随即0~5)&#xff0c;以便让其他sentinel实例准备和调整。如果一切正常&#xff0c;那么leader就需要开始将一个salve提升为master&#xff0c;此slave必须为状态良好(不能处于SDOWN/ODOWN状态)且权重值最低(redis.conf中)的…

机器学习——深度学习之卷积神经网络(CNN)——LeNet卷积神经网络结构

目录 一、卷积神经网络 1、卷积神经的作用 2、LeNet 1&#xff09;数据库准备——minst 2&#xff09;模型 二、关于卷积神经网络结构的一些术语定义 1、特征图&#xff08;Feature map&#xff09; 2、height&#xff08;长度&#xff09;、width&#xff08;宽度&…

工业相机(3D)主要参数详述

一、前言 准确的完成相机选型是一个视觉工程师必备的技能&#xff0c;而选型前必须对其内部参数了如指掌。工业相机是一种比较复杂的产品&#xff0c;其参数很多&#xff0c;每个参数可能会有不同的标准&#xff0c;下面对主要的参数会做比较详细的阐述。 二、参数详述 2.1 …

JAVA8永久代

在Java虚拟机&#xff08;以下简称JVM&#xff09;中&#xff0c;类包含其对应的元数据&#xff0c;比如类的层级信息&#xff0c;方法数据和方法信息&#xff08;如字节码&#xff0c;栈和变量大小&#xff09;&#xff0c;运行时常量池&#xff0c;已确定的符号引用和虚方法表…

Struts 2初体验

Struts2简介&#xff1a; Struts2是一个基于MVC设计模式的Web应用框架&#xff0c;它本质上相当于一个servlet&#xff0c;在MVC设计模式中&#xff0c;Struts2作为控制器(Controller)来建立模型与视图的数据交互。 Struts 2 目录结构:     apps目录&#xff1a;Struts2示例…

机器学习——深度学习之数据库和自编码器

目录 一、数据库——数据获取 1、Mnist 2、ImageNet 二、自编码器&#xff08;Auto-encoder&#xff09;——参数初始化 1、功能 2、基本思想 1&#xff09;训练第一层 2&#xff09;训练第二层及以后的神经网络 ​ 3&#xff09;利用BP对整个神经网络的参数初始值进…

Halcon例程详解 (深度图转换为3D图像)—— xyz_attrib_to_object_model_3d

一、前言 深度图向点云图进行转换是进行3D检测项目时会遇到的问题&#xff0c;halcon里也有针对此问题的相关例程&#xff0c;下面对此例程进行分析。通过学习此例程&#xff0c;我们可以掌握如何将一张深度图像和一张正常二维图像转换为3D点云。 二、分析 * 初始化界面 dev…

动态代理之Cglib浅析

什么是Cglib Cglib是一个强大的&#xff0c;高性能&#xff0c;高质量的代码生成类库。它可以在运行期扩展JAVA类与实现JAVA接口。其底层实现是通过ASM字节码处理框架来转换字节码并生成新的类。大部分功能实际上是ASM所提供的&#xff0c;Cglib只是封装了ASM&#xff0c;简化了…

机器学习——深度学习之卷积神经网络(CNN)——AlexNet卷积神经网络结构

目录 一、AlexNet卷积神经网络结构模型 1、数据库ImageNet 2、AlexNet第一层卷积层 二、AlexNet卷积神经网络的改进 1、非线性变化函数的改变——ReLU 2、最大池化&#xff08;Max Pooling&#xff09;概念的提出——卷积神经网络通用 1&#xff09;池化层 2&#xff0…

POJ - 3470 Walls

小鸟往四个方向飞都枚举一下&#xff0c;数据范围没给&#xff0c;离散以后按在其中一个轴线排序&#xff0c;在线段树上更新墙的id&#xff0c;然后就是点查询在在哪个墙上了。 这题有个trick&#xff0c;因为数据范围没给我老以为是inf设置小了&#xff0c;WA了很多发。&…

C# —— 深入理解委托类型

一. 委托定义 1. 委托与多播委托 委托类型表示对具有特定参数列表和返回类型的方法的引用&#xff0c;定义了委托实例可以调用的某类方法。 通过委托&#xff0c;我们可以动态的通过委托变量来调用委托方法。一般用delegate来命名委托类型,但Action和Func也可以达到同样的效果…

【VS开发】【C++语言】reshuffle的容器实现算法random_shuffle()的使用

假设你需要指定范围内的随机数&#xff0c;传统的方法是使用ANSI C的函数random(),然后格式化结果以便结果是落在指定的范围内。但是&#xff0c;使用这个方法至少有两个缺点。首先&#xff0c;做格式化时&#xff0c;结果常常是扭曲的&#xff0c;所以得不到正确的随机数&…

C#委托——基础2

在上一篇随笔中&#xff0c;简要说明了怎样定义委托&#xff0c;定义事件&#xff0c;订阅事件&#xff0c;最后也实现了效果&#xff0c;就是当员工类的某个对象&#xff0c;执行某个事件时&#xff0c;委托事件被触发&#xff0c;后面也得到了结果&#xff0c;但是想象一下实…

机器学习——深度学习之编程工具、流行网络结构、卷积神经网络结构的应用

目录 一、编程工具 caffe实现LENET-5 二、流行的网络结构 1、VGGNET 2、Googlenet ​ 3、ResNet​ ​ 三、卷积神经网络的应用 1、人脸识别 ​ 2、人脸验证 3、人脸特征点检测 4、卷积神经网络压缩 一、编程工具 caffe的优点&#xff1a;模型标准化&#xff0c;源代码…

Halcon例程详解(激光三角系统标定)—— calibrate_sheet_of_light_calplate.hdev

前言 1 激光三角测距 激光三角测距法原理很简单,是通过一束激光以一定的入射角度照射被测目标,激光在目标表面会产生漫反射,在另一角度利用透镜对反射激光汇聚成像,光斑成像在CCD(Charge-coupled Device,感光耦合组件)位置传感器上。当被测物体沿激光方向发生移动时,…

【转】如何实现一个文件系统

如何实现一个文件系统 摘要 本章目的是分析在Linux系统中如何实现新的文件系统。在介绍文件系统具体实现前先介绍文件系统的概念和作用&#xff0c;抽象出文件系统概念模型。熟悉文件系统的内涵后&#xff0c;我们再进一步讨论Linux系统中文件系统的特殊风格和具体文件系统在Li…

【tenserflow】——数据类型以及常用属性

目录 一、什么是Tensor&#xff1f; 二、Tensorflow常见数据类型 三、Tensorflow常见属性device\cpu\gpu\ndim\shape\rank等 1、创建一个tensor 1&#xff09;tf.constant() 2)tf.Variable() 2、判断一个变量是否为tensor张量 3、生成不同设备&#xff08;cpu,gpu&#x…

C# 事件详解附实例分析

一、定义 事件是两个对象间发布消息和响应后处理消息的过程&#xff0c;通过委托类型来实现的。 事件的机制被称为发布-订阅机制&#xff0c;其算法过程为&#xff1a;首先定义一个委托类型&#xff0c;然后在发布者类中声明一个event事件&#xff0c;同时此类中还有一个用来触…