From 8782ef5caea822f1a501a99cc7dc7c9d45e91c85 Mon Sep 17 00:00:00 2001 From: pzyxcrfui <2361520661@qq.com> Date: Thu, 27 May 2021 19:42:07 +0800 Subject: [PATCH] =?UTF-8?q?=E9=B8=A2=E5=B0=BE=E8=8A=B1=E8=AF=86=E5=88=AB?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- flower.py | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 flower.py diff --git a/flower.py b/flower.py new file mode 100644 index 0000000..e5f48b1 --- /dev/null +++ b/flower.py @@ -0,0 +1,160 @@ +import numpy as np # numpy当中axis=0表示按行操作,axis=1表示按列操作 +import matplotlib.pyplot as plt +import tensorflow as tf +import pandas as pd +from sklearn.neighbors import KNeighborsClassifier + +# 单层神经网络测试(鸢尾花数据集),下载数据集 +Train_aggdress = "http://download.tensorflow.org/data/iris_training.csv" +Train_path = tf.keras.utils.get_file(Train_aggdress.split('/')[-1], Train_aggdress) +Test_aggdress = "http://download.tensorflow.org/data/iris_test.csv" +Test_path = tf.keras.utils.get_file(Test_aggdress.split('/')[-1], Test_aggdress) +c_name = ['Sepal_Length', 'Sepal_Width', 'Petal_Length', 'Petal_Width', 'Species'] +# 花萼长,花萼宽,花瓣长,花瓣宽,品种(山鸢尾,变色鸢尾花,维吉尼亚鸢尾) + +#读取数据集,将数据转换成numpy数组 +df_iris = pd.read_csv(Train_path, names=c_name, header=0) +iris = np.array(df_iris) +figure = plt.figure('Iris Data', figsize=(12, 9)) +figure.suptitle("Anderson's Iris Data set\n(Blue-->Setosa | Red-->Versicolor | Green-->Virginica)", + fontsize=16) # 这里不能使用中文 + +for i in range(4): + for j in range(4): + plt.subplot(4, 4, 4 * i + (j + 1)) # 遍历每一个框图 + if i == j: + plt.text(0.3, 0.4, c_name[i], fontsize=11) # 将文字加上去 + else: + plt.scatter(iris[:, j], iris[:, i], c=iris[:, 4], cmap='brg') + if i == 0: + plt.title(c_name[j]) + if j == 0: + plt.ylabel(c_name[i]) +plt.show() + +#处理数据 +df_iris_train = pd.read_csv(Train_path, header=0) # 读取训练集数据 +df_iris_test = pd.read_csv(Test_path, header=0) # 读取测试集数据 +iris_train = np.array(df_iris_train) # 训练集数据转换为Numpy数组类型 +iris_test = np.array(df_iris_test) # 测试集数据转换为Numpy数组类型 +x_train = iris_train[:, 0:4] # x存放属性值 +y_train = iris_train[:, 4] +x_test = iris_test[:, 0:4] # y存放标签值 +y_test = iris_test[:, 4] +x_train_knn = x_train +y_train_knn = y_train + +x_train = x_train - np.mean(x_train, axis=0) # 属性值的标准化处理(求平均值) +x_test = x_test - np.mean(x_test, axis=0) + +X_train = tf.cast(x_train, tf.float32) #要转换成浮点型,否则计算的时候会报错 +Y_train = tf.one_hot(tf.constant(y_train, dtype=tf.int32), 3) # Y训练集独热编码(鸢尾花数据集的标签值为自然顺序码,应转换为独热编码) +X_test = tf.cast(x_test, tf.float32) +Y_test = tf.one_hot(tf.constant(y_test, dtype=tf.int32), 3) # Y测试集的独热编码 + +learn_rate = 0.55 # 设置超参和,学习率 +display_step = 1 # 显示测试间隔 +# 设置模型参数初始值 +np.random.seed(600) +W = tf.Variable(np.random.randn(4, 3), dtype=tf.float32) # 权值矩阵W为4*3的张量,取正态分布的随机值作为初始值输入为4输出为3种种类 +B = tf.Variable(np.zeros([3]), dtype=tf.float32) # 偏置值B为一维张量,初始化全零 + +# 设置训练模型 +acc_train = [] # 当前训练集 +acc_test = [] # 当前测试集 +loss_train = [] # 当前训练集 +loss_test = [] # 当前测试集 + +# 训练开始!!!!!! +print("训练开始!") +for i in range(1, 101): + with tf.GradientTape() as t: + # 定义梯度带,定义神经网络学习模型 + PRED_train = tf.nn.softmax(tf.matmul(X_train, W) + B) # Y = WX + B,训练集在神经网络上的输出 + LOSS_train = tf.reduce_mean( + tf.keras.losses.categorical_crossentropy(y_true=Y_train, y_pred=PRED_train)) # 训练集的交叉熵损失 + # 第一个参数是独热编码的标签值,第二个为第二个为softmax函数的输出值,结果为一维张量 + PRED_test = tf.nn.softmax(tf.matmul(X_test, W) + B) + LOSS_text = tf.reduce_mean(tf.keras.losses.categorical_crossentropy(y_true=Y_test, y_pred=PRED_test)) + + accuracy_train = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(PRED_train.numpy(), axis=1), y_train), tf.float32)) + accuracy_test = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(PRED_test.numpy(), axis=1), y_test), tf.float32)) + # 记录训练集和测试集的准确率 + acc_train.append(accuracy_train) + acc_test.append(accuracy_test) + loss_train.append(LOSS_train) + loss_test.append(LOSS_text) + + grads = t.gradient(LOSS_train, [W, B]) # 获得训练集损失函数对W和B的偏导数 + W.assign_sub(learn_rate * grads[0]) # 第一个值为损失函数对W的偏导数 + B.assign_sub(learn_rate * grads[1]) # 第二个值为损失函数对B的偏导数 + # 更新模型参数W和B + if i % display_step == 0: + print("训练次数: %i次, 训练集准确度:%f, 训练集损失值: %f, 测试集准确度: %f, 测试集损失值: %f" + % (i, accuracy_train, LOSS_train, accuracy_test, LOSS_text)) + +# PRED_train里面的每一个数表示属于不同种类的概率,数值越大则表示越不属于这个类别,数值越小则表示越属于这个类别 +print("训练结束~") +print() + +# print(tf.argmax(PRED_train.numpy(), axis=1)) # 预测模型训练过后的预测种类集合 +plt.figure(figsize=(6, 5)) +plt.subplot(111) +plt.plot(loss_train, color="blue", label="train") +plt.plot(loss_test, color="yellow", label="test") +plt.xlabel("Iteration") +plt.ylabel("LOSS") +plt.legend() +plt.figure(figsize=(6, 5)) +plt.subplot(111) +plt.plot(acc_train, color="red", label="test") +plt.plot(acc_test, color="green", label="test") +plt.xlabel("Iteration") #1个iteration等于使用batchsize个样本训练一次 +plt.ylabel("Accuracy") +plt.legend() +plt.show() + +# 以下为K最邻近法预测鸢尾花种类 +knn = KNeighborsClassifier(n_neighbors=1) # 获取knn对象 +knn.fit(x_train_knn, y_train_knn) # 利用之前的训练模型进行fit() 拟合功能,生成一个knn模型 +while True: + choose = input("请输入是否要进行预测~ 是(Y/y),否(N/n)\n") + if choose == "Y" or choose == "y": + user_input = [] + flag = False + print("请输入鸢尾花的属性值:") + print("请输入花萼长度:") + Sepal_Length = eval(input()) + user_input.append(Sepal_Length) + print("请输入花萼宽度:") + Sepal_Width = eval(input()) + user_input.append(Sepal_Width) + print("请输入花瓣长度:") + Petal_Length = eval(input()) + user_input.append(Petal_Length) + print("请输入花瓣宽度:") + Petal_Width = eval(input()) + user_input.append(Petal_Width) + for i in range(4): + if user_input[i] >= 8: + flag = True + break + + if flag: + print("输入数据范围有误!\n") + else: + x_new = np.array([user_input]) + # `print("x_new.shape:{}".format(x_new.shape)) + prediction = int(knn.predict(x_new)) # 预测 + if prediction == 0: + print("预测的种类为 %d : 山鸢尾" % prediction) + elif prediction == 1: + print("预测的种类为 %d : 变色鸢尾" % prediction) + else: + print("预测的种类为 %d : 维吉尼亚鸢尾" % prediction) + + elif choose == "N" or choose == "n": + print("程序退出!") + break + else: + print("输入有误~请重新输入!\n") \ No newline at end of file