用Tensorflow。js做了一个动漫分类的功能(二)
前言:
前面已经通过采集拿到了图片,并且也手动对图片做了标注。接下来就要通过Tensorflow。js基于mobileNet训练模型,最后就可以实现在采集中对图片进行自动分类了。
这种功能在应用场景里就比较多了,比如图标素材站点,用户通过上传一个图标,系统会自动匹配出相似的图标,还有二手平台,用户通过上传闲置物品图片,平台自动给出分类等,这些也都是前期对海量图片进行了标注训练而得到一个损失率极低的模型。下面就通过简单的代码实现一个小的动漫分类。
环境:
Node
HttpServer
Parcel
Tensorflow
编码:
1。训练模型
1。1。创建项目,安装依赖包npminstalltensorflowtfjslegacypeerdepsnpminstalltensorflowtfjsnodegpulegacypeerdeps
1。2。全局安装HttpServernpminstallihttpserver
1。3。下载mobileNet模型文件(网上有下载)
1。4。根目录下启动Http服务(开启跨域),用于mobileNet和训练结果的模型可访问httpservercorsp8080
1。5。创建训练执行脚本run。jsconsttfrequire(tensorflowtfjsnodegpu);constgetDatarequire(。data);constTRAINPATH。动漫分类train;constOUTPUToutput;constMOBILENETURLhttp:127。0。0。1:8080datamobilenetwebmodelmodel。json;(async(){const{ds,classes}awaitgetData(TRAINPATH,OUTPUT);console。log(ds,classes);引入别人训练好的模型constmobilenetawaittf。loadLayersModel(MOBILENETURL);查看模型结构mobilenet。summary();constmodeltf。sequential();截断模型,复用了86个层for(leti0;i86;i){constlayermobilenet。layers〔i〕;layer。trainablefalse;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〕});训练模型awaitmodel。fitDataset(ds,{epochs:20});保存模型awaitmodel。save(file:{process。cwd()}{OUTPUT});})();
1。6。创建图片与Tensor转换库data。jsconstfsrequire(fs);consttfrequire(tensorflowtfjsnodegpu);constimg2x(imgPath){constbufferfs。readFileSync(imgPath);清除数据returntf。tidy((){把图片转成tensorconstimgttf。node。decodeImage(newUint8Array(buffer),3);调整图片大小constimgResizetf。image。resizeBilinear(imgt,〔224,224〕);归一化returnimgResize。toFloat()。sub(2552)。p(2552)。reshape(〔1,224,224,3〕);});}constgetDataasync(traindir,output){letclassesfs。readdirSync(traindir,utf8);fs。writeFileSync(。{output}classes。json,JSON。stringify(classes));constdata〔〕;classes。forEach((dir,dirIndex){fs。readdirSync({traindir}{dir})。filter(nn。match(jpg))。slice(0,1000)。forEach(filename{constimgPath{traindir}{dir}{filename};data。push({imgPath,dirIndex});});});console。log(data);打乱训练顺序,提高准确度tf。util。shuffle(data);constdstf。data。generator(function(){constcountdata。length;constbatchSize32;for(letstart0;startcount;startbatchSize){constendMath。min(startbatchSize,count);console。log(当前批次,start);yieldtf。tidy((){constinputs〔〕;constlabels〔〕;for(letjstart;jend;j){const{imgPath,dirIndex}data〔j〕;constximg2x(imgPath);inputs。push(x);labels。push(dirIndex);}constxstf。concat(inputs);constystf。tensor(labels);return{xs,ys};});}});return{ds,classes};}module。exportsgetData;
1。7。运行执行文件noderun。js
2。调用模型
2。1。全局安装parcelnpminstalliparcel
2。2。创建页面index。htmlinputtypefileonchangepredict(this。files〔0〕)
2。3。创建模型调用预测脚本script。jsimportastffromtensorflowtfjs;import{img2x,file2img}from。utils;constMODELPATHhttp:127。0。0。1:8080t7;constCLASSES〔假面骑士,奥特曼,海贼王,火影忍者,龙珠〕;window。onloadasync(){constmodelawaittf。loadLayersModel(MODELPATHoutputmodel。json);window。predictasync(file){constimgawaitfile2img(file);document。body。appendChild(img);constpredtf。tidy((){constximg2x(img);returnmodel。predict(x);});constindexpred。argMax(1)。dataSync()〔0〕;console。log(pred。argMax(1)。dataSync());letpredictStr;if(typeofCLASSES〔index〕undefined){predictStrBRANDCLASSES〔index〕;}else{predictStrCLASSES〔index〕;}setTimeout((){alert(预测结果:{predictStr});},0);};};
2。4。创建图片tensor格式转换库utils。jsimportastffromtensorflowtfjs;exportfunctionimg2x(imgEl){returntf。tidy((){constinputtf。browser。fromPixels(imgEl)。toFloat()。sub(2552)。p(2552)。reshape(〔1,224,224,3〕);returninput;});}exportfunctionfile2img(f){returnnewPromise(resolve{constreadernewFileReader();reader。readAsDataURL(f);reader。onload(e){constimgdocument。createElement(img);img。srce。target。result;img。width224;img。height224;img。onload()resolve(img);};});}
2。5。打包项目并运行parcelindex。html
2。6。运行效果
注意:
1。模型训练过程报错
Inputtoreshapeisatensorwith50176values,buttherequestedshapehas150528
1。1。原因
张量reshape不对,实际输入元素个数与所需矩阵元素个数不一致,就是采集过来的图片有多种图片格式,而不同格式的通道不同(jpg3通道,png4通道,灰色图片1通道),在将图片转换tensor时与代码里的张量形状不匹配。
1。2。解决方法
一种方法是删除灰色或png图片,其二是修改代码tf。node。decodeImage(newUint8Array(buffer),3)
江南物语登临太华沈志权汽车进入华阴境内,已是夕阳西下时,远远望去,太华山在苍翠的群山托举之中,犹如一朵绽放在碧水之中的莲花,在夕阳的映照下,更显奇丽而神秘。华山是我神往已久的一座名山。少时,听父辈
大美昭通,我们来了!五道并行的川滇门户盐津豆沙关走过风雨和沧桑,淌过远古和现代,脚踩五尺道,一目三千年,这里就是川滇门户盐津豆沙关。近日,区融媒体中心荟生活节目组来到闵行对口支援地云南昭通盐津县,向大家展示其深厚的文化底蕴。今天
你见过香格里拉的秋天?香格里拉的在世人眼中是怎样的呢是司腾沉睡百年复活的地方还是狼殿下疾冲和摘星的离别之地亦或是消失地平线的一片净土为什么香格里拉可以如此梦幻可以成为世人眼中的浪漫之地小西觉得大概是,置
广州飞跑信息科技跨境贸易系统平台推动企业外贸发展广州飞跑信息科技有限公司是一家专业从事软件开发软件定制软件实施的高新技术企业。拥有一批长期专业从事软件开发软件定制的专业人才,具有雄厚的技术开发实力,全方位满足企业信息化需求。同时
马龙山间秋色美枫叶惹人醉(组图)来源曲靖市马龙区人民政府图片新闻在月望普坎村山坡上,满山的红叶色彩浓艳,掀起一片片波涛汹涌的红浪,起起伏伏,如地毯般在村落间铺展开来。一眼望去层林尽染,黄色红色斑斓交错,景色怡人。
我,22岁,爱上了跟老年旅行团出游作者hikaru编辑三三这届年轻人最新流行的旅游方式,是报老年旅行团。起因是四川小伙CHAI璧安,带父母去三亚旅游,报了个旅行团。结果进团以后发现,22岁的他是全团最年轻的人。其次
逸仙湖公园人工湖的由来逸仙湖公园6a中山市石岐区境内公园逸仙湖公园位于中山市石岐区繁华的中心商业地带,公园东邻湖滨路,南倚烟墩山。公园的前身是一片农田和水塘。逸仙湖公园的形成有一个发展过程。昔日,员峰村
劳动公园的大足球劳动公园南坡上面有个红白相间的大足球,它是在被拆掉的五一塔原址上面建造的。劳动公园绿山下的大足球市民曲先生回忆说,文革中五一塔被造反派炸过一次,不过塔没有被炸掉,只在塔后边炸出个高
武汉长江队被罚三分,广州双雄看到保级希望,河北队铁定降级按照足协相关要求,各俱乐部必须在7月31日前解决总欠薪的30,否则将面临相应的处罚。近日,足协公布了前期调查结果,三家俱乐部因未完成任务被判罚扣除3分,中超河北队武汉长江队均在列。
这首摇滚没有沧桑和嘶吼,少年感满满那时,正值青春年少,不知柴米油盐酱醋是什么?历经人间冷暖,世道曲折之后,在来不及思考的余生,似乎忘记了少年时,那些干净懵懂纯真以及无所畏惧,不知天高地厚的执念。青春年少,曾经赋予了
越是沮丧的时候,越要学会自我激励即使身处低谷,也要坚信走下去,一定会越来越好,千万别因眼前暂时的困难就泄气。一个人可以有一段糟糕的经历,但绝对不可以过一个糟糕的人生。不是每个人都生而强大,在遭遇困境的当下,我们会