TensorFlow学习:在web前端如何使用Keras 模型

news2025/4/25 21:36:00

前言

在上篇文章 TensorFlow学习:使用官方模型进行图像分类、使用自己的数据对模型进行微调中我们学习了如何使用官方模型,以及使用自己的数据微调模型。

但是吧,代码一直是跑在Python里,而我本身是做前端开发的。我是很想让它在前端进行浏览器里进行运行。

谷歌贴心的为我们准备了 TensorFlow.jsTensorFlow.js 是一个 JavaScript 库,用于在浏览器和 Node.js 训练和部署机器学习模型。

这篇文章我们来学习如何在前端运行模型,模型的话就用上一篇文章里训练的花朵分类模型。

官方文档:TensorFlow.js 官方文档

注: 下面是我的采坑心得,我这是第一次学习,第一次搞。你要是按照我的步骤遇到了其他问题,不要问我,我也不会。

建议按顺序观看,这是一个小系列,适合像我这样的初学者入门

配置环境:windows环境下tensorflow安装

图片分类案例学习:TensorFlow案例学习:对服装图像进行分类

使用官方模型,并进行微调:TensorFlow学习:使用官方模型进行图像分类、使用自己的数据对模型进行微调

将模型转换,在前端使用:TensorFlow学习:在web前端如何使用Keras 模型

学习

处理模型

Keras 模型(通常通过 Python API 创建)可能保存成多种格式之一。完整模型格式可以转换成 TensorFlow.js Layers 格式,这种格式可以直接加载到 TensorFlow.js 中进行推断或进一步训练。

目标 TensorFlow.js Layers 格式是一个包含 model.json 文件和一组二进制格式的分片权重文件的目录。model.json 文件包含模型拓扑(又称“架构”或“计算图”:它是对层及其连接方式的描述)和权重文件的清单。

我们上一篇文章训练出的模型就是Keras 模型,这里需要对其进行转换。

安装

pip install tensorflowjs

就是这一步上来就被搞惨了。
在这里插入图片描述
最开始下载,还没下载多少就超时了,直接下载不了。后来查到可以使用国内镜像下载

 pip install tensorflowjs  -i https://pypi.tuna.tsinghua.edu.cn/simple

下载速度是变快了很多,结果下载到最后又来一个依赖冲突,最后又下载失败了。最终解决完这个问题是因为在web端使用,也需要下载

npm install @tensorflow/tfjs

当时我在想这两个是不是一个东西啊,问了一下gpt,npm下载的这个还真的可以用来进行模型转换。

这里我建议,即使你pip下载成功了,最好还是使用npm下载的这个进行模型转换。因为这样可以保证tensorflowjs版本一致,避免因为版本问题导致最后使用时又出问题

转换

这个也是个坑啊,文档是这样说的
在这里插入图片描述
但是在上一篇文章中,我最后保存的不是.h5格式啊,然后又回去跑模型,最后model.save('my_model.h5'),将模型保存为.h5格式。再然后转换模型

tensorflowjs_converter --input_format=keras flower_model.h5 flower_js_model

在这里插入图片描述
在这里插入图片描述
看样子是成功了,结果还真没成功,在前端加载时又报错了。没办法,百度查、翻文档。然后看见了这个
在这里插入图片描述
还真需要用这个,不过上面的代码有点问题,不需要有\ 符号。正确代码应该是

tensorflowjs_converter --input_format=tf_saved_model   flower_model web_model

这里要注意:

  • 我们还是使用的npm下载的依赖,不是pip下载的依赖
  • --input_format=tf_saved_model,指定输入格式
  • flower_model web_model这是两个路径,前面的是模型的逻辑,后面那个是转换完成后的输出路径
  • 这里加载的模型不是.h5,就是.pb文件所在的文件夹,记住是文件夹,不是目录

总之就是将flower_model下的模型进行转换,将转换后的模型输出到web_model目录下
在这里插入图片描述

在前端使用

