构建Among Us游戏bot时1080x1920输入CNN出现OOM,该如何优化输入尺寸?
可落地的输入尺寸缩减方案
- 先做ROI有效区域裁剪:《Among Us》的有效操作信息仅集中在中间视野区、底部操作栏,顶部状态栏、两侧冗余边框无任何训练价值,直接裁掉无效区域,先把1080x1920的原图压到720x1280甚至更小的有效尺寸,无需保留全画面的冗余信息。
- 固定比例降采样:针对剩下的有效区域,用双三次插值直接缩到270x480、180x320这类小分辨率——《Among Us》色块区分度极高,只要能识别角色、按钮、地图标识的轮廓即可,完全不需要1080p级别的细节。
- 预处理前置到CPU:所有裁剪、缩放操作全部在CPU端完成,只把处理后的小尺寸张量传到GPU参与训练,避免GPU上临时缓存大尺寸原图占用显存。
输入过大导致OOM的行业常规处理逻辑
你当前的OOM本质是输入尺寸+不合理的模型设计共同导致的:报错的tensor维度里的1888569刚好是第一层64x64卷积、步长1无padding后的特征图宽高乘积(1017*1857=1888569),说明仅加的一次2x2池化根本没把维度压下来;直接Flatten接全连接层的设计,会让全连接层的参数量爆炸,显存直接溢出。
常规处理方案分为结构优化和训练侧优化两类:
- 重构CNN的降维链路,从结构上压缩特征图维度:
- 把超大卷积核拆成小卷积核组合:比如把64x64的卷积拆成两层3x3卷积,搭配步长2的下采样层,既可以达到同等的感受野,又能快速压缩特征图尺寸,参数量直接减少90%以上。
- 增加连续下采样层:每经过2-3层卷积就加一次2x2的MaxPool/步长2卷积,把特征图宽高逐次砍半,哪怕输入是1080p,经过3-4次下采样后,最终特征图尺寸会降到几十x几十,Flatten后的维度仅几千量级,不会触发显存爆炸。
- 用全局平均池化替代Flatten:不管最后一层卷积输出的特征图尺寸多大,直接对每个通道求平均,输出维度等于卷积通道数(比如32通道就输出32维),再接后续的全连接层,参数量会比直接Flatten低几个数量级。
- 训练侧显存优化手段:
- 匹配输入尺寸调整batch size:输入缩小后优先把batch size调到显存可容纳的最大值,如果显存还是不够就降到2、4的小batch,你现在报错的tensor shape为
[1,...]说明已经把batch size降到1了,这个优化对你当前的阶段用处不大。 - 开启混合精度训练:用FP16存储权重和特征图,显存占用直接砍半,精度几乎无损失,主流深度学习框架都已默认支持。
- 梯度累积:如果小batch size训练效果不佳,可以累积多步的梯度再做参数更新,等效扩大batch size的同时不增加显存占用。
- 匹配输入尺寸调整batch size:输入缩小后优先把batch size调到显存可容纳的最大值,如果显存还是不够就降到2、4的小batch,你现在报错的tensor shape为
额外纠错:你当前的输出层设计完全不符合任务需求:
用Dense(7, activation='softmax')的输出是互斥的概率分布,总和为1,但你的7个输出分别是4个可同时触发的方向按键、2个连续的点击坐标、1个鼠标按下状态:
- 方向按键、鼠标按下属于独立的二分类任务,应该用sigmoid激活
- x_click、y_click是连续的回归值,应该用线性激活,提前把坐标归一化到0-1范围即可
- 损失函数对应调整为「多标签二分类交叉熵 + 坐标MSE损失」的混合形式,不然模型根本学不到有效控制逻辑。
内容的提问来源于stack exchange,提问作者user14234656
相关产品推荐
相关产品推荐

