反向传播算法代码实践

👋大家好,我是一名正在学习机器学习的小白,最近在写一些关于机器学习基础概念的文章。如果你也对机器学习感兴趣,或者想要了解一些基础知识,欢迎来关注我哦!🤗

梯度下降法

哔哩哔哩-梯度下降视频讲解

  • 定义代价函数
  • 选择起始点
  • 计算梯度
  • 按学习率前进

批量梯度下降

批量梯度下降法是最原始的形式,它是指在每一次迭代时使用所有样本来进行梯度的更新

优点:
(1)一次迭代是对所有样本进行计算,此时利用矩阵进行操作,实现了并行。
(2)由全数据集确定的方向能够更好地代表样本总体,从而更准确地朝向极值所在的方向。当目标函数为凸函数时,BGD一 定能够得到全局最优
缺点:
(1)当样本数目 m 很大时,每迭代一步都需要对所有样本计算,训练过程会很慢。

随机梯度下降

随机梯度下降法不同于批量梯度下降,随机梯度下降是每次迭代使用一个样本来对参数进行更新。使得训练速度加快

优点:
(1)由于不是在全部训练数据上的损失函数,而是在每轮迭代中,随机优化某一条训练数据上的损失函数,这样每一轮参数 的更新速度大大加快。
缺点:
(1)准确度下降。由于即使在目标函数为强凸函数的情况下,SGD仍旧无法做到线性收敛。
(2)可能会收敛到局部最优,由于单个样本并不能代表全体样本的趋势。
(3)不易于并行实现。

解释一下为什么SGD收敛速度比BGD要快:

答:这里我们假设有30W个样本,对于BGD而言,每次迭代需要计算30W个样本才能对参数进行一次更新,需要求得最小值可能需要多次迭代(假设这里是10);而对于SGD,每次更新参数只需要一个样本,因此若使用这30W个样本进行参数更新,则参数会被更新(迭代)30W次,而这期间,SGD就能保证能够收敛到一个合适的最小值上了。也就是说,在收敛时,BGD计算了10×30W10×30W 次,而SGD只计算了 1×30W1×30W 次。

小批量梯度下降

小批量梯度下降,是对批量梯度下降以及随机梯度下降的一个折中办法。其思想是:每次迭代 使用 batch_size个样本来对参数进行更新

优点:
(1)通过矩阵运算,每次在一个batch上优化神经网络参数并不会比单个数据慢太多。
(2)每次 使用一个batch可以大大减小收敛所需要的迭代次数,同时可以使收敛到的结果更加接近梯度下降的效果。(比如上 例中的30W,设置batch_size=100时,需要迭代3000次,远小于SGD的30W次)
(3)可实现并行化。
缺点:
(1)batch_size的不当选择可能会带来一些问题。

batcha_size的选择带来的影响:

(1)在合理地范围内,增大batch_size的好处:
    a. 内存利用率提高了,大矩阵乘法的并行化效率提高。
    b. 跑完一次 epoch(全数据集)所需的迭代次数减少,对于相同数据量的处理速度进一步加快。
    c. 在一定范围内,一般来说 Batch_Size 越大,其确定的下降方向越准,引起训练震荡越小。
(2)盲目增大batch_size的坏处:
    a. 内存利用率提高了,但是内存容量可能撑不住了。
    b. 跑完一次 epoch(全数据集)所需的迭代次数减少,要想达到相同的精度,其所花费的时间大大增加了,从而对参数 的修正也就显得更加缓慢。
    c. Batch_Size 增大到一定程度,其确定的下降方向已经基本不再变化。

1 、实验目的

理解多层神经网络的结构和原理,掌握反向传播算法对神经元的训练过程,了解反向传播公式。通过构建 BP 网络实例,熟悉前馈网络的原理及结构。

2、背景知识

反向传播算法

误差反向传播算法即 BP 算法,是一种适合于多层神经网络的学习算法。其建立在梯度下降方法的基础之上,主要由激励传播和权重更新两个环节组成,经过反复迭代更新、修正权值从而输出预期的结果。

BP 算法整体上可以分成正向传播和反向传播,原理如下:
正向传播过程:信息经过输入层到达隐含层,再经过多个隐含层的处理后到达输出层。

