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

这里总结了TensorFlow入门的要点,你还有懒惰的理由吗?

时间:2023-03-20 20:39:18 科技观察

本文作者StevenDufresne总结了初学者学习TensorFlow所需的核心知识点和实践内容,旨在鼓励更多人使用TensorFlow步入深度学习的殿堂。本课程作为一门基础入门课程,从TensorFlow原理介绍到上手操作,对核心概念一一讲解,非常适合基础薄弱、无从上手的新手。StevenDufresne:我在90年代开始编写神经网络软件。TensorFlow开源后,我一直渴望用它构建一些有趣的东西。谷歌的人工智能系统是目前的新热点。当树莓派上可以安装TensorFlow后,操作就变得非常简单了。我在上面快速构建了一个二元神经网络。在本文中,我将与您分享我的经验,以帮助其他想要尝试和了解神经网络的人更快地入门。什么是TensorFlow?引用TensorFlow官网的话,TensorFlow是一个“使用数据流图进行数值计算的开源软件库”。“数据流图”是什么意思?这是一件很酷的事情。在正式回答之前,先说一下简单神经网络的结构。神经网络基础一个简单的神经网络由输入层(inputunits)、隐藏层(hiddenunits)、阈值(biasunit)、输出层(outputunits)组成。输入层负责接收数据。之所以称为隐藏层,是因为它们从用户的角度来看是隐藏的。输出层输出我们得到的结果。旁边的阈值用来控制隐藏层和输出层的值是否输出(即超过阈值的神经元可以输出)。两个不同的神经元之间的联系就是权重,只是一些数字,需要通过训练得到。训练神经网络就是为权值寻找最佳值,从而使神经网络一步步变得“聪明”。在下面的示例中,输入神经元的值设置为二进制数字0,0,0。然后TensorFlow将执行介于两者之间的所有操作,输出神经元将神奇地包含数字0,0,1。即使你错过了它,它也知道二进制中000之后的下一个数字是001,001之后是010,依此类推直到111。一旦将权重设置为适当的值,它就会知道如何计数。运行神经网络的一个步骤是将每个权重乘以其对应的输入神经元,然后将乘法结果存储在对应的隐藏神经元中。我们可以把这些神经元和权重想象成一个数组,在Python中也被称为列表。从数学的角度来看,它们都是矩阵。在图中,我们只画了一部分。在这里,输入层矩阵乘以权重矩阵得到一个五元素的隐藏层矩阵(也称为列表或序列)。从矩阵到张量在TensorFlow中,这些列表称为张量。矩阵乘法称为一次运算(operation,又译为计算节点或运算),也就是程序员常说的op,在阅读TensorFlow官方文档时也经常遇到。进一步说,神经网络是张量和操作张量的ops的集合,它们共同构成了神经网络图(graph)。下图取自本文《TensorBoard, a tool for visualizing the graph》,用于检测训练前后张量值的变化。张量是图中的连接,上面的数字代表张量的维度。连接到张量的节点是各种操作(op)。双击后,您可以看到更多详细信息。例如下图是双击后第一层(layer1)的细节。最下面的X是占位符操作,给输入张量赋值。左边的线上是输入张量。上面的节点标记为MatMul运算,它将输入张量(inputtensor)和权重张量(weighttensor,另一条线引向MatMul运算)矩阵相乘。这一切只是为了更直观地展示什么是图、什么是张量、什么是运算,让大家更好地理解为什么TensorFlow被称为“一个使用数据流图进行数值计算的开源软件库”。但是我们为什么要创建这些图表?我们为什么要创建图表?目前,TensorFlow只有Python的稳定API,Python是一种解释型语言。神经网络需要大量的计算。大型神经网络包含数千甚至数百万个权重,解释每个步骤的效率极低。因此,我们通过创建张量和运算图来描述神经网络的结构,包括所有数学运算甚至变量的初始值。Graph只有创建好后才能加载到TensorFlow中的Session中。这被称为TensorFlow的“延迟执行”。Session通过高效的代码运行计算图。不仅如此,许多运算,例如矩阵乘法,都可以在GPU上完成。此外,TensorFlow还支持多台机器或GPU同时运行。创建二进制计数器图下面是创建二进制计数器神经网络的脚本,完整代码可以在我的GitHub页面上找到。请注意,TensorBoard中还存储了一些其他代码。下面我们将从这些代码开始创建一张张量和运算图。首先导入“tensorflow”模块,创建一个会话然后使用它。同时,为了让脚本更容易理解,我们还创建了一些变量,包括网络中的神经元数量。然后,我们为输入和输出神经元创建占位符。占位符是TensorFlow中的一种操作,方便后续输入实际值。这里X和y_是图中的两个张量,每个张量都有一个关联的占位符操作。你可能想知道为什么我们把占位符形状定义为一个二维列表[None,NUM_INPUTS]和[None,NUM_OUTPUTS],第一个维度是“None”?总的来说,神经网络有点像每次我们输入一个值,训练它产生一个特定的输出值。但是更高效的方式是一次提供多个输入\输出对(pair),也就是batch。上图中的第一个维度是每批中有多少组输入/输出对。在创建批次之前我们不知道有多少组。事实上,我们后面训练、测试和实际使用都会使用同一张图,所以每次的batchsize不会一样。因此,我们将***维度的大小设置为Python占位符对象“无”。接下来,我们创建神经网络图的第一层:定义权重为W_fc1,阈值(或偏差)为b_fc1,隐藏层为h_fc1。这里“fc”的意思是“完全连接”,因为权重将每个输入神经元连接到每个隐藏神经元。tf.truncated_normal产生一系列操作和张量,这些操作和张量会将所有权重分配给标准化随机数。对Variable的操作会给出初始化值,这里是一个随机数,以后可以多次引用。一旦训练完成,将神经网络保存到文件中也很方便。您可以看到我们在哪里使用matmul运算来执行矩阵乘法。我们插入一个添加操作来添加偏置权重。relu操作执行“激活函数”。矩阵乘法和加法都是线性运算。神经网络对线性运算几乎无能为力。激活方程提供了一些非线性。这里的relu激活函数是将所有小于0的值设置为0,其余值保持不变。信不信由你,这为神经网络的学习打开了一扇全新的大门。神经网络第二层的权值和阈值与第一层设置的相同,只是输出层不同。我们再次进行矩阵乘法,这次将权重和隐藏层相乘,然后添加偏置权重,将激活函数留给下一组代码。和上面的relu类似,sigmoid是另一种激活函数,也是非线性的。我在这里使用sigmoid函数的部分原因是它给出了介于0和1之间的最终输出值,这对于二进制计数器来说是理想的。在我们的示例中,为了表示二进制111,所有输出神经元都可以具有较大的值。这与图像分类不同,在图像分类中,您只想使用一个输出单元来输出很大的值。例如,如果图像中有一只长颈鹿,我们希望代表长颈鹿的输出单元输出一个相当大的值。在这种情况下,使用softmax函数作为激活函数更为合适。仔细看前面的代码,你会发现好像有点重复,我们插入了两次sigmoid。我们实际上在做的是创建两个不同的并行输出。cross_entropy张量将用于训练神经网络。然后,结果张量用于执行经过训练的神经网络,无论其训练目的是什么。这是目前为止我能想到的最好的方法。最后一点就是训练。也就是说,所有的权重都是根据训练数据调整的。请记住,我们仍然只是在这里创建一个图表。真正的“训练”发生在我们开始运行图形时。运行时有很多优化器可以选择,这里我选择tf.train.RMSPropOptimizer。因为和sigmoid一样,更适合所有输出值都可能很大的情况。对于分类情况,例如图像分类,使用tf.train.GradientDescentOptimizer可能会更好。训练和使用二进制计数器创建图表后,就该开始训练了。首先,准备一些训练数据:包括输入变量inputvals和目标变量targetvals。其中inputvals包含输入值,每个输入值都有对应的targetvals目标值。例如inputvals[0]为[0,0,0],对应的输出或目标值为targetvals[0],即[0,0,1]。do_training和save_trained都可以硬编码、每次更改或使用命令行参数设置。首先对张量进行所有Variable操作初始化;然后,从底部到train_step执行之前创建的图形最多10001次;这是添加到图中的最后一件事。我们通过RMSPropOptimizer将inputvals和targetvals导入到train_step操作中。这是在给定输入值的情况下,通过调整权重使输出值不断接近目标值的步骤。只要输出值与目标值的误差足够小,在一定的可接受范围内,循环就会停止。如果您有数百或数千个输入/输出组,您可以一次训练一个子集,即上述批次。但是这里我们一共只有8组,所以每次都放进去。我们也可以将训练好的神经网络保存在文件(file)中,这样下次就不用再训练了。下次可以直接导入一个训练好的神经网络文件,里面只包含变量运算后的张量值,不包含整个图的结构。因此,即使要执行经过训练的图,我们仍然需要脚本来创建图。MetaGraphs可以保存文件和导入图形,但我们在这里不这样做。请注意,我们从图的底部运行到结果张量,在经过训练的网络中重复创建结果。我们输入000,期望它返回一个接近001的值,然后重新输入返回值,再次执行。这样一共运行9次,保证有足够的次数从000数到111,然后再回到000。以下是训练成功后的输出。它在一个循环中训练了200次(步骤)。在实践中,训练10001次后训练误差仍未有效降低的情况非常罕见。一旦训练成功,训练多少次都没有关系。下一步运行二进制计数器如前所述,此处描述的二进制计数神经网络的代码可以在我的Github主页上找到。大家可以根据这些代码开始学习,也可以在TensorFlow官网观看其他入门教程。下一步,我想根据机器人识别物体得到的启发,通过它做一些硬件方面的研究。