神奇植物在哪里?文心大模型助力一秒读懂花草的“前世今生”

news2024/11/26 15:30:18

8dbab27908b11f547af13fe5dca47ab8.jpeg

本期文心开发者说邀请到飞桨开发者技术专家谢杰航老师,分享如何利用AI技术构建风景园林行业的植物知识科普系统,接着还介绍了大模型应用的基本技术流程框架,多模态特征提取以及使用向量数据库的优势,使用飞桨星河社区运行向量数据库的方法,以及创建向量数据库、数据表和embedding操作的过程等。此外,老师还介绍了文心大模型的重要任务,即为不同用户群体生成个性化版本的内容输出。

点击链接 立刻体验:

基于文心大模型的儿童植物识别科普系统

1eda037f0f0bb6cf3fb0d1ead4bbbdb1.jpeg大模型与植物相遇

创新植物科普路径

所有的应用都值得用大模型进行重构,但是在实际过程中,大模型落地可能会存在成本问题。如何去评估大模型,以及这个应用是否值得用大模型去做,我们要认识到大模型能够为应用带来什么样的创新点,能够带来什么样的价值。所以我们在做植物识别科普应用的时候,便对应用市场上的植物识别App做了调研。我们发现目前的同类App都有两个问题,一是只包含了很简单的识别功能,用户扫一下某种植物,App只会输出是哪个品种,没有对识别结果进一步介绍;还有另外一类App,对植物的解释是简单地生搬硬套教科书,专业术语众多,内容缺乏趣味性。

关于植物的教科书内容包含大量专业术语,例如玄参科植物,大部分非植物专业的人群是不知道这些术语的。为了增强内容的趣味性,达到科普的目的,我们使用文心大模型对输出结果进行重写,让输出的植物介绍更加口语化,适应不同群体的阅读需求,吸引大家关注植物、了解植物,让用户产生对植物知识的学习兴趣,这就是我们做这个应用的出发点。如果你是其他行业的,也可能会面临同样的问题。比如产品的说明书,现在很多产品说明书大多晦涩难懂,或者用户提问的时候,客服常常答非所问。这种情况就符合大模型的应用场景,可以根据不同的用户画像,给用户回答的时候,让这个回答更加的自然、更加的流畅、更加的口语化,让用户容易理解接受。

b3cad6322453c1b90dfffea55dbc05e8.jpeg

366cd2be4b3ce2d74bd941ee822cf666.jpeg识别植物不简单

大模型应用的基本技术流程框架

下图是语言大模型应用的基本技术流程框架。

d59166f9aa56045f4b26cbf0131c4eef.jpeg

首先,用户拿手机拍下植物,输入一张植物的图像,我们需要对这个图像进行一个特征提取。特征提取就是把图像变成一个高维向量。我们把这个植物特征输入向量数据库里面做向量比对计算。如果数据库里面已经有相似的植物向量,就把植物名和植物知识直接给到文心大模型做文本重写最后输出文本。

如果输入植物图像是全新的图片,其特征在数据库中未有相似结果,我们把这个图像输入到公版的分类模型,或者输入到自己训练的分类模型做植物图像识别,然后将特征向量和识别结果插入数据库。下次用户上传相似图片的时候,植物特征与前面用户的图像特征具有一定相似度的,那么就可以不通过分类模型,直接通过向量比对的方法确定植物种类。这个方案不需要重复调用分类模型接口,推理整体耗时得到大幅降低。

文心大模型的主要任务是将复杂、专业或书面化的知识转化为易于理解,同时能引起用户阅读兴趣的内容。文心大模型生成植物科普内容后,我们通过向量数据库构建缓存,以便在用户下次读取类似图片时,通过特征抽取和向量对比,快速找到并输出相同的内容,而无需再次调用文心大模型。整个技术架构核心由向量数据库、知识库和文心大模型构成。因此,如果我们要开发一个大模型应用,只要做好这三个技术版块,那么应用的后端也就基本完成了。下面就对每个部分进行详细讲解。

5ac7141045fad729f976ac8b1bda51ac.jpeg特征提取

首先是特征提取,我们使用了PaddleNLP中内置的CLIP多模态模型提取图像特征向量,提取后的特征向量既可用于相似度比较做图像分类,也可用于如图文搜索、图像二次创作生成等其他多模态应用。如果用小模型,比如ResNet50也可以做特征提取,但是它提取的向量只能做单一的任务,不能做其他跨模态任务。所以在软硬件成本条件允许的情况下,比较推荐大家尽可能用一些多模态模型来做特征提取,这能为之后的应用开发提供数据基础。

