前言:笔者一直是电子游戏的爱好者与支持者。少年时代接触过大量GTA、冰封王座这种佳作...这让我并不满足于游戏本身,而是想要了解 游戏机制 以及 图像渲染背后的原理 ,幸运的是目前明确了学习方向。此外,笔者在大学中接触到了深度学习,并将其作为自己目前解决问题的主要工具之一。这二者都与 GPU 这个硬件有着直接关系。那么,“本是”用于打游戏“玩具”,缘何与深度学习有关呢?笔者想在此锻炼自己的表达能力,浅谈图形渲染与深度学习中的“原理”与“数学”。
注:限于篇幅以及笔者本身学识,本文不做深入探讨。此外,我很担心写出有误导性的文章,有错误/问题劳您指正:
piperliu@qq.com
,或微信:PiperLHJ
。
图形渲染
首先我想声明,这并不是什么难以理解的事。世界上很多图形学程序员,并非人人都是天才。读者朋友大可自信地去理解我下面的写的内容(仅仅从字面意义上)。
我们知道,计算机只能存储数据,并且对数据进行运算。你显示器上的花花绿绿,说到底是大量数据计算得到的结果。
因此,我们玩游戏时看到的图形,其背后实际上是大量 美妙的数学成果 。这些 计算机图形学家 总结出的规律既考虑了效率(可以实时渲染出来),又确保了平面上图形的清晰度。
然而,假定我们 已知了或者说会使用这些数学规律 (甚至可以不需要知道这些数学规律具体是什么
), 这一切从工序上说,就极其简单好理解了。
工序1:物体在哪里,直说就好
图1:Unity 截自BV1SC4y187wK
比如,如果我们要模拟一个情景(如图1):
•我们的摄像机在点 1 处,其镜头指向那个白色正方体;•我们希望通过数学运算,得到 2 处的画面,即摄像机中看到了什么。
那么 第一道工序 并不需要数学运算,我们只是让计算机表达各个物体在哪里就好:
•比如,我们可以在内存中表达正方体的位置(用3个量记录,因为3个自由度)、各方向角度(用3个量记录,因为3个自由度)、大小(用1个量记录,因为3个自由度),只需要记录这几个数字或字母在内存就好cube: {x:-1, y:1, z:1, xD:0, yD:0, zD:0, size:2}
;这些信息已知了,自然,正方体的各个面的位置、角度等都可以被轻松推导出来•此外,还要记录相机的位置、指向:camera: {x:4, y:1, z:2, xD:0, yD:-15, zD:-180}
对于游戏设计师来讲,我们仅仅设定这些内容即可, 至于如何通过数学运算,得到 2 处的画面(摄像机中看到了什么),是软件自动帮我们计算出来的(如何计算,是计算机图形学家的任务)。 也就是说,游戏设计师可以将精力放在游戏设计上。
下面的工序,交给计算机图形学家。
工序2:投影变换,数学运算
图2:透视投影 from Lingqi Yan, UC Santa Barbara, GAMES101
如上,对于空间中的物体,我们应该考虑,如何将其 投影在一个平面上 。凭借九年义务教育的直觉,我们知道,这个过程一定有一个严格而通用的数学规律可以描述:
•已知空间中点的坐标为 (x, y, z)
•现在有焦点 (x0, y0, z0)
与平面 Ax By Cz D=0
•稍微费些脑筋,你便可以推出 (x, y, z)
在平面 Ax By Cz D=0
的透视投影的通式
那么另一个问题来了,我们上面讨论的是点的投影, 面尤其是曲面,其投影必将复杂很多,该怎么办呢?
工序1.5:万物三角形
实际上,我们 可以用平面三角形表示近似表示任何曲面,而平面三角形又可以仅由三个点精确表达。
图3:BV1eE411E7Jf
如图3,我们基于三角形,表达复杂的曲面,进而实现光照。
因此,我们进行正交投影,实际上还是对每个点或者说平面进行运算,并不会引入各种平面的投影,增加计算的复杂程度、削弱计算的通性。
工序3:栅格化
图4:像素点 from Lingqi Yan, UC Santa Barbara, GAMES101
如图4,我们的屏幕终究只能控制各个像素,显示一些简单的颜色,因此,如何利用平面关系控制大量像素点,也涉及了数学运算。
图5:栅格化 from Lingqi Yan, UC Santa Barbara, GAMES101
如图5,我们称这个过程为 栅格化 。我们有一个平面的三角形,为了显示在屏幕上,我们在栅格化
这个过程中,计算的就是“点亮”哪些像素点更好些。
总结:互不干涉,并行计算,GPU登场
了解了上述工序,你也许会意识到: 各个三角形的投影计算、栅格化计算都是互不干涉的。都是并行
的。
如果使用串行的 CPU ,则十分不划算,因为各个三角形之间并没有前后运算的要求。因此,我们有了专门 用于并行计算的 GPU (图形处理器, Graphics Processing Unit, GPU)。
GPU 不擅长 CPU 的流水、中断与预测(可以理解为一种高效的处理分支逻辑的硬件实现);二者各司其职。
注:上述图形渲染流程并不严谨,仅适合计算机图形学入门者理解宏观定义使用。此外,图形渲染中还涉及到矩阵运算等,也适于 GPU 计算;而在实际渲染中,存在
光照、漫反射
等因素,三角形之间并非独立,但即便如此,也是存在数学规律的,也可以使用 GPU 进行并行计算。
深度学习 - 神经网络
神经网络中的前向计算
图6:神经网络 from 李宏毅 台湾大学 深度学习课程
对于人工神经网络,某一层神经元A的值总是服从下述计算:
代码语言:javascript复制( 上一层神经元1的值 乘 1与神经元A连接权重 上一层神经元2的值 乘 2与神经元A连接权重 ... ) 神经元A偏置量
对于人工神经网络,如图6,已有连接权重,现在我们输入 [1, -1]
,我们计算一层,则对于第一层,公式为:
4 = ( 1 乘 1 (-1) 乘 -2) 1-2 = ( 1 乘 (-1) (-1) 乘 1) 0
至于 0.98 与 -2 是在 4 与 -2 外包裹的一层激活函数。
可以转换为矩阵运算
图7:神经网络 from 李宏毅 台湾大学 深度学习课程
你可能注意到了, 同一层中每个神经元的计算是独立的。 为了更方便的数学表达,我们可以将每层的计算转化为矩阵形式,如图7。
图8:神经网络 from 李宏毅 台湾大学 深度学习课程
而对于多层神经网络,就是多层矩阵运算,如图8。
这就是 GPU 在深度学习领域大行其道的原因。
注:这里没有讨论深度学习中反向传播、CNNs在操作上的并行性等问题;也没有从软硬件设计层面讨论 GPU 为程序提供的接口工具如 CUDA 等。无论如何,神经网络中的并行性是惊人的美好,让高算力的 GPU 与其搭配成为可能,极大提升了深度学习的普适性。
我并没有很深入地进行探讨,以下是我的参考资料,强烈推荐:
•【编程三分钟】10分钟入门计算机GPU编程、Shader图形编程 - 奇乐编程学院 - 哔哩哔哩 https://www.bilibili.com/video/BV1eE411E7Jf/•31 | GPU(下):为什么深度学习需要使用 GPU?- python_QYF - CSDN - https://blog.csdn.net/qyf__123/article/details/100147909•GAMES101: 现代计算机图形学入门 - 闫令琪 - 计算机图形学与混合现实研讨会 https://sites.cs.ucsb.edu/~lingqi/teaching/games101.html•李宏毅-台湾大学-深度学习课程,可见于 Youtube•为什么深度学习和神经网络需要GPU?- Lebooj的文章 - 知乎 https://zhuanlan.zhihu.com/p/106669828