斯坦福cs231n学习笔记(6)------神经网络初步

从这一篇开始,我们将进入神经网络学习中。

一、起源

说到神经网络,必然先从生物神经元的结构说起:

左边细胞主体(cell body),它的周围有许多突触(dendrites),突触(dendrites)与周围的神经元相连,所有实际上这个神经元周围还有很多的神经元,突触(dendrites)就是与其他神经元相互连接 的桥梁。看图中的蓝色箭头,从突触(dendrites)开始输入,进入神经元,然后通过轴突(axon),用来传递输出。所以一般这个神经元接受输入,如果同时有很多个神经元在工作,这个神经元可以阻断一些信号,选择一个信号传递给轴突(axon),图中的轴突有两个分叉,可以连接到其他的神经元上,其他神经元的树突连接到这个轴突上。总的来说,这个神经元处于一个神经网络中,树突是神经元的输入,轴突是神经元的输出。

二、引入

下面,我们再来看一个数学神经元结构,和这个差不多:

X0是来自其他神经元的轴突(axon),每一个突触(dendrite)都有一个属于它自己的权重,用来表达两个神经元的相似度。轴突携带X0与突触进行交流,然后用这个粗糙的模型进行乘法,所以我们得到W0*X0传向细胞主体(cell body),细胞主体在这里执行了一个操作,把所有输入求和再加上偏置,在后面的轴突上有一个激活方程(activation function),数据经过激活方程,得到这个神经元的输出。在生物学模型中,历史上人们习惯用sigmoid函数作为激活方程,因为经过sigmoid函数得到的结果是介于[0,1]之间的数,我们可以理解为这个是神经元对于某个输入的处理比率,所以激活函数得到的是一个比率值。如果这个神经元在上一个神经元的输出中找到了它喜欢的东西,那么比率值就会很大。
sigmoid

三、一些细节

我们看一下相应的Python伪代码:

class Neuron(object):
  # ... 
  def forward(self, inputs):
    """ assume inputs and weights are 1-D numpy arrays and bias is a number """
    cell_body_sum = np.sum(inputs * self.weights) + self.bias
    firing_rate = 1.0 / (1.0 + math.exp(-cell_body_sum)) # sigmoid activation function
    return firing_rate

一个神经元执行函数,向前传递,它会接受输入,输出都是一个向量,在细胞体内进行线性加和,然后用sigmoid函数作为细胞体上的激发速率,最后这个函数的返回值可以传播到其他的神经元上。
这一模式就像前几篇文章中所提到的线性分类器,有x,w,b。所以,每一个单个的神经元都可以看作是一个小线性分类器,只是这些神经元是彼此相连的,他们可以一起工作,完成interesting的任务。
再来说一下,一些常用的激活函数:

在机器学习的历史上,人们一开始使用的是tanh函数,到了2012年,ReLu开始流行,因为这个函数使神经网络的效率非常高,所以ReLu是非线性函数的默认选择。右边的是一些高级的激活函数。在后面的文章会详细的介绍如何使用它们。

四、神经网络组成

如下图所示,是一个单隐藏层神经网络或者叫2层神经网络,计算神经网络需要算的是有权的层数,而输入层的神经元只有输入值(没有权),也就是说输入层不算在层数中。另外,我们称这些层为全连接层(每一层的神经元都连着下一层的所有神经元)。

Python伪码:

class Neuron(object):
  # ... 
  def forward(self, inputs):
    """ assume inputs and weights are 1-D numpy arrays and bias is a number """
    cell_body_sum = np.sum(inputs * self.weights) + self.bias
    firing_rate = 1.0 / (1.0 + math.exp(-cell_body_sum)) # sigmoid activation function
    return firing_rate

还有对隐藏层神经网络,我们准备这么多层是因为分层设计可以使得计算更加高效,语气设置大量的没有明确组织结构的神经元,并让这些神经元独立计算,不如更倾向于将这些神经元安排到一个个层中,使得我们可以进行向量化的运算,我们可以在一次矩阵乘法中完成一个隐藏层中所有神经元的计算
。分层可以并行的完成所有的计算,换句话说,分层化就是一个计算技巧。下图是一个三层神经网络:

Python伪码:

# forward-pass of a 3-layer neural network:
f = lambda x: 1.0/(1.0 + np.exp(-x)) # activation function (use sigmoid)
x = np.random.randn(3, 1) # random input vector of three numbers (3x1)
h1 = f(np.dot(W1, x) + b1) # calculate first hidden layer activations (4x1)
h2 = f(np.dot(W2, h1) + b2) # calculate second hidden layer activations (4x1)
out = np.dot(W3, h2) + b3 # output neuron (1x1)

五、Demo

我们用一个demo来展示神经网络是如何工作的。这是一个进行二元分类任务的两层神经网络,我们用神经网络来确定分类边界,当隐藏层中的神经元越多,图上的边界就越扭曲,神经网络能计算的函数也就越复杂:

然后,我们再向神经网络中加入正则化,正则化表现的是对高纬度w的惩罚力度,当正则化系数越大,会使得w变得非常小,最终的结果是函数变得非常平滑,也就是说这个函数实际使用的变量的数量也变得很少。当降低正则化系数,这时就可以完成更加复杂的任务,边界的扭曲程度很高,可以说拟合程度更高,起作用的变量数量更多。

如果大家还想看到更多的测试效果,可以访问链接:http://cs.stanford.edu/people/karpathy/convnetjs/demo/classify2d.html
可以自行尝试更换数据,激活函数以及神经网络:



今天,简单引入神经网络,下一篇将深入神经网络。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值