深度学习-手动搭建神经网络

附上一个网址,这个网址可以比较直观的显示一个神经网络模型的样子:

神经网络

页面中以下代码中的数字1,代表一层:

layer_defs.push({type:'fc', num_neurons:1, activation: 'tanh'});
layer_defs.push({type:'fc', num_neurons:1, activation: 'tanh'});

深度学习-手动搭建神经网络_第1张图片

改为3,神经网络模型变得更加准确:

深度学习-手动搭建神经网络_第2张图片

改为10,会发现点分类的很完美了,但是右边的神经网络模型太复杂,这就使得过拟合:

深度学习-手动搭建神经网络_第3张图片

 

神经网络可以通俗的理解为,输入一组数据,通过无数层的计算筛选,最后确定最终输出的数据

深度学习-手动搭建神经网络_第4张图片

每两个层之间,使用权值w进行过度,并且需要加上一个激活函数,如果没有激活函数,就只会包含两个线性运算——点积和加法:output=dot(w,input)+b【这里w代表权值,b代表一般常值初始化,多为0或者1,dot代表矩阵内积运算】,就只能学习输入数据的线性变换,该层的假设空间是所有可能的线性变换集合,这种假设空间非常有限,无法利用多个表示层的优势,为了得到更丰富的假设空间,需要添加非线性的激活函数。

一开始的激活函数一般用sigmoid函数,但是sigmoid函数在x->∞时导数趋近于0,这就容易发生梯度消失,无数权值w连乘时->0,所以如今激活函数一般会使用rule函数,在最后一层使用sigmoid函数。rule函数图像如下,x->∞时会保证梯度一直为1:

深度学习-手动搭建神经网络_第5张图片

 

 

 

下面以一个小例子来讲解怎样创建神经网络模型(为了方便直观激活函数都是用sigmoid函数):

深度学习-手动搭建神经网络_第6张图片

输入一组数据,通过权值w和激活函数的变换,使之接近于输出层数据,每次进行完比较,判断差值,然后反向传播重新计算w值,多次循环,让权值w更符合预期条件。

深度学习-手动搭建神经网络_第7张图片

import numpy as np

def sigmoid(x, deriv=False):
    if (deriv == True):  # True要进行求导操作,是反向传播
        return x * (1 - x)  # 根据前向传播,x=sigmoid(x),求导需要(sigmoid(x)',e,而这里的return语句中的x替换为sigmoid(x)与求导等价)
    return 1 / (1 + np.exp(-x))  # 前向传播

x = np.array([[0, 0, 1],  # 5*3矩阵
              [0, 1, 1],
              [1, 0, 1],
              [1, 1, 1],
              [0, 0, 1]])
y = np.array([[0],  # 5*3矩阵
              [1],
              [1],
              [0],
              [0]])
np.random.seed(1)
w0 = 2 * np.random.random((3, 4)) - 1  # w0左边连3个特征,右边连4个神经元
w1 = 2 * np.random.random((4, 1)) - 1  # w1左边连4个神经元,右边连1个输出值

for j in range(60000):
    l0 = x;
    l1 = sigmoid(np.dot(l0, w0))  # 默认False,是进行前向传播
    l2 = sigmoid(np.dot(l1, w1))
    l2_error = y - l2  # 当前的错误错了多大
    if (j % 10000 == 0):
        print("error:" + str(np.mean(np.abs(l2_error))))
    l2_delta = l2_error * sigmoid(l2, deriv=True)  # 反向传播,误差作为一个权重,误差越大权重越大
    l1_error = l2_delta.dot(w1.T, )  # 矩阵l2_delta乘w1的转置
    l1_delta = l1_error * sigmoid(l1, deriv=True)
    w1 += l1.T.dot(l2_delta)  # y-l2,就是+=,y+l2,就是-=。l2_delta相当于l2的错误中,w1贡献了多少
    w0 += l0.T.dot(l1_delta)  # 因为从后往前,所以先更新w1,后更新w0

深度学习-手动搭建神经网络_第8张图片

你可能感兴趣的:(深度学习)