Automatic image tagging with Gemini AI
I used multimodal generative AI to tag my archive of 2,500 unsorted images. It was surprisingly effective.
Iâm a digital packrat. Disk space is cheap, so why not save everything? That goes double for things out on the internet, especially those on third party servers, where you canât be sure theyâll live forever. One of the sites that hasnât lasted is ffffound!, a pioneering image bookmarking website, which I was lucky enough to be a member of.
Back around 2013 I wrote a quick Ruby web scraper to download my images, and ever since Iâve wondered what to do with the 2,500 or so images. ffffound was deliberately minimal - you got only the URL of the site it was saved from and a page title - so organising them seemed daunting.
A little preview- this is what got pulled out tagged "maps".
The power of AI compels you!
As time went on, I thought about using machine learning to write tags or descriptions, but the process back then involved setting up models, training them yourself, and it all seemed like a lot of work. It's a lot less work now. AI models are cheap (or at least, for the end user, subsidised) and easy to access via APIs, even for multimodal queries.
After some promising quick explorations, I decided to use Googleâs Gemini API to try tagging the images, mainly because they already had my billing details in Google Cloud and enabling the service was really easy.
Prototyping and scripting
My usual prototyping flow is opening an iPython shell and going through tutorials; of course, thereâs one for Gemini, so I skipped to âGenerate text from image and text inputsâ, replaced their example image with one of mine, tweaked the prompt - ending up with âGenerate ten unique, one to three word long, tags for this image. Output them as comma separated, without any additional textâ - and was up and running.
With that working, I moved instead to writing a script. Using the code from the interactive session as a core, I wrapped it in some loops, added a little SQL to persist the tags alongside the images in an existing database, and set it off by passing in a list of files on the command line. (The last step meant I could go from running it on the six files matching images/00\*.jpg up to everything without tweaking the code.) Occasionally it hit rather baffling errors, which werenât well explained in the tutorial - Iâll cover how I handled them in a follow up post.
You can see the resulting script on GitHub. Running it over the entire set of images took a little while - I think the processing time was a few seconds per image, so I did a few runs of maybe an hour each to get all of them - but it was definitely much quicker than tagging by hand. Were the tags any good, though?
Exploring the results
I coded up a nice web interface so I was able to surf around tags. Using that, I could see what the results were. On the whole? Between fine and great. For example, it turns out I really like maps, with 308 of the 2,580 or so images ending up with the tag âmapâ which are almost all, if not actual maps, do at least look cartographic in some way.
The vast majority of the most common tags I ended up with were the same way - the tag was generally applicable to all of the images in some way, even if it wasnât totally obvious at first why. However, it definitely wasnât perfect. One mistake I noticed was this diagram of roads tagged ârailâ - and yet, I can see how a human would have done the same.
Another small criticism? There was a lack of consistency across tags. I can think of a few solutions, including resubmitting the images as a group, making the script batch images together, or adding the most common tags to the prompt so the model can re-use them. (This is probably also a good point to note it might also be interesting to compare results with other multimodal models.)
Finally, there were some odd edge cases to do with colour. I can see why most of these images are tagged âredâ, but why is the telephone box there? While there do turn out to be specks of red in the diagram at the bottom right, Iâd also go with âblack and whiteâ myself over âblackâ, âwhiteâ, and âredâ as distinct tags.
Worth doing?
On the whole, though, I think this experiment was pretty much a success. Tagging the images cost around 25¢ (US) in API usage, took a lot less time than doing so manually, and nudged me into exploring and re-sharing the archive. If you have a similar library, Iâd recommend giving this sort of approach a try.
















