深度学习入门——基于TensorFlow的鸢尾花分类实现(TensorFlow_GPU版本安装、实现)
创始人
2024-02-08 14:17:20

基于TensorFlow的鸢尾花分类实现

  • 0 引言
  • 1 基本介绍和环境搭建
    • 1.1关于TensorFlow-GPU环境搭建
      • 第一步:安装Anaconda:
      • 第二步:安装GPU版本需要,明确显卡型号
      • 第三步:打开conda终端建立Tensorflow环境
      • 第四步:激活虚拟环境:
      • 第五步:安装ensorflow gpu版本:
      • 第六步:安装keras:pip install keras -i 软件源
      • 第七步:进入IDE(Pycharm或者VScode)切换环境为tensorflow-gpu调试
    • 1.2关于鸢尾花数据集介绍
  • 2 实现过程及分析
    • 2.1 数据集可视化化以及PCA降维:
    • 2.2 实验结果如下:
    • 2.3 分析结论
  • 附录(完整Python代码)

Author(作者): Nirvana Of Phoenixl
Proverbs for you(送给你的哦):There is no doubt that good things will always come, and when it comes late, it can be a surprise.

文章可以作为深度学习或者TensorFlow入门的了解学习。使用PyChram和Python实现,安装过程中最容易出现的问题是GPU版本的与显卡的问题。如果需要对应版本的TensorFlow,可以私信一下,呜呜我懒的放上来,可以发一份给你们!

0 引言

  本文主要是基于TensorFlow和Keras框架实现的鸢尾花分类,主要包含关于深度学习TensorFlow-GPU环境的搭建,以及实现框架的实现,其实验目的是实现鸢尾花分类,本质是通过简单的实践理解深度学习基本流程,加深对于代码实现的理解,通过对框架中的参数修改和完善理解调参对于框架识别精度的影响。最终目标是熟悉包括软件安装在内的深度学习环境的搭建、框架的构建、参数的调整做一个系统的学习和理解。

1 基本介绍和环境搭建

1.1关于TensorFlow-GPU环境搭建

  深度学习的核心概念就是以张量(矩阵)运算模拟神经网络的。TensorFlow主要的设计就是让矩阵运算达到最高性能,并且能够在各种不同的平台下运行。TensorFlow最初由谷歌开发,深度学习的发展是由前景的,谷歌希望建立一个开源的社区,强大TensorFlow使其更加完善,最后开源。TensorFlow架构主要由处理器(cpu/gpu/tpu)、平台(win/linux/android/ios/raspi)、tensoflow引擎、前端语言(python/c++)、高级api(keras/TF-learn/TF-slim/TF-layer)组成。如下图所示,TensorFlow架构组成。
TensorFlow架构组成
        图1 TensorFlow架构组成

  TensorFlow是比较低级深度学习API,所以在程序设计模型时必须自行设计:张量乘积、卷积等底层操作,好处是我们可以自行设计各种深度学习模型,但缺点是开发时需要编写更多的程序代码,并且需要花费很长的时间。所以网上的开发社区以TensorFlow为底层开发很多高级的深度学习API,例如Keras、TF-Learn等。这样可以使得开发者使用更简洁、更具可读性的程序代码就可以构建出各种复杂的深度学习模型。本文主要采用Keras,因为Keras功能最为完整。

  下面介绍如何在Windows上安装TensorFlow-GPU版本,因为其计算能力更强。因为之前本人已经安装过了TensorFlow-GPU版本,并搭建了环境,参考代码实现了一些经典数据集的学习训练,比如Keras MINIST、Keras-CIFAR-10等。下面将讲解如何安装和踩坑出现的问题。首先明确,对于GPU版本的TensorFlow主要通过NVIDIA提供的CUDA和cudnn存取GPU,CUDA是NVIDIA推出的整合技术,实质功能就是一种通过应用显卡处理数量较大的数据问题的架构,而cudnn是NVIDIA深度学习SDK的一部分,用于提供GPU深度学习库和加速深度学习的。

