JS做深度学习3——数据结构

最近在上海上班了,很久没有写博客了,闲下来继续关注和研究Tensorflow.js

关于深度学习的文章我也已经写了不少,部分早期作品可能包含了不少错误的认识,在后面的博文中会改进或重新审视。

今天聊聊神经网络的入门知识,tensor!本章的题目就是“数据结构”,之所以把名字的含义取这么广,是因为,今天从tensor这种数据结构开始,但远不止于tensor!

基础

何为tensor?让我们先看看tensorflow官网的解释

Tensors are the core datastructure of TensorFlow.js They are a generalization of vectors and matrices to potentially higher dimensions.

tensor可以翻译为“张量”,他是深度学习,tensorflow的核心数据结构,tensor是向量和矩阵的俗称(generalization一般化,概括),它具备潜在的更庞大的规模。这里可能翻译的不太好,不过可以看出来学习深度学习一定要围绕着tensor来,tensor规模可大可小,他真的太重要了。

构造数据结构

tensorflow.js为我们提供了tensor数据结构的很多构造方法,这其中包含了1维,2维,3维等多种张量的构造方法,初始化方法,buffer缓冲,克隆方法。

tf.tensor( value, shape, dtype )

返回:tf.Tensor类型

这是一个用于构造张量tensor的最基本方法,也是最实用的方法,如果你找不到什么最好的构造的tensor方法或者无法确定一个结构必然是2d,3d等情况下,尽量实用tensor。

const tf = require("@tensorflow/tfjs");

tf.tensor([1,2,3,4]).print()

打印结果:

一维矩阵

这是一个一维矩阵,先不管有什么用,有什么意义,我们暂且理解为一个一维的矩阵。1×4(1行4列)

还可以将一维转成2×2:tf.tensor([1,2,3,4],[2,2]).print();

或者直接构造2×2的tensor:tf.tensor([[1, 2], [3, 4]]).print();,效果同上

这里写图片描述

tf.fill()

返回:tf.Tensor类型

可以对张量tensor进行初始化填充,如下:tf.fill([2, 2], 4).print();

这里写图片描述

fill的第一个参数是矩阵的结构,[2,2]表示2行2列的矩阵,第二个参数是要初始化的值,这就像普通编程下对数组的初始化,将每一个单元填充一个默认数。

tf.buffer()

返回: tf.TensorBuffer

乍一看这个方法有点难以理解,该方法返回一个tensor的buffer,buffer是缓冲的意思,在缓冲区可以对tensor的任何单元随意修改,通过tensorbuffer对象中的set方法动态修改矩阵中某个位置的数据值。来看个实例:

const tf = require("@tensorflow/tfjs");

const bf = tf.buffer([2,2]);
bf.set(3,0,0);
bf.set(2,0,1);
bf.set(5,1,0);
bf.set(1,1,1);
bf.toTensor().print()

运行结果:
这里写图片描述

首先构造了一个tensorbuffer对象用于对矩阵数据的规划,使用set来单独设置矩阵中每一个单元的数据。
案例中使用了set方法传入的参数分别是(值,行,列),也就是说set方法第一个参数是矩阵单元的值,而第2,3,4...代表了这个数据单元在矩阵的位置。
最终使用toTensor将矩阵(张量)从buffer中取出,得到真正的tensor数据结构对象。

注意,tensor有可能是3维的,那样set应该有4个参数了,那么还是用buffer,做个简单例子验证一下猜想:

这里写图片描述

这个矩阵显得就相对复杂一点,这是一个三维张量了,2×2×2,可以这么理解:在空间上数据向三个方向发展,每个方向限量2个值,我不知道在线性代数中,3维度的张量能否称为矩阵,如果我术语有错误还请指正,不过这不重要,大家理解编程中的意思就行,我个人是把张量=tensor=矩阵进行表述的。

更多的对tensor数据结构的构造方法就不做介绍了,我觉得也不常用,使用方式大同小异,例如
tf.tensor1d
tf.tensor2d
tf.tensor3d
...
参考tensorflow官网给出的API。

一些简单实用案例

说了这么多,tensor为什么重要?我们构造这些各种维度的矩阵到底有什么用呢?

这里就要说到数学作为工具在现实生活中的意义了。

数学,我粗略的理解就是,使用数字,符号,逻辑去表达或描述现实。

而某个事物存在的各种属性以及这些属性携带的值都可以用张量来表示,例如在使用深度学习分析一张图片:

