JS,一门从浏览器兴起,却不止于浏览器的脚本,个人一直认为其是最有潜力的脚本语言。不只是因为ES6优雅的语法,更重要的是其易上手,跨平台的优点。

Node将JS从browser带去了client是革命性的,使得常常被冠以“浏览器脚本”的JS成为一门足以和PHP,PY匹敌的通用性脚本。

关于tensorflow,这里就不多做介绍,简而言之就是一个深度学习的框架,而为众人所知的是他对python的支持性非常高,几乎可以说到tf,那就是python的天下,以至于说到深度学习,众人都会联想到py,Google也是首推python在深度学习领域的使用,这和python早期与Google的渊源有关。不过,笔者多次和py的交手后,对py的这种偏自然的语法及其不适应,很难接受这么“优秀的语言”(宁愿ruby,亦不python),这样的感受始于笔者最早一次使用深度学习做金融数据分析的毕业设计,python可把我害苦了。那时的我对JS爱不释手,曾企图使用JS自己构建神经网络。

终于,tfjs还是来了(在做毕设那会我就预言了要深度学习可以完全用JS开发),然而,Google最早对tfjs的态度(其实是在Google大脑工作的开源开发者)似乎还是停留在“JS要在浏览器上跑”的这种观念,所以笔者使用0.0.x版本都是基于浏览器开发的,@tensorflow/tfjs这个项目,其实在vue或者react等项目上非常的合适,但是对于client的node来说就不是那么友好,很多接口是不支持的。

下面来说说,这两个项目的区别,打开 npmjs.com,搜索tfjs



可以看到,tfjs和tfjs-node,下面来说说这个两个项目有什么不同,tfjs是为浏览器端而设计的,而tfjs-node是为node端设计的。

存储

个人认为,这两个项目最大的区别就是存储model的差别,早期的tfjs是基于浏览器的,故而可以将训练后的model存储在localstorage,indexedb,当然还可以通过formdata上传至http服务器。下面我来测试一下:

localStorage存储Model

浏览器代码

<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs/dist/tf.min.js"> </script>
<script>
(async ()=>{
const model = tf.sequential();
model.add(tf.layers.dense({units: 1, inputShape: [1]}));
model.compile({loss: 'meanSquaredError', optimizer: 'sgd'});
const xs = tf.tensor2d([1, 2, 3, 4], [4, 1]);
const ys = tf.tensor2d([1, 3, 5, 7], [4, 1]);
model.fit(xs, ys).then(() => {
model.predict(tf.tensor2d([5], [1, 1])).print();
});
let save = await model.save('localstorage://model-1')
})()
</script>
</head>
<body>
</body>
</html>

在chrome的浏览器application中可以看到已经存储的localstorage,tfjs一共存储了5个key-value,目前不懂里面的意义是什么

indexdb存储Model

事实上我之前做为前端也没有使用过indexdb,主要还是因为indexdb相对于webstorage过于庞大复杂,复杂的数据一般都丢给了后端用MySQL,笔者非常喜欢使用localstorage。以下尝试使用indexdb存储训练模型

浏览器代码

<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs/dist/tf.min.js"> </script>
<script>
(async ()=>{
let model = tf.sequential();
model.add(tf.layers.dense({units: 1, inputShape: [1]}));
model.compile({loss: 'meanSquaredError', optimizer: 'sgd'});
//目标y=2x-1
const xs = tf.tensor2d([1, 2, 3, 4], [4, 1]);
const ys = tf.tensor2d([1, 3, 5, 7], [4, 1]);
console.log('开始训练')
for(let i=0;i<2000;i++) await model.fit(xs, ys)
console.log('训练完毕')
let save = await model.save('indexeddb://model-1')
model = await tf.loadLayersModel('indexeddb://model-1');
model.predict(tf.tensor2d([10],[1,1])).print();
})()
</script>
</head> <body>
</body>
</html>

可以看到训练模型被存储再indexdb数据库中

Model上传至服务器

