独立游戏在AI辅助流程上踩的坑-环球新消息
来源:哔哩哔哩     时间:2023-04-12 02:56:01

背景

先说背景,《玩具帝国》是一个决策复杂、一次任务周期长的策略游戏。


(相关资料图)

游戏基本玩法:

ml-agent

《玩具帝国》的人机AI采用的是Unity的ml-agent,通过强化学习训练能够进行长周期复杂决策的人机AI。原来写决策树很痛苦,现在可以直接挂机炼丹。

ml-agent里给的实例都算是比较简单的决策问题,一次任务的周期也很短,《玩具帝国》的就比较长,决策也很复杂,所以我们使用了“即时奖励”和“预测奖励”进行长周期决策AI的训练。因为数学模型是可调的,所以AI依然可控,只需要根据通过简单的参数调整,就可以改变AI的决策倾向。

推公式还是要一步步推的,希望以后有个AI帮我把这部分工作也做了。

为了让每次输入的向量等长,在观察时,场上的三条路被分成了许多块,在每一块上,统计在其上单位的平均数值或求和,最后加上单独的数值,组合得到完整的向量。

因为不同的文明玩法不一样,但是基本的规则又是一致的,所以先训练一个能掌握基本规则的底模。从教会AI基本的分配工人开始,每次增加训练一项新科目,不断迭代完善,就能得到一个掌握大致规则的底模。在这个底模的基础上做分支训练,就可以得到适用于不同文明策略的模型。

为了避免过拟合,每个Episode前,都对初始条件进行一次随机,譬如不同的资源水平、不同的敌人强度,每次决策时也会对AI的可选项进行随机Dropout,总之尽可能地让AI在训练时接触到所有的可选行为。

ml-agent里默认的决策间隔非常短,但毕竟《玩具帝国》里不需要每时每刻都进行决策,所以我人为地把间隔时间拉长了,这样也能更好地让AI把自己的决策和结果关联起来。

最后基本上只要放着AI在场景里挂机就好了。

进阶一些的话,可以检测一些AI的精彩操作给奖励。毕竟我主要是想训练AI对战略上、宏观的把握,一些小的战术配合可以简单地引导一下,比如在前排有肉盾的时候派出远程。

经过这些调教之后,AI在战术上的表现强了不少。

比如先派骑兵突击,再跟上工人采矿:

比如用近战单位保护远程单位:

比如偷袭(虽然只偷掉了我两个工人):

在训练效果上,修改之后的明显比原生ml-agent强不少:

从全局战略上看,也能看出AI具有很强的倾向性:

AI绘画

游戏里的科技树图标实在太多了,根本画不过来……在没有AI画画之前,我都不敢想啥时候能把这些玩意填完。

AI画画出来之后,我抱着满腔热情去试,结果发现三个严重的问题:

全TM在画二次元,没有适合的风格,想用到游戏里必须自己炼丹。

画出来的画好多都是美少女看镜头,没有叙事性,没法当icon用。

已有素材几乎全是中世纪大胡子男人呆呆站着,图生图不可行,训练出来的泛化性也很差。

一开始的规划是:

画出卡通简笔画风格。

资产条件:有98张人像和8张UI,且人像全是男人。

需要能产出带有该画风的具有一定叙事内容的图像,内容形式一定要多元。

我尝试了最开始的Embedding:

后来换成CKPT(画和训练集里接近的小人已经不错了,但泛化性还是不理想):

然后是Lora(好!很接近了!):

最后是Locon:

现在这个版本画人画物画事都很完美了,甚至能从全是大胡子男人的训练集里学会画女人:

从中世纪里摘出摩托车:

为了引导AI画出前景后景突出的画,还专门画了一组引导图。分别是只保留前景、只保留背景、全图共三张图,在Caption里打组:

由于训练集中人物朝向太固定,此处额外做了镜像处理。

由于训练集缺乏建筑、风景、完整图像,为了丰富训练集,我先进行一次时间较短的训练,并用得到的模型生成与目标画风类似的建筑、风景图像,再将这些图片放回训练集。

