写点什么

使用 DataWorks Notebook 实现智能图片标注,给你的图片加个“注释”

  • 2025-03-21
    浙江
  • 本文字数:5565 字

    阅读完需:约 18 分钟

使用 DataWorks Notebook 实现智能图片标注,给你的图片加个“注释”

DataWorks 作为一站式智能数据开发治理平台,积累和沉淀了阿里巴巴十余年大数据建设方法论和最佳实践,为数仓、数据湖、OpenLake 湖仓一体数据架构提供智能化 ETL 开发、数据分析与主动式数据资产治理服务,助力“Data+AI”全生命周期的数据管理。面向大数据 &AI 协同开发场景,DataWorks 提供了交互式开发和分析工具 Notebook。DataWorks Notebook 具备灵活且可复用的数据处理和分析环境,增强了数据开发和分析体验的直观性、模块化和交互性,能够帮助用户轻松高效地进行数据处理、数据探索、数据可视化和模型构建。


开发者在创建 Notebook 个人开发环境时,可以选择 GPU 类型的资源,以支持进行高性能的计算工作。在此基础上:开发者可在 DataWorks 一个平台即可完成数据清洗、特征工程到模型训练/推理的全流程,无需跨平台迁移数据,真正实现“Data+ AI”一站式数据开发,让数据驱动的未来加速降临。


本文将基于视觉识别模型 RAM 和自然语言处理模型 BERT,介绍如何使用 DataWorks Notebook 实现多模态图片标注,为智能内容生成、多模态数据分析领域提供数据基础。


实践原理与背景:


通过 RAM 的开放词汇视觉识别能力,系统能够从图像中精准检测并提取物体、场景及细粒度属性信息。 结合 BERT 对文本语义的深度理解与生成能力,将视觉特征转化为自然语言描述,实现语义连贯、内容丰富的图像标注。


该方法利用视觉-语言跨模态对齐,在无需领域标注数据的条件下,支持零样本场景下的自动化标注,可广泛应用于智能内容生成及多模态数据分析等领域。

前置步骤

  1. 进入DataWorks Gallery,选择“基于视觉识别模型 RAM 和自然语言处理模型 BERT 实现图片标注”案例


DataWorks Gallery 是最佳实践案例集,提供数十种公共数据集与数据开发实践案例,覆盖大数据+AI 协同开发、RAG、数据预处理多场景,涉及互联网、金融、电商、汽车等多行业,旨在帮助用户快速体验最佳实践。您可以一键载入案例,快速体验。


  1. 点击“载入案例”,选择“工作空间”与“个人开发环境”。

  2. 如何创建工作空间?




填写工作空间基本信息,注意需要将数据开发(DataStudio)(新版)公测开关置为开启才可使用 Notebook。



  1. 如何创建个人开发环境实例?


工作空间创建完后,点击“创建实例”,进入数据开发 Data Studio 创建实例界面


注意选择 GPU 资源类型时,选择以下配置:  


  • GPU 推荐使用 24GB 显存的 A10(ecs.gn7i-c8g1.2xlarge)或更高配置

  • 镜像选择 DSW 官方镜像 modelscope:1.18.0-pytorch2.3.0-gpu-py310-cu121-ubuntu22.04



完成以上配置后,点击“确定”即可完成个人环境实例创建,根据以下实验步骤完成实验。

1. 环境准备

Recognize Anything Model (RAM) 是一个先进的视觉识别模型,旨在通过零样本(zero-shot)或小样本(few-shot)学习,实现开放词汇(open-vocabulary)的通用视觉识别。


运行以下命令,在当前环境中安装 RAM。


输入:


! pip install git+https://github.com/xinyu1205/recognize-anything.git
复制代码

2. 下载数据集

本教程提供了一份多模态对话数据集。


数据集中的样本为单轮对话形式,共计 261 条样本,每条样本都由一条系统提示、一条用户指令和一条模型回答组成。


数据样例如下所示:


