本篇文章我会教大家构建第一个tensorflow程序。
PS:因为本篇文章是我在人工智能教学中给我的二年级学生写的,我已经教会了他们一定的python和人工智能基础知识, 如果你还不具备这些知识,那么可能会看不懂本篇文章。
下面我们通过一个简单的例子来认识tensorflow的基本用法——使用tensorflow来寻找一个w值,这个值可以使函数J(w)=w2-10w+25的结果最小——就像我们训练神经网络时,寻找参数w和b的值来让成本函数的值最小一样。上面的函数其实等价于J(w)= (w-5)2,这个知识点我们小学或者初中时应该就学过了,有些同学可能忘记了。从上面的式子中很容易可以看出当w等于5时函数J的值是最小的。当然,tensorflow是看不出来的,它需要使用梯度下降算法来一步一步地寻找这个让J最小的w值。
就像在python中使用numpy工具库一样,要想在python中使用tensorflow,第一步就是要将其导入。如下所示,将tensorflow导入并且取名为tf,在后面通过tf就可以调用tensorflow的相关功能了(我们的开发环境依然使用Jupyter Notebook)。
首先,我们用下面的语句定义了一个类型为float32的tensorflow变量w。
然后我们再将J(w)函数定义出来。这里我们将J(w)取名为cost。下面代码中的add表示加法运算,multiply表示乘法运算,w**2表示w的平方。
下面我们定义了一个梯度下降的实例对象,它的学习率我们将其设为0.01。然后用这个梯度下降对象来最小化cost函数,也就是来寻找让cost函数最小化的w值。我们把上面这些操作用train变量来表示,也就是说,train变量就代表了上面这些操作。
下面这三行代码可以说是tensorflow固定的表达形式。大家先不用理解他们。只需要知道通过这三行代码就创建一个tensorflow的session对象了,后面就可以通过这个session对象来让tensorflow执行一些操作。例如下面我们用session.run(w)来获取w变量当前的值,然后用print把这个值打印出来。
因为上面我们只是定义了一些操作,还并没有执行这些操作。所以上面打印出来的w的值还是初始值0。下面我们将使用session对象来执行一系列操作,来寻找使cost函数最小化的w的值。
下面我们用session对象来执行一次train操作,也就是执行一次梯度下降操作;然后再将w值打印出来。在经过了一次梯度下降之后,w的值发生了变化。
下面我们再用session对象来执行1000次梯度下降,并把w的值打印出来。可以看到,经过了1000次梯度下降之后,w的值已经非常接近理想值了(前面我们说过,5可以使cost函数的值最小)。
通过上面这些代码,你应该对tensorflow的语法有了一些大致的了解。但是对于他们还不太理解,没有关系,通过对教程后面实战编程的学习后,你对他们的理解程度会越来越深入。
在上面的代码中,我们并没有定义梯度下降的反向传播操作,但是梯度下降却成功的执行了,并且还找到了最小值处。这是为什么呢?因为tensorflow在内部它会自动构建反向传播的相关操作。所以以后我们只需要定义神经网络的前向传播操作就可以了,tensorflow框架会根据前向传播自动生成反向传播操作。相当的强大!相当的方便!
前面我们在定义cost函数时,使用了很多add和multiply函数,代码看起来太臃肿了。其实我们可以用下面这种更加直观简洁的表达形式。因为tensorflow已经重载了这些运算符。所以,只要遇到tensorflow变量,这些符号就会自动转换成tensorflow的add和multipy函数。
下面我再给大家介绍一个tensorflow中非常重要的功能——placehold——占位符功能。我们在训练神经网络时,除了有参数w和b外,还有一个很重要的成员——输入的训练数据。上面cost函数的系数就相当于输入的训练数据的角色。上面cost函数的系数是固定的,分别是1,-10,25。但是在实际应用中,输入数据是变化的。比如我们每一个子训练集都不同。tensorflow的placehold功能可以完美应对这种情况。
我们可以用下面这行代码来定义一个占位符变量x,它是一个维度为(3,1)的float32向量。
然后我们将前面的cost函数的3个系数分别换成上面的占位符变量x中的3个元素。
上面cost函数中的占位符变量中还并没有实际的数值,正如其名,它只是占了一个位置而已。当整个神经网络构建好了之后,我们可以往这些位置里面填充不同的数值。
比如我们可以先通过下面的语句构建一个与上面占位符维度相同的向量,这个向量里面是有实际数值的,这些数值与我们最原始的cost函数的系数是一样的。
然后通过下面的语句将上面的数值向量coefficients填充到我们的占位符x中。这样一来,我们就通过占位符的形式,实现了与前面固定系数时一样的功能了。因为我们往占位符中填充的数值与前面的固定系数是一样的。
重新执行这些代码后,可以看到结果与固定系数时一样。
当然,有了占位符这个功能,我们就可以往构建好的神经网络中填充不同的数据了,非常的方便。比如我们可以改成填充下面的数值。
重新执行代码后,结果是9.9998,这个结果是非常棒的了。因为对于新的系数来说,w等于10的时候,cost函数的值是最小的。
下面我把最终完整的代码一次性贴出来。
有了占位符,我们就可以在执行mini-batch梯度下降时方便地往构建好的神经网络中填充不同的子训练集数据了。
看了本篇文章后,你可能对上面的一些语法还有些陌生。在接下来的实战编程中,我会带领大家进一步熟悉tensorflow,并用它来轻松地构建出非常复杂的神经网络,实战编程中的代码都可以下载运行。
————————————————
版权声明:本文为CSDN博主「人工智能AI技术」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jiangjunshow/article/details/77898283