一、AIGC:人工智能的新年代

AIGC或许会是人工智能的下一个年代。尽管很多人还不知道AIGC是什么。

当还有大批人宣传所谓人工智能、元世界都是概念,而且捂紧了口袋里的两百块钱的时分,人工智能职业发生了几件小事。

首要,由人工智能生成的一幅油画著作《太空歌剧院》,获得了艺术博览会的冠军。

ChatGPT火了,我连夜详解AIGC原理,并实战生成动漫头像

有人感觉这有什么?各种比赛多了去了,不便是获个奖吗?

可是这次不相同,这是一幅油画著作。在此之前,好的油画只能由人工制作。可是现在人工智能也能够制作了,而且还拿了冠军。

很多人类艺术家仰天长叹:“祖师爷啊,我这代人,在目睹艺术死亡!

上一次艺术家们发出这样的感慨,仍是1839年,那时照相机问世了。

随后,ChatGPT横空出世。它真正做到了和人类“对答如流”。

ChatGPT火了,我连夜详解AIGC原理,并实战生成动漫头像

它也能够做数学题、创作诗歌、写小说,乃至也能写代码、改bug。

再说一个震动的报导:由ChatGPT生成的论文,拿下了全班的最高分。导师找到学生,说他上交的论文,段落简练、举例恰当、论据谨慎,乃至引经据典,古今中外,无所不通,教授不敢信任。学生瑟瑟发抖,他说,这是AI生成的,我仅仅想敷衍一下作业

另外,美国89%的大学生都在用ChatGPT做作业。以色列总统在周三发表了一个讲演,内容也是由人工智能写的。

现在全球都在评论,这类人工智能技能,看似是带来了巨大的商业价值,实则或许会给人类带来严重的打击。

这项技能便是AIGC(AI-Generated Content),翻译成中文便是:人工智能生成内容

二、AIGC实战:智能生成动漫头像

其实,利用人工智能生成内容资源,很早就有了。记住有一年的双十一购物节,上万商家的广告图便是人工智能生成的。仅仅现在的数据、算法、硬件,这三个条件跟上了,这才让它大放异彩,全民可用。

下面,我就以人工智能生成动漫头像为例,选用TensorFlow结构,自始至终给大家讲一下AIGC的全进程。从原理到完结都很详细,自己搭建,不调API,终究还带项目源码的那种

2.1 主动生成的含义

那位问了,主动生成内容有什么好处?我的天啊,省事省力省钱呐!

下图是一个游戏中的海洋怪物。这便是人工智能生成的。

ChatGPT火了,我连夜详解AIGC原理,并实战生成动漫头像

这个大型游戏叫《无人深空(No Man’s Sky)》。号称有1840亿颗不同的星球,每个星球都有形态万千的怪物。这游戏玩着得多爽啊?几乎便是视觉震慑呐。这些怪物要是人工来做,得招聘多少团队,得花费多少时间?

用人工智能生成的话,你能够像去网吧相同,跟老板说:嗨,多开几台机子

当然,下面我要做的,没有上面那样地艳丽,乃至很原始。

可是进程相似,原理共同。作用便是AI生成动漫头像:

ChatGPT火了,我连夜详解AIGC原理,并实战生成动漫头像

2.2 主动生成的原理

AIGC的原理,用中国古话能够一语归纳,那便是:读书破万卷,下笔如有神

以生成猫咪的照片来举比如,基本上AIGC的套路是下面这样的:

ChatGPT火了,我连夜详解AIGC原理,并实战生成动漫头像

首要,程序会规划两个人物。一个叫生成器,一个叫辨别器。

为了便于了解,咱们称号生成器为艺术家,称辨别器为评论家。

艺术家负责生产内容,也便是画猫。不要觉得拥有艺术家头衔就很了不起,他或许和你相同,画不好。可是,就算乱画,也得画。所以,他就画啊画啊画。

评论家呢,比较艺术家就负责一些了。他首要调研了大量猫的照片。他知道了猫的特色,有俩眼睛,有斑纹,有胡须。这些特征,他门儿清。

