当前位置: 首页 > news >正文

惠州网站建设培训卓越高职院建设网站

惠州网站建设培训,卓越高职院建设网站,已备案域名买卖,阿里巴巴国际站下载电脑版前言#xff1a; 学习跟随 如何原谅奋力过但无声的 tensorflow 笔记笔记。 本章主要讲解神经网络的优化过程#xff1a;神经网络的优化方法#xff0c;掌握学习率、激活函数、损失函数和正则化的使用#xff0c;用 Python 语言写出 SGD、Momentum、Adagrad、RMSProp、Ada…前言 学习跟随 如何原谅奋力过但无声的 tensorflow 笔记笔记。 本章主要讲解神经网络的优化过程神经网络的优化方法掌握学习率、激活函数、损失函数和正则化的使用用 Python 语言写出 SGD、Momentum、Adagrad、RMSProp、Adam 五种反向传播优化器。 文章目录一、预备知识--几个函数1.1、tf.where()1.2、np.random.RandomState.rand()1.3、np.vstack()1.4、np.mgrid[]、x.ravel()、np.c_[]二、神经网络NN复杂度2.1、学习率 lr三、激活函数3.1、Sigmoid 函数tf.nn.sigmoid(x)3.2、Tanh 函数tf.math.tanh(x)3.3、Relu 函数tf.nn.relu(x)3.4、 Leaky Rulu 函数tf.nn.leaky_relu(x)3.5 总结四、损失函数4.1、均方误差 MSEMean Squared Error4.2、自定义损失函数4.4、softmax 与交叉熵结合五、缓解过拟合5.1、欠拟合5.2、过拟合5.3、正则化缓解过拟合六、优化器6.1、SGD无 momentum6.2、SGDM含 momentum 的 SGD6.3、Adagrad6.4、RMSPropSGD 基础上增加二阶动量6.5 Adam同时结合 SGDM 一阶动量和 RMSProp 二阶动量并在此基础上增加了两个修正项6.5、对比实验 - 用神经网络实现鸢尾花分类7、总结7.1、优化器选择7.2、优化算法的常用 tricks一、预备知识–几个函数 1.1、tf.where() # 条件语句真返回 A条件语句假返回 B tf.where(条件语句真返回 A假返回 B)# demo import tensorflow as tfa tf.constant([1, 2, 3, 1, 1]) # 一维张量 a b tf.constant([0, 1, 3, 4, 5]) # 一维张量 b # 若 a b则返回 a 对应位置的元素否则返回 b 对应位置的元素 c tf.where(tf.greater(a, b), a, b) # 若ab返回a对应位置的元素否则返回b对应位置的元素 print(c, c)1.2、np.random.RandomState.rand() # 返回一个 [0,1) 之间的随机数 np.random.RandomState.rand(维度) # 维度为空返回标量# demo import numpy as np # seed 常数每次生成随机数相同 rdm np.random.RandomState(seed1) a rdm.rand() # 返回一个随机标量 b rdm.rand(2,3) # 返回维度为 2行3列 的随机数矩阵 print(a:,a) print(b:,b)1.3、np.vstack() # 将两个数组按垂直方向进行叠加也就是对数组进行 行方向 的扩展 np.vstack(数组1数组2)# demo import numpy as np a np.array([1,2,3]) b np.array([4,5,6]) c np.vstack((a,b)) # 注意要加括号因为该函数的输入参数只有 1 个 print(c:\n,c) # 数组 c 变成二维数组了1.4、np.mgrid[]、x.ravel()、np.c_[] # 以下三个函数一起使用可以生成网格坐标点 np.mgrid[] # 返回若干组维度相同的等差数组左闭右开区间[起始值结束值) np.mgrid[起始值结束值步长起始值结束值步长...] # 第一个“起始值:结束值:步长”决定了二维数组的行第二个“起始值:结束值:步长”决定了二维数组的列 x.ravel() # 将多维数组 x 变为一维数组“把 . 之前的变量拉直” np.c_[] # 使返回的间隔数值点配对 np.c_[数组1数组2...]# demo import numpy as np # 左闭右开区间[起始值结束值) x, y np.mgrid[1:3:1, 2:4:0.5] # 返回若干组长度相同的等差数组 grid np.c_[x.ravel(), y.ravel()] print(x:, x) print(y:, y) print(grid:\n, grid)二、神经网络NN复杂度 空间复杂度用神经网络层数和神经网络中待优化的参数个数表示。计算神经网络的层数时只统计具有运算能力的层输入层仅把数据传输过来没有运算故在统计神经网络层数时不算输入层输入层和输出层之间的所有层都叫隐藏层。层数 n 个隐藏层的层数 1 个输出层。每个具有计算机能力的神经元小球都要计算前一层的每一个输入特征乘以各自线上的权重再加上这个神经元的偏置项 b。有几条权重线就有几次乘加运算。 2.1、学习率 lr 指数衰减学习率根据当前迭代次数动态改变学习率的值一般写在 for 循环中。 import tensorflow as tfw tf.Variable(tf.constant(5, dtypetf.float32))epoch 40 LR_BASE 0.2 # 最初学习率 LR_DECAY 0.99 # 学习率衰减率 LR_STEP 1 # 喂入多少轮BATCH_SIZE后更新一次学习率for epoch in range(epoch): # for epoch 定义顶层循环表示对数据集循环epoch次此例数据集数据仅有1个w,初始化时候constant赋值为5循环100次迭代。lr LR_BASE * LR_DECAY ** (epoch / LR_STEP)with tf.GradientTape() as tape: # with结构到grads框起了梯度的计算过程。loss tf.square(w 1)grads tape.gradient(loss, w) # .gradient函数告知谁对谁求导w.assign_sub(lr * grads) # .assign_sub 对变量做自减 即w - lr*grads 即 w w - lr*gradsprint(After %s epoch,w is %f,loss is %f,lr is %f % (epoch, w.numpy(), loss, lr))三、激活函数 对于线性函数即使有多层神经元首尾相接构成深层神经网络依旧是线性组合模型的表达力不够。激活函数是用来加入非线性因素的因为线性模型的表达能力不够。引入非线性激活函数可使深层神经网络的表达能力更加强大。 3.1、Sigmoid 函数tf.nn.sigmoid(x) **sigmoid函数把输入值变换到0-1之间输出。**若输入值是非常大的负数那么输出值为 0若输入值是非常大的正数那么输出值就接近 1。相当于对输入进行了归一化。 近年来使用 sigmoid 作为激活函数的网络越来越少了因为深层神经网络更新参数时需要从输出层到输入层需要进行逐层链式求导而 sigmoid 的导数为 0 ~ 0.25 之间的小数链式求导需要多层导数连续相乘会出现多个 0 ~ 0.25 之间的小数连续相乘结果将趋于 0产生梯度消失使得参数无法更新。我们希望输入每层的神经网络特征是以 0 为均值的小数值但是过 sigmoid 函数之后的数据都是正数会使收敛变慢。另外 sigmoid 函数存在幂运算计算复杂度大训练时间长。 sigmoid 函数可应用在训练过程中 sigmoid 函数只能处理两个类多分类问题用 softmaxsigmoid 函数大多运用在神经网络中的最后一层使值在(0,1)之间 3.2、Tanh 函数tf.math.tanh(x) 该激活函数的输出值为零均值但依旧存在**梯度消失和幂运算复杂、训练时间长**的问题但比 sigmoid 函数的收敛速度快。 3.3、Relu 函数tf.nn.relu(x) 分段函数符合“激活函数具备近似恒等性”。 进入激活函数的输入特征为负数时激活函数输出为 0反向传播得到的梯度为 0导致参数无法更新造成神经元死亡。造成神经元死亡的根本原因是经过 relu 函数的负数过多导致可以 改进随机初始化避免过多的负数特征送入 relu 函数通过设置更小的学习率减少参数分布的巨大变化避免训练中产生过多负数特征进入 relu 函数 3.4、 Leaky Rulu 函数tf.nn.leaky_relu(x) 此激活函数是为了解决 rule 函数负区间为 0引起神经元死亡问题而设计的。Leaky ReLU负区间引入了一个固定的斜率α使其负区间不再恒等于 0。虽然 Leaky Relu 函数比 Relu 函数效果更好但是在实际使用过程中使用 relu 作为激活函数的网络更多。 3.5 总结 四、损失函数 损失函数 前向传播计算出来的预测值y与已知标准答案y_的差距。神经网络的优化目标是找到某套参数使得计算出来的结果y和已知标准答案y_无限接近也就是它们的差距 loss 值最小。 4.1、均方误差 MSEMean Squared Error 是回归问题最常用的损失函数。回归问题解决的是对具体数值的预测如房价预测、销量预测这些问题需要预测的不是一个事先定义好的类别而是一个任意实数 demo预测酸奶日销量y即产量影响日销量的因素为x1、x2销量y_。建模前应预先采集的数据有每日 x1、x2和销量 y即已知答案最佳情况产量销量 随机生成x1和x2拟造数据集y_x1x2添加-0.05~0.05的噪声。拟合可以预测销量的函数。 # 自制数据集构建一层神经网络预测酸奶日销量 import tensorflow as tf import numpy as npSEED 23455 # 随机种子保证每次生成的数据集一样实际应用中不写SEEDrdm np.random.RandomState(seedSEED) # 生成[0,1)之间的随机数 x rdm.rand(32, 2) # 生成32行2列的输入特征x包含了32组0-1之间的随机数x1和x2# .rand()生成[0,1)之间的随机数 # 生成标准答案y_ y_ [[x1 x2 (rdm.rand() / 10.0 - 0.05)] for (x1, x2) in x] # 生成噪声[0,1)/10[0,0.1); [0,0.1)-0.05[-0.05,0.05) x tf.cast(x, dtypetf.float32) # x转变数据类型w1 tf.Variable(tf.random.normal([2, 1], stddev1, seed1)) # 随机初始化参数w1初始化为两行一列epoch 15000 # 数据集迭代次数 lr 0.002 # 学习率for epoch in range(epoch):with tf.GradientTape() as tape:y tf.matmul(x, w1) # for循环中用with结构求前向传播计算结果yloss_mse tf.reduce_mean(tf.square(y_ - y)) # 求均方误差损失函数loss_msegrads tape.gradient(loss_mse, w1) # 损失函数对待训练参数w1求偏导w1.assign_sub(lr * grads) # 更新参数w1if epoch % 500 0: # 每迭代500轮数据打印当前参数w1print(After %d training steps,w1 is % (epoch))print(w1.numpy(), \n) print(Final w1 is: , w1.numpy())拟合结果为 y 1.000972 * X10.9977485 * X2与构造数据集的 y X1 X2 一致说明拟合正确。 使用均方误差作为损失函数默认认为销量预测的多了或者少了损失是一样的但真实情况并非如此。 4.2、自定义损失函数 根据具体任务和目的可设计不同的损失函数。损失函数的定义能极大影响模型预测效果好的损失函数设计对于模型训练能够起到良好的引导作用。 预测商品销量预测多了损失成本预测少了损失利润而利润往往 ≠ 成本这种情况下使用均方误差计算 loss无法使利益最大化。 demo预测酸奶销量假设酸奶成本COST1元酸奶利润PROFIT99元。预测少了损失利润99元预测多了损失成本1元显然预测少了损失大希望拟合的函数往多了预测 # 希望拟合的函数尽量往多了预测用自定义损失函数拟合出来的预测酸奶日销量会不会智能地往多了预测 # 以下代码相比上面仅改动了loss函数 import tensorflow as tf import numpy as npSEED 23455 COST 1 PROFIT 99rdm np.random.RandomState(SEED) x rdm.rand(32, 2) y_ [[x1 x2 (rdm.rand() / 10.0 - 0.05)] for (x1, x2) in x] # 生成噪声[0,1)/10[0,0.1); [0,0.1)-0.05[-0.05,0.05) x tf.cast(x, dtypetf.float32)w1 tf.Variable(tf.random.normal([2, 1], stddev1, seed1))epoch 10000 lr 0.002for epoch in range(epoch):with tf.GradientTape() as tape:y tf.matmul(x, w1)# 只改动了损失函数当预测的y多了时损失成本当预测的y少了时损失利润loss tf.reduce_sum(tf.where(tf.greater(y, y_), (y - y_) * COST, (y_ - y) * PROFIT))grads tape.gradient(loss, w1)w1.assign_sub(lr * grads)if epoch % 500 0:print(After %d training steps,w1 is % (epoch))print(w1.numpy(), \n) print(Final w1 is: , w1.numpy())# 自定义损失函数 # 酸奶成本1元酸奶利润99元 # 成本很低利润很高人们希望多预测些生成模型系数大于1往多了预测可见拟合出的参数均1偏大模型的确在尽量往多了预测![在这里插入图片描述](https://img-blog.csdnimg.cn/e3737f68dd1746c1b97c0b0ef87a9ea8.png) ## 4.3、交叉熵损失函数 CECross Entropy 交叉熵表示两个概率分布之间的距离。交叉熵越大两个概率分布越远交叉熵越小两个概率分布越近。通过判断交叉熵的值来判断哪个预测结果与标准答案更接近。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/f9e0cfe8b6ae4e019e3bd9c5dfa8df94.png) # 传入的 y_ 和 y 为列表或array tf.losses.categorical_crossentropy(y_,y)import tensorflow as tfloss_ce1 tf.losses.categorical_crossentropy([1, 0], [0.6, 0.4]) loss_ce2 tf.losses.categorical_crossentropy([1, 0], [0.8, 0.2]) print(loss_ce1:, loss_ce1) print(loss_ce2:, loss_ce2)# 交叉熵损失函数运行结果 loss_ce1: tf.Tensor(0.5108256, shape(), dtypefloat32) loss_ce2: tf.Tensor(0.22314353, shape(), dtypefloat32)4.4、softmax 与交叉熵结合 在执行分类问题时先使用 softmax 函数让输出结果符合概率分布再求 y 和 y_ 的交叉熵损失函数。 // 同时计算概率分布和交叉熵的函数 tf.nn.softmax_cross_entropy_with_logits(y_,y)# 等同于下面两句 # y_pro tf.nn.softmax(y) # tf.losses.categorical_crossentropy(y_,y_pro# softmax与交叉熵损失函数的结合 import tensorflow as tf import numpy as npy_ np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1], [1, 0, 0], [0, 1, 0]]) y np.array([[12, 3, 2], [3, 10, 1], [1, 2, 5], [4, 6.5, 1.2], [3, 6, 1]]) y_pro tf.nn.softmax(y) loss_ce1 tf.losses.categorical_crossentropy(y_,y_pro) loss_ce2 tf.nn.softmax_cross_entropy_with_logits(y_, y) # 一次完成概率分布和交叉熵函数结合print(分步计算的结果:\n, loss_ce1) print(结合计算的结果:\n, loss_ce2) # 输出的结果相同五、缓解过拟合 5.1、欠拟合 欠拟合是模型不能有效拟合数据集对现有数据集学习的不够彻底。 欠拟合的解决方法 增加输入特征项给网络更多维度的输入特征增加网络参数扩展网络规模增加网络深度提升模型表达力减少正则化参数 5.2、过拟合 过拟合是模型对当前数据拟合地太好了但对从未见过的新数据却难以做出正确的判断模型缺乏泛化力。 过拟合的解决方法 数据清洗减少数据集中的噪声使数据集更纯净增加训练集让模型见到更多的数据采用正则化增大正则化参数 5.3、正则化缓解过拟合 正则化在损失函数中引入模型复杂度指标利用给 W 加权值抑制训练数据集中的噪声弱化了训练数据中的噪声正则化通常只对参数 w 使用不对偏执量 b 使用。 dot.csv![在这里插入图片描述](https://img-blog.csdnimg.cn/bdc6dafc09884ff8bf60f5f91be702df.png) **未加入 L2 正则化的代码** # 导入所需模块 import tensorflow as tf from matplotlib import pyplot as plt import numpy as np import pandas as pd# 读入数据/标签 生成x_train y_train df pd.read_csv(dot.csv) x_data np.array(df[[x1, x2]]) y_data np.array(df[y_c])x_train np.vstack(x_data).reshape(-1, 2) y_train np.vstack(y_data).reshape(-1, 1)Y_c [[red if y else blue] for y in y_train]# 转换x的数据类型否则后面矩阵相乘时会因数据类型问题报错 x_train tf.cast(x_train, tf.float32) y_train tf.cast(y_train, tf.float32)# from_tensor_slices函数切分传入的张量的第一个维度生成相应的数据集使输入特征和标签值一一对应 train_db tf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(32)# 生成神经网络的参数输入层为2个神经元隐藏层为11个神经元1层隐藏层输出层为1个神经元 # 用tf.Variable()保证参数可训练 w1 tf.Variable(tf.random.normal([2, 11]), dtypetf.float32) b1 tf.Variable(tf.constant(0.01, shape[11]))w2 tf.Variable(tf.random.normal([11, 1]), dtypetf.float32) b2 tf.Variable(tf.constant(0.01, shape[1]))lr 0.005 # 学习率 epoch 800 # 循环轮数# 训练部分 for epoch in range(epoch):for step, (x_train, y_train) in enumerate(train_db):with tf.GradientTape() as tape: # 记录梯度信息h1 tf.matmul(x_train, w1) b1 # 记录神经网络乘加运算h1 tf.nn.relu(h1)y tf.matmul(h1, w2) b2# 采用均方误差损失函数mse mean(sum(y-out)^2)loss tf.reduce_mean(tf.square(y_train - y))# 计算loss对各个参数的梯度variables [w1, b1, w2, b2]grads tape.gradient(loss, variables)# 实现梯度更新# w1 w1 - lr * w1_grad tape.gradient是自动求导结果与[w1, b1, w2, b2] 索引为0123 w1.assign_sub(lr * grads[0])b1.assign_sub(lr * grads[1])w2.assign_sub(lr * grads[2])b2.assign_sub(lr * grads[3])# 每20个epoch打印loss信息if epoch % 20 0:print(epoch:, epoch, loss:, float(loss))# 预测部分 print(*******predict*******) # xx在-3到3之间以步长为0.01yy在-3到3之间以步长0.01,生成间隔数值点 xx, yy np.mgrid[-3:3:.1, -3:3:.1] # 将xx , yy拉直并合并配对为二维张量生成二维坐标点 grid np.c_[xx.ravel(), yy.ravel()] grid tf.cast(grid, tf.float32) # 将网格坐标点喂入神经网络进行预测probs为输出 probs [] for x_test in grid:# 使用训练好的参数进行预测h1 tf.matmul([x_test], w1) b1h1 tf.nn.relu(h1)y tf.matmul(h1, w2) b2 # y为预测结果probs.append(y)# 取第0列给x1取第1列给x2 x1 x_data[:, 0] x2 x_data[:, 1] # probs的shape调整成xx的样子 probs np.array(probs).reshape(xx.shape) plt.scatter(x1, x2, colornp.squeeze(Y_c)) # squeeze去掉纬度是1的纬度,相当于去掉[[red],[blue]],内层括号变为[red,blue] # 把坐标xx yy和对应的值probs放入contour函数给probs值为0.5的所有点上色 plt.show()后 显示的是红蓝点的分界线 plt.contour(xx, yy, probs, levels[.5]) plt.show()# 读入红蓝点画出分割线不包含正则化 # 不清楚的数据建议print出来查看 从下图中可以看出随着迭代轮数的增加loss 值逐渐减小。 轮廓不够平滑存在过拟合现象。加入 L2 正则化的代码 # 导入所需模块 import tensorflow as tf from matplotlib import pyplot as plt import numpy as np import pandas as pd# 读入数据/标签 生成x_train y_train df pd.read_csv(dot.csv) x_data np.array(df[[x1, x2]]) y_data np.array(df[y_c])x_train x_data y_train y_data.reshape(-1, 1)Y_c [[red if y else blue] for y in y_train]# 转换x的数据类型否则后面矩阵相乘时会因数据类型问题报错 x_train tf.cast(x_train, tf.float32) y_train tf.cast(y_train, tf.float32)# from_tensor_slices函数切分传入的张量的第一个维度生成相应的数据集使输入特征和标签值一一对应 train_db tf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(32)# 生成神经网络的参数输入层为4个神经元隐藏层为32个神经元2层隐藏层输出层为3个神经元 # 用tf.Variable()保证参数可训练 w1 tf.Variable(tf.random.normal([2, 11]), dtypetf.float32) b1 tf.Variable(tf.constant(0.01, shape[11]))w2 tf.Variable(tf.random.normal([11, 1]), dtypetf.float32) b2 tf.Variable(tf.constant(0.01, shape[1]))lr 0.005 # 学习率为 epoch 800 # 循环轮数# 训练部分 for epoch in range(epoch):for step, (x_train, y_train) in enumerate(train_db):with tf.GradientTape() as tape: # 记录梯度信息h1 tf.matmul(x_train, w1) b1 # 记录神经网络乘加运算h1 tf.nn.relu(h1)y tf.matmul(h1, w2) b2# 采用均方误差损失函数mse mean(sum(y-out)^2)loss_mse tf.reduce_mean(tf.square(y_train - y))# 添加l2正则化loss_regularization []# tf.nn.l2_loss(w)sum(w ** 2) / 2loss_regularization.append(tf.nn.l2_loss(w1))loss_regularization.append(tf.nn.l2_loss(w2))# 求和# 例xtf.constant(([1,1,1],[1,1,1]))# tf.reduce_sum(x)# 6loss_regularization tf.reduce_sum(loss_regularization)loss loss_mse 0.03 * loss_regularization # REGULARIZER 0.03# 计算loss对各个参数的梯度variables [w1, b1, w2, b2]grads tape.gradient(loss, variables)# 实现梯度更新# w1 w1 - lr * w1_gradw1.assign_sub(lr * grads[0])b1.assign_sub(lr * grads[1])w2.assign_sub(lr * grads[2])b2.assign_sub(lr * grads[3])# 每200个epoch打印loss信息if epoch % 20 0:print(epoch:, epoch, loss:, float(loss))# 预测部分 print(*******predict*******) # xx在-3到3之间以步长为0.01yy在-3到3之间以步长0.01,生成间隔数值点 xx, yy np.mgrid[-3:3:.1, -3:3:.1] # 将xx, yy拉直并合并配对为二维张量生成二维坐标点 grid np.c_[xx.ravel(), yy.ravel()] grid tf.cast(grid, tf.float32) # 将网格坐标点喂入神经网络进行预测probs为输出 probs [] for x_predict in grid:# 使用训练好的参数进行预测h1 tf.matmul([x_predict], w1) b1h1 tf.nn.relu(h1)y tf.matmul(h1, w2) b2 # y为预测结果probs.append(y)# 取第0列给x1取第1列给x2 x1 x_data[:, 0] x2 x_data[:, 1] # probs的shape调整成xx的样子 probs np.array(probs).reshape(xx.shape) plt.scatter(x1, x2, colornp.squeeze(Y_c)) # 把坐标xx yy和对应的值probs放入contour函数给probs值为0.5的所有点上色 plt.show()后 显示的是红蓝点的分界线 plt.contour(xx, yy, probs, levels[.5]) plt.show()# 读入红蓝点画出分割线包含正则化 # 不清楚的数据建议print出来查看从图片中可以看出加入 L2 正则化之后的曲线更平缓有效缓解了过拟合。六、优化器 参考 五种反向传播优化器总结及Python实现SGD、SGDM、Adagrad、RMSProp、Adam。 神经网络是基于连接的人工智能当网络结构固定后不同参数选取对模型的表达力影响很大更新模型参数的过程仿佛是在教一个孩子理解世界达到学龄的孩子脑神经元的结构、规模是相似的他们都具备了学习的潜力但是不同的引导方法会让孩子具备不同的能力达到不同的高度。 优化器就是引导神经网络更新参数的工具。优化算法可以分为一阶和二阶其中 一阶优化梯度算法及其变种。二阶优化一般是用二阶矩阵Hessian矩阵计算如牛顿法。由于需要计算 Hessian 阵及其逆矩阵计算量较大因此不常用。 定义待优化参数为 w总损失函数为 loss学习率为 lr。训练时为了提高效率数据集中的数据并不是一次喂入神经网络一组而是以 batch 为单位批量喂入神经网络每个 batch 通常包含 2^n 组数据。t 表示当前 batch 迭代的总次数。 更新参数分为四步完成 步骤3和4对于各算法都是一致的主要差别体现在步骤1和2上一阶动量与梯度相关的函数二阶动量与梯度平方相关的函数不同的优化器实质上只是定义了不同的一阶动量和二阶动量公式 6.1、SGD无 momentum 最常用的即是随机梯度下降Stochastic Gradient DecentSGD 与“反向传播参数更新公式”一致反向传播参数更新公式 # SGD对于单层网络 w1.assign_sub(learning_rate * grads[0]) # 参数 w1 的自更新 b1.assign_sub(learning_rate * grads[1]) # 参数 b 的自更新 6.2、SGDM含 momentum 的 SGD 在 SGD 的基础上引入了一阶动量。 动量法是一种使梯度向量向相关方向加速变化、抑制振荡、最终实现加速收敛的方法。为了抑制 SGD 的振荡SGDM 认为梯度下降的过程可以加入惯性下坡时若发现是陡坡那就利用惯性跑的更快一些。 SGDM 一阶动量是各个时刻梯度方向的指数移动平均值约等于最近 1/(1-β) 个时刻的梯度向量和的平均值。也就是说t时刻的下降方向不仅由当前点的梯度方向次要决定还由此前累积的下降方向主要决定。β的经验值为0.9意味着下降方向主要偏向此前累积的下降方向略微偏向当前时刻的下降方向。 每一时刻的一阶动量 m由上一时刻的一阶动量 m 和当前时刻的梯度用 with 结构直接算出损失函数对各个参数的偏导数决定。 # SGDM m_w, m_b 0, 0 beta 0.9m_w beta * m_w (1 - beta) * grads[0] m_b beta * m_b (1 - beta) * grads[1]# 自减操作实现参数 w 和 b 的自更新 w1.assign_sub(lr * m_w) b1.assign_sub(lr * m_b)6.3、Adagrad 在 SGD 基础上增加了二阶动量可以对模型中的每个参数分配自适应学习率。 上述 SGD 一直存在一个超参数即学习率可以理解为参数 w 沿着梯度反方向变化的步长 超参数hyper-parameter训练前需要手动选择的参数前缀 “hyper” 就是利用区别训练工程中可自动更新的参数。 SGD 对所有参数使用统一、固定的学习率一个自然的想法是对每个参数设置不同的学习率然而在大型网络中这是不切实际的。为了解决此问题Adagrad 被提出其做法是给学习率一个缩放比例从而达到自适应学习率的效果Ada Adaptive。其基本思想是对于频繁更新的参数不希望被单个样本影响太大给很小的学习率对于偶尔出现的参数希望能多得到一些信息给较大的学习率。 优点Adagrad 在稀疏数据场景下表现最好因为对于频繁出现的参数学习率衰减快对于稀疏的参数学习率衰减的更慢。缺点在实际很多情况下二阶动量呈单调递增累积从训练开始的梯度学习率会很快减至 0导致参数不再更新训练过程提前结束。 Adagrad 的一阶动量和 SGD 一样是当前的梯度二阶动量是从开始到现在梯度平方的累计和 # Adagrad v_w, v_b 0, 0 # 0 时刻w 和 b 的二阶动量初始值为 0v_w tf.square(grads[0]) v_b tf.square(grads[1])w1.assign_sub(lr * grads[0] / tf.sqrt(v_w)) b1.assign_sub(lr * grads[1] / tf.sqrt(v_b))6.4、RMSPropSGD 基础上增加二阶动量 全称为 Root Mean Square Prop 由于 Adagrad 的学习率衰减太过激进改变二阶动量的计算策略不累计全部梯度只关注过去某一窗口内的梯度。指数移动平均值大约是过去一段时间的平均值反映局部的参数信息用这个方法来计算二阶累积动量。 # RMSProp v_w, v_b 0, 0 # 0 时刻w 和 b 的二阶动量初始值均为 0 beta 0.9v_w beta * v_w (1 - beta) * tf.square(grads[0]) v_b beta * v_b (1 - beta) * tf.square(grads[1])w1.assign_sub(lr * grads[0] / tf.sqrt(v_w)) b1.assign_sub(lr * grads[1] / tf.sqrt(v_b))6.5 Adam同时结合 SGDM 一阶动量和 RMSProp 二阶动量并在此基础上增加了两个修正项 名称来源于 Adaptive Moment Estimation是前述方法的集大成者。 SGDM 在 SGD 基础上增加了一阶动量Adagrad、RMSProp 在 SGD 基础上增加了二阶动量把一阶动量和二阶动量结合起来再修正偏差把修正后的一阶动量和二阶动量带入参数更新公式实现参数自更新即为 Adam # Adam m_w, m_b 0, 0 # 0 时刻一阶动量为 0 v_w, v_b 0, 0 # 0 时刻二阶动量为 0 beta1, beta2 0.9, 0.999 global_step 0 # 训练的总batch数global_step 1 # 在嵌套循环内自加一计数m_w beta1 * m_w (1 - beta1) * grads[0] m_b beta1 * m_b (1 - beta1) * grads[1]v_w beta2 * v_w (1 - beta2) * tf.square(grads[0]) v_b beta2 * v_b (1 - beta2) * tf.square(grads[1])# 修正式 m_w_correction m_w / (1 - tf.pow(beta1, int(global_step))) # int(global_step)为训练开始到当前时刻所经历的总batch数 m_b_correction m_b / (1 - tf.pow(beta1, int(global_step)))v_w_correction v_w / (1 - tf.pow(beta2, int(global_step))) v_b_correction v_b / (1 - tf.pow(beta2, int(global_step)))# 把修正项代入参数更新公式实现参数自更新 w1.assign_sub(lr * m_w_correction / tf.sqrt(v_w_correction)) b1.assign_sub(lr * m_b_correction / tf.sqrt(v_b_correction)6.5、对比实验 - 用神经网络实现鸢尾花分类 利用鸾尾花数据集实现前向传播、反向传播、可视化曲线 1准备数据又包括4步——数据集读入、数据集乱序、生成 train 和 test、把数据配成 [输入特征,标签] 对2搭建网络定义神经网络中的所有可训练参数3更新参数优化可训练参数利用嵌套循环在with结构中求得损失函数loss对每个可训练参数的偏导数更改这些可训练参数4画曲线图为了查看效果程序中可以加入每遍历一次数据集显示当前准确率还可以画出准确率 acc 和损失函数 loss 的变化曲线图 对比五种优化器的处理速度引入时间模块以及 loss 曲线和 acc 曲线。 SGD # 利用鸢尾花数据集实现前向传播、反向传播可视化loss曲线# 本文件较 class1\p45_iris.py 仅添加四处时间记录 用 ##n## 标识 # 请将loss曲线、ACC曲线、total_time记录到 class2\优化器对比.docx 对比各优化器收敛情况# 导入所需模块 import tensorflow as tf from sklearn import datasets from matplotlib import pyplot as plt import numpy as np import time ##1### 导入数据分别为输入特征和标签 x_data datasets.load_iris().data y_data datasets.load_iris().target# 随机打乱数据因为原始数据是顺序的顺序不打乱会影响准确率 # seed: 随机数种子是一个整数当设置之后每次生成的随机数都一样为方便教学以保每位同学结果一致 np.random.seed(116) # 使用相同的seed保证输入特征和标签一一对应 np.random.shuffle(x_data) np.random.seed(116) np.random.shuffle(y_data) tf.random.set_seed(116)# 将打乱后的数据集分割为训练集和测试集训练集为前120行测试集为后30行 x_train x_data[:-30] y_train y_data[:-30] x_test x_data[-30:] 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组数据 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], stddev0.1, seed1)) b1 tf.Variable(tf.random.truncated_normal([3], stddev0.1, seed1))lr 0.1 # 学习率为0.1 train_loss_results [] # 将每轮的loss记录在此列表中为后续画loss曲线提供数据 test_acc [] # 将每轮的acc记录在此列表中为后续画acc曲线提供数据 epoch 500 # 循环500轮 loss_all 0 # 每轮分4个steploss_all记录四个step生成的4个loss的和# 训练部分 now_time time.time() ##2## 用时间戳记录训练的起始时间 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符合概率分布此操作后与独热码同量级可相减求lossy_ tf.one_hot(y_train, depth3) # 将标签值转换为独热码格式方便计算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, axis1) # 返回y中最大值的索引即预测的分类# 将pred转换为y_test的数据类型pred tf.cast(pred, dtypey_test.dtype)# 若分类正确则correct1否则为0将bool型的结果转换为int型correct tf.cast(tf.equal(pred, y_test), dtypetf.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_numberacc total_correct / total_numbertest_acc.append(acc)print(Test_acc:, acc)print(--------------------------) # 用时间戳记录训练结束时间 total_time time.time() - now_time ##3## print(total_time, total_time) ##4### 绘制 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()SGDM # 利用鸢尾花数据集实现前向传播、反向传播可视化loss曲线# 导入所需模块 import tensorflow as tf from sklearn import datasets from matplotlib import pyplot as plt import numpy as np import time ##1### 导入数据分别为输入特征和标签 x_data datasets.load_iris().data y_data datasets.load_iris().target# 随机打乱数据因为原始数据是顺序的顺序不打乱会影响准确率 # seed: 随机数种子是一个整数当设置之后每次生成的随机数都一样为方便教学以保每位同学结果一致 np.random.seed(116) # 使用相同的seed保证输入特征和标签一一对应 np.random.shuffle(x_data) np.random.seed(116) np.random.shuffle(y_data) tf.random.set_seed(116)# 将打乱后的数据集分割为训练集和测试集训练集为前120行测试集为后30行 x_train x_data[:-30] y_train y_data[:-30] x_test x_data[-30:] 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组数据 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], stddev0.1, seed1)) b1 tf.Variable(tf.random.truncated_normal([3], stddev0.1, seed1))lr 0.1 # 学习率为0.1 train_loss_results [] # 将每轮的loss记录在此列表中为后续画loss曲线提供数据 test_acc [] # 将每轮的acc记录在此列表中为后续画acc曲线提供数据 epoch 500 # 循环500轮 loss_all 0 # 每轮分4个steploss_all记录四个step生成的4个loss的和########################################################################## # 加入超参数 m_w, m_b 0, 0 beta 0.9 ########################################################################### 训练部分 now_time time.time() ##2## 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符合概率分布此操作后与独热码同量级可相减求lossy_ tf.one_hot(y_train, depth3) # 将标签值转换为独热码格式方便计算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])########################################################################### sgd-momentun# 更新优化器m_w beta * m_w (1 - beta) * grads[0]m_b beta * m_b (1 - beta) * grads[1]w1.assign_sub(lr * m_w)b1.assign_sub(lr * m_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, axis1) # 返回y中最大值的索引即预测的分类# 将pred转换为y_test的数据类型pred tf.cast(pred, dtypey_test.dtype)# 若分类正确则correct1否则为0将bool型的结果转换为int型correct tf.cast(tf.equal(pred, y_test), dtypetf.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_numberacc total_correct / total_numbertest_acc.append(acc)print(Test_acc:, acc)print(--------------------------) total_time time.time() - now_time ##3## print(total_time, total_time) ##4### 绘制 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()# 请将loss曲线、ACC曲线、total_time记录到 class2\优化器对比.docx 对比各优化器收敛情况Adagrad # 利用鸢尾花数据集实现前向传播、反向传播可视化loss曲线# 导入所需模块 import tensorflow as tf from sklearn import datasets from matplotlib import pyplot as plt import numpy as np import time ##1### 导入数据分别为输入特征和标签 x_data datasets.load_iris().data y_data datasets.load_iris().target# 随机打乱数据因为原始数据是顺序的顺序不打乱会影响准确率 # seed: 随机数种子是一个整数当设置之后每次生成的随机数都一样为方便教学以保每位同学结果一致 np.random.seed(116) # 使用相同的seed保证输入特征和标签一一对应 np.random.shuffle(x_data) np.random.seed(116) np.random.shuffle(y_data) tf.random.set_seed(116)# 将打乱后的数据集分割为训练集和测试集训练集为前120行测试集为后30行 x_train x_data[:-30] y_train y_data[:-30] x_test x_data[-30:] 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组数据 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], stddev0.1, seed1)) b1 tf.Variable(tf.random.truncated_normal([3], stddev0.1, seed1))lr 0.1 # 学习率为0.1 train_loss_results [] # 将每轮的loss记录在此列表中为后续画loss曲线提供数据 test_acc [] # 将每轮的acc记录在此列表中为后续画acc曲线提供数据 epoch 500 # 循环500轮 loss_all 0 # 每轮分4个steploss_all记录四个step生成的4个loss的和########################################################################## # 加入超参数 v_w, v_b 0, 0 ########################################################################### 训练部分 now_time time.time() ##2## 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符合概率分布此操作后与独热码同量级可相减求lossy_ tf.one_hot(y_train, depth3) # 将标签值转换为独热码格式方便计算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])########################################################################### adagrad# 改写优化器v_w tf.square(grads[0])v_b tf.square(grads[1])w1.assign_sub(lr * grads[0] / tf.sqrt(v_w))b1.assign_sub(lr * grads[1] / tf.sqrt(v_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, axis1) # 返回y中最大值的索引即预测的分类# 将pred转换为y_test的数据类型pred tf.cast(pred, dtypey_test.dtype)# 若分类正确则correct1否则为0将bool型的结果转换为int型correct tf.cast(tf.equal(pred, y_test), dtypetf.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_numberacc total_correct / total_numbertest_acc.append(acc)print(Test_acc:, acc)print(--------------------------) total_time time.time() - now_time ##3## print(total_time, total_time) ##4### 绘制 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()# 请将loss曲线、ACC曲线、total_time记录到 class2\优化器对比.docx 对比各优化器收敛情况RMSProp # 利用鸢尾花数据集实现前向传播、反向传播可视化loss曲线# 导入所需模块 import tensorflow as tf from sklearn import datasets from matplotlib import pyplot as plt import numpy as np import time ##1### 导入数据分别为输入特征和标签 x_data datasets.load_iris().data y_data datasets.load_iris().target# 随机打乱数据因为原始数据是顺序的顺序不打乱会影响准确率 # seed: 随机数种子是一个整数当设置之后每次生成的随机数都一样为方便教学以保每位同学结果一致 np.random.seed(116) # 使用相同的seed保证输入特征和标签一一对应 np.random.shuffle(x_data) np.random.seed(116) np.random.shuffle(y_data) tf.random.set_seed(116)# 将打乱后的数据集分割为训练集和测试集训练集为前120行测试集为后30行 x_train x_data[:-30] y_train y_data[:-30] x_test x_data[-30:] 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组数据 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], stddev0.1, seed1)) b1 tf.Variable(tf.random.truncated_normal([3], stddev0.1, seed1))lr 0.1 # 学习率为0.1 train_loss_results [] # 将每轮的loss记录在此列表中为后续画loss曲线提供数据 test_acc [] # 将每轮的acc记录在此列表中为后续画acc曲线提供数据 epoch 500 # 循环500轮 loss_all 0 # 每轮分4个steploss_all记录四个step生成的4个loss的和########################################################################## # 加入超参数 v_w, v_b 0, 0 beta 0.9 ########################################################################### 训练部分 now_time time.time() ##2## 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符合概率分布此操作后与独热码同量级可相减求lossy_ tf.one_hot(y_train, depth3) # 将标签值转换为独热码格式方便计算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])########################################################################### rmsprop 加入优化器v_w beta * v_w (1 - beta) * tf.square(grads[0])v_b beta * v_b (1 - beta) * tf.square(grads[1])w1.assign_sub(lr * grads[0] / tf.sqrt(v_w))b1.assign_sub(lr * grads[1] / tf.sqrt(v_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, axis1) # 返回y中最大值的索引即预测的分类# 将pred转换为y_test的数据类型pred tf.cast(pred, dtypey_test.dtype)# 若分类正确则correct1否则为0将bool型的结果转换为int型correct tf.cast(tf.equal(pred, y_test), dtypetf.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_numberacc total_correct / total_numbertest_acc.append(acc)print(Test_acc:, acc)print(--------------------------) total_time time.time() - now_time ##3## print(total_time, total_time) ##4### 绘制 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()# 请将loss曲线、ACC曲线、total_time记录到 class2\优化器对比.docx 对比各优化器收敛情况Adam # 利用鸢尾花数据集实现前向传播、反向传播可视化loss曲线# 导入所需模块 import tensorflow as tf from sklearn import datasets from matplotlib import pyplot as plt import numpy as np import time ##1### 导入数据分别为输入特征和标签 x_data datasets.load_iris().data y_data datasets.load_iris().target# 随机打乱数据因为原始数据是顺序的顺序不打乱会影响准确率 # seed: 随机数种子是一个整数当设置之后每次生成的随机数都一样为方便教学以保每位同学结果一致 np.random.seed(116) # 使用相同的seed保证输入特征和标签一一对应 np.random.shuffle(x_data) np.random.seed(116) np.random.shuffle(y_data) tf.random.set_seed(116)# 将打乱后的数据集分割为训练集和测试集训练集为前120行测试集为后30行 x_train x_data[:-30] y_train y_data[:-30] x_test x_data[-30:] 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组数据 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], stddev0.1, seed1)) b1 tf.Variable(tf.random.truncated_normal([3], stddev0.1, seed1))lr 0.1 # 学习率为0.1 train_loss_results [] # 将每轮的loss记录在此列表中为后续画loss曲线提供数据 test_acc [] # 将每轮的acc记录在此列表中为后续画acc曲线提供数据 epoch 500 # 循环500轮 loss_all 0 # 每轮分4个steploss_all记录四个step生成的4个loss的和########################################################################## # 加入超参数 m_w, m_b 0, 0 v_w, v_b 0, 0 beta1, beta2 0.9, 0.999 delta_w, delta_b 0, 0 global_step 0 ########################################################################### 训练部分 now_time time.time() ##2## for epoch in range(epoch): # 数据集级别的循环每个epoch循环一次数据集for step, (x_train, y_train) in enumerate(train_db): # batch级别的循环 每个step循环一个batch########################################################################## global_step 1########################################################################## with tf.GradientTape() as tape: # with结构记录梯度信息y tf.matmul(x_train, w1) b1 # 神经网络乘加运算y tf.nn.softmax(y) # 使输出y符合概率分布此操作后与独热码同量级可相减求lossy_ tf.one_hot(y_train, depth3) # 将标签值转换为独热码格式方便计算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])########################################################################### adam 改写优化器m_w beta1 * m_w (1 - beta1) * grads[0]m_b beta1 * m_b (1 - beta1) * grads[1]v_w beta2 * v_w (1 - beta2) * tf.square(grads[0])v_b beta2 * v_b (1 - beta2) * tf.square(grads[1])m_w_correction m_w / (1 - tf.pow(beta1, int(global_step)))m_b_correction m_b / (1 - tf.pow(beta1, int(global_step)))v_w_correction v_w / (1 - tf.pow(beta2, int(global_step)))v_b_correction v_b / (1 - tf.pow(beta2, int(global_step)))w1.assign_sub(lr * m_w_correction / tf.sqrt(v_w_correction))b1.assign_sub(lr * m_b_correction / tf.sqrt(v_b_correction)) ########################################################################### 每个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, axis1) # 返回y中最大值的索引即预测的分类# 将pred转换为y_test的数据类型pred tf.cast(pred, dtypey_test.dtype)# 若分类正确则correct1否则为0将bool型的结果转换为int型correct tf.cast(tf.equal(pred, y_test), dtypetf.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_numberacc total_correct / total_numbertest_acc.append(acc)print(Test_acc:, acc)print(--------------------------) total_time time.time() - now_time ##3## print(total_time, total_time) ##4### 绘制 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()# 请将loss曲线、ACC曲线、total_time记录到 class2\优化器对比.docx 对比各优化器收敛情况对比各优化器收敛情况lr 0.1epoch 500 batch 32 7、总结 7.1、优化器选择 7.2、优化算法的常用 tricks
http://www.dnsts.com.cn/news/41265.html