前端代码,训练的过程是一毛一样的,上述所有浏览器的深度学习法唯独就是最后一步存储不太一样,这里需要用到browserHTTPRequest的request请求,特别注意browserHTTPRequest不可以再node下跑,会提示要求再浏览器中使用,传输的文件形式应该是通过form-data到达服务器的。

前端代码

<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs/dist/tf.min.js"> </script>
<script>
(async ()=>{
let model = tf.sequential();
model.add(tf.layers.dense({units: 1, inputShape: [1]}));
model.compile({loss: 'meanSquaredError', optimizer: 'sgd'});
//目标y=2x-1
const xs = tf.tensor2d([1, 2, 3, 4], [4, 1]);
const ys = tf.tensor2d([1, 3, 5, 7], [4, 1]);
console.log('开始训练')
for(let i=0;i<2000;i++) await model.fit(xs, ys)
console.log('训练完毕')
let save = await model.save(tf.io.browserHTTPRequest('http://localhost:3000/Upload/test', {method: 'PUT'}))
})()
</script>
</head>
<body>
</body>
</html>

后端node实现文件接受,转储

	static async test(req,res){
let json = req.files.model.weights.bin.path
let path = req.files.model.json.path
const r = fs.createReadStream(json)
const w = fs.createWriteStream('./test.json')
r.pipe(w)
}

上述代码是一个代码块,由于我用到了自己构建的一个node框架,是根据TP的MVC模式设计的,关键代码如上,从req的files中取出文件,用fs模块转储到特定目录中。

以上所述均是tfjs框架的存储方式,有很大的缺点,那就是在浏览器端训练,训练后的模型只能存储在浏览器中,无法做大数据的收集,即使可以上传到服务器,训练的模型依然不能得到安全,可持续化,完整的保证,当然也有其一些优点,节省了大量服务器的资源,毕竟深度学习训练如果涉及到图形,音频,语言文字的话是相当复杂和消耗资源的,将训练过程合理的分压到客户端,最后再收集到服务器却是一种很“鸡贼”的手法,在这里我只能说妙啊妙啊,不过这满足不了程序员的控制欲,下面介绍一下tfjs-node的存储,由于tfjs-node的安装比tfjs复杂一些,如何安装tfjs-node请查看笔者上一篇博客。

Node的文件系统fs存储方式

欲用文件系统,请先安装tfjs-node。

node代码

const tf = require("@tensorflow/tfjs-node");
const model = tf.sequential(); //定义网络结构,层数,单元数,输入
model.add(tf.layers.dense({units: 1, inputShape: [1]})); //定义优化器
model.compile({loss: 'meanSquaredError', optimizer: 'sgd'}); //目标:y=2x+1;
const xs = tf.tensor2d([1,2,3,5], [4,1]);
const ys = tf.tensor2d([3,5,7,11], [4,1]); //使用async是因为训练中有异步操作,需要用到await
(async ()=>{
//训练1000次
for(let i=0;i<1000;i++) {
await model.fit(xs,ys);//等待训练的异步操作
console.log(`第${i}次`);
}
model.predict(tf.tensor2d([5,3,99], [3, 1])).print();
let save = await model.save('file://./model')
})();

上述代码中,其实训练过程和存储过程与browser大同小异,且存储的API都是model的save方法。

使用上述代码后,js所在的当前目录会产生一个model目录,并多出两个记忆文件模型。

至此,tfjs-node了却了我半年的顾虑,为js做深度学习保存模型寻找一个文件系统的方式,这样才能完全使用js进行深度学习的开发了。

