【机器学习】卷积神经网络(一)

7acde78c210c793eb87a059cb85771ba.png

一、网络结构

71f281eaf2c25d94b9f55b92f4b87c3a.png

b30a40c5c9a698d4111b1f204443089b.jpeg

典型CNN结构

卷积神经网络是一种能够从图像、声音或其他类型的数据中学习特征的人工智能模型。你可以把它想象成一个有很多层的过滤器,每一层都能够提取出数据中的一些有用的信息,比如边缘、形状、颜色、纹理等。这些信息可以帮助卷积神经网络完成一些任务,比如识别物体、人脸、语音或文字。

卷积神经网络的名字中的“卷积”是一种数学运算,它可以把一个小的矩阵(叫做卷积核或滤波器)在一个大的矩阵(叫做输入或特征图)上滑动,每次滑动一小步,然后把卷积核和输入的对应位置的元素相乘,再把结果加起来,得到一个新的矩阵(叫做输出或特征图)。

卷积的作用是可以把输入中的某些模式或特征提取出来,比如卷积核中的元素是[[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]],那么它就可以检测出输入中的边缘,因为边缘的地方,输入的元素值会有很大的变化,而卷积核的元素值会放大这种变化,从而在输出中形成一个明显的响应。

用下面的代码来比较了不同的卷积核对输入的影响

# 导入必要的库
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
from scipy.signal import convolve2dplt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
# 定义一个函数,用来显示图像
def show_image(image, title):plt.imshow(image, cmap='gray')plt.title(title)plt.axis('off')plt.show()# 读取一张图像,转换成灰度和数组格式
image = Image.open('shinianyimeng.png').convert('L')
image = np.array(image)# 定义不同的卷积核
kernel_1 = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]]) # 边缘检测
kernel_2 = np.array([[1, 1, 1], [1, 1, 1], [1, 1, 1]]) / 9 # 平均滤波
kernel_3 = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]]) # 锐化
kernel_4 = np.array([[0, 1, 0], [1, -4, 1], [0, 1, 0]]) # 拉普拉斯# 对图像进行卷积,得到不同的输出
output_1 = convolve2d(image, kernel_1, mode='same')
output_2 = convolve2d(image, kernel_2, mode='same')
output_3 = convolve2d(image, kernel_3, mode='same')
output_4 = convolve2d(image, kernel_4, mode='same')# 显示原始图像和输出图像
""" show_image(image, '原始图像')
show_image(output_1, '边缘检测')
show_image(output_2, '平均滤波')
show_image(output_3, '锐化')
show_image(output_4, '拉普拉斯') """images=[image,output_1,output_2,output_3,output_4]
titles=['原始图像','边缘检测','平均滤波','锐化','拉普拉斯']n = 5 # 显示的图像数量
plt.figure(figsize=(15, 8))# 大小为15英寸宽,8英寸高
for i in range(5):ax = plt.subplot(2, 3, i + 1)#第一行第i+1列plt.imshow(images[i], cmap='gray')plt.title(titles[i])#plt.axis('off')ax.get_xaxis().set_visible(False)#隐藏子图的x轴ax.get_yaxis().set_visible(False)plt.show()

15f44926328f3542ca4e07f1332be692.png

卷积神经网络的每一层都有很多个卷积核,它们可以同时对输入进行卷积,得到多个输出,这些输出叫做特征图,它们可以表示输入中的不同特征。卷积神经网络的卷积核的元素值是可以通过学习得到的,也就是说,卷积神经网络可以自动地从数据中学习出最合适的卷积核,从而提取出最有用的特征。

2159ed4f8769fb6b2f85010caaea6d9f.png

常用卷积运算

卷积神经网络除了卷积层之外,还有一些其他的层,比如池化层、激活层、全连接层等这些层的作用是:

  • 池化层:池化层是对特征图进行降采样的操作,也就是把特征图变小,从而减少计算量和参数数量,同时保留最重要的信息。池化层有不同的类型,比如最大池化、平均池化等,它们的原理都是把特征图分成若干个小块,然后对每个小块取最大值或平均值,得到一个新的特征图。

  • 激活层:激活层是对特征图的每个元素进行一个非线性变换的操作,也就是把特征图变得更复杂,从而增加卷积神经网络的表达能力。激活层有不同的类型,比如ReLU、sigmoid、tanh等,它们的原理都是把特征图的每个元素用一个函数来替换,得到一个新的特征图

  • 全连接层:全连接层是把特征图的所有元素连接到一个或多个输出节点的操作,也就是把特征图变成一个向量,从而可以用来做分类、回归或其他任务。全连接层有不同的类型,比如softmax、线性等,它们的原理都是把特征图的所有元素乘以一个权重矩阵,然后加上一个偏置向量,得到一个输出向量。