反向传播过程:比较输出结果和正确结果,将误差作为一个目标函数进行反向传播:每一层依次求对权值的偏导数,构成目标函数对权值的梯度,网络权重再依次完成更新调整。依此往复、直到输出达到目标值完成训练。该算法可以总结为:利用输出误差推算前一层的误差,再用推算误差算出更前一层的误差,直到计算出所有层的误差估计。

1986 年,Hinton 在论文《Learning Representations by Back-propagating Errors》中首次系统地描述了如何利用 BP 算法来训练神经网络。从此,BP 算法开始占据有监督神经网络算法的核心地位。它是迄今最成功的神经网络学习算法之一,现实任务中使用神经网络时,大多是在使用 BP 算法进行训练。为了说明 BP 算法的过程,本实验使用一个公司招聘的例子:

假设有一个公司,其人员招聘由 5个人组成的人事管理部门负责,如下图所示:其中张三、李四等人是应聘者,他们向该部门投递简历,简历包括两类数据:学习成绩和社会实践得分,人事部门有三个层级,一科长根据应聘者的学习成绩和实践得分评估其智商,二科长根据同样的资料评估其情商;一处长根据两个科长提供的智商、情商评分,评估应聘者的工作能力,二处长评估工作态度;最后由总裁汇总两位处长的意见,得出最终结论,即是否招收该应聘者。

该模型等价于一个形状为(2,2,2,1)的前馈神经网络,输入层、隐藏层 1、隐藏层 2、输出层各自包含 2、2、2、1 个节点,如下图所示。

image-20230111233719973

image-20230111233741206

3、示例代码

import numpy as np
import matplotlib.pyplot as plt

# 输入数据1行2列,这里只有张三的数据
X = np.array([[1, 0.1]])
# X = np.array([[1,0.1],
#               [0.1,1],
#               [0.1,0.1],
#               [1,1]])
# 标签,也叫真值,1行1列,张三的真值:一定录用
T = np.array([[1]])
# T = np.array([[1],
#               [0],
#               [0],
#               [1]])

# 定义一个2隐层的神经网络:2-2-2-1
# 输入层2个神经元,隐藏1层2个神经元,隐藏2层2个神经元,输出层1个神经元

# 输入层到隐藏层1的权值初始化,2行2列
W1 = np.array([[0.8, 0.2],
               [0.2, 0.8]])
# 隐藏层1到隐藏层2的权值初始化,2行2列
W2 = np.array([[0.5, 0.0],
               [0.5, 1.0]])
# 隐藏层2到输出层的权值初始化,2行1列
W3 = np.array([[0.5],
               [0.5]])

# 初始化偏置值
# 隐藏层1的2个神经元偏置
b1 = np.array([[-1, 0.3]])
# 隐藏层2的2个神经元偏置
b2 = np.array([[0.1, -0.1]])
# 输出层的1个神经元偏置
b3 = np.array([[-0.6]])
# 学习率设置
lr = 0.1
# 定义训练周期数10000
epochs = 10000
# 每训练1000次计算一次loss值  # 定义测试周期数
report = 1000
# 将所有样本分组,每组大小为
batch_size = 1


# 定义sigmoid函数
def sigmoid(x):
    return 1 / (1 + np.exp(-x))


# 定义sigmoid函数导数
def dsigmoid(x):
    return x * (1 - x)


