【机器学习】使用python手写三层神经网络
- 输入层到第一层的传递表示
- 第一层到第二层的传递表示
- 第二层到第三层的传递表示
- 全过程传递表示代码
输入层到第一层的传递表示
首先看输入层到第一层的第一个神经元的信号传递过程:
可以用数学式子表示第一层的第一个神经元的值:
如果用矩阵乘法运算,第一层的加权和可以表示成下面形式:
考虑激活函数的话,也就是这样一个代码表示形式:其中A1就包含了第一层所有节点的加权值。加权值带入到激活函数里得到的Z1是下一层的输入。
A1 = np.dot(X,W1) + B1
Z1 = sigmoid(A1)
第一层到第二层的传递表示
第一层到第二层的信号传递过程图如下:
同理可以写出这个传递的代码表示形式:无非是把Z1作为输入。
a2 = np.dot(z1, W2) + b2
z2 = sigmoid(a2)
第二层到第三层的传递表示
第二层到第三层的信号传递过程图如下:
可以写出这个传递的代码表示形式:
a3 = np.dot(z2, W3) + b3
y = softmax(a3)
# 或者y = a3
这里面加权和不是放到类似前面的激活函数里面。
输出层的激活函数,回归问题用恒等函数,分类问题用softmax函数。
输出层激活函数是恒等函数,则输入信号会原封不动的输出。
softmax函数的数学表示:
softmax函数输出是0-1之间的实数,并且softmax函数输出值总和是1,这样的话,可以把softmax函数的输出解释成概率。即便使用了softmax函数,各个元素之间的大小关系不会改变。
由于softmax函数要进行指数运算,指数函数的值可能会很大,导致溢出问题。
可以把分子分母都乘以C,然后我们把公式变成了exp(ak+c),如果c是输入信号中的最大值,那么公式里面减去c之后,就不会溢出了。
它的代码实现为:
def softmax(a):c = np.max(a)exp_a = np.exp(a-c)#防溢出sum_exp_a = np.sum(exp_a)y = exp_a/sum_exp_areturn y
全过程传递表示代码
代码如下,其中x是输入的图像数据。W1, W2, W3分别代表第1、2、3层的所有权重, b1, b2, b3分别代表第1、2、3层的所有偏置,默认我们的network已经训练好了权重和偏置的值。
def predict(network, x):W1, W2, W3 = network['W1'], network['W2'], network['W3']b1, b2, b3 = network['b1'], network['b2'], network['b3']a1 = np.dot(x, W1) + b1z1 = sigmoid(a1)a2 = np.dot(z1, W2) + b2z2 = sigmoid(a2)a3 = np.dot(z2, W3) + b3y = softmax(a3)return y