卷积神经网络的工作原理是,它先用卷积层和池化层从输入中提取出各种各样的特征,然后用全连接层把这些特征组合起来,得到最终的输出

卷积神经网络是一种非常强大的人工智能模型,它可以在很多领域中发挥重要的作用,比如图像识别、自然语言处理、语音识别、自动驾驶等。卷积神经网络的原理并不难理解,只要你掌握了卷积、池化、激活和全连接这几个基本的操作,你就可以构建出自己的卷积神经网络,或者使用现成的卷积神经网络框架,比如TensorFlow、PyTorch等,来实现你想要的功能。

图像卷积操作前,对图像进行扩充的方式主要有以下几种:

  • 零填充:在图像的边缘添加一些值为零的像素,使得图像的大小增加,卷积后的图像大小不变。

  • 复制填充:在图像的边缘添加一些与边缘像素相同的像素,使得图像的大小增加,卷积后的图像大小不变。

  • 镜像填充:在图像的边缘添加一些与边缘像素对称的像素,使得图像的大小增加,卷积后的图像大小不变。

  • 循环填充:在图像的边缘添加一些与图像的另一边相同的像素,使得图像的大小增加,卷积后的图像大小不变。

多通道卷积

83f0bf795d59d98e9df14cf18b883e09.png

多通道卷积是一种在卷积神经网络中使用的技术,它可以处理具有多个输入和输出通道的图像或特征图。多通道卷积的目的是提取不同通道上的不同特征,增加网络的表达能力和学习能力。

多通道卷积的原理是,对于每个输出通道,使用一个形状为 c_i × k_h × k_w 的卷积核,其中 c_i 是输入通道的数目,k_h 和 k_w 是卷积核的高度和宽度。这个卷积核会对输入的每个通道进行互相关运算,然后将所有通道的结果相加,得到一个二维的输出。如果有多个输出通道,那么就需要多个这样的卷积核,形成一个形状为 c_o × c_i × k_h × k_w 的卷积核张量,其中 c_o 是输出通道的数目。这样,每个输出通道都可以从输入的所有通道中提取特征,而不是只从一个通道中提取。

多通道卷积的作用是,它可以让卷积核同时处理输入特征图的不同通道,从而捕捉输入特征图的不同特征,比如RGB图像的不同颜色,同时,它也可以让输出特征图有多个通道,从而增加输出特征图的维度和信息量,比如输出特征图的不同通道可以表示不同的特征或概念。多通道卷积可以提高卷积神经网络的性能和效果,但是也会增加卷积神经网络的参数数量和计算量,因此需要根据具体的任务和数据来选择合适的通道数和卷积核大小。

感受野(receptive field)

ae43b6decbe220b510d5490e5dea9e2e.png

5dc2df7a3e53625c2a7623b2119ac853.png

9a22612453c3c36fa5dec0b02cb56fc3.png

感受野的大小对卷积神经网络有什么影响?

0bb6ca17dec5534eb18268bb99e12334.png

最大池化与平均池化对比

  • 特征提取能力:最大池化可以保留最显著的特征,比如边缘、角点等,从而突出输入特征图的主要特征;平均池化可以保留最平均的特征,比如背景、纹理等,从而平滑输入特征图的细节特征。因此,最大池化和平均池化可以提取出不同层次的特征,适用于不同的任务和数据。

  • 鲁棒性和泛化能力:最大池化可以让特征图对输入特征图的一些微小的变化或噪声不敏感,从而增强卷积神经网络的鲁棒性和泛化能力;平均池化可以让特征图对输入特征图的一些重要的变化或信息敏感,从而降低卷积神经网络的鲁棒性和泛化能力。因此,最大池化和平均池化有不同的优缺点,需要根据不同的数据质量和复杂度来选择。

  • 计算量和参数数量:最大池化和平均池化都可以把特征图的高度和宽度变小,从而降低特征图的维度,减少后续层的计算量和参数数量,提高卷积神经网络的运行效率和存储空间。因此,最大池化和平均池化在这方面没有太大的差别,只要选择合适的池化核的大小和步长,就可以达到理想的效果。

二、训练算法

反向传播算法(Copilot):卷积层、池化层、全连接层

cb05c0a65bfc2b92728b554828d60280.png

