首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

【深度学习入门】神经网络基础

  • 25-02-16 04:40
  • 2677
  • 8149
blog.csdn.net

1.2 神经网络基础

学习目标

  • 目标
    • 知道逻辑回归的算法计算输出、损失函数
    • 知道导数的计算图
    • 知道逻辑回归的梯度下降算法
    • 知道多样本的向量计算
  • 应用
    • 应用完成向量化运算
    • 应用完成一个单神经元神经网络的结构

1.2.1 Logistic回归

1.2.1.1 Logistic回归

逻辑回归是一个主要用于二分分类类的算法。那么逻辑回归是给定一个xx , 输出一个该样本属于1对应类别的预测概率 y ^ = P ( y = 1 ∣ x ) \hat{y}=P(y=1|x) y^​=P(y=1∣x)。

Logistic 回归中使用的参数如下:

  • 输入的特征向量: x ∈ R n x x \in R^{n_x} x∈Rnx​, x x x是一个 n x nx nx维的特征数量,用于训练的标签: y ∈ 0 , 1 y \in 0,1 y∈0,1
  • 参数:权重: w ∈ R n x w \in R^{n_x} w∈Rnx​, 偏置: b ∈ R b \in R b∈R
  • 输出预测结果: y ^ = σ ( w T x + b ) = σ ( w 1 x 1 + w 2 x 2 + . . . + b ) = σ ( θ T x ) \hat{y} = \sigma(w^Tx+b)=\sigma(w_1x_1+w_2x_2+...+b)=\sigma(\theta^Tx) y^​=σ(wTx+b)=σ(w1​x1​+w2​x2​+...+b)=σ(θTx)
    • Sigmoid 函数: s = σ ( w T x + b ) = σ ( z ) = 1 1 + e − z s = \sigma(w^Tx+b) = \sigma(z) = \frac{1}{1+e^{-z}} s=σ(wTx+b)=σ(z)=1+e−z1​
    • 如果z的结果非常大,那么S的结果接近于1
    • 如果z的结果较小或者是非常大的负数,那么S的结果接近于0
      在这里插入图片描述

e − z e^{-z} e−z的函数如下
在这里插入图片描述

例如:
在这里插入图片描述

1.2.1.2 逻辑回归损失函数

**损失函数(loss function)**用于衡量预测结果与真实值之间的误差。最简单的损失函数定义方式为平方差损失:

L ( y ^ , y ) = 1 2 ( y ^ − y ) 2 L(\hat{y},y) = \frac{1}{2}(\hat{y}-y)^2 L(y^​,y)=21​(y^​−y)2

逻辑回归一般使用 L ( y ^ , y ) = − ( y log ⁡ y ^ ) − ( 1 − y ) log ⁡ ( 1 − y ^ ) L(\hat{y},y) = -(y\log\hat{y})-(1-y)\log(1-\hat{y}) L(y^​,y)=−(ylogy^​)−(1−y)log(1−y^​)

该式子的理解:

  • 如果y=1,损失为 − log ⁡ y ^ - \log\hat{y} −logy^​,那么要想损失越小, y ^ \hat{y} y^​的值必须越大,即越趋近于或者等于1
  • 如果y=0,损失为 1 log ⁡ ( 1 − y ^ ) 1\log(1-\hat{y}) 1log(1−y^​),那么要想损失越小,那么 y ^ \hat{y} y^​的值越小,即趋近于或者等于0

损失函数是在单个训练样本中定义的,它衡量了在单个训练样本上的表现。代价函数(cost function)衡量的是在全体训练样本上的表现,即衡量参数 w 和 b 的效果,所有训练样本的损失平均值

J ( w , b ) = 1 m ∑ i = 1 m L ( y ^ ( i ) , y ( i ) ) J(w,b) = \frac{1}{m}\sum_{i=1}^mL(\hat{y}^{(i)},y^{(i)}) J(w,b)=m1​i=1∑m​L(y^​(i),y(i))

