神经网络实现鸢尾花分类(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()

结果如下:
神经网络实现鸢尾花分类(Tensorflow2.0)_第1张图片
准确率如图所示:
神经网络实现鸢尾花分类(Tensorflow2.0)_第2张图片
损失函数值如下图所示:
神经网络实现鸢尾花分类(Tensorflow2.0)_第3张图片

你可能感兴趣的:(神经网络,分类,tensorflow,python,深度学习)