import numpy as np# 输入 X 的形状为 (n, c, h, w)
# 输出 Y 的形状为 (n, k, p, q)
# 卷积核 W 的形状为 (k, c, r, s)
# 偏置项 b 的形状为 (k,)
# 输出的梯度 dY 的形状为 (n, k, p, q)
# 输入的梯度 dX 的形状为 (n, c, h, w)
# 卷积核的梯度 dW 的形状为 (k, c, r, s)
# 偏置项的梯度 db 的形状为 (k,)# 计算输入的梯度
dX = np.zeros_like(X)
for i in range(h):for j in range(w):for m in range(c):for u in range(i, i + r):for v in range(j, j + s):for k in range(k):dX[i, m, u, v] += dY[i, k, u - i, v - j] * W[k, m, u - i, v - j]# 计算卷积核的梯度
dW = np.zeros_like(W)
for k in range(k):for m in range(c):for a in range(r):for b in range(s):for i in range(h):for j in range(w):dW[k, m, a, b] += dY[i, k, i + a, j + b] * X[i, m, i, j]# 计算偏置项的梯度
db = np.zeros_like(b)
for k in range(k):for i in range(p):for j in range(q):for m in range(n):db[k] += dY[m, k, i, j]

a17d254f5843a671c89634fceda0a9c0.png

import numpy as np# 输入 X 的形状为 (n, c, h, w)
# 输出 Y 的形状为 (n, k, p, q)
# 卷积核 W 的形状为 (k, c, r, s)
# 偏置项 b 的形状为 (k,)
# 输出的梯度 dY 的形状为 (n, k, p, q)
# 输入的梯度 dX 的形状为 (n, c, h, w)
# 卷积核的梯度 dW 的形状为 (k, c, r, s)
# 偏置项的梯度 db 的形状为 (k,)# 计算输入的梯度
dX = np.zeros_like(X)
for i in range(h):for j in range(w):for m in range(c):for u in range(i, i + r):for v in range(j, j + s):for k in range(k):dX[i, m, u, v] += dY[i, k, u - i, v - j] * W[k, m, u - i, v - j]# 计算卷积核的梯度
dW = np.zeros_like(W)
for k in range(k):for m in range(c):for a in range(r):for b in range(s):for i in range(h):for j in range(w):dW[k, m, a, b] += dY[i, k, i + a, j + b] * X[i, m, i, j]# 计算偏置项的梯度
db = np.zeros_like(b)
for k in range(k):for i in range(p):for j in range(q):for m in range(n):db[k] += dY[m, k, i, j]

1c9010327a3ff3dd6659a82cd8027a4b.png

import numpy as np# 输入 X 的形状为 (n, d)
# 输出 Y 的形状为 (n, k)
# 权重矩阵 W 的形状为 (d, k)
# 偏置向量 b 的形状为 (k,)
# 激活函数 f 的类型为 relu, sigmoid, tanh 或 None
# 输出的梯度 dY 的形状为 (n, k)
# 输入的梯度 dX 的形状为 (n, d)
# 权重矩阵的梯度 dW 的形状为 (d, k)
# 偏置向量的梯度 db 的形状为 (k,)# 计算输入的梯度
if f is None:dX = np.dot(dY, W.T)
else:# 计算激活函数的导数if f == 'relu':f_prime = lambda x: np.where(x > 0, 1, 0)elif f == 'sigmoid':f_prime = lambda x: x * (1 - x)elif f == 'tanh':f_prime = lambda x: 1 - x ** 2else:raise ValueError('Invalid activation function')# 计算输入的梯度dX = np.dot(dY * f_prime(X.dot(W) + b), W.T)# 计算权重矩阵的梯度
if f is None:dW = np.dot(X.T, dY)
else:# 计算激活函数的导数if f == 'relu':f_prime = lambda x: np.where(x > 0, 1, 0)elif f == 'sigmoid':f_prime = lambda x: x * (1 - x)elif f == 'tanh':f_prime = lambda x: 1 - x ** 2else:raise ValueError('Invalid activation function')# 计算权重矩阵的梯度dW = np.dot(X.T, dY * f_prime(X.dot(W) + b))# 计算偏置向量的梯度
if f is None:db = np.sum(dY, axis=0)
else:# 计算激活函数的导数if f == 'relu':f_prime = lambda x: np.where(x > 0, 1, 0)elif f == 'sigmoid':f_prime = lambda x: x * (1 - x)elif f == 'tanh':f_prime = lambda x: 1 - x ** 2else:raise ValueError('Invalid activation function')# 计算偏置向量的梯度db = np.sum(dY * f_prime(X.dot(W) + b), axis=0)

随机梯度下降法(Stochastic Gradient Descent,SGD)

f16cd9e06fc1225377dad2f7bd77166d.png

迁移学习:

ba5088db12ee50541a0b7f869aba6754.png

另一版本各种层反向传播算法代码:

import numpy as np
from scipy import ndimage# 定义卷积层的反向传播函数,输入参数为损失函数对输出的梯度dZ (m,i,j,k),输入x (m,h,w,c),过滤器w(f,f,c,k) 和填充方式padding   c: 输入通道数。k:卷积核个数 
def conv_backward(dZ,x,w,padding="same"):# 获取输入的批次大小mm = x.shape[0]# 计算损失函数对偏置b的梯度db,为dZ在批次、高度、宽度维度上的平均值db = (1/m)*np.sum(dZ, axis=(0,1,2), keepdims=True)# 判断填充方式,如果是same,则计算填充的大小pad,为过滤器的一半if padding=="same":pad = (w.shape[0]-1)//2else: #padding is valid - i.e no zero padding# 如果是valid,则不进行填充,pad为0pad =0# 对输入x进行零填充,得到x_padded  对一个四维的数组 x 进行填充,使得它的第二维和第三维在两边各增加 pad 个元素,填充的值为 0,而其他维度不变x_padded = np.pad(x,((0,0),(pad,pad),(pad,pad),(0,0)),'constant', constant_values = 0)# 对x_padded增加一个维度,以便进行广播操作x_padded_bcast = np.expand_dims(x_padded, axis=-1) # shape = (m, i, j, c, 1)# 对dZ增加一个维度,以便进行广播操作dZ_bcast = np.expand_dims(dZ, axis=-2) # shape = (m, i, j, 1, k)  k:卷积核个数  m:批量# 初始化损失函数对过滤器w的梯度dW,形状与w相同dW = np.zeros_like(w)# 获取过滤器的大小ff=w.shape[0]# 获取填充后的输入的宽度w_xw_x = x_padded.shape[1]# 对过滤器的每个元素进行遍历for a in range(f):# a  (0~f-1)for b in range(f):#   b  (0~f-1)# 计算损失函数对过滤器w的梯度dW,为dZ_bcast和x_padded_bcast的对应位置的乘积在批次、高度、宽度维度上的平均值# 注意f-1 - a而不是f-a,因为索引从0...f-1而不是1...f# 输出高度:w-f+1+a-a = w-(f-1)   输出宽度:w-f+1+b-b=w-(f-1)  dW[a,b,:,:] = (1/m)*np.sum(dZ_bcast*x_padded_bcast[:,a:w_x-(f-1 -a),b:w_x-(f-1 -b),:,:],axis=(0,1,2))# 初始化损失函数对输入x的梯度dx,形状与x_padded相同dx = np.zeros_like(x_padded,dtype=float)# 计算对 dZ 进行填充的大小Z_pad,为过滤器的大小减一Z_pad = f-1# 对dZ进行零填充,得到dZ_paddeddZ_padded = np.pad(dZ,((0,0),(Z_pad,Z_pad),(Z_pad,Z_pad),(0,0)),'constant', constant_values = 0)# 对输入的每个批次、每个输出通道、每个输入通道进行遍历for m_i in range(x.shape[0]):#批次for k in range(w.shape[3]):# 输出通道for d in range(x.shape[3]):#输入通道# 计算损失函数对输入x的梯度dx,为dZ_padded和w的对应位置的卷积,去掉边缘部分# 计算输入的第 m_i 个样本,所有高度,所有宽度,第 d 个输入通道的元素的梯度# [f//2:-(f//2),f//2:-(f//2)] 表示从一个二维矩阵中选取从第 f//2 行到倒数第 f//2 行,从第 f//2 列到倒数第 f//2 列的部分,其中 f 是过滤器的大小,// 表示整除运算dx[m_i,:,:,d]+=ndimage.convolve(dZ_padded[m_i,:,:,k],w[:,:,d,k])[f//2:-(f//2),f//2:-(f//2)]# 去掉dx的填充部分,得到最终的dxdx = dx[:,pad:dx.shape[1]-pad,pad:dx.shape[2]-pad,:]# 返回dx,dW,dbreturn dx,dW,db
  • 该代码定义了一个卷积层的反向传播函数,用于根据损失函数对卷积层输出的梯度,计算损失函数对卷积层输入、过滤器和偏置项的梯度。

  • 该函数的输入参数包括损失函数对输出的梯度 dZ,输入 x,过滤器 w,和填充方式 padding。

  • 该函数的输出为损失函数对输入、过滤器和偏置项的梯度,分别为 dx, dW, db。

  • 该函数的主要步骤如下:

    • 首先,计算损失函数对偏置项的梯度 db,为 dZ 在批次、高度、宽度维度上的平均值。

    • 然后,根据填充方式确定填充的大小 pad,并对输入 x 进行零填充,得到 x_padded。

    • 接着,对 x_padded 和 dZ 增加一个维度,以便进行广播操作,得到 x_padded_bcast 和 dZ_bcast。

    • 然后,用双重循环遍历过滤器的每个元素,计算损失函数对过滤器的梯度 dW,为 dZ_bcast 和 x_padded_bcast 的对应位置的乘积在批次、高度、宽度维度上的平均值。

    • 接着,初始化损失函数对输入的梯度 dx,并对 dZ 进行零填充,得到 dZ_padded。

    • 然后,用三重循环遍历输入的每个批次、每个输出通道、每个输入通道,计算损失函数对输入的梯度 dx,为 dZ_padded 和 w 的对应位置的卷积,去掉边缘部分。

    • 最后,去掉 dx 的填充部分,得到最终的 dx,并返回 dx, dW, db。