具体的安装步骤

第一步:安装Anaconda:

  指的是一个开源的Python发行版本,其包含了conda、Python等180多个科学包及其依赖项。(按步骤安装即可)

在这里插入图片描述
        图示上下分别为基本环境和新建的虚拟的GPU环境。

第二步:安装GPU版本需要,明确显卡型号

  (目前绝大多数时NVIDIA的显卡),去官方的网址下载CUDA和cudnn(注意这里需要明确版本对应查找适合是显卡型号的CUDA然后根据CUDA确定cudnn)实际在我测试过程当中可以低版本安装,但是不能高于当前适用的版本安装。(实际显卡提示安装CUAD11.0,cudnn 8.0但是我安装的是CUDA10.0和cudnn7.4)
在这里插入图片描述
      图示 为安装CUDA版本的版本,cudnn对应可以去配置文件里面查看。

第三步:打开conda终端建立Tensorflow环境

conda create –name tensorflow-gpu python=3.7

  建立名为tensorflow-gpu的python3.7的环境(或者在后面加上anaconda直接下载python所有包)如果需要单独安装缺少的包pip install 包名 -i 软件源

第四步:激活虚拟环境:

activate tensorflow-gpu
在这里插入图片描述

  创建的虚拟环境会在anaconda安装路径下envs中出现新建的虚拟环境。

在这里插入图片描述
启用python环境导入tensorflow,显示安装成功。

第五步:安装ensorflow gpu版本:

pip install tensorflow-gpu -i 软件源

中科大软件源https://pypi.mirrors.ustc.edu.cn/simple/,在安装tensorflow gpu版本的时候可以限制具体版本号即pip install tensorflow-gpu=1.14.0 -i 软件源

第六步:安装keras:pip install keras -i 软件源

第七步:进入IDE(Pycharm或者VScode)切换环境为tensorflow-gpu调试

在这里插入图片描述
图示为Tensorflow-gpu虚拟环境。

1.2关于鸢尾花数据集介绍

  Iris 鸢尾花数据集是一个经典数据集,在统计学习和机器学习领域都经常被用作示例。数据集内包含 3 类,共 150 条记录,每类各 50 个数据,每条记录都有 4 项特征:花萼长度Sepal.Length、花萼宽度Sepal.Width、花瓣长度Petal.Length、花瓣宽度Petal.Width,可以通过这4个特征预测鸢尾花卉属于狗尾草iris-setosa、杂色鸢尾花 iris-versicolour、弗吉尼亚鸢尾花 iris-virginica是属于什么类别,在数据集中也包括花萼花瓣长度对应的鸢尾花种类Species数据。
在这里插入图片描述
一般由两种格式.csv和.txt格式。

2 实现过程及分析

  本文主要通过Pycharm开发环境实现,基于tensorflow-gpu完成深度学习框架搭建。

2.1 数据集可视化化以及PCA降维:

在这里插入图片描述

2.2 实验结果如下:

(1)学习率0.1,循环次数为500,当次数为185时,测试准确率刚好为1
Epoch 185, loss: 0.05128058139234781,Test_acc: 1.0
在这里插入图片描述

(2)学习率为0.01,循环次数为500,当次数为500时,测试准确为0.66…
Epoch 499, loss: 0.08802829124033451,Test_acc: 0.6666666666666666
在这里插入图片描述

(3)学习率为0.5,循环次数为500,当次数为500时,精度为1.0
Epoch 499, loss: 0.024999298620969057,Test_acc: 1.0
在这里插入图片描述

(4)学习率为0.1,循环次数为3000,当次数为185时,精度为1
Epoch 185, loss: 0.05128058139234781,Test_acc: 1.0
在这里插入图片描述
(5)学习率为0.1,循环次数186,当次数为185时,精度为1
Epoch 185, loss: 0.05128058139234781,Test_acc: 1.0
在这里插入图片描述