还做了正则化:

模型出来之后,也不是说生了图就能直接用,像一些比较复杂的图,我的方案是先去掉我的微调模型用底模生一张图,然后用ControlNet加上我的微调模型出新图。

下面从左到右就是:底模+微调,底模,底模+微调+ControlNet。

最后效果不错:

而且这个模型在美术做设计参考的时候也能用:

补充一些在训练中印象比较深刻的参数设置:

Epoch

Epoch 是指一次将训练集中的所有样本训练一次(即对每个样本完成一次正向传播与一次反向传播)的过程。有时,由于一个训练样本过于庞大,它会被分成多个小块分批学习,每个小块就叫 batch。

在深度学习中,程序通过不断地将数据集在神经网络中往复传递来更新网络中的权重,以此建立对目标的拟合关系,因此只有反复地迭代才能增强数据集的拟合度。

随着 epoch 的增加,模型将从欠拟合变为过拟合。我们希望能达到中间的效果,即对训练集输出相对准确的结果,又对不在训练集里的输入也有较好的表现。就像刷题不能只刷一遍一样,我们需要不少于一个 epoch 才能建立起较好的拟合关系,当然也不能太多。对于不同的数据集,使用的 epoch 都可能有所不同。

Batch Size

batch size 表示训练时的批量大小,也就是一次训练中选取的样本数量。

这个参数对性能有一定要求,如果性能足够,增加 batch size 在理论上会提高模型的准确性。如果数据集样本量较小,Batch Size 可以等于样本数量,即把所有数据集一起输入网络进行训练,这样的效果也很好;但是如果样本量较大,这肯定让设备吃不消,因此需要减小 Batch Size。

但是,如果 Batch Size 太小,那么意味着在一个 Epoch 中迭代的次数也会减小,训练时权重的调整速度变慢,为了抵消这种影响,还得提高 epoch 才能有更好的效果。所以 Batch Size 与 Epoch 参数二者是相辅相成的,他们二者的关系就好比一次刷多少题和总共刷多少次题。

合适的 batch size 应该让 GPU 正好满载运行。

Learning Rate

学习率指的是一次迭代(即输入一个样本对它学习,并用此次学习的经验调整神经网络)的步长。这个值越大,表明一次学习对模型的影响越大。

为了让学习循序渐进,学习率不应该太高,我们需要 AI 在训练中反复总结一点点经验,最后累积为完整的学习成果。合理的学习率会让学习过程收敛,Loss 达到足够低。

学习率太低,容易出现局部最优解,类似于“一个开车的 AI 稀里糊涂地开完全程,车技很菜”;学习率太高,容易使得模型不收敛,找不到解,类似于“一个开车的 AI 完全不会开车,只会原地打圈瞎操作”。

Learning Rate Scheduler

学习率调度器是一种用于动态调整学习率的技术,它可以在训练过程中根据模型的表现自动调整学习率,以提高模型的训练效果和泛化能力。

通常,学习率在训练开始时设置为比较高的值,允许 AI“在一次训练中学得更多更快”。

随着训练的进行,学习率会降低,逐步收敛到最优。在训练过程中降低学习率也称为退火衰减

Optimizer

优化器。在训练神经网络时,我们需要在反向传播中逐步更新模型的权重参数。优化器的作用就是根据当前模型计算结果与目标的偏差,不断引导模型调整权重,使得偏差不断逼近最小。

Adafactor 和 Lion 是推荐使用的优化器。