# 定义激活层的反向传播函数
def relu(z, deriv = False):# z 是激活层的输入,deriv 是一个布尔值,表示是否求导数# 返回激活层的输出或者激活函数的导数if(deriv): #this is for the partial derivatives (discussed in next blog post)# 如果求导数,返回一个布尔矩阵,表示 z 中的元素是否大于零return z>0 #Note that True=1 and False=0 when converted to floatelse:# 如果不求导数,返回 z 的 relu 激活函数的值,即 z 和 0 的较大值return np.multiply(z, z>0)

这段代码的目的是定义一个激活层的反向传播函数,使用了 relu 激活函数。relu 激活函数的公式是 f(z)=max(0,z),它的导数是 f′(z)=1 如果 z>0,否则是 0。这个函数的参数有两个,一个是 z,表示激活层的输入,一个是 deriv,表示是否求导数。这个函数的返回值根据 deriv 的值而不同,如果 deriv 为 False,那么返回激活层的输出,即 z 的 relu 激活函数的值,如果 deriv 为 True,那么返回激活函数的导数,即 z 中的元素是否大于零的布尔矩阵。这个函数使用了 numpy 库的一些函数,例如 np.multiply 和 z>0,来实现矩阵的逐元素运算。这个函数可以用于卷积神经网络的反向传播过程中,计算激活层的误差项和梯度.

# 定义池化层的前向传播函数
def pool_forward(x,mode="max"):# x 是池化层的输入,mode 是池化方式,可以是最大池化或平均池化# 返回池化层的输出和一个掩码矩阵,用于反向传播# 将输入重塑为一个六维矩阵,每个池化窗口对应一个子矩阵x_patches = x.reshape(x.shape[0],x.shape[1]//2, 2,x.shape[2]//2, 2,x.shape[3])if mode=="max":# 如果是最大池化,对每个子矩阵求最大值,得到输出out = x_patches.max(axis=2).max(axis=3)# 生成一个掩码矩阵,表示输入中的元素是否等于输出中的元素mask  =np.isclose(x,np.repeat(np.repeat(out,2,axis=1),2,axis=2)).astype(int)elif mode=="average":# 如果是平均池化,对每个子矩阵求平均值,得到输出out =  x_patches.mean(axis=3).mean(axis=4)# 生成一个掩码矩阵,表示输入中的元素的权重,即 1/4mask = np.ones_like(x)*0.25# 返回输出和掩码矩阵return out,mask# 定义池化层的反向传播函数
def pool_backward(dx, mask):# dx 是损失函数对池化层输出的梯度,mask 是前向传播时生成的掩码矩阵# 返回损失函数对池化层输入的梯度# 将 dx 沿着宽度和高度方向复制两次,得到和输入相同大小的矩阵return mask*(np.repeat(np.repeat(dx,2,axis=1),2,axis=2))

这段代码的目的是定义一个池化层的前向传播和反向传播函数,使用了最大池化或平均池化的方式。池化层的作用是对输入的特征图进行降采样,减少参数和计算量,增加模型的鲁棒性。这个函数的参数和返回值如下:

  • 前向传播函数的参数有两个,一个是 x,表示池化层的输入,一个是 mode,表示池化方式,可以是最大池化或平均池化。前向传播函数的返回值有两个,一个是 out,表示池化层的输出,一个是 mask,表示一个掩码矩阵,用于反向传播。

  • 反向传播函数的参数有两个,一个是 dx,表示损失函数对池化层输出的梯度,一个是 mask,表示前向传播时生成的掩码矩阵。反向传播函数的返回值有一个,就是损失函数对池化层输入的梯度。

具体的计算过程如下:

  • 在前向传播函数中,首先将输入重塑为一个六维矩阵,每个池化窗口对应一个子矩阵,然后根据 mode 的值,对每个子矩阵求最大值或平均值,得到输出。同时,生成一个掩码矩阵,表示输入中的元素是否等于输出中的元素(最大池化)或者输入中的元素的权重(平均池化),用于反向传播。

  • 在反向传播函数中,首先将 dx 沿着宽度和高度方向复制两次,得到和输入相同大小的矩阵,然后用 mask 乘以这个矩阵,得到损失函数对池化层输入的梯度。这个过程可以看作是将 dx 的梯度分配到输入的相应位置上。