[  {    "conversations": [      {        "from": "system",        "value": "你是一个导游,请生动有趣地回答游客提出的问题"      },      {        "from": "human",        "value": "给我讲讲这个东西<image>"      },      {        "from": "gpt",        "value": "各位游客朋友们,大家好!\n\n现在映入大家眼帘的,是一件极为珍贵的文物——**神面纹玉戚**。它可不是一般的宝贝,而是来自遥远的新石器时代的一件精美玉器哦!\n\n这件宝贝现藏于山西博物院,它的尺寸相当精致:高20.6厘米,宽13.1厘米,厚仅0.4厘米,真是薄如蝉翼,工艺精湛!\n\n1964年,它在黎城县后庄村广志山出土,仿佛穿越时空,向我们诉说着古老的故事。\n\n大家仔细看,这块玉戚采用了线刻工艺,一侧雕刻着神人的半侧面头像,头戴华美的冠饰,披拂着飘逸的长发,眼眉清晰可辨,仿佛在凝视着我们;而另一侧则是一个方形台座上置神人冠饰的形象,显得神秘而威严。\n\n要知道,玉戚在古代可是象征军事统帅权力的神器,握有它,就如同掌握了千军万马!\n\n大家不妨多停留片刻,感受一下这件文物散发出的古老而神秘的气息吧!\n\n谢谢大家的聆听,接下来我们将继续参观其他精彩展品,敬请期待!"      }    ],    "images": [      "images/instance_1579398113581395972.jpg"    ]  }]
复制代码


运行以下命令,下载数据集。


import osregion = os.getenv('DATAWORKS_REGION')
复制代码


!wget https://dataworks-notebook-{region}.oss-{region}-internal.aliyuncs.com/public-datasets/Image_Tagging_GPU/Qwen2-VL-History.zip!mkdir data && unzip -q Qwen2-VL-History.zip -d ./data
复制代码

3. 下载模型

3.1 下载 ram_plus_swin_large_14m 模型

在本教程中,所需的第一个模型为视觉识别模型 ram_plus_swin_large_14m:


https://huggingface.co/xinyu1205/recognize-anything-plus-model/blob/main/ram_plus_swin_large_14m.pth


RAM++ 是下一代 RAM ,能够高精度地识别任何类别,包括预定义的常见类别和多样化的开放类别。


RAM++ 在常见标签类别、不常见标签类别以及人物交互阶段的表现均优于现有的 SOTA 图像基础识别模型。


运行以下命令,下载 ram_plus_swin_large_14m 模型。


注意:该模型文件较大(2.8 GB),下载时长预计 10 分钟。


!mkdir models!wget -P ./models https://dataworks-notebook-{region}.oss-{region}-internal.aliyuncs.com/public-datasets/Image_Tagging_GPU/ram_plus_swin_large_14m.pth
复制代码

3.2 下载 BERT-base-uncased 模型

在本教程中,所需的第一个模型为视觉识别模型 BERT_base_uncased:


https://huggingface.co/google-bert/bert-base-uncased/tree/main


BERT_base_uncased 是使用了掩码语言建模 (MLM) 目标对英语进行预训练的模型。该模型不区分英文大小写。


运行以下命令,下载 BERT_base_uncased 模型。


注意:该模型文件较大(2.9 GB),下载时长预计 10 分钟。


!wget https://dataworks-notebook-{region}.oss-{region}-internal.aliyuncs.com/public-datasets/Image_Tagging_GPU/bert-base-uncased.zip!unzip -q bert-base-uncased.zip -d ./models
复制代码


下载 2 个模型后,在 DataWorks 个人目录中,模型文件将按照以下格式存储:


├─models│  │─ ram_plus_swin_large_14m.pth│  │─ bert-base-uncased│  │   │─coreml│  │   │  │─...│  │   │─config.json│  │   │─model.safetensors│  │   │─pytorch_model.bin│  │   │─...           
复制代码

4. 数据打标

通过如下代码定义图片打标的算子逻辑:


from collections import Counterfrom datasets import Imageimport osimport numpy as np
import torchfrom ram.models import ram_plusfrom ram.transform import get_transform
import logginglogging.basicConfig(level=logging.INFO, format='%(asctime)s:%(name)s:%(levelname)s:%(message)s')
IMAGE_BASE_DIR = './data'

def load_image(path): img_feature = Image() img = img_feature.decode_example(img_feature.encode_example(path)) img = img.convert('RGB') return img

