基于Python实现DNNBP神经网络对不同圆的分类算法

简介: 基于Python实现DNNBP神经网络对不同圆的分类算法

classification_BPNeuralNetwork


本文介绍了通过 Python 实现 BP 神经网络分类算法,对不同半径的圆进行多分类(3 分类),特征即为圆的半径。 输入层 12 节点,一个 6 节点的隐藏层,输出层 3 个节点。

1.目标


通过 BP 算法实现对不同半径的圆的分类。

2.开发环境


IDE:PyCharm 2018.3.3(Community Edition) Python 及相关库的版本号如下图所示:


70ab45a5d54d7f200700e9c0c430c337.png


3.准备数据


目的: 生成 3 类圆在第一象限内的坐标(圆心都是原点) 第 1 类:半径范围为 1~10,分类标识为‘0’ 第 2 类:半径范围为 10~20,分类标识为‘1’ 第 3 类:半径范围为 20~30,分类标识为‘2’


代码如下:data_generate.py

importnumpyasnpimportmathimportrandomimportcsv# 只生成第一象限内的坐标即可。每个圆生成12个坐标(x,y),相当于12个特征维度defgenerate_circle(lower,upper):# 圆在第一象限内的坐标data_ur=np.zeros(shape=(12,2))# 在上下限范围内,随机产生一个值作为半径radius=random.randint(int(lower),int(upper))# 在0~90度内,每隔7.5度取一次坐标,正好取12次angles=np.arange(0,0.5*np.pi,1/24*np.pi)foriinrange(12):temp_ur=np.zeros(2)x=round(radius*math.cos(angles[i]),2)y=round(radius*math.sin(angles[i]),2)temp_ur[0]=xtemp_ur[1]=ydata_ur[i]=temp_urreturndata_ur,label# 将坐标保存到CSV文件中defsave2csv(data,batch,label):out=open("D:\\circles.csv",'a',newline='')csv_write=csv.writer(out,dialect='excel')length=int(data.size/2)foriinrange(length):string=str(data[i][0])+','+str(data[i][1])+','+str(batch)+','+str(label)temp=string.split(',')csv_write.writerow(temp)out.close()if__name__=="__main__":'''
        生成3类圆,标签(label)分别为:0、1、2
        第1类圆的半径下限为1,上限为10
        第2类圆的半径下限为10,上限为20
        第3类圆的半径下限为20,上限为30
        圆心都为原点
    '''lower=[1,10,20]# 半径随机值的下限upper=[10,20,30]# 半径随机值的上限label=['0','1','2']# 种类的标签foriinrange(len(label)):# 每类数据生成50组forjinrange(50):data,label=generate_circle(lower[i],upper[i])batch=50*i+j+1# 数据的批次,用来区分每个坐标是属于哪个圆的save2csv(data,batch,label[i])



共 3 类圆,每类生成 50 个圆,每个圆有 12 个坐标,因此在输出文件 D:\circles.csv 中总共有 3×50×12=1800 行数据:



52fee2b619df13b0e58ae41cfcb85de9.png


通过生成的坐标绘制散点图如下:

6923a2192f0fc46cf83e173a9bfceb6b.png


图中蓝色的点是 label 为 0 的圆,绿色的点是 label 为 1 的圆,红色的点是 label 为 2 的圆。


4.处理数据


目标: 根据第 3 步获得的坐标,计算每个圆的半径(勾股定理)作为神经网络的输入。

代码如下:data_process.py


importcsvimportmathdefprocess(file_name):# 要读取的CSV文件csv_file=csv.reader(open(file_name,encoding='utf-8'))# 要生成的CSV文件out_file=open("D:\\circles_data.csv",'a',newline='')csv_write=csv.writer(out_file,dialect='excel')# 将csv_file每一行的圆坐标取出,如果是同一批次的(同一个圆),则写入到out_file的一行中rows=[rowforrowincsv_file]current_batch='unknown'current_label='unknown'data_list=[]forrinrows:# 将无关字符都替换为空格temp_string=str(r).replace('[','').replace(']','').replace('\'','')# 将字符串以逗号分隔item=str(temp_string).split(',')# 分别取出x轴坐标、y轴坐标、批次、标签x=float(item[0])y=float(item[1])batch=item[2]label=item[3]# 如果是同一批次(同一个圆),则都放入data_list中ifcurrent_batch==batch:# 根据勾股定理计算半径distance=math.sqrt(pow(x,2)+pow(y,2))data_list.append(distance)# 如果不是同一批次(同一个圆),则在末尾加上标签后,作为一行写入输出文件else:iflen(data_list)!=0:# 这个地方需注意一下,最后的标签用3列来表示,而不是一列iflabel.strip()=='0':data_list.append(1)data_list.append(0)data_list.append(0)eliflabel.strip()=='1':data_list.append(0)data_list.append(1)data_list.append(0)else:data_list.append(0)data_list.append(0)data_list.append(1)result_string=str(data_list).replace('[','').replace(']','').replace('\'','').strip()csv_write.writerow(result_string.split(','))# 清空data_list,继续写入下一个批次data_list.clear()distance=math.sqrt(pow(x,2)+pow(y,2))data_list.append(distance)current_batch=batchcurrent_label=label# 确保最后一个批次的数据能写入ifcurrent_label.strip()=='0':data_list.append(1)data_list.append(0)data_list.append(0)elifcurrent_label.strip()=='1':data_list.append(0)data_list.append(1)data_list.append(0)else:data_list.append(0)data_list.append(0)data_list.append(1)result_string=str(data_list).replace('[','').replace(']','').replace('\'','').strip()csv_write.writerow(result_string.split(','))# 关闭输出文件out_file.close()if__name__=="__main__":process('D:\\circles.csv')

需要注意的是,生成的 CSV 文件共有 15 列,前 12 列为坐标对应的半径值,最后三列组合起来表示分类(label):

afa149869d93973411f3bb1289756907.png


(1,0,0)表示类型为“0”的圆,(0,1,0)表示类型为“1”的圆,(0,0,1)表示类型为“2”的圆,这样做的目的是为了下一步使用神经网络时处理起来方便。


5.构建 BP 神经网络


上一步处理好的数据可以作为训练数据,命名为:circles_data_training.csv 重复第 3 步和第 4 步,可以生成另一批数据作为测试数据,命名为:circles_data_test.csv 当然,也可以手动划分出训练数据和测试数据。 训练数据和测试数据在输入时,做了矩阵的转置,将列转置为行。


代码如下:data_analysis_bpnn.py

importpandasaspdimportnumpyasnpimportdatetimefromsklearn.utilsimportshuffle# 1.初始化参数definitialize_parameters(n_x,n_h,n_y):np.random.seed(2)# 权重和偏置矩阵w1=np.random.randn(n_h,n_x)*0.01b1=np.zeros(shape=(n_h,1))w2=np.random.randn(n_y,n_h)*0.01b2=np.zeros(shape=(n_y,1))# 通过字典存储参数parameters={'w1':w1,'b1':b1,'w2':w2,'b2':b2}returnparameters# 2.前向传播defforward_propagation(X,parameters):w1=parameters['w1']b1=parameters['b1']w2=parameters['w2']b2=parameters['b2']# 通过前向传播来计算a2z1=np.dot(w1,X)+b1# 这个地方需注意矩阵加法:虽然(w1*X)和b1的维度不同,但可以相加a1=np.tanh(z1)# 使用tanh作为第一层的激活函数z2=np.dot(w2,a1)+b2a2=1/(1+np.exp(-z2))# 使用sigmoid作为第二层的激活函数# 通过字典存储参数cache={'z1':z1,'a1':a1,'z2':z2,'a2':a2}returna2,cache# 3.计算代价函数defcompute_cost(a2,Y,parameters):m=Y.shape[1]# Y的列数即为总的样本数# 采用交叉熵(cross-entropy)作为代价函数logprobs=np.multiply(np.log(a2),Y)+np.multiply((1-Y),np.log(1-a2))cost=-np.sum(logprobs)/mreturncost# 4.反向传播(计算代价函数的导数)defbackward_propagation(parameters,cache,X,Y):m=Y.shape[1]w2=parameters['w2']a1=cache['a1']a2=cache['a2']# 反向传播,计算dw1、db1、dw2、db2dz2=a2-Ydw2=(1/m)*np.dot(dz2,a1.T)db2=(1/m)*np.sum(dz2,axis=1,keepdims=True)dz1=np.multiply(np.dot(w2.T,dz2),1-np.power(a1,2))dw1=(1/m)*np.dot(dz1,X.T)db1=(1/m)*np.sum(dz1,axis=1,keepdims=True)grads={'dw1':dw1,'db1':db1,'dw2':dw2,'db2':db2}returngrads# 5.更新参数defupdate_parameters(parameters,grads,learning_rate=0.0075):w1=parameters['w1']b1=parameters['b1']w2=parameters['w2']b2=parameters['b2']dw1=grads['dw1']db1=grads['db1']dw2=grads['dw2']db2=grads['db2']# 更新参数w1=w1-dw1*learning_rateb1=b1-db1*learning_ratew2=w2-dw2*learning_rateb2=b2-db2*learning_rateparameters={'w1':w1,'b1':b1,'w2':w2,'b2':b2}returnparameters# 建立神经网络defnn_model(X,Y,n_h,n_input,n_output,num_iterations=10000,print_cost=False):np.random.seed(3)n_x=n_input# 输入层节点数n_y=n_output# 输出层节点数# 1.初始化参数parameters=initialize_parameters(n_x,n_h,n_y)# 梯度下降循环foriinrange(0,num_iterations):# 2.前向传播a2,cache=forward_propagation(X,parameters)# 3.计算代价函数cost=compute_cost(a2,Y,parameters)# 4.反向传播grads=backward_propagation(parameters,cache,X,Y)# 5.更新参数parameters=update_parameters(parameters,grads)# 每1000次迭代,输出一次代价函数ifprint_costandi%1000==0:print('迭代第%i次,代价函数为:%f'%(i,cost))returnparameters# 对模型进行测试defpredict(parameters,x_test,y_test):w1=parameters['w1']b1=parameters['b1']w2=parameters['w2']b2=parameters['b2']z1=np.dot(w1,x_test)+b1a1=np.tanh(z1)z2=np.dot(w2,a1)+b2a2=1/(1+np.exp(-z2))# 结果的维度n_rows=y_test.shape[0]n_cols=y_test.shape[1]# 预测值结果存储output=np.empty(shape=(n_rows,n_cols),dtype=int)# 取出每条测试数据的预测结果foriinrange(n_cols):# 将每条测试数据的预测结果(概率)存为一个行向量temp=np.zeros(shape=n_rows)forjinrange(n_rows):temp[j]=a2[j][i]# 将每条结果(概率)从小到大排序,并获得相应下标sorted_dist=np.argsort(temp)length=len(sorted_dist)# 将概率最大的置为1,其它置为0forkinrange(length):ifk==sorted_dist[length-1]:output[k][i]=1else:output[k][i]=0print('预测结果:')print(output)print('真实结果:')print(y_test)count=0forkinrange(0,n_cols):ifoutput[0][k]==y_test[0][k]andoutput[1][k]==y_test[1][k]andoutput[2][k]==y_test[2][k]:count=count+1acc=count/int(y_test.shape[1])*100print('准确率:%.2f%%'%acc)if__name__=="__main__":# 读取数据data_set=pd.read_csv('D:\\circles_data_training.csv',header=None)data_set=shuffle(data_set)# 打乱数据的输入顺序# 取出“特征”和“标签”,并做了转置,将列转置为行X=data_set.ix[:,0:11].values.T# 前12列是特征Y=data_set.ix[:,12:14].values.T# 后3列是标签Y=Y.astype('uint8')# 开始训练start_time=datetime.datetime.now()# 输入12个节点,隐层6个节点,输出3个节点,迭代10000次parameters=nn_model(X,Y,n_h=6,n_input=12,n_output=3,num_iterations=10000,print_cost=True)end_time=datetime.datetime.now()print("用时:"+str((end_time-start_time).seconds)+'s'+str(round((end_time-start_time).microseconds/1000))+'ms')# 对模型进行测试data_test=pd.read_csv('D:\\circles_data_test.csv',header=None)x_test=data_test.ix[:,0:11].values.Ty_test=data_test.ix[:,12:14].values.Ty_test=y_test.astype('uint8')predict(parameters,x_test,y_test)

上述代码可以参考这篇文章:纯 Python 实现鸢尾属植物数据集神经网络模型。


代码中需要注意的几个关键参数:


  1. learning_rate=0.0075,学习率(可调)
  2. n_h=6,隐藏层节点数(可调)
  3. n_input=12,输入层节点数
  4. n_output=3,输出层节点数
  5. num_iterations=10000,迭代次数(可调)



另外,对于 predict(parameters, x_test, y_test) 函数需要说明一下: a2 矩阵是最终的预测结果,但是是以概率的形式表示的(可以打印看一下)。通过比较 3 个类的概率,选出概率最大的那个置为 1,其它两个置为 0,形成 output 矩阵。


运行结果:

cca70180a694dd4a449b58ac3a31efcc.png


上图中第一红框表示神经网络预测出的分类结果,第二个红框表示测试集中真实的分类((1,0,0)表示这个圆属于类型“0”)。

每次运行时,正确率可能不一样,最高能达到 100%。通过调整刚才提到的关键参数中的学习率、隐藏层节点数、迭代次数可以提高正确率。


总结


神经网络的输入为 12 个半径值,输出结果为一个 3 维向量,其中置 1 的位就是对应的分类。   在实际应用中,12 个半径值对应 12 个特征,3 维向量表示能分 3 类。只要根据实际应用的需要修改特征数和分类数即可将上述程序应用于不同分类场景。


以上就是利用 BP 神经网络实现多特征多分类的全部过程。

相关文章
|
14天前
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的眼疾识别系统实现~人工智能+卷积网络算法
眼疾识别系统,本系统使用Python作为主要开发语言,基于TensorFlow搭建卷积神经网络算法,并收集了4种常见的眼疾图像数据集(白内障、糖尿病性视网膜病变、青光眼和正常眼睛) 再使用通过搭建的算法模型对数据集进行训练得到一个识别精度较高的模型,然后保存为为本地h5格式文件。最后使用Django框架搭建了一个Web网页平台可视化操作界面,实现用户上传一张眼疾图片识别其名称。
67 4
基于Python深度学习的眼疾识别系统实现~人工智能+卷积网络算法
|
24天前
|
存储 缓存 监控
局域网屏幕监控系统中的Python数据结构与算法实现
局域网屏幕监控系统用于实时捕获和监控局域网内多台设备的屏幕内容。本文介绍了一种基于Python双端队列(Deque)实现的滑动窗口数据缓存机制,以处理连续的屏幕帧数据流。通过固定长度的窗口,高效增删数据,确保低延迟显示和存储。该算法适用于数据压缩、异常检测等场景,保证系统在高负载下稳定运行。 本文转载自:https://www.vipshare.com
117 66
|
5天前
|
存储 监控 算法
员工电脑监控屏幕场景下 Python 哈希表算法的探索
在数字化办公时代,员工电脑监控屏幕是保障信息安全和提升效率的重要手段。本文探讨哈希表算法在该场景中的应用,通过Python代码例程展示如何使用哈希表存储和查询员工操作记录,并结合数据库实现数据持久化,助力企业打造高效、安全的办公环境。哈希表在快速检索员工信息、优化系统性能方面发挥关键作用,为企业管理提供有力支持。
34 20
|
13天前
|
存储 算法 Serverless
剖析文件共享工具背后的Python哈希表算法奥秘
在数字化时代,文件共享工具不可或缺。哈希表算法通过将文件名或哈希值映射到存储位置,实现快速检索与高效管理。Python中的哈希表可用于创建简易文件索引,支持快速插入和查找文件路径。哈希表不仅提升了文件定位速度,还优化了存储管理和多节点数据一致性,确保文件共享工具高效运行,满足多用户并发需求,推动文件共享领域向更高效、便捷的方向发展。
|
20天前
|
机器学习/深度学习 算法
基于遗传优化的双BP神经网络金融序列预测算法matlab仿真
本项目基于遗传优化的双BP神经网络实现金融序列预测,使用MATLAB2022A进行仿真。算法通过两个初始学习率不同的BP神经网络(e1, e2)协同工作,结合遗传算法优化,提高预测精度。实验展示了三个算法的误差对比结果,验证了该方法的有效性。
|
21天前
|
算法 网络协议 Python
探秘Win11共享文件夹之Python网络通信算法实现
本文探讨了Win11共享文件夹背后的网络通信算法,重点介绍基于TCP的文件传输机制,并提供Python代码示例。Win11共享文件夹利用SMB协议实现局域网内的文件共享,通过TCP协议确保文件传输的完整性和可靠性。服务器端监听客户端连接请求,接收文件请求并分块发送文件内容;客户端则连接服务器、接收数据并保存为本地文件。文中通过Python代码详细展示了这一过程,帮助读者理解并优化文件共享系统。
|
26天前
|
存储 算法 Python
文件管理系统中基于 Python 语言的二叉树查找算法探秘
在数字化时代,文件管理系统至关重要。本文探讨了二叉树查找算法在文件管理中的应用,并通过Python代码展示了其实现过程。二叉树是一种非线性数据结构,每个节点最多有两个子节点。通过文件名的字典序构建和查找二叉树,能高效地管理和检索文件。相较于顺序查找,二叉树查找每次比较可排除一半子树,极大提升了查找效率,尤其适用于海量文件管理。Python代码示例包括定义节点类、插入和查找函数,展示了如何快速定位目标文件。二叉树查找算法为文件管理系统的优化提供了有效途径。
50 5
|
26天前
|
存储 缓存 算法
探索企业文件管理软件:Python中的哈希表算法应用
企业文件管理软件依赖哈希表实现高效的数据管理和安全保障。哈希表通过键值映射,提供平均O(1)时间复杂度的快速访问,适用于海量文件处理。在Python中,字典类型基于哈希表实现,可用于管理文件元数据、缓存机制、版本控制及快速搜索等功能,极大提升工作效率和数据安全性。
62 0
|
1月前
|
人工智能 数据可视化 数据挖掘
探索Python编程:从基础到高级
在这篇文章中,我们将一起深入探索Python编程的世界。无论你是初学者还是有经验的程序员,都可以从中获得新的知识和技能。我们将从Python的基础语法开始,然后逐步过渡到更复杂的主题,如面向对象编程、异常处理和模块使用。最后,我们将通过一些实际的代码示例,来展示如何应用这些知识解决实际问题。让我们一起开启Python编程的旅程吧!
|
1月前
|
存储 数据采集 人工智能
Python编程入门:从零基础到实战应用
本文是一篇面向初学者的Python编程教程,旨在帮助读者从零开始学习Python编程语言。文章首先介绍了Python的基本概念和特点,然后通过一个简单的例子展示了如何编写Python代码。接下来,文章详细介绍了Python的数据类型、变量、运算符、控制结构、函数等基本语法知识。最后,文章通过一个实战项目——制作一个简单的计算器程序,帮助读者巩固所学知识并提高编程技能。

热门文章

最新文章