机器学习--神经网络

本文介绍了神经网络的基本原理,包括前向传播算法用于预测输出,以及通过反向传播算法进行参数学习的过程。文中详细推导了损失函数及其求导,并展示了如何通过梯度下降法更新权重。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

机器学习–神经网络

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

前向传播

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

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

import numpy as np
form 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层的输出线性组合得到的,所以继续链式求导就行了

#backpropagation
for 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[:,:] / m
theta2_grad[:,0] = theta2_grad[:,:] / m

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值