机器学习--神经网络

来源:互联网 发布:千牛for mac 编辑:程序博客网 时间:2024/06/06 02:11

机器学习–神经网络

如有错误或者疑问,欢迎交流,转载请注明出处

前向传播

神经网络的预测过程,由输入特征前向计算预测输出
course ML引用

除了输入层以外,隐藏层和输出层都是以sigmoid函数作为激活函数,输入层和隐藏层都加了偏置+1

import numpy as npform sigmoid import * #自己写一个sigmoid函数def nn_predict(theta1,theta2,X):    '''    INPUT:    theta1: 输入层到隐藏层参数 (hidden feature dim,input feature dim) ndarray    theta2: 隐藏层到输出层参数 (output label dim,hidden feature dim) ndarray    X: (m,n) ndarray m是测试样本数目     '''    m = x.shape[0]    num_labels = theta2.shape[0]    x = np.c_[np.ones(m),x] #加上偏置    z2 = x.dot(theta1.T)    a2 = sigmoid(z2)    a2 = np.c_[np.ones(m),a2] #加上偏置    z3 = a2.dot(theta2.T)    a3 = sigmoid(z3)    prediction = np.argmax(a3,axis=1) #返回概率最大的index    return prediction

反向传播学习

利用反向传播算法,根据带标签数据学习网络参数
1.定义损失函数
2.损失函数对参数求导
3.梯度法更新参数

  • cross entropy loss
    因为参考了安主的Coursera Machine Learning课程,用了这个损失函数

    J(θ)=1mmi=1Kk=1[y(i)klog((h(x(i)))k)(1y(i)k)log(1(h(x(i)))k)]

    其中m是训练样本数目,K是标签数目,感觉是逻辑回归损失函数的广泛定义,标签y是onehot编码的[0,0,0,1,…,0],类似这种

  • 残差
    残差就是损失函数对某个节点的输入的求导吧,求认证~
    所以

    对输出层的第j个节点的输入求导,有点绕~,固定住损失函数的k,针对一个样例分析,即固定i

    δ(3)j=====z(3)j(yjlogg(z(3)j)(1yj)log(1g(z(3)j)))(yj1g(z(3)j)+(1yj)11g(z(3)j))g(z(3)j)z(3)j(yj1g(z(3)j)+(1yj)11g(z(3)j))(g(z(3)j)(1g(z(3)j))yj(1g(z(3)j)+(1yj)g(z(3)j)g(z(3)j)yj

    写成向量的样子δ(3)=a(3)y
    然后回传到隐藏层,其实是在做链式求导吧~

    δ(2)=(θ(2))Tδ(3)g(z(2)) 就是把导数求到了隐藏层的输入而已吧~

    最终要求的其实是损失函数对参数的求导

    Δ(l)=δ(l+1)(a(l))T

    直观理解就是损失函数求导至l+1层的输入,而l+1层的输入是由参数θ与l层的输出线性组合得到的,所以继续链式求导就行了

#backpropagationfor i in range(m):#m是训练样本数目    a1 = X[i]#(input_layer_size+1,) ndarray    a1 = a1.reshape(1,input_layer_size+1)#这句为了形状正确~    z2 = a1.dot(theta1.T)#theta1(hidden_layer_size,input_layer_size+1)    a2 = sigmoid(z2)    a2 = np.c_[np.ones(1),a2]#增加偏置    z3 = a2.dot(theta2.T)#theta2(output_layer_size,hidden_layer_size+1)    a3 = sigmoid(z3)    delta3 = (a3 - yk[i])#yk:onehot label    z2 = np.c_[np.ones(1),z2]    delta2 = delta3.dot(theta2) * sigmoid_gradient(z2)    theta2_grad = theta2_grad + delta3.T.dot(a2)    theta1_grad = theta1_grad + delta2.T.dot(a1)[1:] #偏置项不反向传递误差theta1_grad[:,0] = theta1_grad[:,:] / mtheta2_grad[:,0] = theta2_grad[:,:] / m

代码可以借鉴一下,和公式有出路,感觉只要写好公式,注意点矩阵的形状,问题不大。

原创粉丝点击