1.2.2 梯度下降算法

目的:使损失函数的值找到最小值

方式:梯度下降

函数的**梯度(gradient)**指出了函数的最陡增长方向。梯度的方向走,函数增长得就越快。那么按梯度的负方向走,函数值自然就降低得最快了。模型的训练目标即是寻找合适的 w 与 b 以最小化代价函数值。假设 w 与 b 都是一维实数,那么可以得到如下的 J 关于 w 与 b 的图:
在这里插入图片描述

可以看到,成本函数 J 是一个凸函数,与非凸函数的区别在于其不含有多个局部最低。

参数w和b的更新公式为:

w : = w − α d J ( w , b ) d w , b : = b − α d J ( w , b ) d b w := w - \alpha\frac{dJ(w, b)}{dw},b := b - \alpha\frac{dJ(w, b)}{db} w:=w−αdwdJ(w,b)​,b:=b−αdbdJ(w,b)​

注:其中 α 表示学习速率,即每次更新的 w 的步伐长度。当 w 大于最优解 w′ 时,导数大于 0,那么 w 就会向更小的方向更新。反之当 w 小于最优解 w′ 时,导数小于 0,那么 w 就会向更大的方向更新。迭代直到收敛。

通过平面来理解梯度下降过程:
在这里插入图片描述

1.2.3 导数

理解梯度下降的过程之后,我们通过例子来说明梯度下降在计算导数意义或者说这个导数的意义。

1.2.3.1 导数

导数也可以理解成某一点处的斜率。斜率这个词更直观一些。

  • 各点处的导数值一样
    在这里插入图片描述

我们看到这里有一条直线,这条直线的斜率为4。我们来计算一个例子

例:取一点为a=2,那么y的值为8,我们稍微增加a的值为a=2.001,那么y的值为8.004,也就是当a增加了0.001,随后y增加了0.004,即4倍

那么我们的这个斜率可以理解为当一个点偏移一个不可估量的小的值,所增加的为4倍。

可以记做 f ( a ) d a \frac{f(a)}{da} daf(a)​或者 d d a f ( a ) \frac{d}{da}f(a) dad​f(a)

  • 各点的导数值不全一致
    在这里插入图片描述

例:取一点为a=2,那么y的值为4,我们稍微增加a的值为a=2.001,那么y的值约等于4.004(4.004001),也就是当a增加了0.001,随后y增加了4倍

取一点为a=5,那么y的值为25,我们稍微增加a的值为a=5.001,那么y的值约等于25.01(25.010001),也就是当a增加了0.001,随后y增加了10倍

可以得出该函数的导数2为2a。

  • 更多函数的导数结果
函数导数
f ( a ) = a 2 f(a) = a^2 f(a)=a2 2 a 2a 2a
f ( a ) = a 3 f(a)=a^3 f(a)=a3 3 a 2 3a^2 3a2
f ( a ) = l n ( a ) f(a)=ln(a) f(a)=ln(a) 1 a \frac{1}{a} a1​
f ( a ) = e a f(a) = e^a f(a)=ea e a e^a ea
σ ( z ) = 1 1 + e − z \sigma(z) = \frac{1}{1+e^{-z}} σ(z)=1+e−z1​ σ ( z ) ( 1 − σ ( z ) ) \sigma(z)(1-\sigma(z)) σ(z)(1−σ(z))
g ( z ) = t a n h ( z ) = e z − e − z e z + e − z g(z) = tanh(z) = \frac{e^z - e^{-z}}{e^z + e^{-z}} g(z)=tanh(z)=ez+e−zez−e−z​ 1 − ( t a n h ( z ) ) 2 = 1 − ( g ( z ) ) 2 1-(tanh(z))^2=1-(g(z))^2 1−(tanh(z))2=1−(g(z))2
1.2.3.2 导数计算图