下面有意思的就来了

艺术家这时还啥也不懂,随便画一笔,然后交给评论家,说画好了。评论家拿旁光一看,瞬间就给否了。还给出一些定见,比如连概括都没有。

ChatGPT火了,我连夜详解AIGC原理,并实战生成动漫头像

艺术家一听,你要概括那我就画个概括。他加了个概括,又交了上去。评论家正眼一看,又给否了。不过,他仍是给出一些定见,比如没有胡须。

就这样,这俩人通过不计其数次的友好磋商(评论家幸好是机器,不然心态崩了)。到后来,艺术家再拿来画作,评论家会看良久,乃至拿出之前的照片挨个对照。终究他乃至还想诈一下艺术家,说你这是假的,艺术家说这次是真的。这时,评论家说好吧,我的确找不出问题了,我看也是真的

至此,剧终。

搞一个造假的,再搞一个验假的。然后练习。跟着练习加深,生成器在生成传神图画方面逐步变强,而辨别器在辨别真伪上逐步变强。当辨别器无法区分真实图片和伪造图片时,练习进程到达平衡。

上面这一套操作叫“生成对立网络(Generative Adversarial Networks)”,简称叫GAN。我感觉,这套流程有点损,叫“干”没缺点。

2.3 数据预备

辨别器是需要学习材料学习的。因而,我预备了20000张这样的动漫头像。

ChatGPT火了,我连夜详解AIGC原理,并实战生成动漫头像

这些数据来自揭露数据集Anime-Face-Dataset。数据文件不大,274MB。你很简略就能够下载下来。这儿面有60000多张图片。我用我的电脑练习了一下。200分钟过去了,一个epoch(把这些数据走一遍)都还没有结束。那……略微有作用得半个月之后了。

乡亲们,我这儿是AI小作坊,干不了大的。所以乎,我就取了20000张图片,而且将尺度缩小到5656像素,再而且将五颜六色改为黑白。这样一来,效率立刻就提高了。2分钟就能够练习一圈。如此,我练习500圈也便是不到一天的时间。这是能够接受的。

上面处理图片的代码:

import cv2
# 存放源图片的文件夹
dir_path = "anime" 
all_files=os.listdir(dir_path)
# 循环里边的每一个文件
for j,res_f_name in enumerate(all_files):
    res_f_path = dir_path+"/"+res_f_name
    # 读入单通道
    img1 = cv2.imread(res_f_path, 0)
    # 从头界说尺度为56
    img2=cv2.resize(img1,(56,56),interpolation=cv2.INTER_NEAREST)
    # 转存到face文件夹下
    cv2.imwrite("face/"+res_f_name, img2)
    # 超越20000退出循环
    if j > 20000: break

信任加上注释后,仍是通俗易懂的。

文件预备好了。尽管维度降了,但看起来,这个辨识度还过得去。

ChatGPT火了,我连夜详解AIGC原理,并实战生成动漫头像

下一步要转为TensorFlow格局化的数据集。

from PIL import Image
import pathlib
import numpy as np
# 将图片文件转为数组
dir_path = "face"
data_dir = pathlib.Path(dir_path)
imgs = list(data_dir.glob('*.jpg'))
img_arr = []
for img in imgs:
    img = Image.open(str(img))
    img_arr.append(np.array(img)) 
train_images = np.array(img_arr)
nums = train_images.shape[0]
train_images = train_images.reshape(nums, 56, 56, 1).astype('float32')
# 归一化
train_images = (train_images - 127.5) / 127.5  
# 转为tensor格局
train_dataset = tf.data.Dataset.from_tensor_slices(train_images).shuffle(nums).batch(256)

我很想说一下数据形态的改变进程。由于这和后续的神经网络结构有关联。

首要,咱们的图片是5656像素,单通道。所以,图片的数据数组img_arr的形状是(20000, 56, 56)。也便是说有20000组5656的数组。这儿面的数是int型的,取值为0到255,表明从纯黑到纯白。

