{ "cells": [ { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# Image summary and visual question answering" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "This notebooks shows how to generate image captions and use the visual question answering with [LAVIS](https://github.com/salesforce/LAVIS). \n", "\n", "The first cell is only run on google colab and installs the [ammico](https://github.com/ssciwr/AMMICO) package.\n", "\n", "After that, we can import `ammico` and read in the files given a folder path." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "execution": { "iopub.execute_input": "2023-09-04T04:51:56.399050Z", "iopub.status.busy": "2023-09-04T04:51:56.397952Z", "iopub.status.idle": "2023-09-04T04:51:56.408927Z", "shell.execute_reply": "2023-09-04T04:51:56.408229Z" } }, "outputs": [], "source": [ "# if running on google colab\n", "# flake8-noqa-cell\n", "import os\n", "\n", "if \"google.colab\" in str(get_ipython()):\n", " # update python version\n", " # install setuptools\n", " # %pip install setuptools==61 -qqq\n", " # install ammico\n", " %pip install git+https://github.com/ssciwr/ammico.git -qqq\n", " # mount google drive for data and API key\n", " from google.colab import drive\n", "\n", " drive.mount(\"/content/drive\")" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2023-09-04T04:51:56.412617Z", "iopub.status.busy": "2023-09-04T04:51:56.412114Z", "iopub.status.idle": "2023-09-04T04:52:09.498495Z", "shell.execute_reply": "2023-09-04T04:52:09.497527Z" }, "tags": [] }, "outputs": [], "source": [ "import ammico\n", "from ammico import utils as mutils\n", "from ammico import display as mdisplay\n", "import ammico.summary as sm" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "execution": { "iopub.execute_input": "2023-09-04T04:52:09.503238Z", "iopub.status.busy": "2023-09-04T04:52:09.502471Z", "iopub.status.idle": "2023-09-04T04:52:09.508220Z", "shell.execute_reply": "2023-09-04T04:52:09.507519Z" }, "tags": [] }, "outputs": [], "source": [ "# Here you need to provide the path to your google drive folder\n", "# or local folder containing the images\n", "images = mutils.find_files(\n", " path=\"data/\",\n", " limit=10,\n", ")" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "execution": { "iopub.execute_input": "2023-09-04T04:52:09.511662Z", "iopub.status.busy": "2023-09-04T04:52:09.511188Z", "iopub.status.idle": "2023-09-04T04:52:09.514773Z", "shell.execute_reply": "2023-09-04T04:52:09.513954Z" }, "tags": [] }, "outputs": [], "source": [ "mydict = mutils.initialize_dict(images)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Create captions for images and directly write to csv" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Here you can choose between two models: \"base\" or \"large\". This will generate the caption for each image and directly put the results in a dataframe. This dataframe can be exported as a csv file.\n", "\n", "The results are written into the columns `const_image_summary` - this will always be the same result (as always the same seed will be used). The column `3_non-deterministic summary` displays three different answers generated with different seeds, these are most likely different when you run the analysis again." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "execution": { "iopub.execute_input": "2023-09-04T04:52:09.518553Z", "iopub.status.busy": "2023-09-04T04:52:09.518082Z", "iopub.status.idle": "2023-09-04T04:54:04.548676Z", "shell.execute_reply": "2023-09-04T04:54:04.470455Z" }, "tags": [] }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "\r", " 0%| | 0.00/2.50G [00:00 2\u001b[0m mydict[key] \u001b[38;5;241m=\u001b[39m \u001b[43msm\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mSummaryDetector\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmydict\u001b[49m\u001b[43m[\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43manalyse_image\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 3\u001b[0m \u001b[43m \u001b[49m\u001b[43msummary_model\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43msummary_model\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43msummary_vis_processors\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43msummary_vis_processors\u001b[49m\n\u001b[1;32m 4\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", "\u001b[0;31mTypeError\u001b[0m: analyse_image() got an unexpected keyword argument 'summary_model'" ] } ], "source": [ "for key in mydict:\n", " mydict[key] = sm.SummaryDetector(mydict[key]).analyse_image(\n", " summary_model=summary_model, summary_vis_processors=summary_vis_processors\n", " )" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "Convert the dictionary of dictionarys into a dictionary with lists:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "execution": { "iopub.execute_input": "2023-09-04T04:54:54.396123Z", "iopub.status.busy": "2023-09-04T04:54:54.395380Z", "iopub.status.idle": "2023-09-04T04:54:54.510289Z", "shell.execute_reply": "2023-09-04T04:54:54.509498Z" }, "tags": [] }, "outputs": [], "source": [ "outdict = mutils.append_data_to_dict(mydict)\n", "df = mutils.dump_df(outdict)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Check the dataframe:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "execution": { "iopub.execute_input": "2023-09-04T04:54:54.520391Z", "iopub.status.busy": "2023-09-04T04:54:54.519752Z", "iopub.status.idle": "2023-09-04T04:54:54.768003Z", "shell.execute_reply": "2023-09-04T04:54:54.766862Z" }, "tags": [] }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
filename
0102141_2_eng
1106349S_por
2102730_eng
\n", "
" ], "text/plain": [ " filename\n", "0 102141_2_eng\n", "1 106349S_por\n", "2 102730_eng" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.head(10)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Write the csv file:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "execution": { "iopub.execute_input": "2023-09-04T04:54:54.774655Z", "iopub.status.busy": "2023-09-04T04:54:54.774106Z", "iopub.status.idle": "2023-09-04T04:54:54.829772Z", "shell.execute_reply": "2023-09-04T04:54:54.829031Z" } }, "outputs": [], "source": [ "df.to_csv(\"data_out.csv\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Manually inspect the summaries\n", "\n", "To check the analysis, you can inspect the analyzed elements here. Loading the results takes a moment, so please be patient. If you are sure of what you are doing.\n", "\n", "`const_image_summary` - the permanent summarys, which does not change from run to run (analyse_image).\n", "\n", "`3_non-deterministic summary` - 3 different summarys examples that change from run to run (analyse_image). " ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "execution": { "iopub.execute_input": "2023-09-04T04:54:54.835153Z", "iopub.status.busy": "2023-09-04T04:54:54.834625Z", "iopub.status.idle": "2023-09-04T04:54:54.885029Z", "shell.execute_reply": "2023-09-04T04:54:54.884071Z" }, "tags": [] }, "outputs": [ { "ename": "TypeError", "evalue": "__init__() got an unexpected keyword argument 'identify'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "Cell \u001b[0;32mIn[10], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m analysis_explorer \u001b[38;5;241m=\u001b[39m \u001b[43mmdisplay\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mAnalysisExplorer\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmydict\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43midentify\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43msummary\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m 2\u001b[0m analysis_explorer\u001b[38;5;241m.\u001b[39mrun_server(port\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m8055\u001b[39m)\n", "\u001b[0;31mTypeError\u001b[0m: __init__() got an unexpected keyword argument 'identify'" ] } ], "source": [ "analysis_explorer = mdisplay.AnalysisExplorer(mydict, identify=\"summary\")\n", "analysis_explorer.run_server(port=8055)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Generate answers to free-form questions about images written in natural language. " ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Set the list of questions as a list of strings:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "execution": { "iopub.execute_input": "2023-09-04T04:54:54.890294Z", "iopub.status.busy": "2023-09-04T04:54:54.889677Z", "iopub.status.idle": "2023-09-04T04:54:54.894807Z", "shell.execute_reply": "2023-09-04T04:54:54.894139Z" } }, "outputs": [], "source": [ "list_of_questions = [\n", " \"How many persons on the picture?\",\n", " \"Are there any politicians in the picture?\",\n", " \"Does the picture show something from medicine?\",\n", "]" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Explore the analysis using the interface:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "execution": { "iopub.execute_input": "2023-09-04T04:54:54.898733Z", "iopub.status.busy": "2023-09-04T04:54:54.898303Z", "iopub.status.idle": "2023-09-04T04:54:54.940244Z", "shell.execute_reply": "2023-09-04T04:54:54.939311Z" } }, "outputs": [ { "ename": "TypeError", "evalue": "__init__() got an unexpected keyword argument 'identify'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "Cell \u001b[0;32mIn[12], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m analysis_explorer \u001b[38;5;241m=\u001b[39m \u001b[43mmdisplay\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mAnalysisExplorer\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmydict\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43midentify\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43msummary\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m 2\u001b[0m analysis_explorer\u001b[38;5;241m.\u001b[39mrun_server(port\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m8055\u001b[39m)\n", "\u001b[0;31mTypeError\u001b[0m: __init__() got an unexpected keyword argument 'identify'" ] } ], "source": [ "analysis_explorer = mdisplay.AnalysisExplorer(mydict, identify=\"summary\")\n", "analysis_explorer.run_server(port=8055)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Or directly analyze for further processing\n", "Instead of inspecting each of the images, you can also directly carry out the analysis and export the result into a csv. This may take a while depending on how many images you have loaded." ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "execution": { "iopub.execute_input": "2023-09-04T04:54:54.947447Z", "iopub.status.busy": "2023-09-04T04:54:54.946834Z", "iopub.status.idle": "2023-09-04T04:55:28.183455Z", "shell.execute_reply": "2023-09-04T04:55:28.178317Z" } }, "outputs": [ { "ename": "FileNotFoundError", "evalue": "[Errno 2] No such file or directory: '102141_2_eng'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mFileNotFoundError\u001b[0m Traceback (most recent call last)", "Cell \u001b[0;32mIn[13], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m key \u001b[38;5;129;01min\u001b[39;00m mydict:\n\u001b[0;32m----> 2\u001b[0m mydict[key] \u001b[38;5;241m=\u001b[39m \u001b[43msm\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mSummaryDetector\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmydict\u001b[49m\u001b[43m[\u001b[49m\u001b[43mkey\u001b[49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43manalyse_questions\u001b[49m\u001b[43m(\u001b[49m\u001b[43mlist_of_questions\u001b[49m\u001b[43m)\u001b[49m\n", "File \u001b[0;32m~/work/AMMICO/AMMICO/ammico/summary.py:244\u001b[0m, in \u001b[0;36mSummaryDetector.analyse_questions\u001b[0;34m(self, list_of_questions)\u001b[0m\n\u001b[1;32m 242\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(list_of_questions) \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m0\u001b[39m:\n\u001b[1;32m 243\u001b[0m path \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msubdict[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mfilename\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n\u001b[0;32m--> 244\u001b[0m raw_image \u001b[38;5;241m=\u001b[39m \u001b[43mImage\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mopen\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpath\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241m.\u001b[39mconvert(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mRGB\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 245\u001b[0m image \u001b[38;5;241m=\u001b[39m (\n\u001b[1;32m 246\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msummary_vqa_vis_processors[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124meval\u001b[39m\u001b[38;5;124m\"\u001b[39m](raw_image)\n\u001b[1;32m 247\u001b[0m \u001b[38;5;241m.\u001b[39munsqueeze(\u001b[38;5;241m0\u001b[39m)\n\u001b[1;32m 248\u001b[0m \u001b[38;5;241m.\u001b[39mto(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msummary_device)\n\u001b[1;32m 249\u001b[0m )\n\u001b[1;32m 250\u001b[0m question_batch \u001b[38;5;241m=\u001b[39m []\n", "File \u001b[0;32m/opt/hostedtoolcache/Python/3.9.17/x64/lib/python3.9/site-packages/PIL/Image.py:3236\u001b[0m, in \u001b[0;36mopen\u001b[0;34m(fp, mode, formats)\u001b[0m\n\u001b[1;32m 3233\u001b[0m filename \u001b[38;5;241m=\u001b[39m fp\n\u001b[1;32m 3235\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m filename:\n\u001b[0;32m-> 3236\u001b[0m fp \u001b[38;5;241m=\u001b[39m \u001b[43mbuiltins\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mopen\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfilename\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mrb\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m 3237\u001b[0m exclusive_fp \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[1;32m 3239\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n", "\u001b[0;31mFileNotFoundError\u001b[0m: [Errno 2] No such file or directory: '102141_2_eng'" ] } ], "source": [ "for key in mydict:\n", " mydict[key] = sm.SummaryDetector(mydict[key]).analyse_questions(list_of_questions)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Convert to dataframe and write csv\n", "These steps are required to convert the dictionary of dictionarys into a dictionary with lists, that can be converted into a pandas dataframe and exported to a csv file." ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "execution": { "iopub.execute_input": "2023-09-04T04:55:28.448267Z", "iopub.status.busy": "2023-09-04T04:55:28.445591Z", "iopub.status.idle": "2023-09-04T04:55:28.487783Z", "shell.execute_reply": "2023-09-04T04:55:28.486923Z" } }, "outputs": [], "source": [ "outdict2 = mutils.append_data_to_dict(mydict)\n", "df2 = mutils.dump_df(outdict2)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "execution": { "iopub.execute_input": "2023-09-04T04:55:28.494419Z", "iopub.status.busy": "2023-09-04T04:55:28.493910Z", "iopub.status.idle": "2023-09-04T04:55:28.515110Z", "shell.execute_reply": "2023-09-04T04:55:28.514224Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
filename
0102141_2_eng
1106349S_por
2102730_eng
\n", "
" ], "text/plain": [ " filename\n", "0 102141_2_eng\n", "1 106349S_por\n", "2 102730_eng" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df2.head(10)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "execution": { "iopub.execute_input": "2023-09-04T04:55:28.528594Z", "iopub.status.busy": "2023-09-04T04:55:28.528074Z", "iopub.status.idle": "2023-09-04T04:55:28.534557Z", "shell.execute_reply": "2023-09-04T04:55:28.533873Z" } }, "outputs": [], "source": [ "df2.to_csv(\"data_out2.csv\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.17" }, "vscode": { "interpreter": { "hash": "f1142466f556ab37fe2d38e2897a16796906208adb09fea90ba58bdf8a56f0ba" } } }, "nbformat": 4, "nbformat_minor": 4 }