范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

用Tensorflow。js做了一个动漫分类的功能(二)

  前言:
  前面已经通过采集拿到了图片,并且也手动对图片做了标注。接下来就要通过 Tensorflow.js 基于 mobileNet 训练模型,最后就可以实现在采集中对图片进行自动分类了。
  这种功能在应用场景里就比较多了,比如图标素材站点,用户通过上传一个图标,系统会自动匹配出相似的图标,还有二手平台,用户通过上传闲置物品图片,平台自动给出分类等,这些也都是前期对海量图片进行了标注训练而得到一个损失率极低的模型。下面就通过简单的代码实现一个小的动漫分类。
  环境:
  Node
  Http-Server
  Parcel
  Tensorflow
  编码:
  1. 训练模型
  1.1. 创建项目,安装依赖包 npm install @tensorflow/tfjs --legacy-peer-deps npm install @tensorflow/tfjs-node-gpu --legacy-peer-deps
  1.2. 全局安装 Http-Server npm install i http-server
  1.3. 下载 mobileNet 模型文件 (网上有下载)
  1.4. 根目录下启动 Http 服务 (开启跨域),用于 mobileNet 和训练结果的模型可访问 http-server --cors -p 8080
  1.5. 创建训练执行脚本 run.js const tf = require("@tensorflow/tfjs-node-gpu");  const getData = require("./data"); const TRAIN_PATH = "./动漫分类/train"; const OUT_PUT = "output"; const MOBILENET_URL = "http://127.0.0.1:8080/data/mobilenet/web_model/model.json";  (async () => {   const { ds, classes } = await getData(TRAIN_PATH, OUT_PUT);   console.log(ds, classes);   //引入别人训练好的模型   const mobilenet = await tf.loadLayersModel(MOBILENET_URL);   //查看模型结构   mobilenet.summary();    const model = tf.sequential();   //截断模型,复用了86个层   for (let i = 0; i < 86; ++i) {     const layer = mobilenet.layers[i];     layer.trainable = false;     model.add(layer);   }   //降维,摊平数据   model.add(tf.layers.flatten());   //设置全连接层   model.add(tf.layers.dense({     units: 10,     activation: "relu"//设置激活函数,用于处理非线性问题   }));    model.add(tf.layers.dense({     units: classes.length,     activation: "softmax"//用于多分类问题   }));   //设置损失函数,优化器   model.compile({     loss: "sparseCategoricalCrossentropy",     optimizer: tf.train.adam(),     metrics:["acc"]   });    //训练模型   await model.fitDataset(ds, { epochs: 20 });   //保存模型   await model.save(`file://${process.cwd()}/${OUT_PUT}`); })();
  1.6. 创建图片与 Tensor 转换库 data.js const fs = require("fs"); const tf = require("@tensorflow/tfjs-node-gpu");  const img2x = (imgPath) => {   const buffer = fs.readFileSync(imgPath);   //清除数据   return tf.tidy(() => {     //把图片转成tensor     const imgt = tf.node.decodeImage(new Uint8Array(buffer), 3);     //调整图片大小     const imgResize = tf.image.resizeBilinear(imgt, [224, 224]);     //归一化     return imgResize.toFloat().sub(255 / 2).p(255 / 2).reshape([1, 224, 224, 3]);   }); }  const getData = async (traindir, output) => {   let classes = fs.readdirSync(traindir, "utf-8");   fs.writeFileSync(`./${output}/classes.json`, JSON.stringify(classes));   const data = [];   classes.forEach((dir, dirIndex) => {     fs.readdirSync(`${traindir}/${dir}`)       .filter(n => n.match(/jpg$/))       .slice(0, 1000)       .forEach(filename => {         const imgPath = `${traindir}/${dir}/${filename}`;          data.push({ imgPath, dirIndex });       });   });    console.log(data);    //打乱训练顺序,提高准确度   tf.util.shuffle(data);    const ds = tf.data.generator(function* () {     const count = data.length;     const batchSize = 32;     for (let start = 0; start < count; start += batchSize) {       const end = Math.min(start + batchSize, count);       console.log("当前批次", start);       yield tf.tidy(() => {         const inputs = [];         const labels = [];         for (let j = start; j < end; ++j) {           const { imgPath, dirIndex } = data[j];           const x = img2x(imgPath);           inputs.push(x);           labels.push(dirIndex);         }         const xs = tf.concat(inputs);         const ys = tf.tensor(labels);         return { xs, ys };       });     }   });    return { ds, classes }; }  module.exports = getData;
  1.7. 运行执行文件 node run.js
  2. 调用模型
  2.1. 全局安装 parcel npm install i parcel
  2.2. 创建页面 index.html  
  2.3. 创建模型调用预测脚本 script.js import * as tf from "@tensorflow/tfjs"; import { img2x, file2img } from "./utils";  const MODEL_PATH = "http://127.0.0.1:8080/t7"; const CLASSES = ["假面骑士","奥特曼","海贼王","火影忍者","龙珠"];   window.onload = async () => {     const model = await tf.loadLayersModel(MODEL_PATH + "/output/model.json");      window.predict = async (file) => {         const img = await file2img(file);         document.body.appendChild(img);         const pred = tf.tidy(() => {             const x = img2x(img);             return model.predict(x);         });          const index = pred.argMax(1).dataSync()[0];         console.log(pred.argMax(1).dataSync());          let predictStr = "";         if (typeof CLASSES[index] == "undefined") {             predictStr = BRAND_CLASSES[index];         } else {             predictStr = CLASSES[index];         }          setTimeout(() => {             alert(`预测结果:${predictStr}`);         }, 0);     }; };
  2.4. 创建图片 tensor 格式转换库 utils.js import * as tf from "@tensorflow/tfjs";  export function img2x(imgEl){     return tf.tidy(() => {         const input = tf.browser.fromPixels(imgEl)             .toFloat()             .sub(255 / 2)             .p(255 / 2)             .reshape([1, 224, 224, 3]);         return input;     }); }  export function file2img(f) {     return new Promise(resolve => {         const reader = new FileReader();         reader.readAsDataURL(f);         reader.onload = (e) => {             const img = document.createElement("img");             img.src = e.target.result;             img.width = 224;             img.height = 224;             img.onload = () => resolve(img);         };     }); }
  2.5. 打包项目并运行 parcel index.html
  2.6. 运行效果
  注意:
  1. 模型训练过程报错
  Input to reshape is a tensor with 50176 values, but the requested shape has 150528
  1.1. 原因
  张量 reshape 不对,实际输入元素个数与所需矩阵元素个数不一致,就是采集过来的图片有多种图片格式,而不同格式的通道不同 (jpg3 通道,png4 通道,灰色图片 1 通道),在将图片转换 tensor 时与代码里的张量形状不匹配。
  1.2. 解决方法
  一种方法是删除灰色或 png 图片,其二是修改代码 tf.node.decodeImage (new Uint8Array (buffer), 3)

时尚模特身材苗条,大码模特体重要求,200公斤也不显肥在我们的印象中,走在时尚前沿的模特都是身材高挑,身材苗条,风度翩翩。蜂腰翘臀长腿,这样的身材更能展现服装的本质,更能表达设计师的理念。但在欧美国家,有这样一个特殊的职业,她们也是模2023年春天穿什么打底衫?pick这3款时髦好搭,赶紧看看衣服真的不是越多越好,买衣服不能只看数量,有时候我们还要考虑到实际的搭配情况,去买合适的衣服,就像在初春季节,如果你买衣服没有思路的话,选择一件打底衫就可以了。打底衫的款式也很多,用老鼠熬油治孩子烫伤导致感染?如果被烫伤了,记住5个步骤在日常生活,大伙儿免不了都是会遇到一些意外伤害。而烫伤就是更为多见的一种,不但开水,包含蒸汽油粥,乃至开好长时间的电灯泡电动遥控车等,都很有可能会引起烫伤。尤其是小朋友,伴随着主题看了这些时髦奶奶的内搭示范,才懂比起打底衫,这些更洋气以为打底衫是扮演内搭的最佳选择,入春了买几件打底衫就能承包整个春天的时尚,但那些善于打扮的时髦奶奶却用穿搭告诉大众,打底衫其实只是退而求其次的选择,换成下面内搭,造型高级感翻倍。本苏定方灭百济唐李治显庆五年,百济自恃有高丽撑腰,屡次入侵新罗。新罗上书唐王朝请求援救。李治以苏定方为行军总管,与刘伯英等一道率水陆十万大军讨伐百济。苏定方率军从海上登陆,百济占据熊津江口抵抗。美媒将拥有欧文的独行侠和杜兰特的太阳进行对比,谁最有可能夺冠202223赛季交易截止日期已经过去了,这可以说是NBA历史上最轰动的交易市场之一。像75大的威少欧文和杜兰特纷纷被球队交易送走,这也是引起了外界的巨大关注。特别是欧文和杜兰特,他C罗的这几个纪录,梅西几乎不可能打破!C罗和梅西作为绝代双骄,共同为球迷贡献近20年的精彩表现。两位王者在个人荣誉和团队荣誉都属于历史级别。虽然在很多方面,梅西的荣誉都要比C罗出彩,比如金球奖梅西以75领先C罗,国家奖勒布朗詹姆斯职业生涯得分纪录牢不可破1984年4月5日,当阿卜杜勒贾巴尔的天勾打破了威尔特张伯伦的职业生涯得分纪录时,传奇的洛杉矶湖人队解说员奇克赫恩宣称这个人完成了一些我不相信的事情,我的意思是真诚的,我认为这不会吃亏是福!勇士成全四方交易,开拓者被质疑,库里冲冠帮手回来了根据NBA名记Woj的消息,勇士关于小佩顿的四方交易压哨正式完成,涉及交易的球员,可以在下一场比赛代表球队出战,这笔交易引起了很多球迷的关注,之所以被关注和开拓者有很大关系,毕竟活场均36。4分钟!名记湖人内部有人质疑詹姆斯的出场时间直播吧2月14日讯据此前报道,名记Haynes透露,詹姆斯的左脚伤势可能是整个赛季都有的问题。在破纪录的比赛,这已经到了无法忍受的程度。今天,知名湖人队记DaveMcMenamin转会新闻热刺有意2门将,切尔西欲签2中场,内马尔想离开巴黎2023年2月14号,外媒又报道了一些欧洲豪门最新的转会消息热刺有意2门将,切尔西无欲签2中场,内马尔想离开巴黎。托特纳姆热刺正在为一名在世界杯上提高了声誉的门将准备一种新的方法,
不要看见别人发光,就觉得自己暗淡,否定自己的选择看到读书群分享千万不要看见别人发光,就觉得自己暗淡!很有感触。讲到生活中人和人的节奏不一样!有人三分钟泡面,有人一小时煲汤。你选择了你要的方式就坚定走下去,别胡思乱想!阳光少女,心帽爷头条创作挑战赛九十四岁的帽爷,老伴走的早,虽然膝下四男双女,儿孙满堂一大片,可他老人家偏偏一直坚守着独守一人过日子。就这样不但不拖累家人,还时不时的给小字辈们点补贴,那日子过得就是静下心来读书,它会一点一滴地滋养你1hr为什么要读书?很多时候,我们之所以陷于痛苦,烦恼不断,根源就是读书太少,囿于有限的学识和认知,没有足够的智慧来解决生活中的难题。读一书,增一智。阅读,才是最好的疗心良药,是真想日常生活中我们是如何进行思考的?想你想对了什么,想错了什么,英尼基海斯著,姚瑞元译,人民邮电出版社,2022年11月。我们大部分思考过程是没有意识的当我们说某人不能一边走路一边嚼口香糖时,这其实是一个由来已久的侮让自己保持优秀的5个习惯树立有意义的目标比起着急赶路,更重要的是先做好充足的准备,制定好缜密的计划。一个目标清晰的人,在前进的路上往往不会迷失方向。试试给自己设定一个有意义且实际的目标吧。找准目标,踏踏实五十岁以后,越能忍的人,往往越有福!年过半百之后,很多该经历的事情我们也都经历过了。慢慢的看人看事都渐渐通透,过去的激进也逐渐转变成了平和。以前无法放下的事情,现在也渐渐的看开放下了。这就是来自于心灵深处的成长,非常男人老了的标准是什么?1老男人最显著的特点就是贪财怕死。活了几十年了,经历过太多的事情,老男人明白了,只有钱和健康是最靠得住的。他知道钱能够解决90以上的问题,他也知道,只有健康的身体才能够让他享受生活父子俩的第56场马拉松,打卡完毕!来源央视新闻今天(19日)上午,深圳马拉松赛场上,一对父子的身影吸引了很多人的目光。来自浙江金华的罗书坚用三轮手推车推着儿子小柏,完成他们的第56场马拉松旅程。约21公里的半程马拉中美芯片公司科技战,美国限制芯片出口!华盛顿最新的出口限制禁止美国人支持目标中国公司的开发或生产芯片受影响公司的几位高管曾在美国半导体行业工作,并在返回中国之前获得了公民身份美国对中国芯片公司的新限制可能会使目标公司的连州市卫健局开展院前急救医疗质评工作日前,连州市卫生健康局组织120急救指挥中心,对市区4家急救网络医院开展院前急救医疗质量考核工作,进一步提升院前急救综合服务能力,促进连州市院前急救医疗工作的同质化发展。本次考核主新视野丨博爱卫生站助力农村医疗服务石榴云新疆日报记者于熙基层医疗网底,事关群众福祉,人民安康。新春伊始,中共中央国务院发布关于做好2023年全面推进乡村振兴重点工作的意见,提出推进医疗卫生资源县域统筹,加强乡村两级