((20000, 56, 56),
 array([[   0,   0,   0,   0,   0, …… 0],
        [  18,  18, 126, 136, 175, …… 0],
        [  0,   0,  253, 253,   0, …… 0]], dtype=uint8))

然后用reshape做一个升维,而且用astype('float32')做一个浮点转化。

升维的意图,是把每一个像素点独自提出来。由于每一个像素点都需要作为学习和判别的依据。浮点转化则是为了提高精确度。

到这一步train_images的形状变为(20000, 56, 56, 1)

((20000, 56, 56, 1),
 array([[   [0.],   [0.],    [0.],   [0.],   [0.], …… [0.]],
        [  [18.],  [18.],  [126.], [136.], [175.], …… [0.]],
        [   [0.],   [0.],  [253.], [253.],   [0.], …… [0.]]], dtype=float32))

接着,进行一个神奇的操作。执行了(train_images-127.5)/127.5这一步。这一步是什么作用呢?咱们知道,色值最大是255,那么他的一半便是127.5。能够看出来,上一步操作便是把数据的区间格局化到[-1,1]之间。

假如你足够敏感的话,或许已经猜到。这是要运用tanh,也便是双曲正切作为激活函数。

ChatGPT火了,我连夜详解AIGC原理,并实战生成动漫头像

这个函数的输出规模也是在-1到1之间。也便是说,通过一系列核算,它终究会输出-1到1之间的数值。这个数值咱们反向转化回去,也便是乘以127.5然后加上127.5,那便是AI生成像素的色值。

2.4 生成器

首要咱们来树立一个生成器。用于生成动漫头像的图片。

