PixGrid 测试算法设计复盘
Last updated on December 28, 2024 pm
今晚处理完毕了 PixGrid 生产服务的最后一部分补强加固。作为 Shugetsu Soft 内部短期孵化机制成功进阶 Incubating 的项目,我们对这个项目在我们已有的 Pixiv 插画数据库基础上深度发掘所能产生的价值抱有厚望。
这篇文章主要对成品展品回报率的内部量化测试流程进行开发复盘;对于主项目的架构和开发复盘,敬请关注 Rorical 的博客。
Image Retrieval
以图搜图任务在学术上被归类为“Image Retrieval”,即“以给定输入查找图像信息”。有别于“查找图像文件”,其重点是算法对图像内容的抽象理解和特征提取。本领域除了“以图搜图”,还包含“以文搜图”等其他类型信息的转译。
Attack & Defence
针对 Image Retrieval 模型的“攻击”本质上是在不断劣化输入图片的过程中优化模型特征提取的准确性。考虑到模型应用的实用性,攻击算法通常会模仿常见的图片劣化路径。本次测试中,我们所设计的攻击路径如下:
- 去色(
grayscale
):将图片直接做灰阶处理。考验模型对非色彩的高频细节抽象能力; - 高斯模糊(
gaussian_blur
):使用对称高斯核,标准差 1.5 像素对图片进行高斯模糊。模拟图片升采样过程中传统方法所造成的高频细节丢失; - 亮度偏移(
brightness_shift
):对图片的每个色彩通道增加 0.25 倍的亮度。丢弃亮区的色彩细节; - 灰滤镜(
alpha_blend
):向图片上叠加透明度 25%,色彩为 # CDD0D3 的颜色层。模拟通过拍摄/扫描所得到图片褪色/洗色的情况; - JPEG 压缩(
jpeg_compression
):质量为 40% 的标准 JPEG 压缩。常见的有损过度处理; - 像素翻转(
bit_flip
):以 5% 的概率随机对图片像素进行色彩翻转。模拟图片损坏的情况; - 黑白噪点(
salt_and_pepper_noise
):以 5% 的概率随机将图片像素设置为纯白或纯黑色。模拟图片损坏的情况; - 随机裁切(
random_crop
):将图片随机裁切至原大小的 65% - 85% 之间。常见的图片信息损失; - 摩尔纹 (
colored_moire
):对 RGB 通道进行错频,叠加一个错角度的交错黑白滤镜,再使用双线性降采样还原图片。会在原图上叠加一层独特的高频色彩纹理,模拟对光栅显示屏拍摄时产生的摩尔纹干扰现象;-
▶测试图(多图炸猫)
-
- Bad Skia 算法错误(
bad_skia
):即经典的 “压图变绿”问题。根源在于 JPEG 压缩中, RGB 转 YUV 时精度不足导致的错误舍入。核心的错误算法模拟(需要在uint8
像素上进行计算):1
2
3
4
5
6
7
8
9
10
11
12
13# Convert to int32 to prevent overflow during calculations
r, g, b = r.astype(np.int32), g.astype(np.int32), b.astype(np.int32)
# YUV to RGB conversion
y = np.clip(((77 * r + 150 * g + 29 * b) >> 8), 0, 255)
u = np.clip((((-43 * r - 85 * g + 128 * b) >> 8) - 1), -128, 127)
v = np.clip((((128 * r - 107 * g - 21 * b) >> 8) - 1), -128, 127)
# RGB to YUV conversion
r1 = np.clip(((65536 * y + 91881 * v) >> 16), 0, 255)
g1 = np.clip(((65536 * y - 22553 * u - 46802 * v) >> 16), 0, 255)
b1 = np.clip(((65536 * y + 116130 * u) >> 16), 0, 255)
Architecture
架构上没什么好说的,使用 Python 实现主要是因为方便。由于查询本身相对很慢(过网络栈,内部又是一个遍历向量数据库的查询,因为内存不足查询操作还要落盘),生成测试样例的倍数增长又会让一个适中的测试样本变得很大,因此做了多线程处理,每个测试单元的所有变种都是并发发出,测试单元又维持在一个并发测试池中滚动收集数据。Python 写多线程真的非常非常恶心,不仅是难以实现,还有难以 Debug 的问题,写起来真的很反人类。
生成测试样例的流程部分用了统一结构,可以挂载任意相同结构的处理函数,主测试脚本会自动遍历流程类下的所有测试函数进行测试。为了尽量快的运行一些样例生成函数,所有的图片运算都用了 NumPy,尽可能使用并行写入像素而非遍历像素,几个关键的热点函数从分钟级处理降低到了秒级。结合并发测试池,平均每个测试组的回收速度比单个测试的极限时间还要快。
Result
以下是程序的原始输出(套了一个 time
计算总时长):
1 |
|
总体来讲其实我不是特别满意。但是作为一个孵化中的项目,我们并没有下真正的努力在优化/微调模型上(并且也没有用于训练的资金——我们在考虑下一步使用 Google 的 Academic TPU Pod 名额),作为一个未经修改的 CLIP 模型应用,对于特定场景(例如切图、偏色等)的准确度高于传统方案(例如 IQDB 或 SauceNAO)已经非常实用了。
我们有注意到去色处理异常的识别率。我们推测这是因为 CLIP 模型训练中强依赖于色彩抽象而非结构抽象所致。这个问题应该也会在项目的下一阶段加以解决。