深度学习之TensorFlow构建神经网络层

深度学习之TensorFlow构建神经网络层

基本法

深度神经网络是一个多层次的网络模型,包含了:输入层,隐藏层和输出层,其中隐藏层是最重要也是深度最多的,经过TensorFlow,python代码能够构建神经网络层函数,好比咱们称之为add_layer()函数,因为神经网络层的工做原理是一层的神经元处理完成后获得一个结果,而后传递给下一个神经元,这就相似于函数的return与参数变量,因此最终代码的模型应该以下图所示:python

神经网络层的实现设计

经过add_layer的层层嵌套,实现上一个add_layer的结果返回给下一个add_layer做为参数变量。网络

激励函数

在深度神经网络中,激励函数的概念很是重要,TensorFlow已经包含了许多的激励函数。dom

什么是激励函数呢?机器学习

在神经网络中,隐层和输出层节点的输入和输出之间具备函数关系,这个函数称为激励函数。常见的激励函数有:线性激励函数、阈值或阶跃激励函数、S形激励函数、双曲正切激励函数和高斯激励函数等。(百度百科)函数

简而言之:隐藏层在处理后获得一个值,这个值要么直接传递给下一层,要么先处理一下再传递下一层,这个处理的过程就是激励函数。从数学角度说,激励就是上一层输出和下一层输入存在一种映射关系,即:学习

F (上一层结果->下一层输入)测试

为什么须要激励函数?优化

想起上一回中介绍了使用TensorFlow求一次函数的系数与偏量的方法,那并无用到激励函数,是由于输入与输出的数据呈现为线性关系,也就是y=kx+b这样的简单关系,但实际的问题中输入数据与输出数据可能会存在某种非线性关系。人工智能

线性关系示例

如图要区分蓝红点,可使用线性函数y>kx+b或者kx+b>y让神经网络快速学会分类spa

非线性关系示例

如图再要区分蓝红点,使用线性函数是作不到的,固然能够选择直接使用非线性函数来处理,在TensorFlow中亦可给出非线性计算的训练单元,可是另外一种更为取巧的办法就是给线性函数嵌套一个非线性函数,使得原来的线性关系变成非线性关系,这就使得隐藏层处理的关注点放在了权重k与偏量b上,这就是激励函数的做用!他把原本复杂的问题简化为只调整两个简单的参数上来。

为何须要分层,深度对学习能力有什么影响?

首先既然说到深度学习,隐藏层应该是多层才算“深”,分层就是为了提升学习能力嘛!那么分层如何作到了学习能力提高?

假定以下场景,咱们有三层隐藏层,每一个层都有一个神经元,咱们对神经元在进行简化,就说他是一个函数y=kx+b,咱们得出下图:

神经网络传递示例

图中每一层都会产生出一个不一样的f(x)=kx+b函数,并且不一样层的函数的系数和偏量都是不同的,经过神经元链接将这些f(x)串联起来,这有点像PHP里的链式操做,并且图中只是简单的线性关系(正如前面所述这些y函数外层还能够嵌套一个激励函数作非线性化转换)。

神经网络存在一个“逆向工程”,就是当最终输出神经元发现与真实值有差距时就会反向传递,经过调整每一层里的函数来纠正,调整的就是系数k和偏量b,调整出来的k,b在不一样层中也是不同的,具体如何调整这就是个黑盒,人类没法掌控,但他最后就是会到达一个合适的值,这个专业名词叫作:拟合!

综上所述:层数越多,k,b可能性越多,函数越多,那么所能表明的可能性越多,从数学上说,无穷多的可能性能够表达宇宙一切信息。

Show me the code!

Talking is cheap, show me the code!

如下咱们给出一个实际的案例,实现上述所述的神经网络设计和构建过程:

import tensorflow as tf
import numpy as np

#the function to create layer
def add_layer(inputs,in_size,out_size,activation_function=None):
    w = tf.Variable(tf.random_normal([in_size,out_size]))
    b = tf.Variable(tf.zeros([1,out_size])+0.1)
    f = tf.matmul(inputs,w) + b
    if activation_function is None:
        outputs = f
    else:
        outputs = activation_function(f)
    return outputs