# 更新权值和偏置值
def update():
    global batch_X, batch_T, W1, W2, W3, lr, b1, b2, b3

    # 隐藏层1输出
    Z1 = np.dot(batch_X, W1) + b1
    A1 = sigmoid(Z1)

    # 隐藏层2输出
    Z2 = (np.dot(A1, W2) + b2)
    A2 = sigmoid(Z2)

    # 输出层输出
    Z3 = (np.dot(A2, W3) + b3)
    A3 = sigmoid(Z3)

    # 求输出层的误差
    delta_A3 = (batch_T - A3)
    delta_Z3 = delta_A3 * dsigmoid(A3)

    # 利用输出层的误差,求出三个偏导(即隐藏层2到输出层的权值改变)    # 由于一次计算了多个样本,所以需要求平均
    delta_W3 = A2.T.dot(delta_Z3) / batch_X.shape[0]
    delta_B3 = np.sum(delta_Z3, axis=0) / batch_X.shape[0]

    # 求隐藏层2的误差
    delta_A2 = delta_Z3.dot(W3.T)
    delta_Z2 = delta_A2 * dsigmoid(A2)

    # 利用隐藏层2的误差,求出三个偏导(即隐藏层1到隐藏层2的权值改变)    # 由于一次计算了多个样本,所以需要求平均
    delta_W2 = A1.T.dot(delta_Z2) / batch_X.shape[0]
    delta_B2 = np.sum(delta_Z2, axis=0) / batch_X.shape[0]

    # 求隐藏层1的误差
    delta_A1 = delta_Z2.dot(W2.T)
    delta_Z1 = delta_A1 * dsigmoid(A1)

    # 利用隐藏层1的误差,求出三个偏导(即输入层到隐藏层1的权值改变)    # 由于一次计算了多个样本,所以需要求平均
    delta_W1 = batch_X.T.dot(delta_Z1) / batch_X.shape[0]
    delta_B1 = np.sum(delta_Z1, axis=0) / batch_X.shape[0]

    # 更新权值
    W3 = W3 + lr * delta_W3
    W2 = W2 + lr * delta_W2
    W1 = W1 + lr * delta_W1

    # 改变偏置值
    b3 = b3 + lr * delta_B3
    b2 = b2 + lr * delta_B2
    b1 = b1 + lr * delta_B1


# 定义空list用于保存loss
loss = []
batch_X = []
batch_T = []
max_batch = X.shape[0] // batch_size
# 训练模型
for idx_epoch in range(epochs):

    for idx_batch in range(max_batch):
        # 更新权值
        batch_X = X[idx_batch * batch_size:(idx_batch + 1) * batch_size, :]
        batch_T = T[idx_batch * batch_size:(idx_batch + 1) * batch_size, :]
        update()
    # 每训练5000次计算一次loss值
    if idx_epoch % report == 0:
        # 隐藏层1输出
        A1 = sigmoid(np.dot(X, W1) + b1)
        # 隐藏层2输出
        A2 = sigmoid(np.dot(A1, W2) + b2)
        # 输出层输出
        A3 = sigmoid(np.dot(A2, W3) + b3)
        # 计算loss值
        print('A3:', A3)
        print('epochs:', idx_epoch, 'loss:', np.mean(np.square(T - A3) / 2))
        # 保存loss值
        loss.append(np.mean(np.square(T - A3) / 2))

# 画图训练周期数与loss的关系图
plt.plot(range(0, epochs, report), loss)
plt.xlabel('epochs')
plt.ylabel('loss')
plt.show()

# 隐藏层1输出
A1 = sigmoid(np.dot(X, W1) + b1)
# 隐藏层2输出
A2 = sigmoid(np.dot(A1, W2) + b2)
# 输出层输出
A3 = sigmoid(np.dot(A2, W3) + b3)
print('output:')
print(A3)


# 因为最终的分类只有0和1,所以我们可以把
# 大于等于0.5的值归为1类,小于0.5的值归为0类
def predict(x):
    if x >= 0.5:
        return 1
    else:
        return 0


# map会根据提供的函数对指定序列做映射
# 相当于依次把A3中的值放到predict函数中计算
# 然后打印出结果
print('predict:')
for i in map(predict, A3):
    print(i)



4、实验内容
请回答下列问题:

1)如果去掉总裁这一层,相应张三的样本修改为(1.0,0.1,1.0,1.0),分别对应张三的学习成绩、张三的实践成绩、张三的工作能力真值、张三的工作态度真值,代码应该如何修改?

import numpy as np
import matplotlib.pyplot as plt

# 输入数据1行2列,这里只有张三的数据
X = np.array([[1, 0.1]])
# 标签,也叫真值,1行1列,张三的真值:一定录用
T = np.array([[1],
              [1]])

# 输入层到隐藏层1的权值初始化,2行2列
W1 = np.array([[0.8, 0.2],
               [0.2, 0.8]])
# 隐藏层1到输出层的权值初始化,2行2列
W2 = np.array([[0.5, 0.0],
               [0.5, 1.0]])

# 初始化偏置值
# 隐藏层1的2个神经元偏置
b1 = np.array([[-1, 0.3]])
# 输出层的2个神经元偏置
b2 = np.array([[0.1, -0.1]])
# 学习率设置
lr = 0.1
# 定义训练周期数10000
epochs = 10000
# 每训练1000次计算一次loss值  # 定义测试周期数
report = 1000
# 将所有样本分组,每组大小为
batch_size = 1


