不知道你会不会经常有这样的一种错觉,20世纪前半夜的人是生活在一个黑白的世界里的,他们的世界中没有颜色,分辨率很低。为了克服这种错觉,你常常要有意的告诉自己,他们生活的世界跟你现在的一样。
全真色彩,视网膜像素,波尔和薛定谔的动作也不是量子态的,他们的世界同样流畅顺滑,走路也不是一卡一卡的。好吧,同样对我5岁的儿子来说,他老妈的青春岁月可能也是,发黄的,高斯模糊的,因为所有那个时代的电影都是这样的。为了让我们的青春重新回到4K,我们需要AI。
AI是如何把模糊不清的老照片变回4K的呢?这就需要用到一种技术,AI超分辨率,现在想象你有一张256*256的图片,你把这张图片放大16倍,它就来到了1024*1024,图片中的每个像素现在变成了16个,如果你不做任何处理,它就可能是这样的,这不是你想得到的结果。于是你决定给这些像素重新添加一下颜色,该怎么做呢?最容易想到的办法就是把相邻的两个像素的颜色值相加一下,然后/2,于是你就得到了一个新的颜色。
电脑也是这样做的,这种算法就叫做插值,利用插值算法,我们可以补充很多像素的颜色,让像素过渡起来更自然。但是简单的插值方法会导致边缘均匀过渡,看起来很模糊,和实际人的主观感受不符。很明显,锐利的画面需要像素值上更陡峭的过渡,你这样一平均,边缘反而变得更模糊了,怎么办呢?
如果修复图像的是人,我们可以自己手动来精修。我们知道图片上是什么,所以可以有意加强边缘和对比,但是电脑对真正的图片一无所知,它只有0101,也就无法根据图片内容做出调整。当然这仅限于二零一几年之前。
2014年深度学习算法横空出世,电脑进入了识图时代,CNN可以提取图片特征。于是电脑终于知道你照片上的猫是一只猫了。接下来生成对抗网络Gan实现了AI作画,AI修复就不再仅仅是填补一些像素了,它可以检测边缘,重新创造细节。于是AI图片修复出现了质的飞跃。这是realesrgan的修复效果,看起来是不是还不错?
接着就是大模型时代了,AI绘画开始达到以假乱真的地步。而开源免费的程序也让普通人拥有了AI创作的机会,AI小姐姐泛滥的时代来临了,创造这种奇迹的是stable diffusion。但是你在阅尽AI小姐姐的闲暇,有没有想过这样的一个问题,stable diffusion到底是如何作画的呢?它是像我们一样勾线上色然后完成一部作品的吗?并不是的。stable diffusion底层使用的是diffusion模型,它用了一种和绘画八竿子打不着的自然现象:扩散。
什么是扩散呢?这是一杯清水,现在我们在水滴中滴一滴墨汁,你会看到什么?墨汁在水中逐渐散开,最后和水融为一体,整杯水变成了一杯深色的水。现在我来问你一个问题,我给你一杯深色的水,让你回到一开始刚刚扩散的样子,你做得到吗?好吧,可能除了信条中的人,谁也做不到这一点。
熵是不可逆的,散开的墨水不可能完全回到之前的样子,但是或许我们可以找到一点点规律。扩散是由布朗运动引起的,为了寻找扩散的规律,我们可以把扩散的过程拍摄下来,然后分成一帧一帧的图片,仔细观察这些图片,我们会发现每一张图片与上一张图片比起来,墨水的微粒都会更散开一点点。这种散开遵循什么物理法则?朗之万方程。
朗之万方程是法国物理学家保罗朗之万在1908年搞出来的,简单来说就是布朗运动粒子平均运动位置离原点距离的平方和时间成正比,这意味着我们可以根据这个规律推算上一个时间点粒子可能的位置,但是请注意平均这两个字,这意味着这只是在大量粒子运动下计算出来的平均值,每个粒子的位置到底在哪里还是不知道。
这就需要另外一个数学概念了,这个概念叫高斯分布。啥是高斯分布?如果你把全世界人的身高做一个统计,以横轴代表每一个身高区间,纵轴代表身高,处于这一身高区间的人数就构成了一个直方图,然后你就会发现它形成这样的一个形状,大部分人集中在中间,这个区域越靠近两边人数就越少,但是下降速度也会变得平缓,这就是高斯分布。
高斯分布也叫正态分布。为什么叫正态分布呢?因为它太常见了,很多大数据量的分布都是高斯分布,比如身高,比如体重、比如收入,比如某些概率扩散也遵循高斯分布。也就是说一个墨水的微粒在下一个时间点出现的位置,概率上是遵循高斯分布。而更妙的是,如果时间间隔足够小,它在上一个时间点曾经所在的位置也是近似高斯分布。
这意味着什么?这意味着这从计算上是可逆的,如果我们知道在某一个时间点微粒在水中的位置,是有可能反推出上一个时间点微粒的位置。当然只是有可能,因为高斯分布是一个统计学上的概念,是一个出现概率,我们不可能确切知道每一个微粒的位置。而且只知道是高斯分布是没用的,因为它可能是又高又瘦,也可能又矮又胖。专业点说,它的均值和方差我们无法确定,也不知道它长什么样。我们希望它尽量是一个又高又瘦的家伙,因为越瘦它取值的范围就越小,我们就越容易确定它的值。
现在你知道了,虽然你的确不能完全繁衍墨水的扩散过程,但是反推大量的微粒的运动过程还是没有问题的。特别是当你看过成千上万个墨水散开的视频以后,你是可以想象出墨水没有散开之前是什么样子的。AI的训练过程也是一样的。首先我们有一张原图,然后我们逐渐在图中添加噪点,其实就是像素上的色值根据高斯分布逐渐扩散的过程,每次散开一些我们就保留一张当前的图片,直到最后完全变成一片看不出来的噪点。这个时候我们告诉AI这片什么也看不出来的噪点,原来是什么让他把原来的样子画出来,这好像有点为难人呐?
但是有了上面关于墨水扩散的经验,我们就可以贴心的提供一点帮助,AI不需要一次生成出最初的图片,它只需要生成出最后一张图片,之前的那张图片就可以了。于是AI调整噪点的分布,将它调整后的分布跟我们给它的图片进行对比,反复尝试,直到收敛成正确的分布,再往前一张走,这样最终一张图片生成下去,来到最初的图片。在经过无数张类似的图片训练之后,我们可以说给我来一张画,AI就可以直接运行这个生成图片的过程,从一堆噪点中反向扩散出一张画了。
就像你从一杯深色的水中想象出墨水散开之前的样子一样,深色的水是熵最高的图,就像全是噪声,然后每次迭代反向扩散,就像是根据当前墨水的状态推测前一个阶段水的状态,最后得到墨水没有散开前的样子,也就是图像最原始的状态,这就是diffusion模型作图的过程了。
既然stable diffusion可以从一堆噪点中反向扩散出一张完美的图,我们直接给他一张有很多噪点的图片,让他去猜一猜原来的图片是什么样子,它能不能搞定呢?太能搞定了,咱这么多年就是这么训练过来的嘛。
所以如果这张有很多噪点的图片是一张老胶片,你就解锁了stable diffusion的新能力,老电影修复。stable diffusion做老电影修复具有很多先天的优势,除了它的训练方式,先天对于去噪点就有很好的适应能力之外,它本身也是一个AI大模型,也就是说它像chatgpt一样经历了大数据的洗礼,阅尽世间万物,这让它了解了世间万物的样子,相当于有了超级强大的脑补能力。
如果画面中有什么已经破损了的信息,让stable diffusion直接给补出来不就完美了?说到这里,你是不是已经跃跃欲试了?想用stable diffusion去修复一下自己的老电影了?等一下。理想很骨感,现实可能很骨折。stable diffusion本身是一个图片生成的AI,它的大量训练也是基于AI生成图片的。所以现在你把它用在老电影修复上,如果不好好拾掇拾掇,可能会遇到不少问题。
我们刚才说了,stable diffusion,阅尽世间万物,遇到损失掉的图像它可以脑补出来。但是啥是损失掉的信息呢?对于老电影来说可能就是污渍、划痕、噪点等等这些东西,stable diffusion是没有见过的,你要让它把它们都识别出来,去掉再补上其他东西,总得让它先能识别这些玩意吧。所以我们需要自己生成出一些污渍、划痕、噪点的数据,然后把这些数据和原来完好无损的影片一起扔给AI,让AI好好学习学习。
当然直接扔给它是不行的,因为stable diffusion拥有很多鲜艳的信息。如果我们直接用一些小数据集训练原来的模型,它可能记住了新的,就把原来学到的搞混了。所以我们只能保持原来的模型不动,在它的基础上增加一层小模型,然后针对污渍、划痕、噪点这些情况进行训练。其次,因为AI生成的能力太强大了,优点是它会贴心的帮你补充一些细节,但缺点是它有可能也会画蛇添足,所以如果完全不加控制,你会发现影片中会出现一些并不存在的伪影,或者AI自作主张搞出来的一些纹理,甚至因为不同帧之间处理的不太一样,影片连起来之后就会闪烁。
这种闪烁经常看AI生成动画的小伙伴是不是表示自己很熟?怎么办呢?为了克制AI创作的随机性,我们可能就需要把模型的边界值调高,也就是说训练的概率分布收窄,这样随机性就会减少。说白了就是降低模型创作的自由度,你好好修片就行了,别有事没事自己创作模型就会相对更稳定。
当然闪烁之类的问题更多的可能是,不同帧之间修复的不同造成的。在这种情况下,我们需要把前后多帧统一考虑进来,这个时候每帧里的光流信息就很重要了。啥是光流呢?简单来说就是三维的世界中不同物体在二维的摄像机平面上不同的运动,我们通过它们相对速度的变化可以反推出三维世界中不同物体的远近角度等等信息,帮助建立三维世界中的模型。所以通过不同帧之间的光流信息,我们可以分辨出视频中不同的物体特征,然后通过建模尽量保持物体在不同帧之间光流信息的统一,这样就能更好的保证视频在不同帧之间平滑的过渡。
回复