感知器模型
人脑中的神经元:一个神经元通常具有多个树突,主要用来接受传入信息;而轴突只有一条,轴突尾端有许多轴突末梢可以给其他多个神经元传递信息。轴突末梢跟其他神经元的树突产生连接,从而传递信号。
而在计算机的神经网络中,神经元模型是一个包含输入,输出与计算功能的模型。输入可以类比为神经元的树突,而输出可以类比为神经元的轴突,计算则可以类比为细胞核。
在感知器模型中,神经元对输入进行的都是线性计算,即:
其中,bia是偏置项 weight是权重项。
感知器模型无法解决线性不可分的问题,比如异或问题。
多层神经网络
感知器只能做简单的分类任务,对于XOR这样的简单分类任务都无法解决。所以需要增加神经网络的层次。以下是一个三层的神经网络(中间两层是隐层)︰
线性计算的问题及其解决-激活函数
如果每个神经元都是只进行线性计算,那么它的结果就只有0和1两种简单地说,多个线性变换的累积结果仍然是线性变换,这使得模型的表现能力很差,无法解决众多复杂的非线性问题。
为了解决这个问题,引入S型神经元来代替感知器。S型神经元与感知器神经元的区别在于,在线性计算之后,增加一个非线性变换,比如Sigmoid函数。这个非线性变换被称为激活函数。
激活函数的主要作用是提供网络的非线性建模能力。如果没有激活函数,那么该网络仅能够表达线性映射,此时即便有再多的隐藏层,其整个网络跟单层神经网络也是等价的。因此也可以认为,只有加入了激活函数之后,深度神经网络才具备分层的非线性映射学习能力。
常见的激活函数: Sigmoid函数、Tanh函数、ReLU函数、P-ReLU函数、Leaky-ReLU函数、ELU函数、Maxout函数等。
多层神经网络
自定义演示:A Neural Network Playground (tensorflow.org)
添加少量隐层的神经网络就叫做浅层神经网络,也叫作传统神经网络,一般为2隐层的神经网络。增多中间层(隐层)的神经网络就叫做深度神经网络(DNN);可以认为深度学习是神经网络的一个发展。
多隐层的神经网络效果要比单隐层的神经网络效果好,同时,增加每一层的神经元数量也有助于提升效果。
对于一些分类的问题来讲,三层的神经网络效果优于两层的神经网络,但是如果把层次不断增加(4,5,6,7....),对于最终的效果不会产生太大的变化。
提升隐层层数或者神经元个数,神经网络的“容量”会变大,那么空间表达能力(模型的预测能力)会变强,从而有可能导致过拟合的问题。
对于视频/图片识别/文本/音频等问题,传统的神经网络(全连接神经网络)不太适合。
多层神经网络的实现
import numpy as np
import matplotlib.pyplot as pltdef sigmoid(x):"""Sigmoid function"""return 1.0 / (1.0 + np.exp(-x))def soft_max_vec(vec):return np.exp(vec)/(np.sum(np.exp(vec)))def soft_max_mat(mat):return np.exp(mat)/(np.sum(np.exp(mat),axis=1).reshape(-1,1))W_1 = np.array([[2,-1,1,4],[-1,2,-3,1],[3,-2,-1,5]])
W_2 = np.array([[3,1,-2,1],[-2,4,1,-4],[-1,-3,2,-5],[3,1,1,1]])
W_3 = np.array([[-1,3,-2],[1,-1,-3],[3,-2,2],[1,2,1]])
x_in = np.array([.5,.8,.2])
x_mat_in = np.array([[.5,.8,.2],[.1,.9,.6],[.2,.2,.3],[.6,.1,.9],[.5,.5,.4],[.9,.1,.9],[.1,.8,.7]])print('the matrix W_1\n')
print(W_1)
print('-'*30)
print('vector input x_in\n')
print(x_in)
print ('-'*30)
print('matrix input x_mat_in -- starts with the vector `x_in`\n')
print(x_mat_in)## A one-line function to do the entire neural net computationdef nn_comp_vec(x):return soft_max_vec(sigmoid(sigmoid(np.dot(x,W_1)).dot(W_2)).dot(W_3))def nn_comp_mat(x):return soft_max_mat(sigmoid(sigmoid(np.dot(x,W_1)).dot(W_2)).dot(W_3))print("--------------------------------------")
print(nn_comp_vec(x_in))
print(nn_comp_mat(x_mat_in))