这里要特别注意对输入图片的处理,一开始就是因为输入图片处理的不正确,导致模型在预测时结果不正确。后来各种查资料,才解决,使用代码如下:

<template>
  <div class="page-container">
    <div class="first-title">
      官方文档:
      <a href="https://tensorflow.google.cn/js/models?hl=zh-cn"
        >https://tensorflow.google.cn/js/models?hl=zh-cn</a
      >
    </div>
    <div class="img-list">
      <img
        v-for="img in imageList"
        :key="img.name"
        :src="img.url"
        :id="img.name"
        :class="activeImg == img.name ? 'img-item img-item-active' : 'img-item'"
        @click="changeImg(img)"
      />
    </div>
    <div style="margin-top: 20px">结果是:{{ result }}</div>
  </div>
</template>

<script setup>
import { ref, onMounted } from "vue";
import * as tf from "@tensorflow/tfjs";

// 图片
const imageList = ref([]);
// 当前选中的图片
const activeImg = ref("f1");
// 结果
const result = ref("");
// 图片列表
const IMAGES = [
  {
    name: "f1",
    url: "../assets/f1.jpg",
  },
  {
    name: "f2",
    url: "../assets/f2.jpg",
  },
  {
    name: "f3",
    url: "../assets/f3.jpg",
  },
  {
    name: "f4",
    url: "../assets/f4.jpg",
  },
];
const IMAGENET_CLASSES = ["雏菊", "蒲公英", "玫瑰", "向日葵", "郁金香"];

onMounted(() => {
  imageList.value = [];

  IMAGES.forEach((item) => {
    import(item.url).then((img) => {
      imageList.value.push({
        name: item.name,
        url: img.default,
      });
    });
  });
});

// 切换图片
const changeImg = async (img) => {
  activeImg.value = img.name;
  // 识别图片
  await identify(img.name);
};

// 识别图片
const identify = async (id) => {
  const imageElement = await document.getElementById(id);
  console.log("图片", imageElement);
  // 载入模型
  const model = await tf.loadGraphModel("../../public/web_model/model.json");
  console.log("模型:", model);

  // 图像预处理
  const imageTensor = preprocessImage(imageElement);

  // 对图片进行预测
  const predictions = await model.predict(imageTensor);

  console.log("predictions:", predictions);

  // 获取预测结果
  const predictedIndex = tf.argMax(predictions, 1).dataSync()[0];
  const predictedLabel = IMAGENET_CLASSES[predictedIndex];
  result.value = predictedLabel;
  console.log("结果:", predictedLabel, predictedIndex);
};

// 图像预处理
const preprocessImage = (img) => {
  // 将图像转换为张量对象并将像素值转换为浮点数类型
  const tensor = tf.browser.fromPixels(img).toFloat();
  // 张量的轴上添加一个维度,以适应模型的输入要求
  const expandedDims = tensor.expandDims();
  // 调整图像的尺寸为224x224,尺寸是模型的要求
  const resizedImg = tf.image.resizeBilinear(expandedDims, [224, 224]);
  // 将像素值归一化到范围[0, 1]之间
  const normalizedImg = tf.div(resizedImg, 255.0);
  // 返回归一化后的图像张量
  return normalizedImg;
};
</script>

<style lang="scss" scoped>
.img-list {
  display: flex;

  .img-item {
    width: 240px;
    height: 180px;
    border-radius: 5px;
    cursor: pointer;
    padding: 10px;
  }

  .img-item-active {
    border: 2px solid red;
  }
}
</style>

最终效果
在这里插入图片描述

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

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

相关文章

京东历史价格数据接口,京东商品历史价格接口,京东API接口

京东商品历史价格数据接口采集方法如下&#xff1a; 注册京东开发者账号&#xff0c;并创建应用&#xff0c;获取到应用ID&#xff08;appID&#xff09;、应用密钥&#xff08;appSecret&#xff09;以及访问令牌&#xff08;accessToken&#xff09;。获取接口请求地址。根据…

