• 神经网络实现鸢尾花分类(Tensorflow2.0)


    1鸢尾花数据
    回顾鸢尾花数据集,其提供了150组鸢尾花数据,每组包括鸢尾花的花萼长、花萼宽、花瓣长、花瓣宽 4个输入特征,同时还给出了这一组特征对应的鸢尾花类别。类别包括狗尾鸢尾、杂色鸢尾、弗吉尼亚鸢尾三类, 分别用数字0、1、2表示。可以使用sklearn来导入其数据。
    2. 流程分析
    ① 准备数据。数据集读入;数据集乱序;生成训练集和测试集;配对。
    ② 搭建网络。定义神经网络中所有可训练的参数。
    ③ 参数优化。嵌套循环迭代,with结构更新参数,显示当前loss。
    ④ 测试效果。计算当前参数前向传播后的准确率,显示当前acc
    3. 代码实现(手撕神经网络)

    import tensorflow as tf
    import numpy as np
    import pandas as pd
    from sklearn.datasets import load_iris
    from sklearn.model_selection import train_test_split
    from matplotlib import pyplot as plt
    def demo16():
        """
        神经网络实现鸢尾花分类
        :return:
        """
        # 数据集读入
        data_iris = load_iris()
        # 获取鸢尾花数据集的特征矩阵
        x_data = data_iris.data
        # 获取鸢尾花数据集的目标值
        y_data = data_iris.target
        # 数据集乱序
        np.random.seed(116)  # 使用相同的seed,使特征/标签一一对应。
        np.random.shuffle(x_data)
        np.random.seed(116)
        np.random.shuffle(y_data)
        tf.random.set_seed(116)
        # 分出训练集和测试集
        # x_train, x_test, y_train, y_test = train_test_split(x_data,y_data,test_size=0.2,random_state=116)
        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)
        # 特征值和目标值配对  每次喂入一小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个神经元
        w1 = tf.Variable(tf.random.truncated_normal([4, 3], stddev=0.1, seed=1))
        b1 = tf.Variable(tf.random.truncated_normal([3], stddev=0.1, seed=1))
        lr = 0.1  # 学习率为0.1
        train_loss_results = []  # 将每轮的loss记录在此列表中,方便后续画图
        test_acc = []  # 将每轮的acc记录在此列表中,方便后续画图
        epoch = 500  # 循环500轮
        loss_all = 0  # 每轮分4个step,loss_all记录着4个step生成的4个loss的和
        # 训练部分
        for epoch in range(epoch):  # 数据集级别的循环
            for step, (x_train, y_train) in enumerate(train_db):  # batch级别的循环
                with tf.GradientTape() as tape:  # 记录梯度信息
                    y = tf.matmul(x_train, w1) + b1  # 神经网络的乘加运算
                    y = tf.nn.softmax(y)  # 使y符合概率分布
                    y_ = tf.one_hot(y_train, depth=3)
                    loss = tf.reduce_mean(tf.square(tf.subtract(y_, y)))  # 采用均方差损失函数
                    loss_all += loss.numpy()  # 将每一步计算的loss累加
                # 计算loss对各个参数的梯度
                grads = tape.gradient(loss, [w1, b1])
                # 实现梯度更新
                w1.assign_sub(lr * grads[0])
                b1.assign_sub(lr * grads[1])
            # 每个epoch,打印loss信息
            print("Epoch{},loss:{}".format(epoch, loss_all / 4))
            train_loss_results.append(loss_all / 4)  # 将4step的loss求的平均记录在此变量中
            loss_all = 0  # 归零
            # 测试部分
            total_corrent, total_number = 0, 0
            for x_test, y_test in test_db:  # 遍历batch
                # 使用更新后的参数进行预测
                y = tf.matmul(x_test, w1) + b1
                y = tf.nn.softmax(y)
                pred = tf.argmax(y, axis=1)  # 返回y中最大值的索引,即预测的分类
                # 将pred转换为y_test数据类型
                pred = tf.cast(pred, dtype=y_test.dtype)
                correct = tf.cast(tf.equal(pred, y_test), dtype=tf.int32)
                # 将每个batch的correct数加起来
                correct = tf.reduce_sum(correct)
                total_corrent += int(correct)
                total_number += x_test.shape[0]
            acc = total_corrent / total_number
            test_acc.append(acc)
            print("Test_acc", acc)
            print("-----------------------------")
        # 绘制loss曲线
        plt.title("loss function curve")
        plt.xlabel("epoch")
        plt.ylabel("loss")
        plt.plot(train_loss_results, label="$loss$")
        plt.legend()
        plt.show()
        # 绘制acc曲线
        plt.title("acc curve")
        plt.xlabel("epoch")
        plt.ylabel("acc")
        plt.plot(test_acc, label="$acc$")
        plt.legend()
        plt.show()
    
    
    if __name__ == '__main__':
        demo16()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98

    结果如下:
    在这里插入图片描述
    准确率如图所示:
    在这里插入图片描述
    损失函数值如下图所示:
    在这里插入图片描述

  • 相关阅读:
    集美大学第九届程序设计竞赛 L.序列 逆序对
    零代码编程:用ChatGPT自动合并多个Word文件
    数据可视化软件使用
    并发编程带来的安全性挑战之同步锁
    Java项目如何实现限流?
    双元科技过会:计划募资6.5亿元,比亚迪和蜂巢能源为主要客户
    Windows环境下下载安装Elasticsearch和Kibana
    系统架构师之软件工程
    FullCalendar日历插件说明文档
    表达式求值过程中会发生哪些隐藏的变化?求值顺序又由什么决定?——详解C表达式求值中的隐式类型转换,算术转换问题,以及操作符的属性
  • 原文地址:https://blog.csdn.net/lianggege88/article/details/126324914