Adam:一种常用的梯度下降算法,被广泛应用于神经网络模型的优化中。它结合了动量梯度下降和自适应学习率方法的优点,既可以加快收敛速度,又可以避免学习率调整不当导致的振荡和陷入局部最优解。并且对于不同的参数有不同的学习率,更加适用于高维度的参数空间。AdamW:对 Adam 算法的改进方案,对惩罚项参数进行控制,能更好地控制模型的复杂度,防止模型过拟合,提高泛化性能。AdamW8bit:8bit 模式的 AdamW,能降低显存占用,略微加快训练速度。Adafactor:自适应优化器,对 Adam 算法的改进方案,降低了显存占用。参考学习率为 0.005[1]。DAdaptation:自适应优化器,比梯度下降(SGD)方法更加稳定有效、使用时请将学习率设置为 1[2]。Lion:自适应优化器,节省更多显存、速度更快,与 AdamW 和 Adafactor 相比有 15%左右的加速。参考学习率为 0.001[3]。SGDNesterov:一种常用的优化算法,基于梯度下降(SGD)方法进行优化,通过引入动量的概念加速收敛速度。SGDNesterov8bit:8bit 模式的 SGDNesterov,能降低显存占用,略微加快训练速度。

Text Encoder 与 Unet

机器不能直接识别人类的语言,Text Encoder 是一种用于将文本数据转换为机器可读形式的模型或算法。对于输入的一串提示词,程序会将它们分解为一个个标记(Token)输入给 Text Encoder(一个 Token 通常代表着一个特征),这样一句话就能被转为一个向量为机器所识别。

Unet 是一种用于图像分割的深度学习模型,它的作用是将图像分割为多个不同的构成部分。经过训练后,它可以来填充图像中缺失或损坏的部分,或者对灰度草图进行着色。

Network Rank(Dimension)

表示神经网络的维度,维度越大,模型的表达能力就越强。

如果训练 lora,该值不要超过 64;如果训练 loha,该值不要超过 32;如果训练locon,该值不要超过 12,但还是要根据具体的训练目标来定,如果目标比较简单,就完全不需要太高的 Rank。

在神经网络中,每一层都由许多个神经元节点构成,它们纵横交错构成了一个 N 维空间。维度越大,代表模型中就越多的神经元节点可以处理各种要素。——当然,这也意味着模型的训练难度就越大,也可能变得更容易过拟合,它可能需要更多的、更准确的数据集,更大的迭代次数。

Network Alpha

对模型过拟合的惩罚权重。它表示对模型在训练时出现完全拟合(即输出结果与样本一致)时的惩罚的权重,适当提高它可以增加模型的泛化能力(当然也不能太高)。

目前经验认为设置为 alpha 设置在 1 以下效果更好[4]。

Gradient checkpointing

梯度检查点(Gradient checkpointing)是一种在训练模型时减少显存占用的方法,但是会增加训练时长。它避免在训练期间一次计算所有权重,而是逐步计算权重,从而减少训练所需的显存量。关闭它不会影响模型的准确性,但打开它后我们可以使用更大的Batch Size。 虽然单次训练的时长可能增加了我们单次训练的时长,但如果我们增大了Batch Size,总的学习时间实际上可能会更快。

Caption Dropout

Dropout是在深度学习中一种防止过拟合的技术,在训练中,可能模型会反复计算某些节点,随着训练的进行,这可能导致错误的路径依赖,即模型会变得总是依赖这些节点解决问题,就像某个学生碰巧刷到了几道解题方法相似的题目,就误认为所有的题目都要用这种解题方法。

Dropout的解决方法是随机关闭某些神经元,迫使模型在训练时减少神经元之间的依赖关系,从而让神经网络的泛化能力更强。当然,在实际使用模型的时候,Dropout是关闭的。

在训练中,我们也可以随机将一些训练集的标记(Caption)剔除。在Drop out caption every n epochs中,我们可以指定每隔多少epoch就剔除一些标记;在Rate of caption dropout中,我们可以指定剔除几成的标记。

AI代码

游戏里的Buff特别多,有些Buff带有不同的执行逻辑,不方便统一配表,撰写这些Buff的代码又非常耗时。

试了下用Cursor让它仿照我的代码写一些Buff,发现生成结果可以直接用。

https://wandb.ai/yepster/tpu-t5-base/reports/Adafactor-learning-rate-0-005-seems-best-for-t5-base-training--VmlldzoxNTgyODIw

https://arxiv.org/pdf/2301.07733.pdf

https://github.com/google/automl/tree/master/lion

https://github.com/KohakuBlueleaf/LyCORIS

标签:

广告

X 关闭

广告

X 关闭