深度学习入门——基于TensorFlow的鸢尾花分类实现(TensorFlow_GPU版本安装、实现)

news2024/11/26 8:57:08

基于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 Axes3D

tf.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.target

x_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5
y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5

plt.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循环一个batch
        with 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和accuracy
            loss = 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_grad
        w1.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为测试的总样本数,将这两个变量都初始化为0
    total_correct, total_number = 0, 0
    for x_test, y_test in test_db:
        # 使用更新后的参数进行预测
        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=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_number

    total_number= int(total_number)               #错误的原因在,一个是numpy对象,一个是Dimension对象,无法相除,                                               #用int函数,将Dimension对象对象转换为int
    acc = total_correct / total_number
    test_# 导入所需模块:
import tensorflow as tf                 # 导入模型框架
from sklearn import datasets            # 从sklearn文件包中导入含有的数据集
from matplotlib import pyplot as plt    # 从python中导入绘图库matplotlib
import numpy as np                      # 导入开源计算包numpy

tf.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循环一个batch
        with 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和accuracy
            loss = 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_grad
        w1.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为测试的总样本数,将这两个变量都初始化为0
    total_correct, total_number = 0, 0
    for x_test, y_test in test_db:
        # 使用更新后的参数进行预测
        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=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_number

    total_number= int(total_number)               #错误的原因在,一个是numpy对象,一个是Dimension对象,无法相除,                                               #用int函数,将Dimension对象对象转换为int
    acc = total_correct / total_number
    test_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                      # 导入开源计算包numpy

tf.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循环一个batch
        with 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和accuracy
            loss = 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_grad
        w1.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为测试的总样本数,将这两个变量都初始化为0
    total_correct, total_number = 0, 0
    for x_test, y_test in test_db:
        # 使用更新后的参数进行预测
        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=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_number

    total_number= int(total_number)               #错误的原因在,一个是numpy对象,一个是Dimension对象,无法相除,                                               #用int函数,将Dimension对象对象转换为int
    acc = total_correct / total_number
    test_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()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/27582.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

最简单例子解释python的transpose函数

二维数组的transpose就是矩阵的转置,这里直接略过。直接讨论三维情况。 首先,我们要弄清楚transpose的轴是什么意思? 0是代表了第一个轴,1是代表了第二个轴,2是代表了第三个轴,这里我们用x,y&…

基于PHP+MySQL米步童鞋商城网站的设计与实现

随时时代的发展,更多的宝妈们希望给宝宝买鞋子的时候能够通过更加简单方便的方式来进行,因为宝妈每天都要面对很多的时候,不能够经常到商场闲逛,所以她们急需一种通过互联网的方式来购买童鞋,所以我们通过PHP语言和MySQL数据开发了米步童鞋商城网站 米步童鞋商城网站的主要功能…

认识JUC

JUC 一、Java JUC 简介 在 Java 5.0 提供了 java.util.concurrent (简称 JUC )包,在此包中增加了在并发编程中很常用 的实用工具类,用于定义类似于线程的自定义子 系统,包括线程池、异步 IO 和轻量级任务框架。 提供…

基于阈值预分割的区域生长分割法研究-含Matlab代码

⭕⭕ 目 录 ⭕⭕✳️ 一、引言✳️ 二、区域生长原理✳️ 三、基于阈值预分割的区域生长算法✳️ 四、确定生长准则✳️ 五、实验结果✳️ 六、参考文献✳️ 七、Matlab代码获取✳️ 一、引言 在区域分割处理技术之中,又包含有区域生长分割技术以及区域分裂合并分割…

车辆工程的入门学习

