使用python手写实现单层神经网络[本质上学习logistic 回归的系数]。单层:有参数的一层;输入不算网络层。
网络用途
或者说应用场景:使用单层神经网络来识别一张图片是否是猫咪。
网络架构
单层神经网络:
- X(input)—> Output($\hat{y}$)
处理过程:
- X –> linear —> sigmoid —> $\hat{y}$
数学表示
训练集: $X = [x^{(1)},x^{(2)},…,x^{(i)},….,x^{(m)}]$ ;对应标签:$Y=[y^{(1)},y^{(2)},…,y^{(i)},…,y^{(m)}]$ ;
对于训练集中的每张照片$x^{(i)}$ 的处理过程:
$z^{(i)} = w^Tx^{(i)}+b$
$\hat{y}^{(i)} = a^{(i)} = sigmoid(z^{(i)})$
$L(a^{(i)},y^{(i)}) = -y^{(i)}log(a^{(i)})-(1-y^{(i)})log(1-a^{(i)})$
成本函数:
$J = \frac{1}{m} \sum_{i=1}^{m} L(a^{(i)},y^{(i)})$
最后通过反向传播算法,计算参数$W$ 和 $b$ 。
模型定义
模型定义步骤
- 定义模型结构(如输入向量的特征数目)
- 初始化模型参数;
- 循环:
- 前向传播,计算loss;
- 反向传播,计算梯度;
- 梯度下降,更新参数;
代码实现
辅助函数
1 | def sigmoid(z): |
参数初始化
权重系数$W$和$b$ 全都初始化为0.
1 | def initialize_with_zeros(dim): |
前向传播和反向传播
由于网络为单层神经网络,前向传播过程和反向传播过程比较简单,所以整合到一起。直接计算出相应的成本函数和相应的系数梯度。
前向传播过程
训练集: $$X = [x^{(1)},x^{(2)},…,x^{(i)},….,x^{(m)}]$$ ;对应标签:$$Y=[y^{(1)},y^{(2)},…,y^{(i)},…,y^{(m)}] $$;
对于训练集中的每张照片$x^{(i)}$ 的处理过程:
$z^{(i)} = w^Tx^{(i)}+b$
$\hat{y}^{(i)} = a^{(i)} = sigmoid(z^{(i)})$
$L(a^{(i)},y^{(i)}) = -y^{(i)}log(a^{(i)})-(1-y^{(i)})log(1-a^{(i)})$
成本函数:$J = \frac{1}{m} \sum_{i=1}^{m} L(a^{(i)},y^{(i)})$
反向传播过程
假设输入数据维度为2;权重系数维度是2.
反向传播的计算图:
以输入维度为2,权重系数w为2维,举例:
1 | def propagate(w, b, X, Y): |
参数优化
参数更新过程–使用梯度下降算法;
1 | def optimize(w,b,X,y,num_iters,learning_rate,print_cost=True): |
模型预测
输入测试集,输出测试标签.
运算过程:做一次前向传播,得到输出;再对输出和threshold阈值作比较,得出类别标签。
1 | def predict(w,b,X): |
函数整合
1 | def model(X_train, y_train, X_test, y_test, num_iters=2000, learning_rate=0.05, print_cost=True): |
测试:500次迭代、学习率为0.001;
1 | d = model(X_train,y_train,X_test,y_test,num_iters=500,learning_rate=0.001) |
输出结果变化:
1 | Cost after iteration 0:0.6931471805599453 |
小结
- 向量化运算能大大提高运算效率;编码实现时最好不要使用for-loop 循环;
- 理解网络运算过程时,画一个运算图很很大程度上帮助理解;
- 编码实现时,注意变量的shape变化是否正确!
完整代码:>>点我