首先,计算机不能“见图识义”,一张图片不能直接交给计算机处理,需要将图片转换为一个张量(矩阵),这个矩阵中单个元素,也就是一个像素点,一般是这样的:[R,G,B,A],而为了构成整个图片,需要行和列,所以最终的tensor数据结构是:[800,600,4],代表有800行,600列,这个平面上的一个单元还拥有4个值,代表了红绿蓝和透明度。

深度学习识别图片所属分类(例如让计算机看出一张图上是一只猫)的过程实际是对多个矩阵特征的学习和分析(理论上无数个),获得矩阵中某个点某个值出现的概率,将这些概率构成网状的多层神经网络,将一个新矩阵(新图片)传入后经过多层的矩阵变化计算,得出一个概率最大的结论。当然其中还有很多的数学知识,例如线性函数,非线性化,归零化,反向求导,优化器等,以后慢慢解释。

我们先不对图片识别做过多的解释,先使用代码模拟一张虚拟图片出来。

const tf = require("@tensorflow/tfjs");

let color = new Array();
for (let i=0;i<400;i++){
    color[i] = new Array();
    for(let j=0;j<300;j++){
        color[i][j] = new Array();
        color[i][j]= [Math.floor(Math.random()*256),Math.floor(Math.random()*256),Math.floor(Math.random()*256),1];
    }
}
console.log(color);
tf.tensor(color,[400,300,4]).print()

这里写图片描述

上述代码构造了一个三维数组,每一个元素是随机生成的0-255的数值,代表RGB值。

这实际是一张800×600,透明度为100%(不透明)的随机彩色图片。(这里不展示出来了,也不难,可以结合html实现)

在这个基础上,我们还可以反向将图片转换为矩阵,我们来看一个官方提供的方法:

tf.fromPixels()

该方法可以将canvas图片转换为tensor,很棒,就是图片转换为矩阵咯,我们来试试。

注意:这里需要在前端中使用tfjs了。我们离开node.js构建浏览器文件。

打开apache或者nginx服务器,启动http,你可以使用nodejs或者wamp,因为以前php开发多,我使用的是wamp集成环境,这里注意,请务必在http下测试该案例,使用IP访问,直接运行html页面,tfjs会报错!这是http secure导致的!

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.11.7"></script>
        <style>
#canvasImg{
    320px;
    height:480px;
}
        </style>
    </head>
    <body>
        <img id="originImg" src="./timg.jpg" alt="">
        <canvas id="canvasImg"> </canvas>

        <script>
            window.onload=function(){
                var originImg = document.getElementById("originImg");
                var canvas = document.getElementById("canvasImg");
                canvas.width=320;
                canvas.height=480;
                canvas.getContext("2d").drawImage(originImg, 0, 0);    

                setTimeout(function(){
                    var tensor = tf.fromPixels(canvas);
                    tensor.print();
                },2000)
            }
        </script>
    </body>
</html>

案例使用的图片如下,320×480像素

这里写图片描述

这里写图片描述

那么,这里已经将图片转换为console中的tensor数据结构,这就是图形识别,图形处理的基础啦,以后就可以使用tensor进行神经元训练,然后发挥想象吧,图像识别,自动绘图,图片美化都不是问题!是不是极有意思呢。更多实践以后进行图形识别项目时再做介绍了。

对了,到这里补充一下_(:з」∠)_,我刚刚发现TensorFlow官方给出了toPixels方法,也就是和fromPixels方法相反,将tensor生成图片,也就是说,我们刚刚生成的随机数图片可以直接通过tfjs转换为图片了,方法如下:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.11.7"></script>
    </head>
    <body>
        <canvas id="canvasImg"> </canvas>

        <script>
            window.onload=function(){
                var tensorImg = randomTensor();
                tensorImg.print();

                var canvas = document.getElementById("canvasImg");
                canvas.width=800;
                canvas.height=600;
                tf.toPixels(tensorImg,canvas)

            }
            function randomTensor(){
                var color = new Array();
                for (let i=0;i<400;i++){
                    color[i] = new Array();
                    for(let j=0;j<300;j++){
                        color[i][j] = new Array();
                        color[i][j]= [Math.floor(Math.random()*256),Math.floor(Math.random()*256),Math.floor(Math.random()*256)];
                    }
                }
                return tf.tensor(color,[400,300,3],'int32');
            }
        </script>
    </body>
</html>

这里写图片描述

根据代码算法,每个点都是随机数,所以生成图也没啥意思,随便看看就行(⊙o⊙)!

原文地址:https://www.cnblogs.com/devilyouwei/p/9259355.html