我正在尝试使用 pytorch-fid 计算两个数据集之间的 FID。代码的 GitHub 链接是:https://github.com/mseitzer/pytorch-fid
尝试1: 我从小规模开始,每个数据集中有 2800 张图像,全部为 512x512。不幸的是,我生成的图像是 PNG,而真实图像是 JPG。因此,我将 cd 放入生成的图像文件夹中,运行以下 bash 脚本(使用 ImageMagick),并将所有 PNG 转换为 JPG:
for file in *.png
do convert "$file" "$(basename "$file" .png).jpg"
done
通过这些,我成功获得了 143.6 的 FID,我承认这相当糟糕。
尝试2: 我认为增加图像数量可能会降低 FID,因此我再次尝试在每个数据集中添加 5000 张图像。我上面编写的 bash 脚本运行时间很长。所以我切换到下面的Python脚本:
import os
directory = <PATH TO MY DIRECTORY>
files = os.listdir(directory)
# Then you rename the files
for file_name in files:
# You give the full path of the file
old_name = os.path.join(directory, file_name)
# You CHANGE the extension
new_name = old_name.replace('.jpg', '.png')
os.rename(old_name, new_name)
我后来意识到这只是将文件扩展名更改为“.jpg”,而不是文件格式。这显然不起作用,我最终收到以下错误:
RuntimeError: Trying to resize storage that is not resizable
尝试3: 我返回到生成的图像文件夹,反转尝试 2 中的代码(将所有 JPG 重新命名为 PNG),并使用 Pillow 运行下面的脚本来实际更改文件格式。请记住,两个数据集现在都有 5000 个 512x512 JPG 图像。
from PIL import Image
import os
path = <PATH TO MY DIRECTORY>
files=os.listdir(path)
for file in files:
if file.endswith(".png"):
img = Image.open('<PATH TO MY DIRECTORY>'+file)
#print(img)
file_name, file_ext = os.path.splitext(file)
img.save('<PATH TO MY DIRECTORY>{}.jpg'.format(file_name))
但是我仍然从尝试 2 中收到运行时错误。可能出了什么问题? Pillow JPG 转换有问题吗?我应该恢复到 ImageMagick 吗?请帮忙!
如果您要处理 5,000 张图像,您不想为 5,000 个
convert
进程付出启动时间。你最好使用:
mogrify -format JPEG *.png
然后您只需支付一次流程启动成本。然而,这只使用单个 CPU 核心,并且可能会溢出你的命令行长度,我的意思是
ARG_MAX
参数。因此,您会更好地使用GNU Parallel,它将并行使用您的所有内核。根据您的 CPU、RAM 和图像大小,您可能需要这样的命令:
find . -name "*.png" -print0 | parallel -0 -n 64 magick mogrify -format JPEG {}
运行
find
来识别所有 PNG 文件,并将列表发送到 GNU Parallel 并以 null 终止,这样空格就不会令您不安。然后,GNU Parallel 将运行与您拥有的 CPU 核心数量一样多的 mogrify
进程,并向每个进程传递 64 个文件进行转换,这意味着您只需为每 64 个文件支付 1 个进程启动费用。它将不断启动新作业,每个作业在之前的作业退出时处理 64 个图像,从而使所有 CPU 核心保持忙碌。
您可能需要调整数字,并可能添加
--eta
或 --bar
以获得进度条,这样您就可以观看它们 “嗖嗖” 过去。示例此处和此处。
与 PIL/Pillow 代码类似,您应该考虑像 this 这样的多重处理。