当前位置: 首页 > 科技观察

真是个天才,把感知器组装在一起是神经网络吗?

时间:2023-03-17 22:25:44 科技观察

大家好,今天继续聊深度学习。有同学跟我说,很久没有更新深度学习模型了,不是不想更新,主要是想一次性把一个技术topic写完。但是看纯技术文章的观众不太喜欢看,所以我一般把纯技术文章放在第二篇。不过由于有同学催我更新,所以我会响应需求,更新一篇。神经网络和感知器的区别我们当时在文章里放了一张图。这张图是多层感知器的图片。看一看,就是下图。这张图乍看没什么问题,但仔细想想,就会觉得有些奇怪。好像我们印象中看到的神经网络的图也是这样的。在这种情况下,它们之间有什么区别?表面上最明显的区别就是名字不同,这是一张神经网络的图片。我们发现也有三层,不过每一层的名字分别是输入层、中间层(隐藏层)和输出层。我们一般将输入层和输出层分开命名,中间的层称为隐藏层或中间层。当然,像感知机一样,也可以用数字来命名层数。例如下图中的输入层称为第0层,中间层称为第一层,最后的输出层称为第二层。我们一般不会认为输出层是一个有效的神经网络,所以下图中的网络被称为二层神经网络而不是三层神经网络。除了名称不同,最关键的区别是激活函数。为了解释这一点,我们先来看看神经网络中的信号传输。信号传输下图是我随便找的一张神经网络图。我们可以看到输入的第一个节点设置为1,这样做是为了方便引入偏移量,但是我们在画图的时候一般不会画偏移量。我们以下图为例,看看信号在神经网络中是如何传输的。到这里还没完,神经网络中的每一层都会有对应的激活函数。一般来说,同一层网络中的激活函数是一样的,我们称它为h,所以这个节点的最终输出不仅仅是得到,而是。我们已经熟悉了激活函数。我们之前已经介绍过很多次了。常用的有:Relu、Sigmoid、tanh、softmax,以及一些派生变体。一般来说,我们通常在输出层之前使用Relu。如果模型是分类模型,我们会在最后使用Sigmoid或softmax。如果是回归模型,我们不会使用任何激活函数。我们已经很熟悉Sigmoid了。如果我们把LR模型看成一个单层神经网络,那么Sigmoid就是它的激活函数。Sigmoid应用于二进制分类场景中的单个输出节点。如果输出值大于0.5,则为真,否则为假。在一些概率估计场景中,也可以认为输出值代表了事件发生的概率。与之对应的是softmax函数,应用于多分类问题,它应用的节点数不是1,而是k。这里k表示多分类场景中的类别数。我们以k=3为例,看下图:图中一共有三个节点,对于每个节点,其公式可以写成:其实和Sigmoid的计算方式是一样的,只是最后计算出一个权重。最后,我们会选择这k个节点中最大的作为最终的分类结果。代码实现最后,我们来尝试编写神经网络的代码。由于我们还没有介绍神经网络的训练方法,所以只能实现它预测的部分。介绍完反向传播算法之后,我们再补上模型训练的流程。如果不考虑反向传播,整个算法的代码其实很简单,只要熟悉Python语法的同学都能看懂。importnumpyasnpdefrelu(x):returnp.where(x>0,x,0)defsigmoid(x):return1/(1+np.exp(-x))classNeuralNetwork():def__init__(self):self.params={}self.params['W1']=np.random.rand(2,3)self.params['b1']=np.random.rand(1,3)self.params['W2']=np.random.rand(3,2)self.params['b2']=np.random.rand(1,2)self.params['W3']=np.random.rand(2,1)self.params['b3']=np.random.rand(1,1)defforward(self,x):a1=np.dot(x,self.params['W1'])+self.params['b1']z1=relu(a1)a2=np.dot(z1,self.params['W2'])+self.params['b2']z2=relu(a2)a3=np.dot(z2,self.params['W3'])+self.params['b3']返回np.where(sigmoid(a3)>0.5,1,0)if__name__=="__main__":nn=NeuralNetwork()print(nn.forward(np.array([3,2])))本文转载自微信公众号「TechFlow」,可通过以下二维码关注。转载请联系TechFlow公众号。