# 定义sigmoid函数
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

# 定义sigmoid函数导数
def dsigmoid(x):
    return x * (1 - x)

# 更新权值和偏置值
def update():
    global batch_X, batch_T, W1, W2, lr, b1, b2

    # 隐藏层1输出
    Z1 = np.dot(batch_X, W1) + b1
    A1 = sigmoid(Z1)

    # 输出层
    Z2 = (np.dot(A1, W2) + b2)
    A2 = sigmoid(Z2)

    # 求输出层的误差
    delta_A2 = (batch_T - A2)
    delta_Z2 = delta_A2 * dsigmoid(A2)

    # 利用输出层的误差,求出三个偏导(即隐藏层1到输出层的权值改变)    # 由于一次计算了多个样本,所以需要求平均
    delta_W2 = A1.T.dot(delta_Z2) / batch_X.shape[0]
    delta_B2 = np.sum(delta_Z2, axis=0) / batch_X.shape[0]

    # 求隐藏层1的误差
    delta_A1 = delta_Z2.dot(W2.T)
    delta_Z1 = delta_A1 * dsigmoid(A1)

    # 利用隐藏层1的误差,求出三个偏导(即输入层到隐藏层1的权值改变)    # 由于一次计算了多个样本,所以需要求平均
    delta_W1 = batch_X.T.dot(delta_Z1) / batch_X.shape[0]
    delta_B1 = np.sum(delta_Z1, axis=0) / batch_X.shape[0]

    # 更新权值
    W2 = W2 + lr * delta_W2
    W1 = W1 + lr * delta_W1

    # 改变偏置值
    b2 = b2 + lr * delta_B2
    b1 = b1 + lr * delta_B1


# 定义空list用于保存loss
loss = []
batch_X = []
batch_T = []
max_batch = X.shape[0] // batch_size
# 训练模型
for idx_epoch in range(epochs):

    for idx_batch in range(max_batch):
        # 更新权值
        batch_X = X[idx_batch * batch_size:(idx_batch + 1) * batch_size, :]
        batch_T = T[idx_batch * batch_size:(idx_batch + 1) * batch_size, :]
        update()
    # 每训练5000次计算一次loss值
    if idx_epoch % report == 0:
        # 隐藏层1输出
        A1 = sigmoid(np.dot(X, W1) + b1)
        # 输出层输出
        A2 = sigmoid(np.dot(A1, W2) + b2)
        # 计算loss值
        print('A2:', A2)
        print('epochs:', idx_epoch, 'loss:', np.mean(np.square(T - A2) / 2))  # 各样本损失函数均值
        # 保存loss值
        loss.append(np.mean(np.square(T - A2) / 2))

# 画图训练周期数与loss的关系图
plt.plot(range(0, epochs, report), loss)
plt.xlabel('epochs')
plt.ylabel('loss')
plt.show()

# 隐藏层1输出
A1 = sigmoid(np.dot(X, W1) + b1)
# 输出层输出
A2 = sigmoid(np.dot(A1, W2) + b2)
print('output:')
print(A2)


# 因为最终的分类只有0和1,所以我们可以把
# 大于等于0.5的值归为1类,小于0.5的值归为0类
def predict(x):
    if x.all() >= 0.5:
        return 1
    else:
        return 0


# map会根据提供的函数对指定序列做映射
# 相当于依次把A2中的值放到predict函数中计算
# 然后打印出结果
print('predict:')
for i in map(predict, A2):
    print(i)

2)如果增加一个样本,李四(0.1,1.0,0),分别对应李四的学习成绩,李四的实践成绩,李四被招聘可能性的真值,代码应该如何修改?此时是一个样本计算一次偏导、更新一次权值,还是两个样本一起计算一次偏导、更新一次权值?(提示:注意 batch_size 的作用)

import numpy as np
import matplotlib.pyplot as plt

# 输入数据1行2列,这里有张三、李四的数据
X = np.array([[1, 0.1],
              [0.1, 1]])
# 标签,也叫真值
T = np.array([[1],
              [0]])

# 定义一个2隐层的神经网络:2-2-2-1
# 输入层2个神经元,隐藏1层2个神经元,隐藏2层2个神经元,输出层1个神经元

# 输入层到隐藏层1的权值初始化,2行2列
W1 = np.array([[0.8, 0.2],
               [0.2, 0.8]])
