此代码是tesnorflow2搭建神经网络的一般流程,希望自己能够背过。


文章目录

  • 实验结果
  • 实验步骤
  • 一、准备数据
  • 二、搭建网络
  • 三、参数优化
  • 四、测试效果
  • 五、acc/loss可视化
  • 完整代码及注释


实验结果

鸢尾花数据集神经网络bp算法 bp神经网络鸢尾花分类_数据

鸢尾花数据集神经网络bp算法 bp神经网络鸢尾花分类_鸢尾花数据集神经网络bp算法_02

实验步骤

一、准备数据

1.读入鸢尾花数据集

鸢尾花数据集(Iris),共有数据150组,每组包括4个输入特征,1个标签类别。

鸢尾花总共分为三类,分别用数字0,1,2表示。

下载数据集,可从sklearn包datasets读入,语法为:

from sklearn.datasets import load_iris
import pandas as pd

# 1.读入数据集
x_data = load_iris().data       # 返回iris数据集所有的输入特征
y_data = load_iris().target     # 返回iris数据集所有标签

# 2.数据表格化,增加可读性
x_data = pd.DataFrame(x_data, columns=['花萼长度','花萼宽度','花瓣长度','花瓣宽度']) # 为每一列增加中文标签
pd.set_option('display.unicode.east_asian_width',True)  # 设置列名对齐
x_data['类别'] = y_data   # 新加一列,标签为类别
print(x_data)

2.数据集乱序

随机打乱数据(因为原始数据是顺序的,标签从0,1,2依次排列的数据,顺序不打乱会影响准确率)。

seed:随机数种子,是一个整数,当设置之后,每次生成的随机数都一样。

3.生成训练集和测试集

选择,训练集为前120行,测试集为后30行。

并转换x的数据类型,否则后面矩阵相乘时会因数据类型不一致报错

4.配成对,每次读入一小撮(batch)

配对使输入特征和标签值一一对应。最后,把数据集分批次,每个批次batch组数据。

二、搭建网络

定义神经网络中所有可训练的参数。

生成神经网络的参数,4个输入特征,所以输入层为4个输入节点;因为3分类,所以输出层为3个神经元。

用tf.Variable()标记参数可训练。

使用seed使得每次生成的随机数相同,可以保证多个人的神经网络参数一样。

三、参数优化

嵌套循环迭代,with结构更新参数,显示当前loss。

四、测试效果

在每一个Epoch中,计算当前参数前向传播后的准确率,显示acc。

五、acc/loss可视化

使用matplotlib函数画出正确率acc和losss的变化曲线。

完整代码及注释

import tensorflow as tf
import numpy as np
from matplotlib import pyplot as plt
from sklearn.datasets import load_iris      # 导入数据集iris

# 定义超参数
epoch = 500    # 循环遍历数据集500次
lr = 0.1       # 学习率
loss_all = 0   # 记录每一轮遍历的,4个step的loss和
test_acc = []  # 将每一轮的acc记录在此列表中,便与后续画图
train_loss_results = []   # 将每一轮的loss记录在此列表中,便与后续画图

######################### 一、准备数据 ##############################

# 1.读入数据集
x_data = load_iris().data       # 返回iris数据集所有的输入特征
y_data = load_iris().target     # 返回iris数据集所有标签

# 2.数据集乱序
np.random.seed(116)        # 使用相同的seed,使得特征标签打乱后,仍然一一对相应
np.random.shuffle(x_data)
np.random.seed(116)
np.random.shuffle(y_data)
tf.random.set_seed(116)

# 3.划分训练集和测试集
x_train = x_data[:-30]   # 取前120个数据作为训练集
y_train = y_data[:-30]   # -30表示倒数第30
x_test = x_data[-30:]    # 取后30个数据作为测试集
y_test = y_data[-30:]

x_train = tf.cast(x_train, tf.float32)  # 转换x的数据类型,避免矩阵相乘时报错
x_test = tf.cast(x_test, tf.float32)

# 4.配成对,每次喂入一小撮(batch)

train_db = tf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(32) #配对,每32对数据作为一小撮
test_db = tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(32)

##################### 二、神经网络中所有可训练参数 #################

# 定义4个输入单元,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))

###################### 三、嵌套循环,更新参数 #####################

for epoch in range(epoch):   # 在数据集上迭代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符合概率分布(此操作后,与独热码相减求loss)
            y_ = tf.one_hot(y_train,depth=3)     # 3种分类转化成独热码
            loss = tf.reduce_mean(tf.square(y_ - y))   # 损失函数均方差
            loss_all += loss.numpy()      # 将每个step的loss累加,方便求loss平均值
        grads = tape.gradient(loss,[w1,b1])
        w1.assign_sub(lr*grads[0])  # 参数自更新
        b1.assign_sub(lr*grads[1])
    print("Epoch:{},loss:{}".format(epoch,loss_all/4)) #120/32=4,求得每次step迭代的平均loss
    train_loss_results.append(loss_all / 4)     # 将4个step的loss求平均纪录在此变量中
    loss_all = 0  # loss_all归零,未记录下一个epoch做准备

    ####################### 测试,计算准确率acc ##########################
    total_correct, total_number = 0, 0
    for x_test, y_test in test_db:
        y = tf.matmul(x_test, w1) + b1   # y为预测结果
        y = tf.nn.softmax(y)             # 让y符合概率分布
        pred = tf.argmax(y, axis=1)      # 返回y中最大值的索引,即预测的分类
        pred = tf.cast(pred, dtype=y_test.dtype)  # 调整pred类型与标签一致
        correct = tf.cast(tf.equal(pred,y_test),tf.int32)   # 若分类正确,则correct=1,将bool型结果转换为int型
        correct = tf.reduce_sum(correct)     # 计算该batch中所有分类正确的点的个数
        total_correct += int(correct)        # 将所有batch中的correct数加起来
        total_number += x_test.shape[0]      # 计算当前测试的样本数
    acc = total_correct/total_number
    test_acc.append(acc)
    print("test_acc:", acc)
    print("-" * 50)  # 提示结束一轮数据集遍历

# 绘制 loss 曲线
plt.title('Loss Function Curve')   # 图片标题
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.plot(train_loss_results, label="$Loss$")
plt.legend()  #画出曲线图标
plt.show()

# 绘制 Accuracy 曲线
plt.title('Acc Curve')   # 图片标题
plt.xlabel('Epoch')
plt.ylabel('Acc')
plt.plot(test_acc, label="$Acc$")
plt.legend()  #画出曲线图标
plt.show()