吴恩达深度学习【听课笔记】__4.向量化__

向量化

  • 向量化是去除代码中显示for循环的艺术。

  • 假设现在x和W都是一个向量:
    x = ( x 1 . . . x n ) , W = ( W 1 . . . W n ) x =\left(\begin{matrix} x_1 \\ ... \\ x_n \end{matrix} \right), W = \left(\begin{matrix} W_1 \\ ... \\ W_n \end{matrix} \right) x= x1...xn ,W= W1...Wn
    并有函数:
    Z = W × x + b Z = W\times x + b Z=W×x+b
    非向量化计算函数Z:

    int Z = 0;
    int W[n] = {....};
    int x[n] = {....};
    int b = arg;
    for(int i = 1; i <= n; i++){
        Z += W[i]*x[i];
    }
    Z += b;
    

    向量化计算函数Z:

    int vectorFunc(int* W, int* x); 
    // 专门用于计算矩阵乘法的函数
    int Z = 0;
    int W[n] = {....};
    int x[n] = {....};
    int b = arg;
    Z = vectorFunc(W, x) + b;
    

    向量化消除了代码中显示的for循环。

  • 这里有一条编写神经网络的建议:“Whenever possible, avoid explicit for-loops.”

    “尽可能的避免显示的for循环。”

Logisitic的向量化

  • 我们用以下算式对M个样本进行Logistic:
    z ( 1 ) = W T x ( 1 ) + b z^{(1)}=W^Tx^{(1)}+b z(1)=WTx(1)+b

    z ( 2 ) = W T x ( 2 ) + b z^{(2)}=W^Tx^{(2)}+b z(2)=WTx(2)+b

    . . . . . . ... ... ......

    z ( m ) = W T x ( m ) + b z^{(m)}=W^Tx^{(m)}+b z(m)=WTx(m)+b

    其中,z和b都是实数,而W和x都是一维向量:
    z ∈ R , b ∈ R , W T = ( w 1 . . . w n ) , X = ( x 1 . . . x n ) z \in R, b\in R, W^T= \left(\begin{matrix} w_1 & ... & w_n \end{matrix} \right), X = \left(\begin{matrix} x_1 \\ ... \\ x_n \end{matrix} \right) zR,bR,WT=(w1...wn),X= x1...xn

  • 我们使用向量化简化上述的m个算式,只需要把z和b也都定义为向量:
    Z = ( z 1 . . . z n ) , b = ( b 1 . . . b n ) Z = \left(\begin{matrix} z_1 & ... & z_n \end{matrix} \right), b = \left(\begin{matrix} b_1 & ... & b_n \end{matrix} \right) Z=(z1...zn),b=(b1...bn)
    此时,m个算式可简化为一个:
    Z = ( z 1 . . . z n ) = W T X + b = ( w 1 . . . w n ) × ( x 1 . . . x n ) + ( b 1 . . . b n ) Z = \left(\begin{matrix} z_1 & ... & z_n \end{matrix} \right)=W^TX+b = \left(\begin{matrix} w_1 & ... & w_n \end{matrix} \right)\times \left(\begin{matrix} x_1 \\... \\x_n\end{matrix} \right)+\left(\begin{matrix}b_1&... &b_n\end{matrix} \right) Z=(z1...zn)=WTX+b=(w1...wn)× x1...xn +(b1...bn)

    Z = [ ( W T x ( 1 ) + b 1 ) ( W T x ( 2 ) + b 2 ) . . . ( W T x ( n ) + b n ) ] Z = \left[\begin{matrix} (W^Tx^{(1)} + b_1) & (W^Tx^{(2)}+b_2) &... & (W^Tx^{(n)}+b_n) \end{matrix} \right] Z=[(WTx(1)+b1)(WTx(2)+b2)...(WTx(n)+bn)]

  • 以上的计算过程为正向传播(forward),同样可以使用向量化反向传播(backward)。