这一步可以简单通过调用paddlenlp.transformers的CLIPProcessor类,对图片进行特征向量提取,提取后得到一组由浮点数组成的特征向量。

b2d8ccf04ba0edb4be4e1fd9883573b5.jpeg

特征提取

from PIL import Image
import requests
from paddlenlp.transformers import CLIPProcessor, CLIPVisionModelWithProjection

model = CLIPVisionModelWithProjection.from_pretrained("openai/clip-vit-base-patch32")
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")

def extractFeatures(image: Image.Image):
    inputs = processor(images=image, return_tensors="pd")
    outputs = model(**inputs)
    imageEmbeds = outputs.image_embeds
    imageEmbedding = imageEmbeds.numpy() 
    return imageEmbedding

ce410736384ea1b14cd7b8523e2f4d16.jpeg向量数据库解决方案

在本项目中,我们选择Milvus作为向量数据库。Milvus是用Go语言编写的,它天然支持分布式和高并发的特性,在这方面相比其他数据库具有一定优越性。此外,它与飞桨的融合度也很高,星河社区中已经有一些使用Milvus的案例可供我们更好地学习和上手实践。

43dd1347ceff6de312228b72903aceca.jpeg

为什么我们要使用向量数据库而不是直接使用分类模型来进行植物识别呢?

它的第一个好处是向量数据库可以存储、管理和检索特征向量。特征向量除了可以用于相似度比较之外,还能为文—图搜索、图—图搜索、图文生成,图像生成等多模态应用提供数据基础。

第二个好处在于其速度快。深度学习模型推理过程较为耗费GPU资源。在一般情况下,采用相似度计算的方法得到图片分类,计算速度会更快,并且可以全程使用CPU进行计算,而无需依赖GPU,从而节约了成本。

第三个优势在于具有较强的泛化能力。在面对识别准确率下降和罕见样本的情况时,基于深度学习模型的解决方案通常需要重新训练或微调模型,需要较高的时间和算力成本。相比之下,采用向量数据库的方案,可以通过添加若干正例图片到数据库中,从而快速有效地提高识别精度。

92d6a6ec5fee7bff495aface6a0ddab0.jpeg

3a741cbc693cd8997fba950382849b53.jpeg创建向量数据库

接着介绍Milvus向量数据库的创建操作。下面将用milvus轻量化版本做部署演示。首先引入milvus.default_server将它启动,连接到数据库后,打印数据库的版本确定启动成功后,创建一个命名为plant的数据库以及同名的集合(数据表在Milvus里面被称为集合)。plant的集合里包含了plant_id自增字段,记录数据库内的数据量。plant_name是植物名称字段,plant_info是对植物的介绍信息字段,字符串类型数据通过向量数据库存储,可以免去跨多个数据库操作的过程。embeddings向量存储字段,它的数据维度是512。最后通过CollectionSchema将fileds封装起来,通过调用Collection函数创建集合。

启动并创建数据库

from milvus import default_server
from pymilvus import connections, utility, db

启动向量数据库
default_server.start()

检查是否连接成功
connections.connect(host='127.0.0.1', port=default_server.listen_port)
print("Milvus version:", utility.get_server_version())

创建数据库
database = db.create_database("plant")
db.using_database("plant")

创建数据库(集合)

from pymilvus import Collection, CollectionSchema, FieldSchema, DataType

# 定义集合名
collection_name = "plant"

# 定义数据列
plantId = FieldSchema(
  name = "plant_id",
  dtype = DataType.INT64,
  is_primary = True,
  auto_id = True,
)

plantName = FieldSchema(
  name = "plant_name",
  dtype = DataType.VARCHAR,
  max_length = 200,
)

plantInfo = FieldSchema(
  name = "plant_info",
  dtype = DataType.VARCHAR,
  max_length = 10000,
)

plantEmbeddings = FieldSchema(
  name="embeddings",
  dtype=DataType.FLOAT_VECTOR,
  dim=512
)

# 创建schema
schema = CollectionSchema(
  fields=[plantId, plantName, plantInfo, plantEmbeddings],
  description="plant embeddings database",
  enable_dynamic_field=True
)

