Deep Learning学习笔记(1)

时间:2022-12-14 22:48:50

DeepLearning学习笔记


大纲

Logisitic Regression逻辑回归
1. 二分分类
2. 符号约定
3. 逻辑回归
4. 梯度下降法
5. Vectorization向量化
6. Python Broadcasting广播

Logisitic Regression逻辑回归

二分分类

输入对象--->提取特征向量\(x\)(维度为\(n\))--->分类器--->输出预测标签\(y\)(\(1\)\(0\))

符号约定

训练样本\((x,y)\)----\(x\)代表\(n\)维的特征向量, \(y\)代表标签(\(0\)\(1\)), \(m\)个样本即为\((x_1,y_2),(x_2,y_2), ... ,(x_m,y_m)\)

训练样本集\(X\)----\(X = (x_1, x_2, ... , x_m)\), 维度为\((n * m)\)

标签集\(Y\)----\(Y = (y_1, y_2, ... , y_m)\), 维度为\((1 * m)\)

回归函数\(z\)----\(z = w^Tx + b\)

微分符号----\(dz = \frac{dJ}{dz}, dw = \frac{\partial J}{\partial w}, db = \frac{\partial J}{\partial b}\)

逻辑回归

  • 思路: 特征向量\(x\)--->算法--->预测标签\(\hat y\)(概率值\(P\in (0, 1)\))
  • 参数: \(w\)(\(n\)维向量), \(b\)(实数\(R\)
  • 逻辑回归算法: 用于计算预测输出值\(\hat y\)
    \[\hat y = \sigma(w^Tx + b)\]
    \[\sigma(z) = \frac{1}{e^{-z} + 1}, z = w^Tx + b\]
    Deep Learning学习笔记(1)
    由图示可见
  1. \(z\to \infty\), \(\sigma(z)\to 1\)
  2. \(z\to 0\)\(\sigma(z)\to 0\)
  • Loss Function损失函数: 用于衡量预测输出值\(\hat y\)与标签\(y\)有多接近(衡量单个训练样本的表现)
    \[L(\hat y, y) = - (ylg\hat y + (1 - y)lg(1 - \hat y))\]
    \(L\)值越小, 则预测值与真实值越接近, 即损失损越小
    分析可知:
  1. \(y = 1\)时, \(L(\hat y, y) = -lg\hat y\), \(L\to 0 \Rightarrow \hat y\to 1\)
  2. \(y = 0\)时, \(L(\hat y, y) = - lg(1 - \hat y)\), \(L\to 0 \Rightarrow \hat y\to 0\)
  • 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_ilg\hat y_i + (1 - y_i)lg(1 - \hat y_i)]\]

梯度下降法

梯度下降法用于得到回归算法中合适的参数\(w\)\(b\), 即让\(J(w, b)\)尽量小的\(w\)\(b\)

\(J(w, b)\)是凹函数, 当\(w\)\(b\)都仅为一个实数时, \(J(w, b)\)如图