def make_generator_model():
    model = tf.keras.Sequential()
    model.add(layers.Dense(7*7*256, use_bias=False, input_shape=(160,)))
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())
    model.add(layers.Reshape((7, 7, 256)))
    assert model.output_shape == (None, 7, 7, 256)
    model.add(layers.Conv2DTranspose(128, (5, 5), strides=(1, 1), padding='same', use_bias=False))
    assert model.output_shape == (None, 7, 7, 128)
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())
    ……
    model.add(layers.Conv2DTranspose(1, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh'))
    assert model.output_shape == (None, 56, 56, 1)
    return model
# 生成一个试试
generator = make_generator_model()
noise = tf.random.normal([1, 160])
generated_image = generator(noise, training=False)

由于我终究会放出悉数源码,所以这个当地省略了几层相似的神经网络。

从结构上看,输入层是巨细为160的一维噪点数据。然后通过Conv2DTranspose完结上采样,一层传递一层,生成改变的图画。终究到输出层,通过tanh激活函数,输出5656组数据。这将会是咱们要的像素点。

假如输出一下,生成器生成的图片。是下面这个样子。

ChatGPT火了,我连夜详解AIGC原理,并实战生成动漫头像

这没错,一开端生成的图画,便是随机的像素噪点。它只有一个确认项,那便是5656像素的尺度。

这就能够了。它已经通过杂乱的神经网络,生成图片了。这个生成器有脑细胞,但刚出生,啥也不懂。

这就像是艺术家榜首步能制作线条了。假如想要画好猫,那就得找评论家多去交流。

2.5 辨别器

咱们来树立一个辨别器。用于判别一张动漫头像是不是真的。

def make_discriminator_model():
    model = tf.keras.Sequential()
    model.add(layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same', input_shape=[56, 56, 1]))
    model.add(layers.LeakyReLU())
    model.add(layers.Dropout(0.3))
    model.add(layers.Conv2D(128, (5, 5), strides=(2, 2), padding='same'))
    model.add(layers.LeakyReLU())
    model.add(layers.Dropout(0.3))
    model.add(layers.Flatten())
    model.add(layers.Dense(1))
    return model
# 辨别上一个生成的噪点图片generated_image试试
discriminator = make_discriminator_model()
decision = discriminator(generated_image)

咱们来看一下这个模型。它的输入形状是(56, 56, 1)。也便是前期预备的数据集的形状。它的输出形状是(1),表明辨别的成果。中心是两层卷积,用于把输入向输出靠拢。选用的是LeakyReLU激活函数。

咱们把生成器生成的那个噪点图,辨别一下,看看啥作用。

tf.Tensor([[0.00207942]], shape=(1, 1), dtype=float32)

看这个输出成果,数值极小,表明或许性极低。

咱们仅仅树立了一个空的模型。并没有练习。它这时就判别出了不是动漫头像。倒不是由于它智能,而是它看啥都是假的。它现在也是个小白。

下面就该练习练习了。

2.6 练习数据

开练!GAN!

cross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True)
def discriminator_loss(real_output, fake_output):
    real_loss = cross_entropy(tf.ones_like(real_output), real_output)
    fake_loss = cross_entropy(tf.zeros_like(fake_output), fake_output)
    total_loss = real_loss + fake_loss
    return total_loss
def generator_loss(fake_output):
    return cross_entropy(tf.ones_like(fake_output), fake_output)
……
@tf.function
def train_step(images):
    noise = tf.random.normal([BATCH_SIZE, noise_dim])
    with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:
        generated_images = generator(noise, training=True)
        real_output = discriminator(images, training=True)
        fake_output = discriminator(generated_images, training=True)
        gen_loss = generator_loss(fake_output)
        disc_loss = discriminator_loss(real_output, fake_output)
    gradients_of_generator = gen_tape.gradient(gen_loss, generator.trainable_variables)
    gradients_of_discriminator = disc_tape.gradient(disc_loss, discriminator.trainable_variables)
    generator_optimizer.apply_gradients(zip(gradients_of_generator, generator.trainable_variables))
    discriminator_optimizer.apply_gradients(zip(gradients_of_discriminator, discriminator.trainable_variables))
for epoch in range(500):
    for image_batch in dataset:
        train_step(image_batch)

相同,我仍是只放出了部分要害代码。不然影响你的阅读。终究我会开源这个项目,不要着急。

咱们来分析原理,一定要反复看,精彩和烧脑程度堪比《三国演义》。我连图片都不敢加,怕打断你的思绪。

首要看丢失函数。

算法练习的一个途径,便是让丢失函数的值越变越小。丢失函数表明距离,猜测的距离和实际距离缩小,表明猜测变准。

先看一下生成器的丢失函数。位置在代码中的generator_loss部分。它返回两个数据之间的距离。榜首个数是造假的成果fake_output,这个成果是辨别器给的。另一个数据是标准的成功成果。跟着练习的进行,算法结构会让这个函数的值往小了变。那其实便是让生成器猜测出来的数据,同辨别器判别出来的成果,两者之间的距离变得越来越小。这一番操作,也便是让结构留心,假如整体趋势是生成器欺骗辨别器的才能增强,那就加分。

再看辨别器的丢失函数。也便是代码中的discriminator_loss函数。它这儿略微杂乱一些。咱们看到它的值是real_lossfake_loss,是两项丢失值的总和。real_lossreal_output和标准答案的距离。fake_lossfake_output和标准答案的距离。

那这两个值又是怎么来的呢?得去train_step函数里看。real_output是辨别器对练习数据的判别。fake_loss是辨别器对生成器造假成果的判别。看到这儿,我感叹人工智能的心计之重。它什么都要。

跟着大量学习材料的循环,它告知人工智能结构,它要训练自己对现有学习材料辨别的才能。假如自己猜对了学习材料,也便是那20000张动漫头像。请提示我,我要调整自己的见识,修改内部参数。代码中界说的training=True,意思便是可跟着练习主动调理参数。

一起,伴着它学习现有材料的进程中,它还要实践。它还要去判别生成器是不是造假了。它也告知结构,我要以我现在学到的辨别才能,去判别那小子造的图假不假。

由于人工智能要想办法让丢失函数变小。因而得让fake_loss的值变小,才干确保discriminator_loss整体变小。所以,结构又去找生成器。告知它,辨别器又学习了一批新常识,现在人家辨认造假的才能增强了。不过,我能够偷偷地告知你,它学了这个还有那个。这么一来,生成器造假的身手,也增强了。

如此循环往复。结构相当于一个“挑唆者”。一边让辨别器提高辨别才能,一边也告知生成器怎么完结更高档的造假。终究,世间全部的常识,两方悉数都学到了。辨别器再也没有新的常识能够学习。生成器的造假,辨别器悉数认可,也不需要再有新的造假计划。全部防伪常识全透明

这时AIGC就成功了。

2.7 主动生成

我对20000张动漫图片练习了500轮。每一轮都打印一个九宫格的大头贴。终究咱们能够看到这500轮的演变作用。这张图大约25秒,只播放一遍(假如放完了,拖出来再看),需要耐性看。

ChatGPT火了,我连夜详解AIGC原理,并实战生成动漫头像

从动态图看,整体趋势是往画面更明晰的方向发展的。

动图比较快,我放上一张静态图。这彻底是由人工智能生成的图片。

生成的代码很简略。

# 加载练习模型
if os.path.exists(checkpoint_dir+"/checkpoint"):
    checkpoint.restore(tf.train.latest_checkpoint(checkpoint_dir))
# 生成噪点作为输入
test_input = tf.random.normal([1, 160])
# 交给生成器批量生成
predictions = generator(test_input, training=False)
# 取出一张成果
img_arr = predictions[0][:, :, 0]
# 将成果恢复成图片像素色值数据
img_arr = img_arr* 127.5 + 127.5

ChatGPT火了,我连夜详解AIGC原理,并实战生成动漫头像

这是20000张图,500轮练习的作用。假如是百万张图片,几千轮练习呢?彻底仿真很简略。

项目开源地址:gitee.com/bigcool/gan…

三、咱们对AIGC该有的情绪

AIGC的火爆出圈,引起全球的激烈评论。很多当地乃至打算立法,禁止学生运用它做作业。

尽管我说了这么多。或许直到现在,仍然有人觉得这是噱头:我的作业这么高档,是有灵魂的作业,人工智能写文章能比我通畅?它还写代码?它懂逻辑吗?

国外有一个IT老哥叫David Gewirtz。他从1982年开端就写代码,干了40多年,也在苹果公司待过。他认为用ChatGPT写代码不会有啥惊喜。直到呈现成果,却吓了他一大跳。

ChatGPT火了,我连夜详解AIGC原理,并实战生成动漫头像

他的需求是给它老婆写一个网站的插件,用于挑选顾客,并滚动顾客的姓名展现。这个需要几天完结的作业,ChatGPT很快就完结了。而且代码朴实简练,极其标准。它还告知你该操作哪个文件,该怎么布置

现阶段的人工智能,或许没有自己的考虑,可是它有自己的核算。

你会写文章,由于你读过300多本书,而且记住了里边20%的内容。这些让你引认为傲。可是人工智能,它读过人类历史上呈现过的全部文献,只需硬盘够,它悉数都能记住。而且它还不停对这些内容做分析、加工、收拾:这儿和这儿有关联,这儿和那里都是在介绍橙子的营养成分。它通过核算,让全部常识发生互联互通。

当有人向人工智能表明人类的担忧时,人工智能也给出了自己的答复。

ChatGPT火了,我连夜详解AIGC原理,并实战生成动漫头像

我比较附和它的观念。

抱有其他观念的人,首要忧虑有了人工智能,人类就会变得不动脑子了。时间长就废了。

我觉得,这些都是东西。相机出来的时分,也是被画家抵抗,由于成像太简略了。现在想想,太简略有问题吗?没有!相同的还有核算器之于算盘,打字之于手写。乃至TensorFlow 2.0出来时,也被1.0的用户抵抗。他们说开发太简略了,这让开发者底子接触不到底层。殊不知,1.0出来的时分,那些写汇编语言的开发者也想,他们蜕化了,居然不操作寄存器。

其实,我感觉这些忧虑是剩余的。每个年代都有会归于自己年代的产品。就像现在咱们不必毛笔写字了,可是咱们的祖先也没有敲过键盘呀!或许下一个年代的人,连键盘也不敲了。

我是@TF男孩,一位编程表演艺术家。