精华内容
下载资源
问答
  • 本例中包含两层BP神经网络模板程序(可以直接调用,可定制中间层神经元个数,设置学习率,绘制衰减曲线,可用于简单的模式识别和预测)、一个调用的例程(包括简单的数据预处理如归一化的使用,测试结果准确率为98.3...
  • 利用BP算法实现对鸢尾花分类,C++实现,包含text格式数据集
  • BP神经网络鸢尾花分类)C++代码.rar 将Iris(鸢尾花)数据集分为训练集(Iris-train.txt)和测试集(Iris-test.txt),分别含75个样本,每个集合中每种花各有25个样本。
  • 本代码主要利用MATLAB工具进行MATLAB——有导师学习神经网络分类——鸢尾花种类识别
  • BP神经网络鸢尾花分类

    千次阅读 2020-05-15 20:38:56
    .reshape(1,-1) test_x=test_data[:,:2] test_y=test_data[:,2:].reshape(1,-1) w1=np.random.rand(2,4)#第一层四个神经元,2个特征 b1=np.random.rand(1,4) w2=np.random.rand(4,1)#输出层有一个神经元,上一层每个...
    import numpy as np
    import matplotlib.pyplot as plt
    
    def sigmoid(x):
        return 1/(1+np.exp(-x))
    def doit(num,w1,b1,w2,b2):#输入迭代次数
        number=num
        train_number=0
        totalE=[]
        totalN=[]
        while(number>0):
            number-=1
            train_number+=1
            E=0
            for index,i in enumerate(train_x):
                #对x中的每一个样本进行正`向传播
                #中间层的输入
                a1=np.dot(i,w1)#[1,4]
                #隐藏层的输出
                y1=sigmoid(a1+b1)#[1,4]
                #输出层的输入
                #print(w2)
                #print(y1)
                a2=np.dot(y1,w2)#[1,1]
                #输出层的输出
                y2=sigmoid(a2+b2)#[1,1]
                #print(y2)
                #反向传播
                g=np.multiply((train_y[0][index]-y2),np.multiply(y2,(1-y2)))#1*19
                #print(g)
                #更新输出层的权值w和偏置值b
                w2=w2+lr*np.dot(y1.T,g)
                b2=b2+lr*g
                #print("第"+str(index+1)+"个样本")
                #print("更新后的输出层权重w2",w2)
                #print("更新后的输出层b2",b2)
                #print("下面开始更新中间层权重w1和偏置值b1")
                w1=w1+lr*i.reshape(2,1)*np.multiply(np.multiply(y1,(1-y1)),np.dot(w2,g.T).T)
                b1=b1+lr*np.multiply(np.multiply(y1,(1-y1)),np.dot(w2,g.T).T)
                #print("更新后的输出层权重w1", w1)
                #print("更新后的输出层b1", b1)
                E+=(1/2.0*(y2[0][0]-train_y[0][index])**2)
            #print(E)
            totalE.append(E)
            totalN.append(train_number)
        print("训练完毕,输出权重和偏置值:")
        print("更新后的输出层权重w2",w2)
        print("更新后的输出层b2",b2)
        print("下面开始更新中间层权重w1和偏置值b1")
        print("更新后的输出层权重w1", w1)
        print("更新后的输出层b1", b1)
        
        #画图
        fig = plt.figure()
        # 将画图窗口分成1行1列,选择第一块区域作子图
        ax1 = fig.add_subplot(1, 1, 1)
        # 设置标题
        ax1.set_title('Result Analysis')
        # 设置横坐标名称
        ax1.set_xlabel('times')
        # 设置纵坐标名称
        ax1.set_ylabel('Error')
        # 画散点图
        ax1.scatter(totalN, totalE, s=20, c='#DC143C', marker='.')
        plt.show() 
        
        #预测
        output = []
        output1 = []
        for index,i in enumerate(test_x):
            #对x中的每一个样本进行正`向传播
            #中间层的输入
            a1=np.dot(i,w1)#[1,4]
            #隐藏层的输出
            y1=sigmoid(a1+b1)#[1,4]
            #输出层的输入
            #print(w2)
            #print(y1)
            a2=np.dot(y1,w2)#[1,1]
            #输出层的输出
            y2=sigmoid(a2+b2)#[1,1]
            #print(y2)
            if y2[0][0]>0.5:
                output.append(1)
            else:
                output.append(0)
        print("预测值:",output)
        trueOutPut=test_y.tolist()
        print("真实值:",trueOutPut[0])
        successNumber=0
        for index,i in enumerate(trueOutPut[0]):
            if output[index]==trueOutPut[0][index]:
                successNumber+=1
        print("成功率:",successNumber/test_y.shape[1])
            
            
        
    if __name__=='__main__':
        train_data=np.loadtxt("train.txt",delimiter=',')
        test_data=np.loadtxt("test.txt",delimiter=',')
        train_x=train_data[:,:2]
        train_y=train_data[:,2:].reshape(1,-1)
        test_x=test_data[:,:2]
        test_y=test_data[:,2:].reshape(1,-1)
        w1=np.random.rand(2,4)#第一层四个神经元,2个特征
        b1=np.random.rand(1,4)
    
        w2=np.random.rand(4,1)#输出层有一个神经元,上一层每个神经元生成一个特征,共四个特征
        b2=np.random.rand(1,1)
    
        lr=0.5#学习率
        doit(1000,w1,b1,w2,b2)

     

    展开全文
  • BP神经网络鸢尾花进行分类

    千次阅读 多人点赞 2020-05-15 21:51:42
    一、实验项目: BP神经网络鸢尾花进行分类 二、实验目的: 掌握BP神经网络学习算法,利用BP神经网络进行数据分类 三、实验内容: 1、编程实现BP神经网络算法 2、建立三层BP神经网络,节点个数、参数自拟 3、选择...

    题目:BP神经网络分类器
    一、实验项目: BP神经网络对鸢尾花进行分类
    二、实验目的:
    掌握BP神经网络学习算法,利用BP神经网络进行数据分类
    三、实验内容:
    1、编程实现BP神经网络算法
    2、建立三层BP神经网络,节点个数、参数自拟
    3、选择iris-人工神经网络.txt中的一部分数据集作为训练集,通过训练集对BP神经网络的连接权重进行学习
    4、记录实验数据(连接权值的变化、迭代次数、总的误差变化)
    5、用剩下的数据集作为测试集,验证学习的效果
    四、实验要求:
    1、画出实验所用的BP神经网络的结构图
    2、附上主体代码清单
    3、写清楚实验步骤和实验结果
    4、调节参数后,得到不同的实验数据,对数据进行分析

    在这里插入图片描述
    在这里插入图片描述
    代码:

    import numpy as np
    import pandas as pd
    
    '''
        构建一个具有1个隐藏层的神经网络,隐层的大小为5
        输入层为2个特征,输出层为2个分类
        0为第一类,1为第二类
    '''
    # 1.初始化参数
    def initialize_parameters(n_x, n_h, n_y):
        np.random.seed(2)
    
        # 权重和偏置矩阵
        w1 = np.random.randn(n_h, n_x) * 0.01
        b1 = np.zeros(shape=(n_h, 1))
        w2 = np.random.randn(n_y, n_h) * 0.01
        b2 = np.zeros(shape=(n_y, 1))
        
        print('输入层与隐含层之间的初始权值:')
        print(w1)
        print('输入层与隐含层之间的初始偏置:')
        print(b1)
        print('隐含层与输出层之间的初始权值:')
        print(w2)
        print('隐含层与输出层之间的初始偏置:')
        print(b2)
        
        # 通过字典存储参数
        parameters = {'w1': w1, 'b1': b1, 'w2': w2, 'b2': b2}
        return parameters
    
    # 2.前向传播
    def forward_propagation(X, parameters):
        w1 = parameters['w1']
        b1 = parameters['b1']
        w2 = parameters['w2']
        b2 = parameters['b2']
    
        # 通过前向传播来计算a2
      
        z1 = np.dot(w1, X) + b1     # 这个地方需注意矩阵加法:虽然(w1*X)和b1的维度不同,但可以相加
        a1 = np.tanh(z1)            # 使用tanh作为第一层的激活函数
        z2 = np.dot(w2, a1) + b2
        a2 = 1 / (1 + np.exp(-z2))  # 使用sigmoid作为第二层的激活函数
    
        # 通过字典存储参数
        cache = {'z1': z1, 'a1': a1, 'z2': z2, 'a2': a2}
    
        return a2, cache
    
    # 3.计算代价函数
    def compute_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) / m
    
        return cost
    
    # 4.反向传播(计算代价函数的导数)
    def backward_propagation(parameters, cache, X, Y):
        m = Y.shape[1]
    
        w2 = parameters['w2']
    
        a1 = cache['a1']
        a2 = cache['a2']
    
        # 反向传播,计算dw1、db1、dw2、db2
        dz2 = a2 - Y
        dw2 = (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}
    
        return grads
    
    # 5.更新参数
    def update_parameters(parameters, grads, learning_rate=0.4):
        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_rate
        b1 = b1 - db1 * learning_rate
        w2 = w2 - dw2 * learning_rate
        b2 = b2 - db2 * learning_rate
    
        parameters = {'w1': w1, 'b1': b1, 'w2': w2, 'b2': b2}
    
        return parameters
    
    # 6.模型评估
    def predict(parameters, x_test, y_test):
        w1 = parameters['w1']
        b1 = parameters['b1']
        w2 = parameters['w2']
        b2 = parameters['b2']
        
        print('训练集训练后,输入层与隐含层之间的权值为:')
        print(w1)
        print('训练集训练后,输入层与隐含层之间的偏置为:')
        print(b1)
        print('训练集训练后,隐含层与输出层之间的权值为:')
        print(w2)
        print('训练集训练后,隐含层与输出层之间的偏置为:')
        print(b2)
        print('================================================================')
        print('================================================================')
    
        z1 = np.dot(w1, x_test) + b1
        a1 = np.tanh(z1)
        z2 = np.dot(w2, a1) + b2
        a2 = 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)
    
        for i in range(n_rows):
            for j in range(n_cols):
                if a2[i][j] > 0.5:
                    output[i][j] = 1
                else:
                    output[i][j] = 0
        
       
        print('预测结果:')
        print(output)
        print('真实结果:')
        print(y_test)
        
    
        count = 0
        for k in range(0, n_cols):
            if output[0][k] == y_test[0][k] :
                count = count + 1
            else:
                print(k)
    
        acc = count / int(y_test.shape[1]) * 100
        print('准确率:%.2f%%' % acc)
    
    
    
    # 建立神经网络
    def nn_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          # 输出层节点数
        
        print('================================================================')
        print('================================================================')
        # 1.初始化参数
        parameters = initialize_parameters(n_x, n_h, n_y)
        print('================================================================')
        print('================================================================')
        
        # 2.前向传播
        a2, cache = forward_propagation(X, parameters)
         # 3.计算代价函数
        cost0 = compute_cost(a2, Y, parameters)
         # 4.反向传播
        grads = backward_propagation(parameters, cache, X, Y)
            # 5.更新参数
        parameters = update_parameters(parameters, grads)
        
        # 梯度下降循环
        for i in range(1, num_iterations+1):
            # 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次迭代,输出一次代价函数
    # =============================================================================
    #         if print_cost and i % 1000 == 0:
    #             print('迭代第%i次,代价函数为:%f' % (i, cost))
    # =============================================================================
                
        print('迭代次数为:%i次,总的误差变化为:%f' % (i, cost-cost0))
        print('================================================================')
        print('================================================================')
    
    
        return parameters
    
    
    if __name__ == "__main__":
        # 读取数据
        f=open('F:\\小n\\程凝\\智能计算\\实验\\实验3\\iris数据集\\iris-人工神经网络-训练集.txt')
        data_set = pd.read_table(f,sep=',', header=None)
    	# 不同的取数据的方式
        X = data_set[data_set.columns[0:2]].values.T
        Y = data_set[data_set.columns[2:3]].values.T
       
        Y = Y.astype('uint8')
    
       
        # 输入2个节点,隐层5个节点,输出1个节点,迭代10000次
        parameters = nn_model(X, Y, n_h=5, n_input=2, n_output=1, num_iterations=10000, print_cost=True)
        # 对模型进行测试
        f1=open('F:\\小n\\程凝\\智能计算\\实验\\实验3\\iris数据集\\iris-人工神经网络-测试集.txt')
        data_test = pd.read_csv(f1, header=None)
        x_test = data_test[data_test.columns[0:2]].values.T
        y_test = data_test[data_test.columns[2:3]].values.T
        y_test = y_test.astype('uint8')
    
        predict(parameters, x_test, y_test)
    

    运行结果:
    在这里插入图片描述
    参考文章:
    Python 基于BP神经网络的鸢尾花分类
    pandas之 read_table函数读取txt文件

    总结一下遇到的小问题:
    (1)敲pandas出错?
    (第一次用pandas库)误以为就是panda,运行的时候发现没有这个模块。
    (2)利用pandas不能直接读含有中文的路径,否则会报错

     #路径中含有中文,pandas不能直接读,报错
     data_set = pd.read_table('F:\\小n\\程凝\\智能计算\\实验\\实验3\\iris数据集\\iris-人工神经网络-训练集.txt',sep=',', header=None)
     
     #如何解决
     f=open('F:\\小n\\程凝\\智能计算\\实验\\实验3\\iris数据集\\iris-人工神经网络-训练集.txt')
        data_set = pd.read_table(f,sep=',', header=None)
    

    (3)如何用pandas来读取txt文件数据(非常方便,尤其是对txt文件中的数据切片取行或取列时),使用read_table()方法。pandas的read_table返回一个DataFrame,二维型的,会像一棋盘那样标识数据。事实上,所谓的txt文件中的数据就是一个DataFrame。如下图所示:
    在这里插入图片描述

    data_set = pd.read_table(f,sep=',', header=None)
    

    其中,f是读入的txt文件的路径;sep=’,’ 表示txt文件单行数据之间的分隔符为逗号,这个参数可缺省,默认为sep=’\t’,制表符;header=None 表示txt文件的第一行不是列的名字,是数据。
    (4)最简单的对DataFrame取列的方式:
    (一个txt文件中的数据,就是一个DataFrame)

     X = data_set[data_set.columns[0:2]].values.T  #取第1,2列
     Y = data_set[data_set.columns[2:3]].values.T   #取第3列
    

    (5)BP神经网络构建一个分类器的思路:
    第一步:初始化参数(包括权值和偏置)
    第二步:前向传播
    第三步:计算代价函数
    第四步:反向传播
    第五步:更新参数
    第六步:模型评估
    其中:第二、三、四、五步是建立训练集的基础上进行的,得到一组训练后的权值和偏置,到目前为止就实现了一个分类器;以这一组新的权值和偏置作为测试集的初始化参数,通过前向传播的结果与真实结果的对比来估计这个分类器的好坏。

    结语

    如果你喜欢我写的文章,欢迎来踩我个人搭建的博客~
    ChengNing’s Blog

    展开全文
  • Python 基于BP神经网络鸢尾花分类

    万次阅读 多人点赞 2019-12-27 15:26:18
    本文用Python实现了BP神经网络分类算法,根据鸢尾花的4个特征,实现3种鸢尾花分类

    本文用Python实现了BP神经网络分类算法,根据鸢尾花的4个特征,实现3种鸢尾花的分类。
    算法参考文章:纯Python实现鸢尾属植物数据集神经网络模型

    2020.07.21更新: 增加了分类结果可视化result_visualization
    2020.07.09更新: 完善代码中取数据部分的操作。


    代码及鸢尾花数据集可从GitHub上获取:点这里

    1.数据准备

    鸢尾花数据集包含4种特征,萼片长度(Sepal Length)、萼片宽度(Sepal Width)、花瓣长度(Petal Length)和花瓣宽度(Petal Width),以及3种鸢尾花Versicolor、Virginica和Setosa。

    数据集共151行,5列:

    • 第1行是数据说明,“150”表示共150条数据;“4”表示特征数;“setosa、versicolor、virginica”是三类花的名字
    • 第2行至第151行是150条数据
    • 第1至4列是Sepal Length、Sepal Width、Petal Length、Petal
      Width 4个特征
    • 第5列是花的类别,用0、1、2表示
      iris数据集为方便起见,需要对数据集稍作处理:
    1. 将150条数据分隔为两个文件,前120条另存为iris_training.csv,即训练集;后30条另存为iris_test.csv,即测试集;
    2. 训练集和测试集都删去第1行;
    3. 训练集和测试集都删去原来的最后1列,并新增加3列,目的是用3列来表示鸢尾花的分类:如果原来最后一列是0,则新增加的3列为(0,0,0);如果原来最后一列是1,则新增加的3列为(0,1,0);如果原来最后一列是2,则新增加的3列为(0,0,1)。
      iris训练集

    2.算法实现

    纯Python实现鸢尾属植物数据集神经网络模型 这篇文章中讲解得更为详细。本人对代码做了略微的修改,并增加了评估模型准确率的predict()函数。

    import pandas as pd
    import numpy as np
    import datetime
    import matplotlib.pyplot as plt
    from pandas.plotting import radviz
    '''
        构建一个具有1个隐藏层的神经网络,隐层的大小为10
        输入层为4个特征,输出层为3个分类
        (1,0,0)为第一类,(0,1,0)为第二类,(0,0,1)为第三类
    '''
    
    
    # 1.初始化参数
    def initialize_parameters(n_x, n_h, n_y):
        np.random.seed(2)
    
        # 权重和偏置矩阵
        w1 = np.random.randn(n_h, n_x) * 0.01
        b1 = np.zeros(shape=(n_h, 1))
        w2 = np.random.randn(n_y, n_h) * 0.01
        b2 = np.zeros(shape=(n_y, 1))
    
        # 通过字典存储参数
        parameters = {'w1': w1, 'b1': b1, 'w2': w2, 'b2': b2}
    
        return parameters
    
    
    # 2.前向传播
    def forward_propagation(X, parameters):
        w1 = parameters['w1']
        b1 = parameters['b1']
        w2 = parameters['w2']
        b2 = parameters['b2']
    
        # 通过前向传播来计算a2
        z1 = np.dot(w1, X) + b1     # 这个地方需注意矩阵加法:虽然(w1*X)和b1的维度不同,但可以相加
        a1 = np.tanh(z1)            # 使用tanh作为第一层的激活函数
        z2 = np.dot(w2, a1) + b2
        a2 = 1 / (1 + np.exp(-z2))  # 使用sigmoid作为第二层的激活函数
    
        # 通过字典存储参数
        cache = {'z1': z1, 'a1': a1, 'z2': z2, 'a2': a2}
    
        return a2, cache
    
    
    # 3.计算代价函数
    def compute_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) / m
    
        return cost
    
    
    # 4.反向传播(计算代价函数的导数)
    def backward_propagation(parameters, cache, X, Y):
        m = Y.shape[1]
    
        w2 = parameters['w2']
    
        a1 = cache['a1']
        a2 = cache['a2']
    
        # 反向传播,计算dw1、db1、dw2、db2
        dz2 = a2 - Y
        dw2 = (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}
    
        return grads
    
    
    # 5.更新参数
    def update_parameters(parameters, grads, learning_rate=0.4):
        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_rate
        b1 = b1 - db1 * learning_rate
        w2 = w2 - dw2 * learning_rate
        b2 = b2 - db2 * learning_rate
    
        parameters = {'w1': w1, 'b1': b1, 'w2': w2, 'b2': b2}
    
        return parameters
    
    
    # 6.模型评估
    def predict(parameters, x_test, y_test):
        w1 = parameters['w1']
        b1 = parameters['b1']
        w2 = parameters['w2']
        b2 = parameters['b2']
    
        z1 = np.dot(w1, x_test) + b1
        a1 = np.tanh(z1)
        z2 = np.dot(w2, a1) + b2
        a2 = 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)
    
        for i in range(n_rows):
            for j in range(n_cols):
                if a2[i][j] > 0.5:
                    output[i][j] = 1
                else:
                    output[i][j] = 0
    
        print('预测结果:')
        print(output)
        print('真实结果:')
        print(y_test)
    
        count = 0
        for k in range(0, n_cols):
            if output[0][k] == y_test[0][k] and output[1][k] == y_test[1][k] and output[2][k] == y_test[2][k]:
                count = count + 1
            else:
                print(k)
    
        acc = count / int(y_test.shape[1]) * 100
        print('准确率:%.2f%%' % acc)
    	
    	return output
    
    
    # 建立神经网络
    def nn_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)
    
        # 梯度下降循环
        for i in range(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次迭代,输出一次代价函数
            if print_cost and i % 1000 == 0:
                print('迭代第%i次,代价函数为:%f' % (i, cost))
    
        return parameters
    
    
    # 结果可视化
    # 特征有4个维度,类别有1个维度,一共5个维度,故采用了RadViz图
    def result_visualization(x_test, y_test, result):
        cols = y_test.shape[1]
        y = []
        pre = []
    
        # 反转换类别的独热编码
        for i in range(cols):
            if y_test[0][i] == 0 and y_test[1][i] == 0 and y_test[2][i] == 1:
                y.append('setosa')
            elif y_test[0][i] == 0 and y_test[1][i] == 1 and y_test[2][i] == 0:
                y.append('versicolor')
            elif y_test[0][i] == 1 and y_test[1][i] == 0 and y_test[2][i] == 0:
                y.append('virginica')
    
        for j in range(cols):
            if result[0][j] == 0 and result[1][j] == 0 and result[2][j] == 1:
                pre.append('setosa')
            elif result[0][j] == 0 and result[1][j] == 1 and result[2][j] == 0:
                pre.append('versicolor')
            elif result[0][j] == 1 and result[1][j] == 0 and result[2][j] == 0:
                pre.append('virginica')
            else:
                pre.append('unknown')
    
        # 将特征和类别矩阵拼接起来
        real = np.column_stack((x_test.T, y))
        prediction = np.column_stack((x_test.T, pre))
    
        # 转换成DataFrame类型,并添加columns
        df_real = pd.DataFrame(real, index=None, columns=['Sepal Length', 'Sepal Width', 'Petal Length', 'Petal Width', 'Species'])
        df_prediction = pd.DataFrame(prediction, index=None, columns=['Sepal Length', 'Sepal Width', 'Petal Length', 'Petal Width', 'Species'])
    
        # 将特征列转换为float类型,否则radviz会报错
        df_real[['Sepal Length', 'Sepal Width', 'Petal Length', 'Petal Width']] = df_real[['Sepal Length', 'Sepal Width', 'Petal Length', 'Petal Width']].astype(float)
        df_prediction[['Sepal Length', 'Sepal Width', 'Petal Length', 'Petal Width']] = df_prediction[['Sepal Length', 'Sepal Width', 'Petal Length', 'Petal Width']].astype(float)
    
        # 绘图
        plt.figure('真实分类')
        radviz(df_real, 'Species', color=['blue', 'green', 'red', 'yellow'])
        plt.figure('预测分类')
        radviz(df_prediction, 'Species', color=['blue', 'green', 'red', 'yellow'])
        plt.show()
    
    
    if __name__ == "__main__":
        # 读取数据
        data_set = pd.read_csv('D:\\iris_training.csv', header=None)
        
        # 第1种取数据方法:
        X = data_set.iloc[:, 0:4].values.T          # 前四列是特征,T表示转置
        Y = data_set.iloc[:, 4:].values.T           # 后三列是标签
    
        # 第2种取数据方法:
        # X = data_set.ix[:, 0:3].values.T
        # Y = data_set.ix[:, 4:6].values.T
    
        # 第3种取数据方法:
        # X = data_set.loc[:, 0:3].values.T
        # Y = data_set.loc[:, 4:6].values.T
    
        # 第4种取数据方法:
        # X = data_set[data_set.columns[0:4]].values.T
        # Y = data_set[data_set.columns[4:7]].values.T
        Y = Y.astype('uint8')
        
        # 开始训练
        start_time = datetime.datetime.now()
        # 输入4个节点,隐层10个节点,输出3个节点,迭代10000次
        parameters = nn_model(X, Y, n_h=10, n_input=4, 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:\\iris_test.csv', header=None)
        x_test = data_test.iloc[:, 0:4].values.T
        y_test = data_test.iloc[:, 4:].values.T
        y_test = y_test.astype('uint8')
    
        result = predict(parameters, x_test, y_test)
    
        # 分类结果可视化
        result_visualization(x_test, y_test, result)
    
    

    最终结果:
    结果
    分类的可视化效果,左侧为测试集的真实分类,右侧为模型的预测分类结果,采用的是RadViz图
    分类可视化
    每次运行时准确率可能都不一样,可以通过调整学习率、隐节点数、迭代次数等参数来改善模型的效果。

    3.总结

    算法的实现总共分为6步:

    1. 初始化参数
    2. 前向传播
    3. 计算代价函数
    4. 反向传播
    5. 更新参数
    6. 模型评估

    欢迎关注我的微信公众号:
    微信公众号

    展开全文
  • 本文用Python实现了BP神经网络分类算法,根据鸢尾花的4个特征,实现3种鸢尾花分类。 算法参考文章: iris_data_classification_bpnn_V1.py 需使用 bpnn_V1数据集 文件夹中的数据 iris_data_classification_bpnn_V2...
  • 使用Tensorflow训练BP神经网络实现鸢尾花分类

    千次阅读 多人点赞 2021-05-08 08:47:04
    使用tensorflow实现鸢尾花分类,详细易懂。

    Hello,兄弟们,开始搞深度学习了,今天出第一篇博客,小白一枚,如果发现错误请及时指正,万分感谢。
    在这里插入图片描述

    使用软件

    Python 3.8,Tensorflow2.0

    问题描述

    鸢尾花主要分为狗尾草鸢尾(0)、杂色鸢尾(1)、弗吉尼亚鸢尾(2)。
    人们发现通过计算鸢尾花的花萼长、花萼宽、花瓣长、花瓣宽可以将鸢尾花分类。
    所以只要给出足够多的鸢尾花花萼、花瓣数据,以及对应种类,使用合适的神经网络训练,就可以实现鸢尾花分类。

    搭建神经网络

    输入数据是花萼长、花萼宽、花瓣长、花瓣宽,是n行四列的矩阵。
    而输出的是每个种类的概率,是n行三列的矩阵。
    我们采用BP神经网络,设X为输入数据,Y为输出数据,W为权重,B偏置。有
    y = x ∗ w + b y = x*w+b y=xw+b
    因为x为n行四列的矩阵,y为n行三列的矩阵,所以w必须为四行三列的矩阵,每个神经元对应一个b,所以b为一行三列的的矩阵。
    神经网络如下图。
    在这里插入图片描述
    所以,只要找到合适的w和b,就能准确判断鸢尾花的种类。
    下面就开始对这两个参数进行训练。

    训练参数

    损失函数

    损失函数表达的是预测值(y*)和真实值(y)的差距,我们采用均方误差公式作为损失函数。
    M S E ( y , y ∗ ) = ∑ i = 0 n ( y − y ∗ ) 2 n = l o s s MSE(y, y*) = {\sum_{i=0}^n (y-y*)^2 \over n} = loss MSE(y,y)=ni=0n(yy)2=loss
    损失函数值越小,说明预测值和真实值越接近,w和b就越合适。
    如果人来一组一组试,那肯定是不行的。所以我们采用梯度下降算法来找到损失函数最小值。
    梯度:对函数求偏导的向量。梯度下降的方向就是函数减少的方向。
    w t + 1 = w t − a ∗ ∂ l o s s ∂ w b t + 1 = b t − a ∗ ∂ l o s s ∂ b w_{t+1} = w_t - a*\frac{\partial loss}{\partial w} \qquad b_{t+1} = b_t - a*\frac{\partial loss}{\partial b} wt+1=wtawlossbt+1=btabloss
    其中a为学习率,即梯度下降的步长,如果a太大,就可能错过最优值,如果a太小,则就需要更多步才能找到最优值。所以选择合适的学习率很关键。
    在这里插入图片描述

    参数优化

    通过反向传播来优化参数。
    反向传播:从后向前,逐层求损失函数对每层神经元参数的偏导数,迭代更新所有参数。
    比如
    l o s s = w 2 ∂ l o s s ∂ w = 2 w loss = w^2 \qquad \frac{\partial loss}{\partial w} = 2w loss=w2wloss=2w
    初始化w为5,学习率a为0.3,带入 w t + 1 = w t − a ∗ ∂ l o s s ∂ w w_{t+1} = w_t - a*\frac{\partial loss}{\partial w} wt+1=wtawloss

    序号 w t w_t wt w t + 1 w_{t+1} wt+1
    155-0.3*(2*5) = 2
    222-0.3*(2*2) = 0.8
    30.80.8-0.3*(2*0.8) = 0.32

    可以看到w会逐渐趋向于loss的最小值0。
    以上就是我们训练的全部关键点。

    代码

    数据集

    我们使用sklearn包提供的鸢尾花数据集。共150组数据。
    打乱保证数据的随机性,取前120个为训练集,后30个为测试集。

    # 导入数据,分别为输入特征和标签
    x_data = datasets.load_iris().data ## 存花萼、花瓣特征数据
    y_data = datasets.load_iris().target # 存对应种类
    # 随机打乱数据(因为原始数据是顺序的,顺序不打乱会影响准确率)
    # seed: 随机数种子,是一个整数,当设置之后,每次生成的随机数都一样(为方便教学,以保每位同学结果一致)
    np.random.seed(116)  # 使用相同的seed,保证输入特征和标签一一对应
    np.random.shuffle(x_data)
    np.random.seed(116)
    np.random.shuffle(y_data)
    tf.random.set_seed(116)
    # 将打乱后的数据集分割为训练集和测试集,训练集为前120行,测试集为后30行
    x_train = x_data[:-30]
    y_train = y_data[:-30]
    x_test = x_data[-30:]
    y_test = y_data[-30:]
    # 转换x的数据类型,否则后面矩阵相乘时会因数据类型不一致报错
    x_train = tf.cast(x_train, tf.float32)
    x_test = tf.cast(x_test, tf.float32)
    # from_tensor_slices函数使输入特征和标签值一一对应。(把数据集分批次,每个批次batch组数据)
    train_db = tf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(32)
    test_db = tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(32)
    

    参数

    # 生成神经网络的参数,4个输入特征故,输入层为4个输入节点;因为3分类,故输出层为3个神经元
    # 用tf.Variable()标记参数可训练
    w1 = tf.Variable(tf.random.truncated_normal([4, 3], stddev=0.1)) # 四行三列,方差为0.1
    b1 = tf.Variable(tf.random.truncated_normal([3], stddev=0.1)) # 一行三列,方差为0.1
    

    训练

    a = 0.1  # 学习率为0.1
    epoch = 500  # 循环500轮
    # 训练部分
    for epoch in range(epoch):  # 数据集级别的循环,每个epoch循环一次数据集
        for step, (x_train, y_train) in enumerate(train_db):  # batch级别的循环 ,每个step循环一个batch
            with tf.GradientTape() as tape:  # with结构记录梯度信息
                y = tf.matmul(x_train, w1) + b1  # 神经网络乘加运算
                y = tf.nn.softmax(y)  # 使输出y符合概率分布
                y_ = tf.one_hot(y_train, depth=3)  # 将标签值转换为独热码格式,方便计算loss
                loss = tf.reduce_mean(tf.square(y_ - y))  # 采用均方误差损失函数mse = mean(sum(y-y*)^2)
            # 计算loss对w, b的梯度
            grads = tape.gradient(loss, [w1, b1])
            # 实现梯度更新 w1 = w1 - lr * w1_grad    b = b - lr * b_grad
            w1.assign_sub(a * grads[0])  # 参数w1自更新
            b1.assign_sub(a * grads[1])  # 参数b自更新
    

    测试

    # 测试部分
    total_correct, total_number = 0, 0
    for x_test, y_test in test_db:
        # 前向传播求概率
        y = tf.matmul(x_test, w1) + b1
        y = tf.nn.softmax(y)
        predict = tf.argmax(y, axis=1)  # 返回y中最大值的索引,即预测的分类
        # 将predict转换为y_test的数据类型
        predict = tf.cast(predict, dtype=y_test.dtype)
        # 若分类正确,则correct=1,否则为0,将bool型的结果转换为int型
        correct = tf.cast(tf.equal(predict, y_test), dtype=tf.int32)
        # 将每个batch的correct数加起来
        correct = tf.reduce_sum(correct)
        # 将所有batch中的correct数加起来
        total_correct += int(correct)
        # total_number为测试的总样本数,也就是x_test的行数,shape[0]返回变量的行数
        total_number += x_test.shape[0]
    # 总的准确率等于total_correct/total_number
    acc = total_correct / total_number
    print("测试准确率 = %.2f %%" % (acc * 100.0))
    my_test = np.array([[5.9, 3.0, 5.1, 1.8]])
    print("输入 5.9  3.0  5.1  1.8")
    my_test = tf.convert_to_tensor(my_test)
    my_test = tf.cast(my_test, tf.float32)
    y = tf.matmul(my_test, w1) + b1
    y = tf.nn.softmax(y)
    species = {0: "狗尾鸢尾", 1: "杂色鸢尾", 2: "弗吉尼亚鸢尾"}
    predict = np.array(tf.argmax(y, axis=1))[0]  # 返回y中最大值的索引,即预测的分类
    print("该鸢尾花为:" + species.get(predict))
    

    结果:
    在这里插入图片描述

    结语

    以上就是全部内容,鸢尾花分类作为经典案例,应该重点掌握理解。有一起学习的伙伴可以把想法打在评论区,大家多多交流,我也会及时回复的!
    在这里插入图片描述

    展开全文
  • 神经网络(BP网)—鸢尾花分类问题华南师范大学计算机学院 – 神经网络鸢尾花分类BP网实现作者:杨劲松2013-4-24BPBPBBPP鸢尾花分类 网实现� 问题描述� 感知器网络� BPBP� 用 网实现鸢尾花分类问题2013-4-24 2/...
  • 神经网络实现鸢尾花分类及结果可视化,详见https://blog.csdn.net/qq_41573860/article/details/105870072
  • MATLAB BP_神经网络(鸢尾花数据分类自编代码)

    千次阅读 热门讨论 2019-08-13 13:54:08
    周志华《机器学习》中的BP神经网络有其变量的推导,很详细,我在以下给出几页推导过程。我在我的资源里上传了PDF版的,谁要的话可以下载。 以下是我的代码,仅供参考,大部分是矩阵直接运算 clear clc ...
  • BP神经网络算法(鸢尾花)附带相关训练集及测试集,Iris(鸢尾花)数据集分为训练集(Iris-train.txt)和测试集(Iris-test.txt),分别含75个样本,每个集合中每种花各有25个样本。
  • IDE:jupyter 数据集请查看:鸢尾花数据集 测试效果预览 成功率96.7% 代码已上传到码云 转载于:https://www.cnblogs.com/MC-Curry/p/9105908.html
  • 鸢尾花识别经典算法有很多,处于分类的一块的知识,对于分类的技术也有很多很多,通过BP神经网络也可以实现,在这里介绍一种更好的神经网络来实现鸢尾花的识别问题。
  • BP神经网络鸢尾花卉进行分类

    千次阅读 2018-03-04 20:32:29
    BP神经网络鸢尾花卉进行分类 摘要 Iris数据集是常用的分类实验数据集,由Fisher, 1936收集整理。Iris也称鸢尾花卉数据集,是一类多重变量分析的数据集。数据集包含150个数据集,分为3类,每类50个数据,每个...
  • IDE:jupyter 目前我知道的数据集来源有两个,一个是csv数据集文件另一个是从sklearn.datasets导入 1.1 csv格式的数据集(下载地址已上传到博客园----数据集.rar) ...3 df = pd.read_csv(fi...
  • BP神经网络鸢尾花

    千次阅读 2017-11-30 21:13:22
    BP神经网络基本原理: 误差逆传播(back propagation, BP)算法是一种计算单个权值变化引起网络性能变化的较为简单的方法。由于BP算法过程包含从输出节点开始,反向地向第一隐含层(即最接近输入层的隐含层)传播由总...
  • 添加神经网络层的函数 inputs -- 输入内容 in_size -- 输入尺寸 out_size -- 输出尺寸 activation_function --- 激励函数,可以不用输入 """ def add_layer(inputs,in_size,out_size,activation_function=None...
  • 文章目录 一、数据集和资料 二、鸢尾花分类 三、西瓜分类 四、一些笔记 Sklearn部分资料 pandas部分函数 一、数据集和资料 数据集,提取码:zmlc 大佬笔记,提取码:ytfa 二、鸢尾花分类 # -*- coding: utf-8 -* # ...
  • 鸢尾花分类——神经网络详解

    万次阅读 多人点赞 2016-04-26 19:16:34
    设计合理地神经网络通过对系统输入输出样本对进行自动学习,能够以任意精度逼近任何复杂的非线性映射。神经网络的这一优点能使其可以作为多维非线性函数的通用数学模型。该模型的表达式非解析的,输入输出数据之间的...
  • 本代码(MATLAB)可直接运行,对Iris鸢尾花数据分类,准确率96%左右,随机2/3数据训练,1/3数据测试。对于新手有帮助,多为矩阵运算。
  • 基于BP神经网络,测试集辛烷值含量预测结果对比亲测可用, 谢谢支持。
  • Java 实现 BP 神经网络完成 Iris 数据分类

    千次阅读 多人点赞 2017-06-07 12:33:26
    继了解了 BP 神经网络的原理后,笔者之前用 Java 实现三层的 BP 神经网络完成 Iris 鸢尾花数据集的分类预测,特此记录了实现过程,附源码。 1. Iris 鸢尾花数据集 Iris 也称鸢尾花卉数据集,是一类多重变量分析...
  • 本例采用BP神经网络,对鸢尾花数据做分类,实现比较高的分类准确率
  • 输出维度为3,分别是样本为三种鸢尾花的可能性 源代码 #include<stdio.h> #include<math.h> #include<time.h> #include<stdlib.h> #include<string.h> #define Data 113

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 384
精华内容 153
关键字:

bp神经网络鸢尾花分类