2.3 分析结论

实际上我们可以对比发现,(1)(2)每轮循环次数一样学习率不同导致的情况不同,当学习率过小的时候会影响模型的收敛时间,直观来看明显使得过程缓慢;(1)(3)可以得到学习率过大,会导致梯度会在最小值附近可能来回震荡,严重的可能导致无法收敛。从一定程度上来看,(4)(5)学习率一定循环次数在达到一个固定的值后,再多次循环不影响精度值。
具体实现代码见附录。

附录(完整Python代码)


```python
#导入所需模块:
import tensorflow as tf                 # 导入模型框架
from sklearn import datasets            # 从sklearn文件包中导入含有的数据集
from matplotlib import pyplot as plt    # 从python中导入绘图库matplotlib
import numpy as np                      # 导入开源计算包numpy
from sklearn.decomposition import PCA
from mpl_toolkits.mplot3d import Axes3Dtf.enable_eager_execution(config=None,device_policy=None,execution_mode=None)     # 在即将到来的TensorFlow2.0中将对部分机制做出重大调整,其中之一就是将原有的静态图机制调整为动态图机制,这将使得TensorFlow更加灵活和易用,2.0版本之前,可以通过 tf.enable_eager_execution() 方法来启用动态图机制#导入数据可视化数据集
#————————————————————————————————
iris = datasets.load_iris()
X = iris.data[:, :2]  # 列切片索引:只取前两个特征.
y = iris.targetx_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5
y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5plt.figure(2, figsize=(8, 6))
plt.clf()绘制训练数据点
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Set1,edgecolor='k')
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')plt.xlim(x_min, x_max)
plt.ylim(y_min, y_max)
plt.xticks(())
plt.yticks(())为了对数据的各个维度之间的相互作用有一个更好地理解,
#绘制前三个 PCA dimensions。
fig = plt.figure(1, figsize=(8, 6))
ax = Axes3D(fig, elev=-150, azim=110)
X_reduced = PCA(n_components=3).fit_transform(iris.data)
ax.scatter(X_reduced[:, 0], X_reduced[:, 1], X_reduced[:, 2], c=y,cmap=plt.cm.Set1, edgecolor='k', s=40)
ax.set_title("First three PCA directions")
ax.set_xlabel("1st eigenvector")
ax.w_xaxis.set_ticklabels([])
ax.set_ylabel("2nd eigenvector")
ax.w_yaxis.set_ticklabels([])
ax.set_zlabel("3rd eigenvector")
ax.w_zaxis.set_ticklabels([])plt.show()
#————————————————————————————————————
#框架模型搭建以及实现
#导入数据:共计数据150组,分别为输入特征(x)和标签(y)
x_data = datasets.load_iris().data
y_data = datasets.load_iris().target输入数据预处理:随机打乱数据(因为原始数据是顺序的,顺序不打乱会影响准确率)
np.random.seed(116)  # 使用相同的seed,保证输入特征和标签一一对应(seed参数每一个数对应一个随机规则,数字一样随机规则一样产生的随机结果也一样)
np.random.shuffle(x_data)   # 重新排序返回一个随机序列,在原数组上进行,改变自身序列,无返回值
np.random.seed(116)
np.random.shuffle(y_data)
tf.compat.v1.random.set_random_seed(116)     # 版本原因导致的一些写法错误,tf.random.set_seed(116)修改内容#分割数据集:将打乱后的数据集(共有数据150行)分割为训练集和测试集,训练集为前120行,测试集为后30行
x_train = x_data[:-30]         # x_data[:-30]=x_data[0:120]
y_train = y_data[:-30]
x_test = x_data[-30:]          # x_data[-30:]=x_data[120:150]
y_test = y_data[-30:]#数据处理:转换x的数据类型,否则后面矩阵相乘时会因数据类型不一致报错
x_train = tf.cast(x_train, tf.float32)
x_test = tf.cast(x_test, tf.float32)#数据切片: from_tensor_slices((数据特征,标签)),函数使输入特征和标签值一一对应。(把数据集分批次,每个批次batch组数据)
#batch(数据集大小/batch大小),两个数字可能不是整除,会导致一个batch大小可能小于等于batch size
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个神经元
#用tf.Variable()标记参数可训练使用seed使每次生成的随机数相同(方便教学,使大家结果都一致,在现实使用时不写seed)
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记录在此列表中,为后续画loss曲线提供数据
test_acc = []  # 将每轮的acc记录在此列表中,为后续画acc曲线提供数据
epoch = 186 # 循环500轮
loss_all = 0  # 每轮分4个step,loss_all记录四个step生成的4个loss的和#训练部分for epoch in range(epoch):  # 数据集级别的循环,每个epoch循环一次数据集for step, (x_train, y_train) in enumerate(train_db):  # batch级别的循环 ,每个step循环一个batchwith tf.GradientTape() as tape:  # with结构记录梯度信息y = tf.matmul(x_train, w1) + b1  # 神经网络乘加运算y = tf.nn.softmax(y)  # 使输出y符合概率分布(此操作后与独热码同量级,可相减求loss)y_ = tf.one_hot(y_train, depth=3)  # 将标签值转换为独热码格式,方便计算loss和accuracyloss = tf.reduce_mean(tf.square(y_ - y))  # 采用均方误差损失函数mse = mean(sum(y-out)^2)loss_all += loss.numpy()  # 将每个step计算出的loss累加,为后续求loss平均值提供数据,这样计算的loss更准确# 计算loss对各个参数的梯度grads = tape.gradient(loss, [w1, b1])# 实现梯度更新 w1 = w1 - lr * w1_grad    b = b - lr * b_gradw1.assign_sub(lr * grads[0])  # 参数w1自更新b1.assign_sub(lr * grads[1])  # 参数b自更新# 每个epoch,打印loss信息print("Epoch {}, loss: {}".format(epoch, loss_all/4))train_loss_results.append(loss_all / 4)  # 将4个step的loss求平均记录在此变量中loss_all = 0  # loss_all归零,为记录下一个epoch的loss做准备# 测试部分# total_correct为预测对的样本个数, total_number为测试的总样本数,将这两个变量都初始化为0total_correct, total_number = 0, 0for x_test, y_test in test_db:# 使用更新后的参数进行预测y = tf.matmul(x_test, w1) + b1y = tf.nn.softmax(y)pred = tf.argmax(y, axis=1)  # 返回y中最大值的索引,即预测的分类# 将pred转换为y_test的数据类型pred = tf.cast(pred, dtype=y_test.dtype)# 若分类正确,则correct=1,否则为0,将bool型的结果转换为int型correct = tf.cast(tf.equal(pred, y_test), dtype=tf.int32)# 将每个batch的correct数加起来correct = tf.reduce_sum(correct)# 将所有batch中的correct数加起来total_correct += int(correct)# total_number为测试的总样本数,也就是x_test的行数,shape[0]返回变量的行数total_number += x_test.shape[0]# 总的准确率等于total_correct/total_numbertotal_number= int(total_number)               #错误的原因在,一个是numpy对象,一个是Dimension对象,无法相除,                                               #用int函数,将Dimension对象对象转换为intacc = total_correct / total_numbertest_# 导入所需模块:
import tensorflow as tf                 # 导入模型框架
from sklearn import datasets            # 从sklearn文件包中导入含有的数据集
from matplotlib import pyplot as plt    # 从python中导入绘图库matplotlib
import numpy as np                      # 导入开源计算包numpytf.enable_eager_execution(config=None,device_policy=None,execution_mode=None)     # 在即将到来的TensorFlow2.0中将对部分机制做出重大调整,其中之一就是将原有的静态图机制调整为动态图机制,## 这将使得TensorFlow更加灵活和易用,2.0版本之前,可以通过 tf.enable_eager_execution() 方法来启用动态图机制导入数据:共计数据150组,分别为输入特征(x)和标签(y)
x_data = datasets.load_iris().data
y_data = datasets.load_iris().target输入数据预处理:随机打乱数据(因为原始数据是顺序的,顺序不打乱会影响准确率)
np.random.seed(116)  # 使用相同的seed,保证输入特征和标签一一对应(seed参数每一个数对应一个随机规则,数字一样随机规则一样产生的随机结果也一样)
np.random.shuffle(x_data)   # 重新排序返回一个随机序列,在原数组上进行,改变自身序列,无返回值
np.random.seed(116)
np.random.shuffle(y_data)
tf.compat.v1.random.set_random_seed(116)     # 版本原因导致的一些写法错误,tf.random.set_seed(116)修改内容#分割数据集:将打乱后的数据集(共有数据150行)分割为训练集和测试集,训练集为前120行,测试集为后30行
x_train = x_data[:-30]         # x_data[:-30]=x_data[0:120]
y_train = y_data[:-30]
x_test = x_data[-30:]          # x_data[-30:]=x_data[120:150]
y_test = y_data[-30:]#数据处理:转换x的数据类型,否则后面矩阵相乘时会因数据类型不一致报错
x_train = tf.cast(x_train, tf.float32)
x_test = tf.cast(x_test, tf.float32)数据切片: from_tensor_slices((数据特征,标签)),函数使输入特征和标签值一一对应。(把数据集分批次,每个批次batch组数据)batch(数据集大小/batch大小),两个数字可能不是整除,会导致一个batch大小可能小于等于batch size
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个神经元
#用tf.Variable()标记参数可训练
#使用seed使每次生成的随机数相同(方便教学,使大家结果都一致,在现实使用时不写seed)
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记录在此列表中,为后续画loss曲线提供数据
test_acc = []  # 将每轮的acc记录在此列表中,为后续画acc曲线提供数据
epoch = 186 # 循环500轮
loss_all = 0  # 每轮分4个step,loss_all记录四个step生成的4个loss的和训练部分for epoch in range(epoch):  # 数据集级别的循环,每个epoch循环一次数据集for step, (x_train, y_train) in enumerate(train_db):  # batch级别的循环 ,每个step循环一个batchwith tf.GradientTape() as tape:  # with结构记录梯度信息y = tf.matmul(x_train, w1) + b1  # 神经网络乘加运算y = tf.nn.softmax(y)  # 使输出y符合概率分布(此操作后与独热码同量级,可相减求loss)y_ = tf.one_hot(y_train, depth=3)  # 将标签值转换为独热码格式,方便计算loss和accuracyloss = tf.reduce_mean(tf.square(y_ - y))  # 采用均方误差损失函数mse = mean(sum(y-out)^2)loss_all += loss.numpy()  # 将每个step计算出的loss累加,为后续求loss平均值提供数据,这样计算的loss更准确# 计算loss对各个参数的梯度grads = tape.gradient(loss, [w1, b1])# 实现梯度更新 w1 = w1 - lr * w1_grad    b = b - lr * b_gradw1.assign_sub(lr * grads[0])  # 参数w1自更新b1.assign_sub(lr * grads[1])  # 参数b自更新# 每个epoch,打印loss信息print("Epoch {}, loss: {}".format(epoch, loss_all/4))train_loss_results.append(loss_all / 4)  # 将4个step的loss求平均记录在此变量中loss_all = 0  # loss_all归零,为记录下一个epoch的loss做准备# 测试部分# total_correct为预测对的样本个数, total_number为测试的总样本数,将这两个变量都初始化为0total_correct, total_number = 0, 0for x_test, y_test in test_db:# 使用更新后的参数进行预测y = tf.matmul(x_test, w1) + b1y = tf.nn.softmax(y)pred = tf.argmax(y, axis=1)  # 返回y中最大值的索引,即预测的分类# 将pred转换为y_test的数据类型pred = tf.cast(pred, dtype=y_test.dtype)# 若分类正确,则correct=1,否则为0,将bool型的结果转换为int型correct = tf.cast(tf.equal(pred, y_test), dtype=tf.int32)# 将每个batch的correct数加起来correct = tf.reduce_sum(correct)# 将所有batch中的correct数加起来total_correct += int(correct)# total_number为测试的总样本数,也就是x_test的行数,shape[0]返回变量的行数total_number += x_test.shape[0]# 总的准确率等于total_correct/total_numbertotal_number= int(total_number)               #错误的原因在,一个是numpy对象,一个是Dimension对象,无法相除,                                               #用int函数,将Dimension对象对象转换为intacc = total_correct / total_numbertest_acc.append(acc)print("Test_acc:", acc)print("--------------------------")#绘制 loss 曲线
plt.title('Loss Function Curve')  # 图片标题
plt.xlabel('Epoch')  # x轴变量名称
plt.ylabel('Loss')  # y轴变量名称
plt.plot(train_loss_results, label="$Loss$")  # 逐点画出trian_loss_results值并连线,连线图标是Loss
plt.legend()  # 画出曲线图标
plt.show()  # 画出图像绘制 Accuracy 曲线
plt.title('Acc Curve')  # 图片标题
plt.xlabel('Epoch')  # x轴变量名称
plt.ylabel('Acc')  # y轴变量名称
plt.plot(test_acc, label="$Accuracy$")  # 逐点画出test_acc值并连线,连线图标是Accuracy
plt.legend()
plt.show()
#导入所需模块:
import tensorflow as tf                 # 导入模型框架
from sklearn import datasets            # 从sklearn文件包中导入含有的数据集
from matplotlib import pyplot as plt    # 从python中导入绘图库matplotlib
import numpy as np                      # 导入开源计算包numpytf.enable_eager_execution(config=None,device_policy=None,execution_mode=None)     # 在即将到来的TensorFlow2.0中将对部分机制做出重大调整,其中之一就是将原有的静态图机制调整为动态图机制,## 这将使得TensorFlow更加灵活和易用,2.0版本之前,可以通过 tf.enable_eager_execution() 方法来启用动态图机制#导入数据:共计数据150组,分别为输入特征(x)和标签(y)
x_data = datasets.load_iris().data
y_data = datasets.load_iris().target#输入数据预处理:随机打乱数据(因为原始数据是顺序的,顺序不打乱会影响准确率)
np.random.seed(116)  # 使用相同的seed,保证输入特征和标签一一对应(seed参数每一个数对应一个随机规则,数字一样随机规则一样产生的随机结果也一样)
np.random.shuffle(x_data)   # 重新排序返回一个随机序列,在原数组上进行,改变自身序列,无返回值
np.random.seed(116)
np.random.shuffle(y_data)
tf.compat.v1.random.set_random_seed(116)     # 版本原因导致的一些写法错误,tf.random.set_seed(116)修改内容#分割数据集:将打乱后的数据集(共有数据150行)分割为训练集和测试集,训练集为前120行,测试集为后30行
x_train = x_data[:-30]         # x_data[:-30]=x_data[0:120]
y_train = y_data[:-30]
x_test = x_data[-30:]          # x_data[-30:]=x_data[120:150]
y_test = y_data[-30:]数据处理:转换x的数据类型,否则后面矩阵相乘时会因数据类型不一致报错
x_train = tf.cast(x_train, tf.float32)
x_test = tf.cast(x_test, tf.float32)#数据切片: from_tensor_slices((数据特征,标签)),函数使输入特征和标签值一一对应。(把数据集分批次,每个批次batch组数据)
#batch(数据集大小/batch大小),两个数字可能不是整除,会导致一个batch大小可能小于等于batch size
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个神经元
#用tf.Variable()标记参数可训练
#使用seed使每次生成的随机数相同(方便教学,使大家结果都一致,在现实使用时不写seed)
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记录在此列表中,为后续画loss曲线提供数据
test_acc = []  # 将每轮的acc记录在此列表中,为后续画acc曲线提供数据
epoch = 186 # 循环500轮
loss_all = 0  # 每轮分4个step,loss_all记录四个step生成的4个loss的和#训练部分for epoch in range(epoch):  # 数据集级别的循环,每个epoch循环一次数据集for step, (x_train, y_train) in enumerate(train_db):  # batch级别的循环 ,每个step循环一个batchwith tf.GradientTape() as tape:  # with结构记录梯度信息y = tf.matmul(x_train, w1) + b1  # 神经网络乘加运算y = tf.nn.softmax(y)  # 使输出y符合概率分布(此操作后与独热码同量级,可相减求loss)y_ = tf.one_hot(y_train, depth=3)  # 将标签值转换为独热码格式,方便计算loss和accuracyloss = tf.reduce_mean(tf.square(y_ - y))  # 采用均方误差损失函数mse = mean(sum(y-out)^2)loss_all += loss.numpy()  # 将每个step计算出的loss累加,为后续求loss平均值提供数据,这样计算的loss更准确# 计算loss对各个参数的梯度grads = tape.gradient(loss, [w1, b1])# 实现梯度更新 w1 = w1 - lr * w1_grad    b = b - lr * b_gradw1.assign_sub(lr * grads[0])  # 参数w1自更新b1.assign_sub(lr * grads[1])  # 参数b自更新# 每个epoch,打印loss信息print("Epoch {}, loss: {}".format(epoch, loss_all/4))train_loss_results.append(loss_all / 4)  # 将4个step的loss求平均记录在此变量中loss_all = 0  # loss_all归零,为记录下一个epoch的loss做准备# 测试部分# total_correct为预测对的样本个数, total_number为测试的总样本数,将这两个变量都初始化为0total_correct, total_number = 0, 0for x_test, y_test in test_db:# 使用更新后的参数进行预测y = tf.matmul(x_test, w1) + b1y = tf.nn.softmax(y)pred = tf.argmax(y, axis=1)  # 返回y中最大值的索引,即预测的分类# 将pred转换为y_test的数据类型pred = tf.cast(pred, dtype=y_test.dtype)# 若分类正确,则correct=1,否则为0,将bool型的结果转换为int型correct = tf.cast(tf.equal(pred, y_test), dtype=tf.int32)# 将每个batch的correct数加起来correct = tf.reduce_sum(correct)# 将所有batch中的correct数加起来total_correct += int(correct)# total_number为测试的总样本数,也就是x_test的行数,shape[0]返回变量的行数total_number += x_test.shape[0]# 总的准确率等于total_correct/total_numbertotal_number= int(total_number)               #错误的原因在,一个是numpy对象,一个是Dimension对象,无法相除,                                               #用int函数,将Dimension对象对象转换为intacc = total_correct / total_numbertest_acc.append(acc)print("Test_acc:", acc)print("--------------------------")#绘制 loss 曲线
plt.title('Loss Function Curve')  # 图片标题
plt.xlabel('Epoch')  # x轴变量名称
plt.ylabel('Loss')  # y轴变量名称
plt.plot(train_loss_results, label="$Loss$")  # 逐点画出trian_loss_results值并连线,连线图标是Loss
plt.legend()  # 画出曲线图标
plt.show()  # 画出图像
#绘制 Accuracy 曲线
plt.title('Acc Curve')  # 图片标题
plt.xlabel('Epoch')  # x轴变量名称
plt.ylabel('Acc')  # y轴变量名称
plt.plot(test_acc, label="$Accuracy$")  # 逐点画出test_acc值并连线,连线图标是Accuracy
plt.legend()
plt.show()

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...