这段代码使用了 numpy 库的一些函数,例如 np.reshape, np.max, np.mean, np.isclose, np.repeat, np.ones_like 等,来实现矩阵的重塑,求最大值,求平均值,比较相等,复制,生成全一矩阵等操作。这个函数可以用于卷积神经网络的前向传播和反向传播过程中,实现池化层的功能。

# 定义全连接层的反向传播函数
def fc_backward(dA,a,x,w,b):# dA 是损失函数对全连接层输出的梯度,a 是全连接层的输入,x 是全连接层的前一层的输出,w 是全连接层的权重矩阵,b 是全连接层的偏置向量# 返回损失函数对全连接层输入、权重矩阵和偏置向量的梯度,分别为 dx, dW, db# 获取输入的样本数m = dA.shape[1]# 计算全连接层的输入的梯度,即对输出的梯度乘以 relu 激活函数的导数dZ = dA*relu(a,deriv=True)# 计算权重矩阵的梯度,即对输入的梯度和前一层的输出的矩阵乘法的平均值dW = (1/m)*dZ.dot(x.T)# 计算偏置向量的梯度,即对输入的梯度求和db = (1/m)*np.sum(dZ,axis=1,keepdims=True)# 计算前一层的输出的梯度,即对权重矩阵的转置和输入的梯度的矩阵乘法dx =  np.dot(w.T,dZ)# 返回输入、权重矩阵和偏置向量的梯度return dx, dW,db

这段代码的目的是定义一个全连接层的反向传播函数,使用了 relu 激活函数。全连接层的作用是对输入的特征进行线性变换和非线性激活,实现分类或回归的功能。这个函数的参数和返回值如下:

  • 反向传播函数的参数有五个,一个是 dA,表示损失函数对全连接层输出的梯度,一个是 a,表示全连接层的输入,一个是 x,表示全连接层的前一层的输出,一个是 w,表示全连接层的权重矩阵,一个是 b,表示全连接层的偏置向量。反向传播函数的返回值有三个,分别是损失函数对全连接层输入、权重矩阵和偏置向量的梯度,分别为 dx, dW, db。

具体的计算过程如下:

  • 在反向传播函数中,首先获取输入的样本数,然后计算全连接层的输入的梯度,即对输出的梯度乘以 relu 激活函数的导数。然后计算权重矩阵的梯度,即对输入的梯度和前一层的输出的矩阵乘法的平均值。然后计算偏置向量的梯度,即对输入的梯度求和。最后计算前一层的输出的梯度,即对权重矩阵的转置和输入的梯度的矩阵乘法。

这段代码使用了 numpy 库的一些函数,例如 np.sum, np.dot, np.multiply 等,来实现矩阵的求和,矩阵乘法,逐元素相乘等操作。这个函数可以用于卷积神经网络的反向传播过程中,计算全连接层的误差项和梯度。

# 定义 softmax 层的反向传播函数
def softmax_backward(y_pred, y, w, b, x):# y_pred 是 softmax 层的输出,y 是真实的标签,w 是 softmax 层的权重矩阵,b 是 softmax 层的偏置向量,x 是 softmax 层的输入# 返回损失函数对 softmax 层输入、权重矩阵和偏置向量的梯度,分别为 dx, dW, db# 获取输入的样本数m = y.shape[1]# 计算 softmax 层的输入的梯度,即对输出和真实标签的差值dZ = y_pred - y# 计算权重矩阵的梯度,即对输入的梯度和输入的矩阵乘法的平均值dW = (1/m)*dZ.dot(x.T)# 计算偏置向量的梯度,即对输入的梯度求和db = (1/m)*np.sum(dZ,axis=1,keepdims=True)# 计算输入的梯度,即对权重矩阵的转置和输入的梯度的矩阵乘法dx =  np.dot(w.T,dZ)# 返回输入、权重矩阵和偏置向量的梯度return dx, dW,db

这段代码的目的是定义一个 softmax 层的反向传播函数,使用了 softmax 激活函数和交叉熵损失函数。softmax 层的作用是对输入的特征进行归一化和分类,实现多分类的功能。这个函数的参数和返回值如下:

  • 反向传播函数的参数有五个,一个是 y_pred,表示 softmax 层的输出,一个是 y,表示真实的标签,一个是 w,表示 softmax 层的权重矩阵,一个是 b,表示 softmax 层的偏置向量,一个是 x,表示 softmax 层的输入。反向传播函数的返回值有三个,分别是损失函数对 softmax 层输入、权重矩阵和偏置向量的梯度,分别为 dx, dW, db。