那么接下来我们来看看含有多个变量的导数流程图,假设 J ( a , b , c ) = 3 ( a + b c ) J(a,b,c) = 3{(a + bc)} J(a,b,c)=3(a+bc)

我们以下面的流程图代替
在这里插入图片描述

这样就相当于从左到右计算出结果,然后从后往前计算出导数

  • 导数计算

问题:那么现在我们要计算J相对于三个变量a,b,c的导数?

假设b=4,c=2,a=7,u=8,v=15,j=45

  • d J d v = 3 \frac{dJ}{dv}=3 dvdJ​=3

增加v从15到15.001,那么 J ≈ 45.003 J\approx45.003 J≈45.003

  • d J d a = 3 \frac{dJ}{da}=3 dadJ​=3

增加a从7到7.001,那么 v = ≈ 15.001 v=\approx15.001 v=≈15.001, J ≈ 45.003 J\approx45.003 J≈45.003

这里也涉及到链式法则

1.2.3.3 链式法则
  • d J d a = d J d v d v d a = 3 ∗ 1 = 3 \frac{dJ}{da}=\frac{dJ}{dv}\frac{dv}{da}=3*1=3 dadJ​=dvdJ​dadv​=3∗1=3

J相对于a增加的量可以理解为J相对于v, v相对于a增加的

接下来计算

  • d J d b = 6 = d J d u d u d b = 3 ∗ 2 = 6 \frac{dJ}{db}=6=\frac{dJ}{du}\frac{du}{db}=3*2=6 dbdJ​=6=dudJ​dbdu​=3∗2=6
  • d J d c = 12 = d J d u d u d c = 3 ∗ 4 = 12 \frac{dJ}{dc}=12=\frac{dJ}{du}\frac{du}{dc}=3*4=12 dcdJ​=12=dudJ​dcdu​=3∗4=12
1.2.3.4 逻辑回归的梯度下降

逻辑回归的梯度下降过程计算图,首先从前往后的计算图得出如下

  • z = w T x + b z = w^Tx + b z=wTx+b
  • y ^ = a = σ ( z ) \hat{y} =a= \sigma(z) y^​=a=σ(z)
  • L ( y ^ , y ) = − ( y log ⁡ a ) − ( 1 − y ) log ⁡ ( 1 − a ) L(\hat{y},y) = -(y\log{a})-(1-y)\log(1-a) L(y^​,y)=−(yloga)−(1−y)log(1−a)

那么计算图从前向过程为,假设样本有两个特征

在这里插入图片描述

问题:计算出$J 关于 关于 关于z$的导数

  • d z = d J d a d a d z = a − y dz = \frac{dJ}{da}\frac{da}{dz} = a-y dz=dadJ​dzda​=a−y
    • d J d a = − y a + 1 − y 1 − a \frac{dJ}{da} = -\frac{y}{a} + \frac{1-y}{1-a} dadJ​=−ay​+1−a1−y​
    • d a d z = a ( 1 − a ) \frac{da}{dz} = a(1-a) dzda​=a(1−a)

所以我们这样可以求出总损失相对于 w 1 w_1 w1​, w 2 w_2 w2​, b b b参数的某一点导数,从而可以更新参数

  • d J d w 1 = d J d z d z d w 1 = d z ∗ x 1 \frac{dJ}{dw_1} = \frac{dJ}{dz}\frac{dz}{dw_1}=dz*x1 dw1​dJ​=dzdJ​dw1​dz​=dz∗x1
  • d J d w 2 = d J d z d z d w 1 = d z ∗ x 2 \frac{dJ}{dw_2} = \frac{dJ}{dz}\frac{dz}{dw_1}=dz*x2 dw2​dJ​=dzdJ​dw1​dz​=dz∗x2
  • d J d b = d z \frac{dJ}{db}=dz dbdJ​=dz

相信上面的导数计算应该都能理解了,所以当我们计算损失函数的某个点相对于 w 1 w_1 w1​, w 2 w_2 w2​, b b b的导数之后,就可以更新这次优化后的结果。

