想像一下您在網上購物時發現了一種您喜歡的產品,但不知道它的名字。上傳圖片並讓應用程式為您找到它,這不是很棒嗎?
在本文中,我們將向您展示如何建立此功能:使用 Spring Boot 和 Google Cloud Vertex AI 的基於圖像的產品搜尋功能。
此功能允許用戶上傳圖像並接收與其匹配的產品列表,使搜尋體驗更加直觀和視覺驅動。
基於圖像的產品搜尋功能利用 Google Cloud Vertex AI 處理圖像並提取相關關鍵字。然後使用這些關鍵字在資料庫中搜尋匹配的產品。
我們將逐步完成設定此功能的過程。
首先,我們需要為此在 Google Console 上建立一個新專案。
我們需要造訪 https://console.cloud.google.com 並建立一個新帳戶(如果您已有帳戶)。如果您有,請登入該帳戶。
如果您新增銀行帳戶,Google Cloud 將為您提供免費試用。
建立帳戶或登入現有帳戶後,您可以建立新項目。
在搜尋列上,我們需要找到 Vertex AI 並啟用所有建議的 API。
Vertex AI 是 Google Cloud 完全託管的機器學習 (ML) 平台,旨在簡化 ML 模型的開發、部署和管理。它允許您透過提供 AutoML、自訂模型訓練、超參數調整和模型監控等工具和服務來大規模建置、訓練和部署 ML 模型
Gemini 1.5 Flash 是 Google Gemini 系列模型的一部分,專為 ML 應用程式中的高效和高效推理而設計。 Gemini 模型是 Google 開發的一系列高級 AI 模型,常用於自然語言處理 (NLP)、視覺任務和其他 AI 驅動的應用
注意:對於其他框架,您可以直接在 https://aistudio.google.com/app/prompts/new_chat 使用 Gemini API。使用結構提示功能,因為您可以自訂輸出以匹配輸入,這樣您將獲得更好的結果。
在這一步,我們需要自訂一個與您的應用程式相符的提示。
Vertex AI Studio 在提示庫提供了許多範例提示。我們使用範例圖像文字到JSON來提取與產品圖像相關的關鍵字。
我的應用程式是 CarShop,所以我建立了一個像這樣的提示。我期望模型會用與圖像相關的關鍵字清單來回覆我。
我的提示:將名稱 car 提取到清單關鍵字並以 JSON 格式輸出。如果您沒有找到有關汽車的任何信息,請將列表輸出為空。 n回應範例:[“rolls”, “royce”, “wraith”]
我們根據您的應用程式自訂合適的提示後。現在,我們就來探討如何與 Spring Boot Application 整合。
我建立了一個關於汽車的電子商務應用程式。所以我想透過圖像來找到汽車。
首先,在 pom.xml 檔案中,您應該更新您的依賴項:
<!-- config version for dependency--> <properties> <spring-cloud-gcp.version>5.1.2</spring-cloud-gcp.version> <google-cloud-bom.version>26.32.0</google-cloud-bom.version> </properties> <!-- In your dependencyManagement, please add 2 dependencies below --> <dependencyManagement> <dependencies> <dependency> <groupId>com.google.cloud</groupId> <artifactId>spring-cloud-gcp-dependencies</artifactId> <version>${spring-cloud-gcp.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.google.cloud</groupId> <artifactId>libraries-bom</artifactId> <version>${google-cloud-bom.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <!-- In your tab dependencies, please add the dependency below --> <dependencies> <dependency> <groupId>com.google.cloud</groupId> <artifactId>google-cloud-vertexai</artifactId> </dependency> </dependencies>
在 pom.xml 檔案中完成設定後,建立一個設定類別 GeminiConfig.java
import com.google.cloud.vertexai.VertexAI; import com.google.cloud.vertexai.generativeai.GenerativeModel; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration(proxyBeanMethods = false) public class GeminiConfig { private static final String MODEL_NAME = "gemini-1.5-flash"; private static final String LOCATION = "asia-southeast1"; private static final String PROJECT_ID = "yasmini"; @Bean public VertexAI vertexAI() { return new VertexAI(PROJECT_ID, LOCATION); } @Bean public GenerativeModel getModel(VertexAI vertexAI) { return new GenerativeModel(MODEL_NAME, vertexAI); } }
其次,建立圖層Service、Controller來實現尋車功能。建立類服務。
因為 Gemini API 以 markdown 格式回應,所以我們需要建立一個函數來幫助轉換為 JSON,然後我們將 JSON 轉換為 Java 中的 List 字串。
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.cloud.vertexai.api.Content; import com.google.cloud.vertexai.api.GenerateContentResponse; import com.google.cloud.vertexai.api.Part; import com.google.cloud.vertexai.generativeai.*; import com.learning.yasminishop.common.entity.Product; import com.learning.yasminishop.common.exception.AppException; import com.learning.yasminishop.common.exception.ErrorCode; import com.learning.yasminishop.product.ProductRepository; import com.learning.yasminishop.product.dto.response.ProductResponse; import com.learning.yasminishop.product.mapper.ProductMapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; @Service @RequiredArgsConstructor @Slf4j @Transactional(readOnly = true) public class YasMiniAIService { private final GenerativeModel generativeModel; private final ProductRepository productRepository; private final ProductMapper productMapper; public List<ProductResponse> findCarByImage(MultipartFile file){ try { var prompt = "Extract the name car to a list keyword and output them in JSON. If you don't find any information about the car, please output the list empty.\nExample response: [\"rolls\", \"royce\", \"wraith\"]"; var content = this.generativeModel.generateContent( ContentMaker.fromMultiModalData( PartMaker.fromMimeTypeAndData(Objects.requireNonNull(file.getContentType()), file.getBytes()), prompt ) ); String jsonContent = ResponseHandler.getText(content); log.info("Extracted keywords from image: {}", jsonContent); List<String> keywords = convertJsonToList(jsonContent).stream() .map(String::toLowerCase) .toList(); Set<Product> results = new HashSet<>(); for (String keyword : keywords) { List<Product> products = productRepository.searchByKeyword(keyword); results.addAll(products); } return results.stream() .map(productMapper::toProductResponse) .toList(); } catch (Exception e) { log.error("Error finding car by image", e); return List.of(); } } private List<String> convertJsonToList(String markdown) throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); String parseJson = markdown; if(markdown.contains("``` json")){ parseJson = extractJsonFromMarkdown(markdown); } return objectMapper.readValue(parseJson, List.class); } private String extractJsonFromMarkdown(String markdown) { return markdown.replace(" ```json\n", "").replace("\n``` ", ""); } }
我們需要建立一個控制器類別來為前端建立端點
import com.learning.yasminishop.product.dto.response.ProductResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.util.List; @RestController @RequestMapping("/ai") @RequiredArgsConstructor @Slf4j public class YasMiniAIController { private final YasMiniAIService yasMiniAIService; @PostMapping public List<ProductResponse> findCar(@RequestParam("file") MultipartFile file) { var response = yasMiniAIService.findCarByImage(file); return response; } }
Spring Boot 應用程式無法驗證您的身份,也無法讓您接受 Google Cloud 中的資源。
所以我們需要登入Google並提供授權。
連結教學:https://cloud.google.com/sdk/docs/install
檢查上面的連結並將其安裝到您的電腦上
gcloud auth login
注意:登入後,憑證將保存在 Google Maven 套件中,重啟 Spring Boot 應用程式時無需再次登入。
所以上面這些都是基於我的電子商務專案實現的,你可以根據你的專案、你的框架進行修改。在其他框架中,除了 Spring Boot(NestJs,..),您可以使用 https://aistudio.google.com/app/prompts/new_chat。並且不需要建立新的 Google Cloud 帳戶。
具體實作可以在我的倉庫中查看:
後端:https://github.com/duongminhhieu/YasMiniShop
前端:https://github.com/duongminhhieu/YasMini-Frontend
學習愉快! ! !
以上是使用 Spring Boot、Google Cloud Vertex AI 和 Gemini 模型進行基於圖像的產品搜索的詳細內容。更多資訊請關注PHP中文網其他相關文章!