Logistic向量化的梯度下降

  • 我们多样本Logistic的代码是这样写的:

    #define MAX_TIMES N 
    // 假设我们希望更新W的次数为N,即梯度下降N次
    int W , b;
    // 进行梯度下降的W和b
    for(int j = 0; j<MAX_TIMES; j++){
        int dw = 0, db = 0, dz=0, z[m], x[m], a[m];
        // dw是每一轮的求导值,db是参数,dz存放每一轮的损失函数值
        // z[m]存放每一轮的计算结果(forward),x[m]是每一轮输入的数据
        // a[m]存放是每一轮的真实值,a[i]-z[i]即为损失值
        for(int i = 1; i<m; i++){	// ===将这个for循环去除====
            z[i] = W*x[i] + b;
            dz = a[i] - z[i];	// 这样求出dz有些草率,这里只做演示
            int dwi = x[i]*dz;
            int dbi = dz;
            // 这个计算dwi和dbi的方式写在前面的简化里
            dw += dwi;
            db += dbi;
            // 求和
        }
        dw /= m;
        db /= b;
        // 求平均值
        w = w - a*dw;
        b = b - a*db;
        // 更新w和b的值
    }
    

    最外层的循环我们不需要去掉,因为这是在遍历参数的更新次数。但是内循环可以去掉,可以将m个样本一次计算完。

逐句向量化for循环内的代码

  • 其中的z[i] = W*x[i] + b可以简化为向量操作(共有m个样本,每个样本n个值):
    z = ( w 1 . . . w n ) × [ x 1 1 . . . x 1 m . . . . . . . . . x n 1 . . . . x n m ] + [ b 1 . . . b m ] z = \left(\begin{matrix} w_1 & ... & w_n \end{matrix} \right)\times \left[\begin{matrix} x_1^1&...&x_1^m \\ ...& ... &...\\ x_n^1 & .... & x_n^m \end{matrix} \right] + \left[\begin{matrix} b_1 &...& b_m\end{matrix} \right] z=(w1...wn)× x11...xn1..........x1m...xnm +[b1...bm]

  • 最终的z是一个一维m列的向量:
    z = [ z 1 . . . z m ] z = \left[\begin{matrix} z_1 &...& z_m\end{matrix} \right] z=[z1...zm]

  • 对应的真实值a,同样是一个一维m列的向量:
    a = [ a 1 . . . a m ] a = \left[\begin{matrix} a_1 &...& a_m\end{matrix} \right] a=[a1...am]

  • 其中的dz = a[i] - z[i]就可以写为向量操作:
    d z = [ ( a i − z i ) . . . ( a m − z m ) ] , dz = \left[\begin{matrix} (a_i-z_i) & ... & (a_m-z_m) \end{matrix} \right], dz=[(aizi)...(amzm)],

  • 其中的int dwi = dz*x[i]同样转换为向量操作,dwi同样会变成m列的一维矩阵:
    d w i = [ ( a i − z i ) . . . ( a m − z m ) ] × [ x 1 1 . . . x 1 m . . . . . . . . . x n 1 . . . . x n m ] dw_i = \left[\begin{matrix} (a_i-z_i) & ... & (a_m-z_m) \end{matrix} \right] \times \left[\begin{matrix} x_1^1&...&x_1^m \\ ...& ... &...\\ x_n^1 & .... & x_n^m \end{matrix} \right] dwi=[(aizi)...(amzm)]× x11...xn1..........x1m...xnm
    d w i = [ d w 1 . . . d w m ] dw_i = \left[\begin{matrix} dw_1 & ... & dw_m \end{matrix} \right] dwi=[dw1...dwm]

  • 其中int dbi = dz;转换为向量化操作:
    d b i = [ ( a i − z i ) . . . ( a m − z m ) ] dbi = \left[\begin{matrix} (a_i-z_i) & ... & (a_m-z_m) \end{matrix} \right] dbi=[(aizi)...(amzm)]

  • 其中,dw += dwi;db += dbi;是两个求和操作,把矩阵的每一列相加即可,这一步通常都有现成的方法。
    d w = d w 1 + d w 2 + . . . + d w m dw = dw_1 + dw_2 + ...+ dw_m dw=dw1+dw2+...+dwm
    d b = d b 1 + d b 2 + . . . + d b m db = db_1 + db_2 + ...+ db_m db=db1+db2+...+dbm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值