Python深度学习--深度学习入门-神经网络基础

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)
核心定义为
二分分类器‌:给定特征向量 x∈Rn\mathbf{x} \in \mathbb{R}^nxRn,输出样本属于正类(y=1y=1y=1)的概率预测:
y^=P(y=1∣x)=11+e−(wTx+b) \hat{y} = P(y=1|\mathbf{x}) = \frac{1}{1 + e^{-(\mathbf{w}^T\mathbf{x} + b)}} y^=P(y=1∣x)=1+e(wTx+b)1
其中 w\mathbf{w}w 为权重向量,bbb 为偏置项,Sigmoid函数将线性组合映射到(0,1)区间

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

  • 输入的特征向量x∈Rnxx \in R^{n_x}xRnx,xxx是一个 nxnxnx维的特征数量,用于训练的标签:y∈0,1y \in 0,1y0,1
  • 参数:权重:w∈Rnxw \in R^{n_x}wRnx, 偏置:b∈Rb \in RbR
  • 输出预测结果:y^=σ(wTx+b)=σ(w1x1+w2x2+...+b)=σ(θTx)\hat{y} = \sigma(w^Tx+b)=\sigma(w_1x_1+w_2x_2+...+b)=\sigma(\theta^Tx)y^=σ(wTx+b)=σ(w1x1+w2x2+...+b)=σ(θTx)
    • Sigmoid 函数: s=σ(wTx+b)=σ(z)=11+e−zs = \sigma(w^Tx+b) = \sigma(z) = \frac{1}{1+e^{-z}}s=σ(wTx+b)=σ(z)=1+ez1
    • 如果z的结果非常大,那么S的结果接近于1
    • 如果z的结果较小或者是非常大的负数,那么S的结果接近于0
      在这里插入图片描述

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

例如:

在这里插入图片描述

1.2.1.2 逻辑回归损失函数

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

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

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

该式子的理解:

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

直观解释‌:

  • 当真实标签 y=1y=1y=1 时,L=−log⁡(y^)\mathcal{L} = -\log(\hat{y})L=log(y^),预测值 y^\hat{y}y^ 越接近1损失越小
  • 当真实标签 y=0y=0y=0 时,L=−log⁡(1−y^)\mathcal{L} = -\log(1-\hat{y})L=log(1y^),预测值 y^\hat{y}y^ 越接近0损失越小

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

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

1.2.2 梯度下降算法

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

方式:梯度下降

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

img

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

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

w:=w−αdJ(w,b)dw,b:=b−αdJ(w,b)dbw := 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 就会向更大的方向更新。迭代直到收敛。

通过平面来理解梯度下降过程:

在这里插入图片描述

工作原理可视化

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 蓝色箭头:负梯度方向(最速下降方向)
  • 红色轨迹:参数更新路径
  • 谷底:目标极小值点

数学本质

泰勒展开视角

在当前位置 θt\theta_tθt 进行二阶泰勒近似:
J(θ)≈J(θt)+∇J(θt)T(θ−θt)+12(θ−θt)TH(θ−θt) J(\theta) \approx J(\theta_t) + \nabla J(\theta_t)^T(\theta-\theta_t) + \frac{1}{2}(\theta-\theta_t)^T H(\theta-\theta_t) J(θ)J(θt)+J(θt)T(θθt)+21(θθt)TH(θθt)
沿负梯度方向 θ−θt=−η∇J\theta-\theta_t = -\eta \nabla Jθθt=ηJ 更新,保证损失下降最快

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)da\frac{f(a)}{da}daf(a)或者ddaf(a)\frac{d}{da}f(a)dadf(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)=a2f(a) = a^2f(a)=a22a2a2a
f(a)=a3f(a)=a^3f(a)=a33a23a^23a2
f(a)=ln(a)f(a)=ln(a)f(a)=ln(a)1a\frac{1}{a}a1
f(a)=eaf(a) = e^af(a)=eaeae^aea
σ(z)=11+e−z\sigma(z) = \frac{1}{1+e^{-z}}σ(z)=1+ez1σ(z)(1−σ(z))\sigma(z)(1-\sigma(z))σ(z)(1σ(z))
g(z)=tanh(z)=ez−e−zez+e−zg(z) = tanh(z) = \frac{e^z - e^{-z}}{e^z + e^{-z}}g(z)=tanh(z)=ez+ezezez1−(tanh(z))2=1−(g(z))21-(tanh(z))^2=1-(g(z))^21(tanh(z))2=1(g(z))2
1.2.3.2 导数计算图

那么接下来我们来看看含有多个变量的导数流程图,假设J(a,b,c)=3(a+bc)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

  • dJdv=3\frac{dJ}{dv}=3dvdJ=3

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

  • dJda=3\frac{dJ}{da}=3dadJ=3

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

这里也涉及到链式法则

1.2.3.3 链式法则
  • dJda=dJdvdvda=3∗1=3\frac{dJ}{da}=\frac{dJ}{dv}\frac{dv}{da}=3*1=3dadJ=dvdJdadv=31=3

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

