使用没有隐含层的单层前馈型神经网络来实现对鸢尾花的分类
import pandas as pd import numpy as np import tensorflow as tf tf.enable_eager_execution() # 关键 import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = "SimHei" plt.rcParams['axes.unicode_minus'] = False # 目标:使用花萼长度、花萼宽度、花瓣长度、花瓣宽度四种属性将三种鸢尾花区分开 # 第一步:加载数据集 TRAIN_URL = "http://download.tensorflow.org/data/iris_training.csv" train_path = tf.keras.utils.get_file(TRAIN_URL.split('/')[-1], TRAIN_URL) df_iris_train = pd.read_csv(train_path, header=0) # 表示第一行数据作为列标题 TEST_URL = "http://download.tensorflow.org/data/iris_test.csv" test_path = tf.keras.utils.get_file(TEST_URL.split('/')[-1], TEST_URL) df_iris_test = pd.read_csv(test_path, header=0) # 第二步:数据处理 # 2.1 转化为NumPy数组 iris_train = np.array(df_iris_train) # 将二维数据表转换为 Numpy 数组, (120, 5), iris的训练集中有120条样本, iris_test = np.array(df_iris_test) # 将二维数据表转换为 Numpy 数组, (30, 5), iris的测试集中有30条样本, # 2.2 提取属性和标签 train_x = iris_train[:, 0:4] # 取出鸢尾花训练数据集中属性列 train_y = iris_train[:, 4] # 取出最后一列作为标签值, (120,) test_x = iris_test[:, 0:4] # 取出鸢尾花训练数据集中属性列 test_y = iris_test[:, 4] # 取出最后一列作为标签值, (30, ) # 2.3 数据归一化 # 可以看出这两个属性的尺寸相同,因此不需要进行归一化,可以直接对其进行中心化处理 # 对每个属性进行中心化, 也就是按列中心化, 所以使用下面这种方式 train_x = train_x - np.mean(train_x, axis=0) test_x = test_x - np.mean(test_x, axis=0) # 此时样本点的横坐标和纵坐标的均值都是0 # 鸢尾花数据集中的属性值和标签值都是64位的浮点数 print(train_x.dtype) # float64 print(train_y.dtype) # float64 # 2.4 生成多元模型的属性矩阵和标签列向量 X_train = tf.cast(train_x, tf.float32) # 创建张量函数tf.constant() Y_train = tf.one_hot(tf.constant(train_y, dtype=tf.int32), 3) # 将标签值转换为独热编码的形式 print(X_train.shape) # (120, 4) print(Y_train.shape) # (120, 3) X_test = tf.cast(test_x, tf.float32) # 创建张量函数tf.constant() Y_test = tf.one_hot(tf.constant(test_y, dtype=tf.int32), 3) # 将标签值转换为独热编码的形式 print(X_test.shape) # (30, 4) print(Y_test.shape) # (30, 3) # 第三步:设置超参数和显示间隔 learn_rate = 0.2 itar = 500 display_step = 100 # 第四步:设置模型参数初始值 np.random.seed(612) # 这里的W是一个(4, 3) 的矩阵 W = tf.Variable(np.random.randn(4, 3), dtype=tf.float32) # 这里的B是一个(3, ) 的一维张量, 初始化为0 B = tf.Variable(np.zeros([3]), dtype=tf.float32) # 第五步:训练模型 cross_train = [] # 列表cross_train用来保存每一次迭代的交叉熵损失 acc_train = [] # 用来存放训练集的分类准确率 cross_test = [] # 列表cross_test用来保存每一次迭代的交叉熵损失 acc_test = [] # 用来存放测试集的分类准确率 for i in range(0, itar + 1): with tf.GradientTape() as tape: # softmax 函数 # X - (120, 4), W - (4, 3) , 所以 Pred_train - (120, 3), 是每个样本的预测概率 Pred_train = tf.nn.softmax(tf.matmul(X_train, W) + B) # 计算训练集的平均交叉熵损失函数 Loss_train = tf.reduce_mean(tf.keras.losses.categorical_crossentropy(y_true=Y_train, y_pred=Pred_train)) Pred_test = tf.nn.softmax(tf.matmul(X_test, W) + B) # 计算测试集的平均交叉熵损失函数 Loss_test = tf.reduce_mean(tf.keras.losses.categorical_crossentropy(y_true=Y_test, y_pred=Pred_test)) # 计算准确率函数 -- 因为不需要对其进行求导运算, 因此也可以把这条语句写在 with 语句的外面 Accuarcy_train = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(Pred_train.numpy(), axis=1), train_y), tf.float32)) Accuarcy_test = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(Pred_test.numpy(), axis=1), test_y), tf.float32)) # 记录每一次迭代的交叉熵损失和准确率 cross_train.append(Loss_train) cross_test.append(Loss_test) acc_train.append(Accuarcy_train) acc_test.append(Accuarcy_test) # 对交叉熵损失函数 W 和 B 求偏导 grads = tape.gradient(Loss_train, [W, B]) # 函数assign_sub的作用是实现 Variable 变量的减法赋值 # 更新模型参数 W W.assign_sub(learn_rate * grads[0]) # grads[0] 是 dL_dw, 形状为(4,3) # 更新模型偏置项参数 B B.assign_sub(learn_rate * grads[1]) # grads[1] 是 dL_db, 形状为(3, ) if i % display_step == 0: print("i: %i, TrainLoss: %f, TrainAccuracy: %f, TestLoss: %f, TestAccuracy: %f" % (i, Loss_train, Accuarcy_train, Loss_test, Accuarcy_test)) """ i: 0, TrainLoss: 2.066978, TrainAccuracy: 0.333333, TestLoss: 1.880855, TestAccuracy: 0.266667 i: 100, TrainLoss: 0.223813, TrainAccuracy: 0.933333, TestLoss: 0.280151, TestAccuracy: 0.933333 i: 200, TrainLoss: 0.171492, TrainAccuracy: 0.950000, TestLoss: 0.200843, TestAccuracy: 0.966667 i: 300, TrainLoss: 0.144387, TrainAccuracy: 0.958333, TestLoss: 0.161774, TestAccuracy: 0.966667 i: 400, TrainLoss: 0.127350, TrainAccuracy: 0.966667, TestLoss: 0.137980, TestAccuracy: 0.966667 i: 500, TrainLoss: 0.115541, TrainAccuracy: 0.966667, TestLoss: 0.121931, TestAccuracy: 0.966667 """ # 第六步:数据可视化 plt.figure(figsize=(12, 5)) plt.subplot(121) plt.plot(acc_train, color="blue", label="train") plt.plot(acc_test, color="red", label="test") plt.title("迭代次数和损失值曲线图", fontsize=22) plt.xlabel('迭代次数', color='r', fontsize=16) plt.ylabel('损失值', color='r', fontsize=16) plt.legend() plt.subplot(122) plt.plot(cross_train, color="blue", label="train") plt.plot(cross_test, color="red", label="test") plt.title("迭代次数和准确率曲线图", fontsize=22) plt.xlabel('迭代次数', color='r', fontsize=16) plt.ylabel('准确率', color='r', fontsize=16) plt.legend() plt.show()
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141第一层是输入层到隐含层,相应的权值矩阵为 W1 ,隐含层中的阈值是 B1 ,隐含层的输出是:
假设增加的隐含层中有 16 个神经元(结点),那么 B1 的形状就是 (16,),因为输入层中有四个结点,因此, W1 的形状是 (4,16),第二层是隐含层到输出层,从隐含层到输出层的权值矩阵为 W2 ,输出层中的阈值是 B2 ,因为输出层中有三个节点,所以B2 的形状是(3,),W2 的形状是(16,3)。
import pandas as pd import numpy as np import tensorflow as tf tf.enable_eager_execution() # 关键 import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = "SimHei" plt.rcParams['axes.unicode_minus'] = False # 目标:使用花萼长度、花萼宽度、花瓣长度、花瓣宽度四种属性将三种鸢尾花区分开 # 第一步:加载数据集 TRAIN_URL = "http://download.tensorflow.org/data/iris_training.csv" train_path = tf.keras.utils.get_file(TRAIN_URL.split('/')[-1], TRAIN_URL) df_iris_train = pd.read_csv(train_path, header=0) # 表示第一行数据作为列标题 TEST_URL = "http://download.tensorflow.org/data/iris_test.csv" test_path = tf.keras.utils.get_file(TEST_URL.split('/')[-1], TEST_URL) df_iris_test = pd.read_csv(test_path, header=0) # 第二步:数据处理 # 2.1 转化为NumPy数组 iris_train = np.array(df_iris_train) # 将二维数据表转换为 Numpy 数组, (120, 5), iris的训练集中有120条样本, iris_test = np.array(df_iris_test) # 将二维数据表转换为 Numpy 数组, (30, 5), iris的测试集中有30条样本, # 2.2 提取属性和标签 train_x = iris_train[:, 0:4] # 取出鸢尾花训练数据集中属性列 train_y = iris_train[:, 4] # 取出最后一列作为标签值, (120,) test_x = iris_test[:, 0:4] # 取出鸢尾花训练数据集中属性列 test_y = iris_test[:, 4] # 取出最后一列作为标签值, (30, ) # 2.3 数据归一化 # 可以看出这两个属性的尺寸相同,因此不需要进行归一化,可以直接对其进行中心化处理 # 对每个属性进行中心化, 也就是按列中心化, 所以使用下面这种方式 train_x = train_x - np.mean(train_x, axis=0) test_x = test_x - np.mean(test_x, axis=0) # 此时样本点的横坐标和纵坐标的均值都是0 # 2.4 生成多元模型的属性矩阵和标签列向量 X_train = tf.cast(train_x, tf.float32) # 创建张量函数tf.constant() Y_train = tf.one_hot(tf.constant(train_y, dtype=tf.int32), 3) # 将标签值转换为独热编码的形式 print(X_train.shape) # (120, 4) print(Y_train.shape) # (120, 3) X_test = tf.cast(test_x, tf.float32) # 创建张量函数tf.constant() Y_test = tf.one_hot(tf.constant(test_y, dtype=tf.int32), 3) # 将标签值转换为独热编码的形式 print(X_test.shape) # (30, 4) print(Y_test.shape) # (30, 3) # 第三步:设置超参数和显示间隔 learn_rate = 0.5 itar = 50 display_step = 10 # 第四步:设置模型参数初始值 np.random.seed(612) # 隐含层 # 这里的 W1 是一个(4, 16) 的矩阵 W1 = tf.Variable(np.random.randn(4, 16), dtype=tf.float32) # 这里的 B1 是一个(16, ) 的一维张量, 初始化为 0 B1 = tf.Variable(np.zeros([16]), dtype=tf.float32) # 输出层 # 这里的 W2 是一个(16, 3) 的矩阵 W2 = tf.Variable(np.random.randn(16, 3), dtype=tf.float32) # 这里的 B2 是一个(3, ) 的一维张量, 初始化为 0 B2 = tf.Variable(np.zeros([3]), dtype=tf.float32) # 第五步:训练模型 cross_train = [] # 列表cross_train用来保存每一次迭代的交叉熵损失 acc_train = [] # 用来存放训练集的分类准确率 cross_test = [] # 列表cross_test用来保存每一次迭代的交叉熵损失 acc_test = [] # 用来存放测试集的分类准确率 for i in range(0, itar + 1): with tf.GradientTape() as tape: # 5.1:定义网络结构 # H = X*W1 + B1 Hidden_train = tf.nn.relu(tf.matmul(X_train, W1) + B1) # Y = H*W2 + B2 Pred_train = tf.nn.softmax(tf.matmul(Hidden_train, W2) + B2) # 计算训练集的平均交叉熵损失函数 Loss_train = tf.reduce_mean(tf.keras.losses.categorical_crossentropy(y_true=Y_train, y_pred=Pred_train)) # H = X*W1 + B1 Hidden_test = tf.nn.relu(tf.matmul(X_test, W1) + B1) # Y = H*W2 + B2 Pred_test = tf.nn.softmax(tf.matmul(Hidden_test, W2) + B2) # 计算测试集的平均交叉熵损失函数 Loss_test = tf.reduce_mean(tf.keras.losses.categorical_crossentropy(y_true=Y_test, y_pred=Pred_test)) # 计算准确率函数 -- 因为不需要对其进行求导运算, 因此也可以把这条语句写在 with 语句的外面 Accuarcy_train = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(Pred_train.numpy(), axis=1), train_y), tf.float32)) Accuarcy_test = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(Pred_test.numpy(), axis=1), test_y), tf.float32)) # 记录每一次迭代的交叉熵损失和准确率 cross_train.append(Loss_train) cross_test.append(Loss_test) acc_train.append(Accuarcy_train) acc_test.append(Accuarcy_test) # 对交叉熵损失函数 W 和 B 求偏导 grads = tape.gradient(Loss_train, [W1, B1, W2, B2]) # 函数assign_sub的作用是实现 Variable 变量的减法赋值 # 更新模型参数 W1 W1.assign_sub(learn_rate * grads[0]) # grads[0] 是 dL_dw1, 形状为(4, 16) # 更新模型偏置项参数 B1 B1.assign_sub(learn_rate * grads[1]) # grads[1] 是 dL_db1, 形状为(16, ) # 更新模型参数 W2 W2.assign_sub(learn_rate * grads[2]) # grads[0] 是 dL_dw2, 形状为(16, 3) # 更新模型偏置项参数 B2 B2.assign_sub(learn_rate * grads[3]) # grads[1] 是 dL_db2, 形状为(3, ) if i % display_step == 0: print("i: %i, TrainLoss: %f, TrainAccuracy: %f, TestLoss: %f, TestAccuracy: %f" % (i, Loss_train, Accuarcy_train, Loss_test, Accuarcy_test)) """ i: 0, TrainLoss: 2.205641, TrainAccuracy: 0.433333, TestLoss: 1.721138, TestAccuracy: 0.400000 i: 10, TrainLoss: 0.205314, TrainAccuracy: 0.941667, TestLoss: 0.249661, TestAccuracy: 0.966667 i: 20, TrainLoss: 0.149540, TrainAccuracy: 0.950000, TestLoss: 0.167103, TestAccuracy: 1.000000 i: 30, TrainLoss: 0.122346, TrainAccuracy: 0.958333, TestLoss: 0.124693, TestAccuracy: 1.000000 i: 40, TrainLoss: 0.105099, TrainAccuracy: 0.958333, TestLoss: 0.099869, TestAccuracy: 1.000000 i: 50, TrainLoss: 0.092934, TrainAccuracy: 0.958333, TestLoss: 0.084885, TestAccuracy: 1.000000 """ # 第六步:数据可视化 plt.figure(figsize=(12, 5)) plt.subplot(121) plt.plot(acc_train, color="blue", label="train") plt.plot(acc_test, color="red", label="test") plt.title("迭代次数和损失值曲线图", fontsize=22) plt.xlabel('迭代次数', color='r', fontsize=16) plt.ylabel('损失值', color='r', fontsize=16) plt.legend() plt.subplot(122) plt.plot(cross_train, color="blue", label="train") plt.plot(cross_test, color="red", label="test") plt.title("迭代次数和准确率曲线图", fontsize=22) plt.xlabel('迭代次数', color='r', fontsize=16) plt.ylabel('准确率', color='r', fontsize=16) plt.legend() plt.show()
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
对比单层神经网络和多层神经网络实现的对鸢尾花数据集的分类的效果。
相关知识
【实战】tensorflow 花卉识别
TensorFlow学习记录(八)
TensorFlow入门
TensorFlow机器学习实战指南——山鸢尾花分类
探索中文命名实体识别:BiLSTM+CRF模型实战指南
tensorflow识别花朵
深度学习入门——基于TensorFlow的鸢尾花分类实现(TensorFlow
AI应用开发实战
TensorFlow 训练自己的目标检测器
[tensorflow]图片新类别再训练
网址: TensorFlow实战 https://m.huajiangbk.com/newsview1354143.html
上一篇: 机器学习——鸢尾花简单神经网络实 |
下一篇: python库提供的鸢尾花数据集 |