让 Visual Studio 用上 ChatGPT

一、简介 Visual chatGPT Studio 是 Visual Studio 的一个免费扩展&#xff0c;它直接在 IDE 中添加了 chatGPT 功能。它允许用户以可以根据菜单功能的方式使用 chatGPT。 二、功能介绍 该扩展提供了一组使用 ChatGPT 命令&#xff0c;可以在编辑器中选择你需要处理的代码或…

Python数据挖掘:入门、进阶与实用案例分析——自动售货机销售数据分析与应用

文章目录 摘要01 案例背景02 分析目标03 分析过程04 数据预处理1. 清洗数据1.1 合并订单表并处理缺失值1.2 增加“市”属性1.3 处理订单表中的“商品详情”属性1.4 处理“总金额&#xff08;元&#xff09;”属性 2.属性选择3.属性规约 05 销售数据可视化分析1.销售额和自动售货…

视频批量剪辑与分割:这些技巧帮你提高生成m3u8文件的效率

在数字媒体时代&#xff0c;m3u8文件已经成为了一种常见的流媒体格式&#xff0c;广泛应用于网络视频播放。这种文件由一系列音视频片段组成&#xff0c;对于提供高质量的视频体验至关重要。本文将介绍如何通过云炫AI智剪将视频批量剪辑与分割技巧来提高生成m3u8文件的效率&…

计算机网络第四层 运输层

一&#xff0c;运输层引入的目的 1&#xff0c;网络通信主体标识 网络通信的本质是运行的主机上的进程之间的通信 同一个主机上有多个进程在工作&#xff0c;进程如何加以区分标识&#xff08;PID&#xff09;---本地主机 网络上的主机需要一个统一的进程标识分配机制 逻辑…

基于单目相机的2D测量(工件尺寸和物体尺寸)

目录 1.简介 2.基于单目相机的2D测量 2.1 想法&#xff1a; 2.2 代码思路 2.2 主函数部分 1.简介 基于单目相机的2D测量技术在许多领域中具有重要的背景和意义。 工业制造&#xff1a;在工业制造过程中&#xff0c;精确测量是确保产品质量和一致性的关键。基于单目相机的2…

uniapp编译到小程序Component is not found in path “components/energy/illumination“

Component is not found in path "components/energy/illumination" 直接清除缓存重新编译

如何保护我们的网络安全

保护网络安全是至关重要的&#xff0c;尤其是在今天的数字化时代。以下是一些保护网络安全的基本步骤&#xff1a; 1、使用强密码&#xff1a;使用包含字母、数字和特殊字符的复杂密码。不要在多个网站上重复使用相同的密码。定期更改密码。 2、启用双因素认证 (2FA)&#xff…

JavaScript反爬虫技巧详细攻略

在互联网时代&#xff0c;网站采取了各种手段来防止被爬虫抓取数据&#xff0c;其中最常见的就是JavaScript反爬虫技巧。本文将揭示一些常用的JavaScript反爬虫技巧&#xff0c;并提供一些实际操作建议&#xff0c;帮助您保护自己的爬虫免受检测和封禁。 1、为什么网站使用Java…

CentOS 搭建 OpenVPN 服务

CentOS 搭建 OpenVPN 服务 概述OpenVPN 应用场景OpenVPN 主机准备OpenVPN 服务端搭建部署安装配置证书软件创建证书安装openvpn并写入服务端配置文件启动并检查端口 OpenVPN客户端配置&#xff08;linux端&#xff09;配置openvpn测试连接 OpenVPN客户端搭建部署&#xff08;wi…

AMD Zen5、Zen6架构细节首次曝光:原生32核心!直奔2nm工艺

AMD将在明年推出Zen5架构的锐龙8000系列、霄龙9005/8005系列&#xff0c;更下一代的Zen6架构也已经崭露头角&#xff0c;据说可以支持到史无前例的16通道内存。 现在&#xff0c;MLID曝光了一份AMD架构路线图&#xff0c;列出了Zen5、Zen6的不少细节&#xff0c;尤其是…