接下来计算

  • dJdb=6=dJdududb=3∗2=6\frac{dJ}{db}=6=\frac{dJ}{du}\frac{du}{db}=3*2=6dbdJ=6=dudJdbdu=32=6
  • dJdc=12=dJdududc=3∗4=12\frac{dJ}{dc}=12=\frac{dJ}{du}\frac{du}{dc}=3*4=12dcdJ=12=dudJdcdu=34=12
1.2.3.4 逻辑回归的梯度下降

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

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

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

在这里插入图片描述

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

  • dz=dJdadadz=a−ydz = \frac{dJ}{da}\frac{da}{dz} = a-ydz=dadJdzda=ay
    • dJda=−ya+1−y1−a\frac{dJ}{da} = -\frac{y}{a} + \frac{1-y}{1-a}dadJ=ay+1a1y
    • dadz=a(1−a)\frac{da}{dz} = a(1-a)dzda=a(1a)

所以我们这样可以求出总损失相对于w1w_1w1,w2w_2w2,bbb参数的某一点导数,从而可以更新参数

  • dJdw1=dJdzdzdw1=dz∗x1\frac{dJ}{dw_1} = \frac{dJ}{dz}\frac{dz}{dw_1}=dz*x1dw1dJ=dzdJdw1dz=dzx1
  • dJdw2=dJdzdzdw1=dz∗x2\frac{dJ}{dw_2} = \frac{dJ}{dz}\frac{dz}{dw_1}=dz*x2dw2dJ=dzdJdw1dz=dzx2
  • dJdb=dz\frac{dJ}{db}=dzdbdJ=dz

相信上面的导数计算应该都能理解了,所以当我们计算损失函数的某个点相对于w1w_1w1,w2w_2w2,bbb的导数之后,就可以更新这次优化后的结果。

w1:=w1−αdJ(w1,b)dw1w_1 := w_1 - \alpha\frac{dJ(w_1, b)}{dw_1}w1:=w1αdw1dJ(w1,b)

w2:=w2−αdJ(w2,b)dw2w_2 := w_2 - \alpha\frac{dJ(w_2, b)}{dw_2}w2:=w2αdw2dJ(w2,b)

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

1.2.4 向量化编程

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

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

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

初始化,假设

J=0,dw1=0,dw2=0,db=0{J} = 0, dw_1=0, dw_2=0, db={0}J=0,dw1=0,dw2=0,db=0

for i in m:

zi=wTxi+bz^i = w^Tx^i+{b}zi=wTxi+b

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

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

每个梯度计算结果相加

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

dw1+=x1idzidw_1 += x_1^idz^idw1+=x1idzi

dw2+=x2idzidw_2 +=x_2^idz^idw2+=x2idzi

db+=dzidb+=dz^idb+=dzi

最后求出平均梯度

J/=mJ /=mJ/=m

dw1/=mdw_1 /= mdw1/=m

dw2/=mdw_2 /= mdw2/=m

db/=mdb /= mdb/=m

1.2.4.1 向量化优势

什么是向量化

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

在公式z=wTx+bz = w^Tx+bz=wTx+bwww,xxx都可能是多个值,也就是wˉ=(w1⋮wn),xˉ=(x1⋮xn)\bar w = \left( \begin{array}{c}w_{1} \\ \vdots \\w_{n}\end{array}\right), \bar x= \left(\begin{array}{c}x_{1} \\\vdots \\x_{n} \end{array}\right)wˉ=w1wn,xˉ=x1xn

import numpy as np
import time
a = np.random.rand(100000)
b = np.random.rand(100000)
  • 第一种方法
# 第一种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")
  • 第二种向量化方式使用np.dot
# 向量化运算
start = time.time()
c = np.dot(a, b)
end = time.time()
print("计算所用时间%s " % str(1000*(end-start)) + "ms")

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

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

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

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

可以变成这样的计算

wˉ=(w1⋮wn),xˉ=(⋮⋮⋮⋮⋮x1x2x3⋮xm⋮⋮⋮⋮⋮)\bar w = \left(\begin{array}{c}w_{1} \\ \vdots \\w_{n}\end{array}\right), \bar{x} = \left(\begin{array}{cccc}\vdots & \vdots & \vdots & \vdots &\vdots \\ x^1& x^2 & x^3 & \vdots & x^m \\ \vdots &\vdots & \vdots & \vdots & \vdots \end{array}\right)wˉ=w1wnxˉ=x1x2x3xm

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

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

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

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

J=0,W=np.zeros([n,1]),b=0J = 0, W=np.zeros([n,1]), b={0}J=0,W=np.zeros([n,1]),b=0

Z=np.dot(WT,X)+bZ= np.dot(W^T,X)+{b}Z=np.dot(WT,X)+b

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

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

dZ=A−YdZ = {A}-{Y}dZ=AY

dW=1mXdZTdW = \frac{1}{m}X{dZ}^{T}dW=m1XdZT

db=1mnp.sum(dZ)db=\frac{1}{m}np.sum(dZ)db=m1np.sum(dZ)

更新

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

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

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

1.2.5 正向传播与反向传播

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

扁舟钓雪

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

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

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

打赏作者

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

抵扣说明:

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

余额充值