具体的计算过程如下:

  • 在反向传播函数中,首先获取输入的样本数,然后计算 softmax 层的输入的梯度,即对输出和真实标签的差值。然后计算权重矩阵的梯度,即对输入的梯度和输入的矩阵乘法的平均值。然后计算偏置向量的梯度,即对输入的梯度求和。最后计算输入的梯度,即对权重矩阵的转置和输入的梯度的矩阵乘法。

这段代码使用了 numpy 库的一些函数,例如 np.sum, np.dot 等,来实现矩阵的求和,矩阵乘法等操作。这个函数可以用于卷积神经网络的反向传播过程中,计算 softmax 层的误差项和梯度。


参考网址:

https://www.analyticsvidhya.com/blog/2022/01/convolutional-neural-network-an-overview/ Convolutional Neural Network: An Overview (analyticsvidhya.com)

https://mukulrathi.com/demystifying-deep-learning/conv-net-backpropagation-maths-intuition-derivation/  卷积神经网络中的反向传播 (mukulrathi.com)

https://medium.com/@ngocson2vn/a-gentle-explanation-of-backpropagation-in-convolutional-neural-network-cnn-1a70abff508b  A gentle explanation of Backpropagation in Convolutional Neural Network (CNN) | by Son Nguyen | Medium

https://zhuanlan.zhihu.com/p/61898234 卷积神经网络(CNN)反向传播算法推导 - 知乎 (zhihu.com)

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

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

相关文章

【Matlab】ELM极限学习机时序预测算法

资源下载: https://download.csdn.net/download/vvoennvv/88681649 一,概述 ELM(Extreme Learning Machine)是一种单层前馈神经网络结构,与传统神经网络不同的是,ELM的隐层神经元权重以及偏置都是随机产生的…

【Android12】Android Framework系列---tombstone墓碑生成机制