# 隐藏层1到隐藏层2的权值初始化,2行2列
W2 = np.array([[0.5, 0.0],
               [0.5, 1.0]])
# 隐藏层2到输出层的权值初始化,2行1列
W3 = np.array([[0.5],
               [0.5]])

# 初始化偏置值
# 隐藏层1的2个神经元偏置
b1 = np.array([[-1, 0.3]])
# 隐藏层2的2个神经元偏置
b2 = np.array([[0.1, -0.1]])
# 输出层的1个神经元偏置
b3 = np.array([[-0.6]])
# 学习率设置
lr = 0.1
# 定义训练周期数10000
epochs = 10000
# 每训练1000次计算一次loss值  # 定义测试周期数
report = 1000
# 将所有样本分组,每组大小为
batch_size = 1


# 定义sigmoid函数
def sigmoid(x):
    return 1 / (1 + np.exp(-x))


# 定义sigmoid函数导数
def dsigmoid(x):
    return x * (1 - x)


# 更新权值和偏置值
def update():
    global batch_X, batch_T, W1, W2, W3, lr, b1, b2, b3

    # 隐藏层1输出
    Z1 = np.dot(batch_X, W1) + b1
    A1 = sigmoid(Z1)

    # 隐藏层2输出
    Z2 = (np.dot(A1, W2) + b2)
    A2 = sigmoid(Z2)

    # 输出层输出
    Z3 = (np.dot(A2, W3) + b3)
    A3 = sigmoid(Z3)

    # 求输出层的误差
    delta_A3 = (batch_T - A3)
    delta_Z3 = delta_A3 * dsigmoid(A3)

    # 利用输出层的误差,求出三个偏导(即隐藏层2到输出层的权值改变)    # 由于一次计算了多个样本,所以需要求平均
    delta_W3 = A2.T.dot(delta_Z3) / batch_X.shape[0]
    delta_B3 = np.sum(delta_Z3, axis=0) / batch_X.shape[0]

    # 求隐藏层2的误差
    delta_A2 = delta_Z3.dot(W3.T)
    delta_Z2 = delta_A2 * dsigmoid(A2)

    # 利用隐藏层2的误差,求出三个偏导(即隐藏层1到隐藏层2的权值改变)    # 由于一次计算了多个样本,所以需要求平均
    delta_W2 = A1.T.dot(delta_Z2) / batch_X.shape[0]
    delta_B2 = np.sum(delta_Z2, axis=0) / batch_X.shape[0]

    # 求隐藏层1的误差
    delta_A1 = delta_Z2.dot(W2.T)
    delta_Z1 = delta_A1 * dsigmoid(A1)

    # 利用隐藏层1的误差,求出三个偏导(即输入层到隐藏层1的权值改变)    # 由于一次计算了多个样本,所以需要求平均
    delta_W1 = batch_X.T.dot(delta_Z1) / batch_X.shape[0]
    delta_B1 = np.sum(delta_Z1, axis=0) / batch_X.shape[0]

    # 更新权值
    W3 = W3 + lr * delta_W3
    W2 = W2 + lr * delta_W2
    W1 = W1 + lr * delta_W1

    # 改变偏置值
    b3 = b3 + lr * delta_B3
    b2 = b2 + lr * delta_B2
    b1 = b1 + lr * delta_B1


# 定义空list用于保存loss
loss = []
batch_X = []
batch_T = []
max_batch = X.shape[0] // batch_size
# 训练模型
for idx_epoch in range(epochs):

    for idx_batch in range(max_batch):
        # 更新权值
        batch_X = X[idx_batch * batch_size:(idx_batch + 1) * batch_size, :]  # 矩阵切片操作,取需要的行与列
        batch_T = T[idx_batch * batch_size:(idx_batch + 1) * batch_size, :]
        update()
    # 每训练5000次计算一次loss值
    if idx_epoch % report == 0:
        # 隐藏层1输出
        A1 = sigmoid(np.dot(X, W1) + b1)
        # 隐藏层2输出
        A2 = sigmoid(np.dot(A1, W2) + b2)
        # 输出层输出
        A3 = sigmoid(np.dot(A2, W3) + b3)
        # 计算loss值
        print('A3:', A3)
        print('epochs:', idx_epoch, 'loss:', np.mean(np.square(T - A3) / 2))
        # 保存loss值
        loss.append(np.mean(np.square(T - A3) / 2))