知乎 汽车控制需要了解的 汽车的行驶阻力与驱动力 做好汽车控制需要学什么 车辆控制工程 off-road vehicle 越野车 各智能系统介绍 制动防抱死系统(anti-lock brake system, ABS) 电子稳定性控制(electronic stability control,…

SAP ADM100-1.1之SAP系统架构

一、SAP系统组成结构 SAP系统包括一个逻辑数据库、一个或多个实例。实例(也称为Central Instance中央实例)与数据库一起形成功能性的SAP系统。在每个SAP系统中都应该配置一个Central Instance中央实例。如果系统中仅有一个单实例那就存在“中央系统”,并且与它的数据库运行在…

上海亚商投顾:沪指冲高回落 中字头板块爆发领涨

上海亚商投顾前言:无惧大盘大跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。 市场情绪沪指今日冲高回落,3100点得而复失,黄白二线分化严重,权重走强题材弱势&#xff…

[附源码]java毕业设计校园跑腿系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

深度学习入门(四十六)计算机视觉——区域卷积神经网络(R-CNN)系列

深度学习入门(四十六)计算机视觉——区域卷积神经网络(R-CNN)系列前言计算机视觉——区域卷积神经网络(R-CNN)系列课件R-CNN兴趣区域(RoI)池化层Faster R-CNNFaster R-CNNMask R-CNN精度和速度比较总结教材…

Maven基础学习——tomcat插件配置(含web工程配置)

tomcat插件配置一、前言二、步骤1.登录网站后搜索TomcatMaven2.找到插件坐标3.选择插件版本4.将插件配置到web工程中5.测试插件三、Web工程配置1.在webapp下新建文件2.删除web.xml中多余代码3.pom.xml文件一、前言 在学习Maven时,肯定会遇到tomcat插件,…

ESP8266--Arduino开发(驱动OLED显示文字和图片)

文章目录一、0.96 IIC OLED介绍二、安装库文件2.1、库屏幕控制相关API2.2、库绘制相关API2.3、文本相关API2.4、图像相关API三、显示字母四、显示汉字五、显示图片一、0.96 IIC OLED介绍 OLED是一种利用多层有机薄膜结构产生电致发光的器件,它很容易制作&#xff0…

SPARKSQL3.0-Catalog源码剖析

SPARKSQL3.0-Catalog源码剖析 一、前言 阅读本节需要先掌握Analyzer阶段的相关知识 在Spark SQL 系统中,Catalog 主要用于各种函数资源信息和元数据信息 (数据库、数据表数据视图、数据分区等)的统一管理。 初次看这种解释还是比较模糊&a…

5周年,时过境迁,千变万化

2022年11月22日 小雪 长沙 阴小雨 下午 吃饭 遇雨 跑 不知不觉开始博客5年啦,注册账号有6年了。 ~~~那就浅写一首不像诗的诗聊表纪念吧~~~ 其实偶尔还是会迷茫, 但不必过分紧张, 每个时代都有每个时代化的特色的机遇与挑战, …

服务案例|AI算法在Oracle指标异常检查、故障预测之牛刀小试

LinkSLA与南京大学合作,将AI算法引入运维平台,将趋势性、周期性强的指标数据通过机器学习,实现异常检测、故障预测等功能。 下面分享一个通过AI算法,对Oracle数据库故障预测的案例。 在3月16日,MOC工程师接到某公司的…

中学数学教学参考杂志社中学数学教学参考编辑部2022年第27期目录

谈学论教 “平行四边形”章首课的教学思考 李斌; 1-3 高中数学课程中的函数教学 孔鑫辉; 3-4《中学数学教学参考》投稿:cn7kantougao163.com 对方程起始课教学的探究 梅琴; 5-7 注重师生互动,激活数学课堂 董启福; 8-9 例析高中数学体验教学法的…

RPC框架(一)——简易RPC

RPC介绍 RPC,Remote Procedure Call 即远程过程调用,远程过程调用其实对标的是本地过程调用 一个RPC框架要进行使用应该要具有如下的组件(功能) 从整体层次来看,一个RPC协议的框架应该具有三个层面: 服…

RSE2021/云检测:基于小波变换和连续多尺度空间注意的上下块深度网络云检测

RSE2021/云检测Deep network based on up and down blocks using wavelet transform and successive multi-scale spatial attention for cloud detection基于小波变换和连续多尺度空间注意的上下块深度网络云检测0.摘要1.概述2.方法3.背景4.实验数据5.我们的方法5.1.UD-NET5.1…

frp内网穿透

文章目录原理如果没有配置ssh,需要先配置ssh免密登录到pc内网穿透流程frp自启动frps自启动frpc自启动原理 1、在公网中转服务器上面搭建FRP服务器。同时,在内网服务器上面安装FRP客户端。 2、按照UP的FRP客户端配置文件进行说明。7000端口是FRP服务端开放…

tk跨境电商好做吗?有什么技巧吗?

最近tiktok大热,不少小伙伴都在蠢蠢欲动了,但他们都在担心tk跨境电商到底好不好做?有什么技巧没有?因为怕耗时耗力最后一场空。这里我们大家就来简单聊聊吧! tk跨境电商好做吗? 其实个人认为tk跨境电商现阶…

fork函数相关资源复制问题验证

前言 fork是什么?克隆当前的进程,然后创建一个子进程。本文分几个验证实例代码,主要是为解决验证一些小问题。 一 fork与文件描述符 fork之前打开一个文件的测试。 问题:fork之后,父进程关闭文件,子进程是…