w 1 : = w 1 − α d J ( w 1 , b ) d w 1 w_1 := w_1 - \alpha\frac{dJ(w_1, b)}{dw_1} w1​:=w1​−αdw1​dJ(w1​,b)​

w 2 : = w 2 − α d J ( w 2 , b ) d w 2 w_2 := w_2 - \alpha\frac{dJ(w_2, b)}{dw_2} w2​:=w2​−αdw2​dJ(w2​,b)​

b : = b − α d J ( w , b ) d b b := b - \alpha\frac{dJ(w, b)}{db} b:=b−αdbdJ(w,b)​

1.2.4 向量化编程

每更新一次梯度时候,在训练期间我们会拥有m个样本,那么 这样每个样本提供进去都可以做一个梯度下降计算。所以我们要去做在所有样本上的计算结果、梯度等操作

J ( w , b ) = 1 m ∑ i = 1 m L ( a ( i ) , y ( i ) ) J(w,b) = \frac{1}{m}\sum_{i=1}^mL({a}^{(i)},y^{(i)}) J(w,b)=m1​i=1∑m​L(a(i),y(i))

计算参数的梯度为: d ( w 1 ) i , d ( w 2 ) i , d ( b ) i d(w_1)^{i}, d(w_2)^{i},d(b)^{i} d(w1​)i,d(w2​)i,d(b)i,这样,我们想要得到最终的 d w 1 , d w 2 , d b d{w_1},d{w_2},d{b} dw1​,dw2​,db,如何去设计一个算法计算?伪代码实现:

初始化,假设

J = 0 , d w 1 = 0 , d w 2 = 0 , d b = 0 {J} = 0, dw_1=0, dw_2=0, db={0} J=0,dw1​=0,dw2​=0,db=0

for i in m:

z i = w T x i + b z^i = w^Tx^i+{b} zi=wTxi+b

a i = σ ( z i ) a^i = \sigma(z^i) ai=σ(zi)

J + = − [ y i l o g ( a i ) + ( 1 − y i ) l o g ( 1 − a i ) ] J +=-[y^ilog(a^i)+(1-y^i)log(1-a^i)] J+=−[yilog(ai)+(1−yi)log(1−ai)]

每个梯度计算结果相加

$ dz^i = ai-y{i}$

d w 1 + = x 1 i d z i dw_1 += x_1^idz^i dw1​+=x1i​dzi

d w 2 + = x 2 i d z i dw_2 +=x_2^idz^i dw2​+=x2i​dzi

d b + = d z i db+=dz^i db+=dzi

最后求出平均梯度

J / = m J /=m J/=m

d w 1 / = m dw_1 /= m dw1​/=m

d w 2 / = m dw_2 /= m dw2​/=m

d b / = m db /= m db/=m

1.2.4.1 向量化优势

什么是向量化

由于在进行计算的时候,最好不要使用for循环去进行计算,因为有Numpy可以进行更加快速的向量化计算。

在公式 z = w T x + b z = w^Tx+b z=wTx+b中 w w w, x x x都可能是多个值,也就是 w ˉ = ( w 1 ⋮ w n ) , x ˉ = ( x 1 ⋮ x n ) \bar w = \left(

w1⋮wn
\right), \bar x= \left(
x1⋮xn
\right) wˉ= ​w1​⋮wn​​ ​,xˉ= ​x1​⋮xn​​ ​

import numpy as np
import time
a = np.random.rand(100000)
b = np.random.rand(100000)
  • 1
  • 2
  • 3
  • 4
  • 第一种方法
# 第一种for 循环
c = 0
start = time.time()
for i in range(100000):
    c += a[i]*b[i]
end = time.time()