#create test data(as real data)
x_data = np.linspace(-1,1,300,dtype=np.float32)[:,np.newaxis]
noise = np.random.normal(0,0.05,x_data.shape)
y_data = np.square(x_data)-0.5+noise

#give tensorflow input placeholder
xs = tf.placeholder(tf.float32,[None,1])
ys = tf.placeholder(tf.float32,[None,1])
l1 = add_layer(x_data,1,10,activation_function=tf.nn.relu)
prediction = add_layer(l1,10,1,activation_function=None)

loss = tf.reduce_mean(tf.reduce_sum(tf.square(y_data-prediction),reduction_indices=[1]))

train = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

for i in range(1000):
    sess.run(train,feed_dict={xs:x_data,ys:y_data})
    if(i % 50 == 0):
        print sess.run(loss,feed_dict={xs:x_data,ys:y_data})

额,不要在乎代码中我垃圾的英语注释。

咱们简单分析一下代码的含义,其实若是读懂了代码前所述的理论概念,代码就能一下理解了。

首先,咱们开头定义了一个create_layer函数,这个函数做用是建立一个神经网络层!参数变量是:输入值,输入值的矩阵行数,矩阵列数,激励函数。这里为何是矩阵?由于实际处理的现实问题所携带的数据是多个维度的,人类通常能理解到三维,三维以上计算机能够理解。不用过于在乎这个细节,之后结合实际问题解释为何是矩阵的y=kx+b运算,如今要记住x是个多维矩阵就行了,不是简单的数。

create_layer内部作了什么?

函数内部首先是使用numpy给出了随机数,这个随机数也是个矩阵,表明了系数k与偏量b,tf.Varible()让TensorFlow学习过程当中改变这两个变量(叫作权重,偏量调整),而后tf.matmul进行了矩阵的运算,给出这一层的输出值,if—else语句负责判断是否要给输出值套上一个激励函数,将其非线性化。

placeholder干什么的?

因为神经网络的学习要求咱们输入测试的数据,placeholder的做用是提供输入数据的空位,实际问题产生的原始数据丢入到placeholder中,而后被一个叫feed_dict的对象收集到TensorFlow当中,再交给神经网络去处理获得一个预测结果。placeholder就是是原始数据的入口。

loss是什么?

损失值,用于优化训练过程,很简单,咱们要让学习结果和真实结果接近,就要求他们之间的差愈来愈小,这个值就表明了他们的“差”,这个差可不是数学上的减减就行的,能够看到咱们用到了:

tf.reduce_sum(tf.square(y_data-prediction),reduction_indices=[1])

这么长的计算方式,实际值和真实值的差的平方,而后还累加了矩阵中的差平方值,很复杂呢。反正这个值越小越好就对了。

控制台输出结果

运行以上python代码,获得的是损失值,这是为了验证TensorFlow在学习过程当中是否是真的在优化本身,loss愈来愈小就是优化了:

代码运行结果

确认:损失值减少,学习优化了!

题外话

我的以为如今的深度学习的人工智能和传统的人工智能对比,就好像物理上的“量子力学”与“相对论”,怎么说?传统的人工智能认为机器学习过程是正向的,人类为机器设定好规则,在代码中呈现为if then if then......的特色,而深度学习是只给出输入值,让机器去“推理”出一个结果,与正确结果对比,错了就逆向去从新修改“推理”的逻辑,这就是一个无穷多可能的事情,这有点像“量子力学”中只有当观察量子世界中某一个现象时,才能获得一个肯定的状态(结果),不观察时,这个魔盒中的可能性是无穷多的,答案落在任何一块区域中,怎么样,是否是很神奇?再通俗比喻一下,这就像武功的最高境界“无招胜有招”!只要能赢就是厉害!经过不断的输,修改招式,最后取得胜利,成为大师的时候固定招式已经不复存在了。

相关文章
相关标签/搜索