# 创建数据集合
collection = Collection(
    name=collection_name,
    schema=schema,
    using='default',
    shards_num=2

对图像的特征向量进行相似度计算,需要对embeddings字段做索引。我们这里用的是L2(欧氏距离计算方法),索引的类型选择IVF-FLAT类型。如果是真实业务场景,用户量、并发量、数据量较大的情况下,建议使用IVFSQ8对向量数据进行压缩,它的存储成本更低,计算速度更快,内存占用更少。“nlist”是聚合的数量,一般设置固定,数量越大,内存的消耗成本越高。创建索引后,将集合数据加载到内存中。

创建索引

index_params = {
  "metric_type":"L2",
  "index_type":"IVF_FLAT",
  "params":{"nlist":1024}
}

collection = Collection("plant")
collection.create_index(
  field_name="embeddings", 
  index_params=index_params
)
utility.index_building_progress("plant")

# 加载集合
collection.load()

下一步是向量检索,即相似度比对计算。假设V1为图片1的向量,V2是向量数据库内的向量,计算这两个向量的相似度,当高度相似时可以直接输出V2对应的plant_name作为V1的识别结果。具体代码操作是将V1向量输入collection.search函数,Milvus自动计算出与V1相似度最高向量结果V2,最终输出植物名、介绍和相似度结果。

向量检索(相似度比对)

import numpy as np 

search_params = {
    "metric_type": "L2", 
    "ignore_growing": False, 
    "params": {"nprobe": 10}
}

def searchDb(embeddings: np.ndarray):
    results = collection.search(
                data=embeddings, 
                anns_field="embeddings", 
                param=search_params,
                limit=1,
                expr=None,
                output_fields=['plant_name', "plant_info"],
                consistency_level="Strong"
            )
    return results[0][0].entity.get('plant_name'), results[0][0].entity.get('plant_info'), results[0].distances[0]

当相似度较低时要借助其他小模型,或者是百度云植物识别的API辅助判断。此外,有能力的开发者和机构可以将该模块替换为私有植物图像分类模型和植物知识库。以公版模型接口为例,用户上传向日葵的图片,然后给用户返回相对应的植物名称和简介。

图像识别

from aip import AipImageClassify
from io import BytesIO
from PIL import Image

def plantRec(image: Image.Image):
    bytesIO = BytesIO()
    img.save(bytesIO, format='PNG')
    client = AipImageClassify(BDAPPID, BDAK, BDSK)
    options = {
        "baike_num": 1
    }
    result = client.plantDetect(bytesIO.getvalue(), options)

    name = result["result"][0]["name"]
    info = result["result"][0]["baike_info"]["description"]
    return name, info

接下来对这个模块进行简单封装,例如用户提供04.jpg图像文件,对输入图像进行特征提取后得到一组512维的向量。通过前面封装好的searchDB函数在数据库中找相似的向量,得到一个检索结果相似度。如果相似度较高,直接返回到plant_name和plant_info。如果数据库没有相似的向量,则请求公版模型识别,同时将结果存入向量数据库中用于日后数据比对,节省下一次相似数据请求识别返回的时间。

32a565968146efa8ca388855e5ac6bb4.jpeg

b745ac4ca4ec6d32fab90a574dd8f8f6.jpeg个性化定制植物科普内容 

让不同人群重新认识花草

在本项目中文心大模型的任务是根据不同的用户画像,输出不同版本的植物介绍,对植物科普内容进行定制化输出。这一步骤使用到ERNIE Bot SDK接口,飞桨星河社区为每位开发者提供了100万tokens的免费调用额度。

基本流程如下,引入ERNIE Bot的SDK,配置token,这一步有个重点概念叫prompt template,即做好的prompt模版。在模板中输入用户画像、需要介绍的植物、语言风格要求、参考材料给大模型,文心大模型可以为prompt template生成个性化定制内容,输出结果给前端用户。(视频 最终效果演示)

5ca545c5d62a92a8e32a55f952d43f7d.jpeg

文心大模型生成定制化内容

import erniebot

erniebot.api_type = "aistudio"
erniebot.access_token = ERNIETOKEN

templatePrompts = """
    作为一名植物科普员,你将要写一份面向{role}的植物科普内容,介绍的植物是{plant}。
    为了让孩子们更好地了解{plant},请提供一份轻松明快、通俗易懂的介绍内容。
    你可以从{plant}的外形、生长环境、果实特点等方面入手,让孩子们对这种植物有更深入的了解。
    同时,你也可以参考一些相关的图片、视频或其他资料,丰富孩子们的知识,提高他们的学习兴趣。
    请注意,你的介绍语言生动形象,让孩子们愿意听、记得住,并且能够对{plant}产生兴趣和好奇心。
    为了你的内容准确无误,请参考以下材料:{info}。开头不要有标题,内容最后不要出现参考文献。
""".format(role=role, plant=plantName, info=plantInfo)

response = erniebot.ChatCompletion.create(
        model="ernie-bot",
        messages=[{"role": "user", "content": templatePrompts}]
    )

print(response.result)

视频效果演示

飞桨开发者技术专家谢杰航老师,他为大家带来如何用文心大模型助力实现植物种类的识别,以及如何用AI技术构建风景园林行业的一个植物知识科普系统。同时他也在直播中讲解了创作过程当中的代码和步骤,帮助大家更好理解大模型应用开发的相关知识。想要了解技术详情可加入文心开发者说课程观看回放:飞桨AI Studio星河社区-人工智能学习与实训社区

其他领域开发者也可以根据不同的行业特点制作不同的prompt template,应用大模型进行个性化定制。希望大家在飞桨星河社区里面去学习更多大模型的知识,制作更多基于大模型的原生应用。

相关阅读

  • 飞桨星河社区项目链接:飞桨AI Studio星河社区项目

  • 文心开发者说课程:飞桨AI Studio星河社区-人工智能学习与实训社区

d11166103da73eeeaf37117361bca6ee.jpeg

88ea458058aac826be93c350628fee2e.jpeg

841982cbf63dc8375caa377c0cc3ee1e.jpeg

71cf9408c9540deaa831f7f96aadcc57.jpeg

027f146b4d6186f773f941c17eae5528.jpeg

关注【飞桨PaddlePaddle】公众号

获取更多技术内容~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1264828.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

解决git action发布报错:Input required and not supplied: upload_url

现象: 这个问题死活都找不到原因,后来打了一段调试的代码 - name: Debug Create Release Output run: | echo "Release ID: ${{ env.RELEASE_ID }}" echo "Release Upload URL: ${{ env.RELEASE_UPLOAD_URL }}" env: RELEASE_ID: ${…

css-tricks网站图例

使用css实现钟表 <template><div><p><small>CSS sin() and cos() does <strong>NOT</strong> work in your browser.</small></p><div class"clock"><div id"app" class"clock-face"…

解决:SyntaxError: Non-UTF-8 code starting with À in file but no encoding declared

解决&#xff1a;SyntaxError: Non-UTF-8 code starting with in file but no encoding declared 文章目录 解决&#xff1a;SyntaxError: Non-UTF-8 code starting with in file but no encoding declared背景报错问题报错翻译报错原因解决方法使用utf-8格式使用gbk格式今天…

89基于matlab的人工蜂群和粒子群混合优化的路径规划算法

基于matlab的人工蜂群和粒子群混合优化的路径规划算法&#xff0c;起点和终点确定的前提下&#xff0c;在障碍物中寻找最佳路径。数据可更换自己的&#xff0c;程序已调通&#xff0c;可直接运行。 89人工蜂群和粒子群混合优化 (xiaohongshu.com)https://www.xiaohongshu.com/e…

【数据结构】排序效率最优解之一:二叉树-堆

Hello everybody!今天打算给大家介绍一个功能比较强大的数据结构的基础&#xff0c;它不仅具有很高的应用价值而且排序效率很高。冒泡排序都知道叭&#xff0c;它的时间复杂度为O(n^2)&#xff0c;而堆排序的时间复杂度为O(n*logn)。堆排序直接碾压冒泡排序。在c语言阶段&#…

MySQL- CRUD

一、INSERT 添加 公式 INSERT INTO table_name [(column [, column...])] VALUES (value [, value...]); 示例&#xff1a; CREATE TABLE goods (id INT ,good_name VARCHAR(10),price DOUBLE ); #添加数据 INSERT INTO goods (id,good_name,price ) VALUES (20,华为手机,…

【SpringCloud系列】@FeignClient微服务轻舞者

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

【Rust】所有权的认识

所有权 所有程序都必须管理其运行时使用计算机内存的方式。一些语言中具有垃圾回收机制&#xff0c;在程序运行时有规律地寻找不再使用的内存&#xff1b;在另一些语言中&#xff0c;程序员必须亲自分配和释放内存。 Rust 则选择了第三种方式&#xff1a;通过所有权系统管理内…

L型骨牌覆盖问题。

问题&#xff1a;解决一个2k*2k的特殊棋牌上的L型骨牌覆盖问题。 思路&#xff1a; 棋盘覆盖实现的基本方法为分治法 当k0时(1ⅹ1棋盘)&#xff0c;及特殊方格&#xff0c;骨牌数为0 当k >0时&#xff0c;将2kⅹ2k棋盘分割为4个2k-1ⅹ2k-1子棋盘了 特殊方格位于4个较小…

深入了解Java8新特性-日期时间API:OffsetDateTime类

阅读建议 嗨&#xff0c;伙计&#xff01;刷到这篇文章咱们就是有缘人&#xff0c;在阅读这篇文章前我有一些建议&#xff1a; 本篇文章大概24000多字&#xff0c;预计阅读时间长需要20分钟。本篇文章的实战性、理论性较强&#xff0c;是一篇质量分数较高的技术干货文章&…

python实现C++简易自动压行

突发奇想&#xff0c;想要将自己的c压行之后交上去。但是苦于手动压行效率太低&#xff0c;在网上搜索压行网站没有找到&#xff0c;突然发现压行不就是检查检查去个换行符吗。于是心血来潮&#xff0c;用python实现了一个简易压行程序。 首先&#xff0c;宏定义等带#的文件不…

计算机杂谈系列精讲100篇-【计算机应用】PyTorch部署及分布式训练

目录 C平台PyTorch模型部署流程 1.模型转换 1. 不支持的操作 2. 指定数据类型 2.保存序列化模型 3.C load训练好的模型 4. 执行Script Module PyTorch分布式训练 分布式并行训练概述 Pytorch分布式数据并行 手把手渐进式实战 A. 单机单卡 B. 单机多卡DP C. 多机多卡DDP D. L…

android13(T) 客制化预置语言列表

效果图 需求分析 这个列表界面一般都是后来手动添加后才现实的&#xff0c;通过分析源码发现通过如下值可控 adb shell settings get system system_locales zh-CN,ja-JP,en-AT 所以只需查询出这个值&#xff0c;然后加在 SettingProvider 中即可 隐藏 bug 如果客户要求默…

【SpringCloud】注册中心和Ribbon负载均衡

SpringCloud 1.Eureka注册中心 1.1 Eureka的作用 注册中心拉取服务负载均衡远程调用 order-service得知user-service实例地址流程&#xff1a; user-service服务实例启动后&#xff0c;将自己的信息注册到eureka-server&#xff08;Eureka服务端&#xff09;&#xff0c;称…

使用STM32 HAL库驱动光电传感器的设计和优化

光电传感器在许多应用中起着重要的作用&#xff0c;例如自动计数、距离测量等。STM32微控制器和HAL库提供了丰富的功能和易于使用的接口&#xff0c;使得光电传感器的设计和优化变得更加便捷。本文将介绍如何使用STM32 HAL库驱动光电传感器的设计和优化&#xff0c;包括硬件设计…

电子印章管理系统:是什么、3个平台推荐

说到印章&#xff0c;相信看过近现代电视剧的人都见过&#xff0c;一般在订立合约时最常用到&#xff0c;双方在合约上加盖印鉴&#xff0c;即代表着合约的成立。 我小时候还见过我父亲的印章&#xff0c;只是随着时代的发展&#xff0c;印章因为不易携带&#xff0c;容易被盗…

livox 半固体激光雷达 gazebo 仿真 | 更换环境与雷达型号

livox 半固体激光雷达 gazebo 仿真 | 更换环境与雷达型号 livox 半固体激光雷达 gazebo 仿真 | 更换环境与雷达型号livox 介绍更换环境更换livox激光雷达型号 livox 半固体激光雷达 gazebo 仿真 | 更换环境与雷达型号 livox 介绍 览沃科技有限公司&#xff08;Livox&#xff…

java设计模式学习之【原型模式】

文章目录 引言原型模式简介定义与用途实现方式UML 使用场景优势与劣势原型模式在spring中的应用员工记录示例代码地址 引言 原型模式是一种创建型设计模式&#xff0c;它允许对象能够复制自身&#xff0c;以此来创建一个新的对象。这种模式在需要重复地创建相似对象时非常有用…

开放式耳机性价比排行榜、开放式耳机性价比排行榜前十

目前市面上的蓝牙耳机品类繁多&#xff0c;开放式蓝牙耳机是这几年比较新兴的&#xff0c;因为不入耳、佩戴舒适、安全系数高等优点&#xff0c;一直备受运动人士追捧&#xff0c;还有像我们这样日常用但是耳道比较小或者戴入耳式觉得头晕恶心的人&#xff0c;开放式耳机真的是…

【开发实践】网页预览excel表格原版样式

一、需求分析 由于业务部门需要&#xff0c;在导出excel表格页面&#xff0c;不需要先下载&#xff0c;就可以直接在页面上预览该表格文件。 二、代码实现 使用Luckysheet实现&#xff1a; 什么是Luckysheet Luckysheet &#xff0c;一款纯前端类似excel的在线表格&#xff0…