tfjs-node初体验:训练模型的存储的更多相关文章

  1. node初体验(一)

    1.node.js是一个构建在chrome V8引擎上的javascript运行环境 2.node.js特点:单线程.事件驱动.非阻塞IO模型.轻量 3.node.js是单线程的(多个请求都是一个线程 ...

  2. Blazor初体验之寻找存储client-side jwt token的方法

    https://www.cnblogs.com/chen8854/p/securing-your-blazor-apps-authentication-with-clientside-blazor-u ...

  3. node初体验(二)

    1.静态资源访问,需要设置路由和响应标头 2.url模块.path模块.querystring模块 Url { protocol: null, slashes: null, auth: null, h ...

  4. Node.js 网页瘸腿爬虫初体验

    延续上一篇,想把自己博客的文档标题利用Node.js的request全提取出来,于是有了下面的初哥爬虫,水平有限,这只爬虫目前还有点瘸腿,请看官你指正了. // 内置http模块,提供了http服务器 ...

  5. node.js 初体验

    node.js 初体验 2011-10-31 22:56 by 聂微东, 174545 阅读, 118 评论, 收藏, 编辑 PS: ~ 此篇文章的进阶内容在为<Nodejs初阶之express ...

  6. Microsoft IoT Starter Kit 开发初体验-反馈控制与数据存储

    在上一篇文章<Microsoft IoT Starter Kit 开发初体验>中,讲述了微软中国发布的Microsoft IoT Starter Kit所包含的硬件介绍.开发环境搭建.硬件 ...

  7. node.js + express 初体验【hello world】

    [node.js]  一个神奇的XX 呵呵 :) 不知道怎么形容他才好! [express] 是node.js 开发web应用程序的框架 开发环境:XP 大家共同进步吧 :) 一:前期准备: 1:下载 ...

  8. (数据科学学习手札35)tensorflow初体验

    一.简介 TensorFlow时谷歌于2015年11月宣布在Github上开源的第二代分布式机器学习系统,目前仍处于快速开发迭代中,有大量的新功能新特性在陆续研发中: TensorFlow既是一个实现 ...

  9. Flume日志采集系统——初体验(Logstash对比版)

    这两天看了一下Flume的开发文档,并且体验了下Flume的使用. 本文就从如下的几个方面讲述下我的使用心得: 初体验--与Logstash的对比 安装部署 启动教程 参数与实例分析 Flume初体验 ...

随机推荐

  1. coures包下载和安装 可解决报错ImportError: No module named '_curses'

    http://blog.csdn.net/liyaoqing/article/details/54949253 coures curses 库 ( ncurses )提供了控制字符屏幕的独立于终端的方 ...

  2. [Algo] 132. Deep Copy Undirected Graph

    Make a deep copy of an undirected graph, there could be cycles in the original graph. Assumptions Th ...

  3. webgis笔记

    3.8(02) .特点:由服务端进行数据管理 开源的GO sever WMS/WCS/WTS 1sever/2engine/3database/4standard 扩展的空间数据库,存矢量.栅格.直接 ...

  4. PowerShell-Selenium技术实时调试和操作Chrome浏览器

    只需要4行代码: $AnyWindow=$Chrome.WindowHandles.Item() $Chrome=$Chrome.SwitchTo().Window($AnyWindow) Write ...

  5. C/S 和 B/S架构

    C/S 和 B/S架构 一.单机架构 应用领域: 植物大战僵尸 office 二.C/S架构 [ 应用领域: QQ 大型网络游戏 计算机发展初期用户去取数据,直接就去主机拿,从这里开始就分出了客户端和 ...

  6. 6.windows-oracle实战第六课 --数据管理

    数据库管理员: 每个oracle数据库应该至少有一个数据库管理员(dba),对于一个小的数据库,一个dba就够了,但是对于一个大的数据库可能需要多个dba分担不同的管理职责. 对于dba来说,会权限管 ...

  7. 论文翻译——Deep contextualized word representations

    Abstract We introduce a new type of deep contextualized word representation that models both (1) com ...

  8. 吴裕雄--天生自然 pythonTensorFlow图形数据处理:数据集高层操作

    import tempfile import tensorflow as tf # 1. 列举输入文件. # 输入数据生成的训练和测试数据. train_files = tf.train.match_ ...

  9. Django中间件-跨站请求伪造-django请求生命周期-Auth模块-seettings实现可插拔配置(设计思想)

    Django中间件 一.什么是中间件 django中间件就是类似于django的保安;请求来的时候需要先经过中间件,才能到达django后端(url,views,models,templates), ...

  10. Vue项目中跨域问题解决

    后台更改header 使用http-proxy-middleware 代理解决(项目使用vue-cli脚手架搭建) Jquery jsonp 一.后台更改header header('Access-C ...