tombstone墓碑生成机制 Android中程序在运行时会遇到各种各样的问题,相应的就会产生各种异常信号,比如常见的异常信号 Singal 11:Segmentation fault表示无效的地址进行了操作,比如内存越界、空指针调用等。 Android中在进程(主要…

Apache-ActiveMQ 反序列化漏洞(CVE-2015-5254)复现

CVE-2016-3088 一、环境搭建 Java:jdk8 影响版本 Apache ActiveMQ < 5.13.0 二、用docker搭建漏洞环境 访问一下web界面 然后进入admin目录登录 账号:admin 密码:admin 三、工具准备 cd /opt wget https://github.com/matthiaskaiser/jmet/releases/download/0.1.0/jmet-0…

QT上位机开发(第一个应用)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 不管是软件&#xff0c;还是硬件&#xff0c;如果我们能够顺利启动第一个应用&#xff0c;点亮第一个电路的话&#xff0c;这对我们的信心来说会有…

如何恢复 iPhone 上永久删除的照片?

2007年&#xff0c;苹果公司推出了一款惊天动地的智能手机&#xff0c;也就是后来的iPhone。你会惊讶地发现&#xff0c;迄今为止&#xff0c;苹果公司已经售出了 7 亿部 iPhone 设备。根据最新一项调查数据&#xff0c;智能手机利润的 95% 都进了苹果公司的腰包。 如此受欢迎…

【Vue2+3入门到实战】(16)VUEVue路由的重定向、404、编程式导航、path路径跳转传参 详细代码示例

目录 一、Vue路由-重定向1.问题2.解决方案3.语法4.代码演示 二、Vue路由-4041.作用2.位置3.语法4.代码示例 三、Vue路由-模式设置1.问题2.语法 四、编程式导航-两种路由跳转方式1.问题2.方案3.语法4.path路径跳转语法5.代码演示 path跳转方式6.name命名路由跳转7.代码演示通过n…

2023十大编程语言及未来展望

2023十大编程语言及未来展望 1. 2023年十大编程语言排行榜2. 十大编程语言未来展望PythonCCJavaC#JavaScriptPHPVisual BasicSQLAssembly language 1. 2023年十大编程语言排行榜 TIOBE排行榜是根据互联网上有经验的程序员、课程和第三方厂商的数量&#xff0c;并使用搜索引擎&a…

阿里云PolarDB数据库优惠价格表11元一天起

阿里云数据库PolarDB租用价格表&#xff0c;云数据库PolarDB MySQL版2核4GB&#xff08;通用&#xff09;、2个节点、60 GB存储空间55元5天&#xff0c;云数据库 PolarDB 分布式版标准版2核16G&#xff08;通用&#xff09;57.6元3天&#xff0c;阿里云百科aliyunbaike.com分享…

ansible管理windows测试

一、环境介绍 Ansible管理主机&#xff1a; 系统: redhat7.6 Linux管理服务器需安装pywinrm插件 Windows客户端主机&#xff1a; 系统: Server2012R2 Windows机器需要安装或升级powershell4.0以上版本&#xff0c;Server2008R2默认的版本是2.0&#xff0c;因此必须升…

使用flutter开发windows桌面软件读取ACR22U设备的nfc卡片id,5分钟搞定demo

最近有个需求&#xff0c;要使用acr122u读卡器插入电脑usb口&#xff0c;然后读取nfc卡片的id&#xff0c;并和用户账号绑定&#xff0c;调研了很多方式&#xff0c;之前使用rust实现过一次&#xff0c;还有go实现过一次&#xff0c;然后使用electron的时候遇到安装pcsc-lite失…

MacBook查看本机IP

嘚吧嘚 其实这也不是什么困难的问题&#xff0c;但是今年刚刚入坑Mac&#xff0c;外加用的频率不是很高&#xff0c;每次使用的时候都查&#xff0c;用完就忘&#xff0c;下次用的时候再查&#x1f92e;。真的把自己恶心坏了&#x1f648;。 所以写篇文章记录一下&#x1f92…

[C++] : 贪心算法专题(第一部分)

1.柠檬水找零&#xff1a; 1.思路一&#xff1a; 柠檬水找零 class Solution { public:bool lemonadeChange(vector<int>& bills) {int file0;int ten 0;for(auto num:bills){if(num 5) file;else if(num 10){if(file > 0)file--,ten;elsereturn false;}else{i…

产品经理学习-策略产品指标

目录&#xff1a; 数据指标概述 通用指标介绍 Web端常用指标 移动端常用指标 如何选择一个合适的数据指标 数据指标概述 指标是衡量目标的一个参数&#xff0c;指一项活动中预期达到的指标、目标等&#xff0c;一般用数据表示&#xff0c;因此又称为数据指标&#xff1b;…

Flask笔记

一&#xff1a;模板渲染 一般的话都序列化成字符串 二&#xff1a;项目拆分 2.1 项目拆分 app.py init.py views.py models.py 模型数据 2.2 蓝图 三&#xff1a;路由参数 3.1 String 重点 3.2 int 3.3 path 3.4 UUID 3.5 any 四&#xff1a;请求方式 五&#xff1a;Requ…

苹果CMS超级播放器专业版无授权全开源,附带安装教程

源码介绍 超级播放器专业版v1.0.8&#xff0c;内置六大主流播放器&#xff0c;支持各种格式的视频播放&#xff0c;支持主要功能在每一个播放器内核中都相同效果。 搭建教程 1.不兼容IE浏览器 2.php版本推荐7.4 支持7.1~7.4 3.框架引入不支持同时引入多个播放器 json对接教…

新版 macos下安装python 2.7 python 3.x多版本简单方法 pyenv python多版本管理工具

在新版本的macos中已经将默认的python升级成了3.x , 今天介绍一个简单的方法在新版本的macos中快速安装 python 2.7的方法, 就是使用brew安装python版本管理工具 pyenv来安装python2.7 # 安装pyenv版本管理工具 brew install pyenv # 安装python2.7 可以安装多个版本的ptyhon…

C#进阶-IIS应用程序池崩溃的解决方案

IIS是微软开发的Web服务器软件&#xff0c;被广泛用于Windows平台上的网站托管。在使用IIS过程中&#xff0c;可能会遇到应用程序池崩溃的问题&#xff0c;原因可能有很多&#xff0c;包括代码错误、资源不足、进程冲突等。本文将为大家介绍IIS应用程序池崩溃的问题分析和解决方…

【计算机毕业设计】python+django数码电子论坛系统设计与实现

本系统主要包括管理员和用户两个角色组成&#xff1b;主要包括&#xff1a;首页、个人中心、用户管理、分类管理、数码板块管理、数码评价管理、数码论坛管理、畅聊板块管理、系统管理等功能的管理系统。 后端&#xff1a;pythondjango 前端&#xff1a;vue.jselementui 框架&a…

MySQL数据库的安装与环境配置

下载 下载MySQL8 安装 解压 配置MySQL环境变量 系统环境变量path D:\ProgramFiles\mysql-8.0.20-winx64\bin 1.点击属性 2.点击高级系统设置 3.点击环境变量 4.在系统变量中找到path 注意这里不是用户变量 5.新建后输入解压的地址 MySQL初始化和启动 以管理员身份运行cmd…

汽车制造厂批量使用成华制造弹簧平衡器

数年来&#xff0c;成华制造都在不断的向各行各界输出着自己的起重设备&#xff0c;与众多企业达成合作&#xff0c;不断供应优质产品。近些年&#xff0c;成华制造以其卓越的产品质量和高效的生产能力&#xff0c;成功实现了弹簧平衡器的大规模批量供应&#xff0c;为重庆数家…