相关文章:

  • 一般做网站宽高多少做此广告的网站
  • 自己做彩票网站公司做网站要注意什么
  • wordpress建站 图片宏润建设集团网站
  • 成都建站模板创建一个网站流程图
  • 自己做传奇网站网站开发整体流程图
  • 公司建设网站的报告吉首做网站
  • 南充网站建设网站wordpress主题加载语言包
  • 做网站 搜索引擎模拟建筑2022手机版
  • 做网站的过程中有哪些问题seo策略是什么
  • 正规建网站公司个人网页制作模板下载
  • 百度餐饮网站建设图片1600px做网站
  • 旅游网站建设计划书邢台网站建设电话
  • 看一个网站是哪里做的麻六记网络营销方式
  • 中国十大品牌网站网站源代码分列怎么做
  • 建门户网站哪家最好免费注册qq
  • 简繁英3合1企业网站生成管理系统V1.6网站的开发建设要做什么的
  • 25亿企业网站管理系统嘉兴网站制作星讯网络科技
  • 为何上不了建设银行网站wordpress 分类目录 标签
  • 建设网站费用计入什么费用柯桥做网站哪家好
  • 做农产品网站需要做的准备手机在线制作图片
  • 建设银行互联网网站首页超级折扣2WordPress
  • 唐山门户网站建设谷德设计网站官网入口
  • win10记事本怎么做网站中升乙源建设公司网站
  • 网站框架指的是什么网页设计提升班有哪些
  • 假网站的域名招聘类网站该怎么做
  • 网站路径301重定向怎么做做视频网站要什么软件
  • 怎么做盗版网站网站访问统计报告模板
  • 我的个人网站怎么做软件开发专业名词
  • 网站建设一站式自助建站信息网
  • 上海美容论坛网站建设做炫光素材的网站