Element Plus阻止 el-dropdown、el-switch等冒泡事件

最近做vue3项目&#xff0c;使用Element Plus,又遇到坑了&#xff01; 问题点&#xff1a;组件中遇到事件冒泡问题了&#xff0c;el-checkbox 中 change事件要求阻止冒泡&#xff0c;如下代码中要求点击checkbox时不调用li标签的show方法 <li click"show()">…

UE4和C++ 开发-C++与UMG的交互2(C++获取UMG的属性)

1、...C获取UMG的属性 1.1、第一种方法&#xff1a;通过名称获取控件。 void UMyUserWidget::NativeConstruct() {Super::NativeConstruct();//通过名字&#xff0c;获取蓝图控件中的按钮引用。CtnClic Cast<UButton>(GetWidgetFromName(TEXT("Button_44"))…

什么是实验室超声波乳化?超声波乳化的工作原理?

乳液是什么&#xff1f;它是两种或多种不相混合的液体的共同体。那么&#xff0c;这些互不相容的液体是如何混合在一起的呢&#xff1f;这就要归功于超声波的神奇力量。超声波乳化棒&#xff0c;就像一个无形的魔法师&#xff0c;将高强度的超声波能量耦合到液体中&#xff0c;…

【API篇】一、执行环境API

文章目录 0、认识1、创建执行环境2、执行模式3、触发程序执行4、关于executeAsync方法 0、认识 DataStream API是Flink的核心层API。一个Flink程序&#xff0c;其实就是对数据源DataStream的各种转换。具体来说&#xff0c;代码基本上都由以下几部分构成&#xff1a; 后面章节…

早安心语|不委屈不将就,让生活充满仪式感

1、让自己的生活多一种可能&#xff0c;给自己的未来多一份惊喜&#xff0c;人生所有的机会和惊喜&#xff0c;都是在你全力以赴的道路上遇到的。 2、推开自己喜欢的人叫成长&#xff0c;留住自己喜欢的人叫本事&#xff0c;总有人嫌你不够好&#xff0c;也有人觉得你哪都好&am…

【RKNN】YOLO V5中pytorch2onnx,pytorch和onnx模型输出不一致,精度降低

在yolo v5训练的模型&#xff0c;转onnx&#xff0c;再转rknn后&#xff0c;测试发现&#xff1a; rknn模型&#xff0c;量化与非量化&#xff0c;相较于pytorch模型&#xff0c;测试精度都有降低onnx模型&#xff0c;相较于pytorch模型&#xff0c;测试精度也有降低&#xff…

The Foundry Nuke 15视频后期合成和特效制作Mac软件

Nuke 15 是一款专业的合成软件&#xff0c;主要用于电影、电视和广告制作中的后期合成和特效制作。 Nuke 15 提供了强大的合成工具和功能&#xff0c;可以对多个图像、视频和3D元素进行无缝融合和合成。它支持多通道图像处理&#xff0c;能够处理高动态范围&#xff08;HDR&…

算法通关村第18关【青铜】| 回溯

回溯算法是一种解决组合优化问题和搜索问题的算法。它通过尝试各种可能的选择来找到问题的解决方案。回溯算法通常用于问题的解空间非常大&#xff0c;而传统的穷举法会导致计算时间爆炸的情况。回溯算法可以帮助限制搜索空间&#xff0c;以提高效率。 回溯算法的核心思想是在…

ARM作业2

.设置按键中断&#xff0c;按键1按下&#xff0c;LED亮&#xff0c;再按一次&#xff0c;灭 按键2按下&#xff0c;蜂鸣器响。再按一次&#xff0c;不响 按键3按下&#xff0c;风扇转&#xff0c;再按一次&#xff0c;风扇停 头文件key_it.h #ifndef __KEY_IT_H__ #define …