print("计算所用时间%s " % str(1000*(end-start)) + "ms")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 第二种向量化方式使用np.dot
# 向量化运算
start = time.time()
c = np.dot(a, b)
end = time.time()
print("计算所用时间%s " % str(1000*(end-start)) + "ms")
  • 1
  • 2
  • 3
  • 4
  • 5

Numpy能够充分的利用并行化,Numpy当中提供了很多函数使用

函数作用
np.ones or np.zeros全为1或者0的矩阵
np.exp指数计算
np.log对数计算
np.abs绝对值计算

所以上述的m个样本的梯度更新过程,就是去除掉for循环。原本这样的计算

1.2.4.2 向量化实现伪代码
  • 思路
z 1 = w T x 1 + b z^1 = w^Tx^1+b z1=wTx1+b z 2 = w T x 2 + b z^2 = w^Tx^2+b z2=wTx2+b z 3 = w T x 3 + b z^3 = w^Tx^3+b z3=wTx3+b
a 1 = σ ( z 1 ) a^1 = \sigma(z^1) a1=σ(z1) a 2 = σ ( z 2 ) a^2 = \sigma(z^2) a2=σ(z2) a 3 = σ ( z 3 ) a^3 = \sigma(z^3) a3=σ(z3)

可以变成这样的计算

w ˉ = ( w 1 ⋮ w n ) , x ˉ = ( ⋮ ⋮ ⋮ ⋮ ⋮ x 1 x 2 x 3 ⋮ x m ⋮ ⋮ ⋮ ⋮ ⋮ ) \bar w = \left(

w1⋮wn
\right), \bar{x} = \left(
⋮x1⋮⋮x2⋮⋮x3⋮⋮⋮⋮⋮xm⋮
\right) wˉ= ​w1​⋮wn​​ ​,xˉ= ​⋮x1⋮​⋮x2⋮​⋮x3⋮​⋮⋮⋮​⋮xm⋮​ ​

注:w的形状为(n,1), x的形状为(n, m),其中n为特征数量,m为样本数量

我们可以让 Z = W T X + b = ( z 1 , z 2 , z 3 ⋯ z m ) + b = n p . d o t ( W T , X ) + b Z= {W^T}X + b=\left(z^1, z^2,z^3\cdots z^m \right)+b=np.dot(W^T,X)+b Z=WTX+b=(z1,z2,z3⋯zm)+b=np.dot(WT,X)+b,得出的结果为(1, m)大小的矩阵 注:大写的 W , X W,X W,X为多个样本表示

  • 实现多个样本向量化计算的伪代码

初始化,假设n个特征,m个样本

J = 0 , W = n p . z e r o s ( [ n , 1 ] ) , b = 0 J = 0, W=np.zeros([n,1]), b={0} J=0,W=np.zeros([n,1]),b=0

Z = n p . d o t ( W T , X ) + b Z= np.dot(W^T,X)+{b} Z=np.dot(WT,X)+b

A = σ ( Z ) A = \sigma(Z) A=σ(Z)

每个样本梯度计算过程为:

d Z = A − Y dZ = {A}-{Y} dZ=A−Y

d W = 1 m X d Z T dW = \frac{1}{m}X{dZ}^{T} dW=m1​XdZT

d b = 1 m n p . s u m ( d Z ) db=\frac{1}{m}np.sum(dZ) db=m1​np.sum(dZ)

更新

W : = W − α d W W := W - \alpha{dW} W:=W−αdW

b : = b − α d b b := b - \alpha{db} b:=b−αdb

这相当于一次使用了M个样本的所有特征值与目标值,那我们知道如果想多次迭代,使得这M个样本重复若干次计算

1.2.5 正向传播与反向传播

前面我们所做的整个过程分为两个部分,一个是从前往后的计算出梯度与损失,另外一部分是从后往前计算参数的更新梯度值。所以在神经网络当中会经常出现两个概念,正向传播与反向传播。

注:本文转载自blog.csdn.net的道友老李的文章"https://blog.csdn.net/u014608435/article/details/144378510"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2491) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top