设定参数\(w\)\(b\)的初始值, 获得对应的\(J(w, b)\)函数, 令
\[w' = w - \alpha\frac{\partial J(w,b)}{\partial w}\]
\[b' = b - \alpha\frac{\partial J(w,b)}{\partial b}\]
其中\(\alpha\)是学习率。然后令\(w = w', b = b'\), 使\(w\)\(b\)的值得到更新, 通过不断重复这个步骤, 最终将得到使\(J(w, b)\)趋于最小值时的\(w, b\)

根据导数计算可得

\[dz_i = \hat y_i -y_i, dw = \frac{1}{m}\sum_{i=1}^m x_idz_i\]
\[db = \frac{1}{m}\sum_{i=1}^m dz_i\]

Vectorization向量化

处理庞大的数据样本时应避免使用非向量化算法, 如for loop, 下面是向量化和非向量化算法在相同运算量下的速度差别

import numpy as np                   #导入numpy
import time

a = np.random.rand(1000000) #两个一百万维的矩阵
b = np.random.rand(1000000)

tic = time.time() #计算前的时间
c = np.dot(a,b) #向量化运算
toc = time.time() #计算后的时间

print(c)
print("Vectorized version: " + str(1000*(toc-tic)) + "ms") #计算用时

c = 0
tic = time.time()
for i in range(1000000): #非向量化运算
c += a[i]*b[i]
toc = time.time()

print(c)
print("for loop: " + str(1000*(toc-tic)) + "ms")

输出结果

249919.47604
Vectorized version: 1.5935897827148438ms
249919.47604
for loop: 330.3234577178955ms

np.function()这样的内置函数能充分利用并行化去进行更快的计算, 将多个数据整合成一个向量矩阵, 从而实现并行化运算, 这就是并行的主要思想

  • 逻辑回归的向量化
    现在将逻辑回归的数学形式转换为向量化的结构
    由向量乘法运算可知

    \(Z = (z_1, z_2, ..., z_m) = (w^Tx_1 + b, w^Tx_2 + b, ..., w^Tx_m + b)= w^TX + (b, b, ..., b) = np.dot(w.T,x) + b\)

    \(A = \sigma(Z)\)

    \(dZ = (dz_1, dz_2, ..., dz_m) = (\hat y_1 - y_1, \hat y_2 - y_2, ..., \hat y_m - y_m) = A - Y\) (求导可得)

    \(db = \frac{1}{m}\sum_{i = 1}^m dz_i = \frac{1}{m} np.sum(dZ)\) (求导可得)

    \(dw = \frac{1}{m}\sum_{i = 1}^m x_idz_i = \frac{1}{m}XdZ^T\) (求导可得)
    \(w' = w - \alpha dw\)

    \(b' = b - \alpha db\) (更新\(w\)\(b\))

    这样就将原本需要两次for循环的结构高度向量化了, 如果需要多次更新\(w\)\(b\)值, 则还是需要使用for循环

Python Broadcasting广播

Python中的广播特性能够简化计算的输入, 让代码运行更快。 其主要用来处理对一个矩阵的所有行或所有列做相同的变换的情况, 下面是一些例子

\[\begin{pmatrix} 2 \\ 0 \\ 3 \\ 7 \end{pmatrix} \qquad + \qquad 300 \qquad \Rightarrow \qquad \begin{pmatrix} 2 \\ 0 \\ 3 \\ 7 \end{pmatrix} \qquad + \qquad \begin{pmatrix} 300 \\ 300 \\ 300 \\ 300 \end{pmatrix}\]

\[\begin{pmatrix} 1 & 2 & 3 \\ 2 & 3 & 6 \end{pmatrix} + \begin{pmatrix} 300 & 500 & 900 \end{pmatrix} \Rightarrow \begin{pmatrix} 1 & 2 & 3 \\ 2 & 3 & 6 \end{pmatrix} + \begin{pmatrix} 300 & 500 & 900 \\ 300 & 500 & 900 \end{pmatrix}\]

\[\begin{pmatrix} 7 & 5 & 3 \\ 2 & 4 & 6 \end{pmatrix} \quad + \quad \begin{pmatrix} 200 \\ 700 \end{pmatrix} \quad \Rightarrow \quad \begin{pmatrix} 7 & 5 & 3 \\ 2 & 4 & 6 \end{pmatrix} \quad + \quad \begin{pmatrix} 200 & 200 & 200 \\ 700 & 700 & 700 \end{pmatrix}\]

可以在NumPy文档中的“广播“中了解到更广义的用法


KNN: 是一个模型, 和迭代过程是不一样的概念

图片数据: 三个矩阵数据,分别用于存储图像所有像素的R,G,B值

SIMD指令: 并行化指令, 单指令流多数据流

numpy向量说明: 避免使用\(r(A)\)\(1\)的行向量, 或用reshape将其转化为列向量; 使用assert(a.shape == (m,m))确保_a_是一个向量