class ImageTaggingMapper(object): """Generate image tags. """
def __init__(self, image_filed: str = 'images', tag_field_name: str = 'image_tags', *args, **kwargs): """ Initialization method. :param image_filed: the field name of images. :param tag_field_name: the field name to store the tags. :param args: extra args :param kwargs: extra args """ super().__init__(*args, **kwargs)
self.image_filed = image_filed
logging.info('Loading recognizeAnything model...') self.model = ram_plus( pretrained='./models/ram_plus_swin_large_14m.pth', text_encoder_type='./models/bert-base-uncased', image_size=384, vit='swin_l', threshold=0.68) self.device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu') self.model.to(self.device).eval() self.transform = get_transform(image_size=384) self.tag_field_name = tag_field_name
def process_single(self, sample): # 检查标签是否已生成 if self.tag_field_name in sample: return sample
# 如果图像不存在,则返回空标签 if self.image_filed not in sample or not sample[self.image_filed]: sample[self.tag_field_name] = np.array([[]], dtype=np.str_) return sample
# 加载图像 image_paths = sample[self.image_filed] image_tags = [] for img_path in image_paths: img_path = os.path.join(IMAGE_BASE_DIR, img_path) # 获取图像的路径 image = load_image(img_path)
image_tensor = torch.unsqueeze(self.transform(image), dim=0).to(self.device) with torch.no_grad(): tags, _ = self.model.generate_tag(image_tensor)
words = [word.strip() for word in tags[0].split('|')] word_count = Counter(words) sorted_word_list = [item for item, _ in word_count.most_common()] image_tags.append(np.array(sorted_word_list, dtype=np.str_))
sample[self.tag_field_name] = image_tags return sample
复制代码


对数据集中的图片进行打标:


from datasets import load_dataset
data_path = './data/train.json'tag_data_path = './out_tag_data.json'
# 加载数据dataset = load_dataset('json', data_files=data_path)
# 初始化打标算子image_tagging_op = ImageTaggingMapper()
# 数据集打标dataset = dataset.map(function=image_tagging_op.process_single)
# 保存打标结果,在原数据文件中新增一个tag field保存打标结果dataset['train'].to_json(tag_data_path, force_ascii=False)
复制代码


查看 1 条打标的数据,可以看到在原数据基础上新增了一个image_tags字段保存打标的结果:


!head -n 1 ./out_tag_data.json
复制代码


打标结果可视化:


import matplotlib.pyplot as pltfrom PIL import Image, ImageDraw, ImageFontimport osimport jsonimport random

TAG_FONT_SIZE = 30FONT_PATH = "./DingTalk JinBuTi.ttf" # 使用字体文件TAG_COLOR = "red"

# 可视化函数def visualize_with_tags(image_path, tags): try: # 加载图片 img = Image.open(image_path) draw = ImageDraw.Draw(img) # 加载字体并设置大小 try: font = ImageFont.truetype(FONT_PATH, TAG_FONT_SIZE) except Exception as e: print('load default font') font = ImageFont.load_default() # 默认字体可能无法缩放 # 在图片左上角添加标签 tag_text = "标签:\n" + ", \n".join(tags) draw.text((10, 10), tag_text, fill=TAG_COLOR, font=font) # 显示图片 plt.figure(figsize=(10, 8)) plt.imshow(img) plt.axis("off") plt.title(os.path.basename(image_path)) plt.show() except FileNotFoundError: print(f"图片文件不存在:{image_path}") except Exception as e: print(f"处理图片时发生错误:{str(e)}")

# 加载数据with open(tag_data_path, 'r') as f: data_list = f.readlines() random.shuffle(data_list) # 有一些连续相同的图像,shuffle 显示不同的图像 # 批量可视化 for item in data_list[:3]: # 显示3个样本 item = json.loads(item) images = item['images'] tags = item['image_tags'] for i in range(len(images)): image_path = os.path.join(IMAGE_BASE_DIR, images[i]) tag = item['image_tags'][i] print(f"图片路径:{images[i]}") print(f"标注标签:{tags[i]}") visualize_with_tags(image_path, tag)
复制代码


输出:


图片路径:images/instance_1579398113589784578.jpg标注标签:['calligraphy', 'ink', 'manuscript', 'mark', 'pen', 'scroll', 'text', 'write', 'writing']
复制代码



图片路径:images/instance_1579398113581395972.jpg标注标签:['artifact', 'hole', 'metal', 'rust', 'writing']
复制代码



图片路径:images/instance_1586990758474346497.jpg标注标签:['architecture', 'building', 'city', 'pillar', 'entrance', 'palace', 'place', 'plaza', 'red', 'shrine', 'sky', 'structure', 'temple', 'worship']
复制代码



案例详情请点击DataWorks Gallery查看。

用户头像

还未添加个人签名 2020-10-15 加入

分享阿里云计算平台的大数据和AI方向的技术创新和趋势、实战案例、经验总结。

评论

发布
暂无评论
使用DataWorks Notebook实现智能图片标注,给你的图片加个“注释”_大数据_阿里云大数据AI技术_InfoQ写作社区