# 画图训练周期数与loss的关系图
plt.plot(range(0, epochs, report), loss)
plt.xlabel('epochs')
plt.ylabel('loss')
plt.show()

# 隐藏层1输出
A1 = sigmoid(np.dot(X, W1) + b1)
# 隐藏层2输出
A2 = sigmoid(np.dot(A1, W2) + b2)
# 输出层输出
A3 = sigmoid(np.dot(A2, W3) + b3)
print('output:')
print(A3)


# 因为最终的分类只有0和1,所以我们可以把
# 大于等于0.5的值归为1类,小于0.5的值归为0类
def predict(x):
    if x >= 0.5:
        return 1
    else:
        return 0


# map会根据提供的函数对指定序列做映射
# 相当于依次把A3中的值放到predict函数中计算
# 然后打印出结果
print('predict:')
for i in map(predict, A3):
    print(i)

3)样本为张三[1,0.1,1]、李四[0.1,1,0]、王五[0.1,0.1,0]、赵六[1,1,1],请利用 batch_size 实现教材 279 页提到的“批量梯度下降”、“随机梯度下降”和“小批量梯度下降”,请注意“随机梯度下降”和“小批量梯度下降”要体现随机性。

三种梯度下降的区别在于每次更新权值的样本规模不同,修改每次迭代的样本规模即可

批量梯度下降

# 训练模型
for idx_epoch in range(epochs):
    # 更新权值
    batch_X = X  # 矩阵切片操作,取需要的行与列
    batch_T = T
    update()
    # 每训练5000次计算一次loss值
    if idx_epoch % report == 0:
        # 隐藏层1输出
        A1 = sigmoid(np.dot(X, W1) + b1)
        # 隐藏层2输出
        A2 = sigmoid(np.dot(A1, W2) + b2)
        # 输出层输出
        A3 = sigmoid(np.dot(A2, W3) + b3)
        # 计算loss值
        print('A3:', A3)
        print('epochs:', idx_epoch, 'loss:', np.mean(np.square(T - A3) / 2))
        # 保存loss值
        loss.append(np.mean(np.square(T - A3) / 2))

小批量梯度下降

batch_size = 2    # 小批量梯度下降,这里每次迭代样本容量为2
# 训练模型
for idx_epoch in range(epochs):
    for idx_batch in range(max_batch):
        # 更新权值
        batch_X = X[idx_batch * batch_size:(idx_batch + 1) * batch_size, :]  # 矩阵切片操作,取需要的行与列
        batch_T = T[idx_batch * batch_size:(idx_batch + 1) * batch_size, :]
        update()
    # 每训练5000次计算一次loss值
    if idx_epoch % report == 0:
        # 隐藏层1输出
        A1 = sigmoid(np.dot(X, W1) + b1)
        # 隐藏层2输出
        A2 = sigmoid(np.dot(A1, W2) + b2)
        # 输出层输出
        A3 = sigmoid(np.dot(A2, W3) + b3)
        # 计算loss值
        print('A3:', A3)
        print('epochs:', idx_epoch, 'loss:', np.mean(np.square(T - A3) / 2))
        # 保存loss值
        loss.append(np.mean(np.square(T - A3) / 2))

随机梯度下降

# 训练模型
for idx_epoch in range(epochs):
    randomNum = random.randint(X.shape[0])  # 生成一个n到m之间的随机数, 随机梯度下降
    # 更新权值
    batch_X = X[randomNum:(randomNum + 1), :]
    batch_T = T[randomNum:(randomNum + 1), :]
    update()
    # 每训练5000次计算一次loss值
    if idx_epoch % report == 0:
        # 隐藏层1输出
        A1 = sigmoid(np.dot(X, W1) + b1)
        # 隐藏层2输出
        A2 = sigmoid(np.dot(A1, W2) + b2)
        # 输出层输出
        A3 = sigmoid(np.dot(A2, W3) + b3)
        # 计算loss值
        print('A3:', A3)
        print('epochs:', idx_epoch, 'loss:', np.mean(np.square(T - A3) / 2))
        # 保存loss值
        loss.append(np.mean(np.square(T - A3) / 2))

随机梯度下降每次画出的训练周期数与loss的关系图都不一样,因为每次迭代都是随机选取一个样本来更新权值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浩茫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值