深度学习笔记(三)——神经网络和深度学习(神经网络基础二)

1.向量化

深度学习算法中,数据量很大,在程序中应该尽量减少使用loop循环语句,而可以使用向量运算来提高程序运行速度。向量化(Vectorization)就是利用矩阵运算的思想,从而大大提高运算速度。

为了加快深度学习神经网络运算速度,可以使用比CPU运算能力更强大的GPU。事实上,GPU和CPU都有并行指令(parallelization instructions),称为Single Instruction Multiple Data(SIMD)。SIMD是单指令多数据流,能够复制多个操作数,并把它们打包在大型寄存器的一组指令集。SIMD能够大大提高程序运行速度,例如python的numpy库中的内建函数(built-in function)就是使用了SIMD指令。相比而言,GPU的SIMD要比CPU更强大一些。

在python的numpy库中,我们通常使用np.dot()函数来进行矩阵运算。我们将向量化的思想使用在逻辑回归算法上,尽可能减少for循环,而只使用矩阵运算。值得注意的是,算法最顶层的迭代训练的for循环是不能替换的。而每次迭代过程对J,dw,b的计算是可以直接使用矩阵运算。

2.向量化logistic回归及其梯度输出

利用向量化的思想,所有m个样本的线性输出Z可以用矩阵表示:

Z = w^{T}X + b

在python的numpy库中可以表示为:

Z = np.dot(w.T,X) + b
A = sigmoid(Z)

其中,w^{T}表示w的转置。

这样,我们就能够使用向量化矩阵运算代替for循环,对所有m个样本同时运算,大大提高了运算速度。

对于所有m个样本,dZ的维度是(1,m),可表示为:

dZ = A - Y

db可表示为:

db = \frac{1}{m}\sum_{i=1}^{m}d z^{(i)}

对应的程序为:

db = 1/m*np.sum(dZ)

dw可表示为:

dw = \frac{1}{m}X\cdot dZ^{T}

对应的程序为:

dw = 1/m*np.dot(X,dZ.T)

这样,整个逻辑回归中的for循环尽可能用矩阵运算代替,对于单次迭代,梯度下降算法流程如下所示:

Z = np.dot(w.T,X) + b
A = sigmoid(Z)
dZ = A-Y
dw = 1/m*np.dot(X,dZ.T)
db = 1/m*np.sum(dZ)

w = w - alpha*dw
b = b - alpha*db

其中,alpha是学习因子,决定w和b的更新速度。上述代码只是对单次训练更新而言的,外层还需要一个for循环,表示迭代次数。

3.Python中的广播

python中的广播机制可由下面四条表示:

  • 让所有输入数组都向其中shape最长的数组看齐,shape中不足的部分都通过在前面加1补齐

  • 输出数组的shape是输入数组shape的各个轴上的最大值

  • 如果输入数组的某个轴和输出数组的对应轴的长度相同或者其长度为1时,这个数组能够用来计算,否则出错

  • 当输入数组的某个轴的长度为1时,沿着此轴运算时都用此轴上的第一组值

简而言之,就是python中可以对不同维度的矩阵进行四则混合运算,但至少保证有一个维度是相同的。

在python程序中为了保证矩阵运算正确,可以使用reshape()函数来对矩阵设定所需的维度。

 4.关于python/numpy向量的说明

python中,如果我们用下列语句来定义一个向量:

a = np.random.randn(5)

这条语句生成的a的维度是(5,)。它既不是行向量也不是列向量,它是rank 1 array。如果对a进行转置,会得到a本身。所以,如果要定义(5,1)的列向量或者(1,5)的行向量,最好使用下面的标准语句。

a = np.random.randn(5,1)
b = np.random.randn(1,5)

还可以使用assert语句对向量或数组的维度进行判断:

assert(a.shape == (5,1))

assert会对内嵌语句进行判断,即判断a的维度是不是(5,1)的。如果不是,则程序在此处停止。使用assert语句是一种能够及时检查、判断语句是否正确的好习惯。

此外,还可以使用reshape函数对数组设定所需的维度:

a.reshape((5,1))

5.Jupyter/Ipython笔记本的快速指南

分享两篇大佬的博客:

Jupyter notebook入门教程(上)

Jupyter notebook入门教程(下)

6.(选修)logistic损失函数的解释

预测输出\hat{}\hat{y}的表达式可以写成:

\hat{y} = \sigma (w^{T}x + b)
其中,\sigma (z) = \frac{1}{1-e^{-z}}

\hat{y}可以看成是预测输出为1的概率:

\hat{y} = P(y = 1|x)

当y=1时:

p(y|x) = \hat{y}
当y=0时:

p(y|x) = 1 - \hat{y}

上述两个式子可以合并为:

P(y|x) = \hat{y}^{y}(1-\hat{y})^{(1-y)}

由于log函数是严格单调递增的函数,所以可以把上面的式子处理成:

logP(y|x) = ylog\hat{y} + (1-y)log(1-\hat{y})

这就是前面所提到的单个训练样本成本函数的负值。前面有一个负号的原因是:当训练学习算法时,希望算法输出值的概率是最大的。但在logistic回归中,我们需要最小化损失函数,最小化损失函数就是最大化logP(y|x)

如果对于所有m个训练样本,假设样本之间是独立同分布(IID)的,那么还是希望总的概率越大越好:

max\prod_{i=1}^{m}P(y^{(i)}|x^{(i)})

取log,加上负号,转化为前面提到的Cost function:

J(w,b) = -\frac{1}{m}\sum_{i=1}^{m}L(\hat{y}^{(i)},y^{(i)}) = -\frac{1}{m}\sum_{i=1}^{m}y^{(i)}log\hat{y}^{(i)}+(1-y^{(i)})log(1-\hat{y}^{(i)})

其中\frac{1}{m}是缩放因子,表示对所有m个样本的Cost function求平均。

猜你喜欢

转载自blog.csdn.net/zhao2018/article/details/82931409