Tensorflow.js:串联张量时,WebGL上下文丢失

时间:2018-10-12 12:58:26

标签: webgl concat tensorflow.js

我正在使用tensorflow.js转移学习tutorial/guide源代码,并在连接两个张量时出现以下错误:

Couldn't parse line number in error:                      tfjs@0.13.0:2 

  precision highp float;                                  tfjs@0.13.0:2 
  precision highp int;
  varying vec2 resultUV;
  const vec2 halfCR = vec2(0.5, 0.5);

  struct ivec5
  {
    int x;
    int y;
    int z;
    int w;
    int u;
  };

  struct ivec6
  {
    int x;
    int y;
    int z;
    int w;
    int u;
    int v;
  };

  bool isNaN(float val) {
    return (val < 0.0 || 0.0 < val || val == 0.0) ? false : true;
  }

  bool hasNaN(vec4 values) {
    vec4 v1 = values * values;
    vec4 v2 = values * values;
    return any(notEqual(v1, v2));
  }

  float getNaN(vec4 values) {
    return dot(vec4(1), values);
  }

  int round(float value) {
    return int(floor(value + 0.5));
  }

  int imod(int x, int y) {
    return x - y * (x / y);
  }

  //Based on the work of Dave Hoskins
  //https://www.shadertoy.com/view/4djSRW
  #define HASHSCALE1 443.8975
  float random(float seed){
    vec2 p = resultUV * seed;
    vec3 p3  = fract(vec3(p.xyx) * HASHSCALE1);
    p3 += dot(p3, p3.yzx + 19.19);
    return fract((p3.x + p3.y) * p3.z);
  }


vec2 UVfrom1D(int texNumR, int texNumC, int index) {
  int texR = index / texNumC;
  int texC = index - texR * texNumC;
  return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);
}


vec2 UVfrom2D(int texNumR, int texNumC, int numC, int row, int col) {
  int index = row * numC + col;
  int texR = index / texNumC;
  int texC = index - texR * texNumC;
  return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);
}


vec2 UVfrom3D(int texNumR, int texNumC, int stride0,
    int stride1, int row, int col, int depth) {
  // Explicitly use integer operations as dot() only works on floats.
  int index = row * stride0 + col * stride1 + depth;
  int texR = index / texNumC;
  int texC = index - texR * texNumC;
  return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);
}


vec2 UVfrom4D(int texNumR, int texNumC, int stride0,
    int stride1, int stride2, int row, int col, int depth,
    int depth2) {
  // Explicitly use integer operations as dot() only works on floats.
  int index = row * stride0 + col * stride1 + depth * stride2 + depth2;
  int texR = index / texNumC;
  int texC = index - texR * texNumC;
  return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);
}


vec2 UVfrom5D(int texNumR, int texNumC, int stride0,
    int stride1, int stride2, int stride3, int row, int col, int depth,
    int depth2, int depth3) {
  // Explicitly use integer operations as dot() only works on floats.
  int index = row * stride0 + col * stride1 +
              depth * stride2 + depth2 * stride3 + depth3;
  int texR = index / texNumC;
  int texC = index - texR * texNumC;
  return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);
}


vec2 UVfrom6D(int texNumR, int texNumC, int stride0,
    int stride1, int stride2, int stride3, int stride4,
    int row, int col, int depth, int depth2, int depth3, int depth4) {
  // Explicitly use integer operations as dot() only works on floats.
  int index = row * stride0 + col * stride1 + depth * stride2 + depth2 *
    stride3 + depth3 * stride4 + depth4;
  int texR = index / texNumC;
  int texC = index - texR * texNumC;
  return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);
}



  float sampleTexture(sampler2D textureSampler, vec2 uv) {
    return texture2D(textureSampler, uv).r;
  }


  void setOutput(float val) {
    gl_FragColor = vec4(val, 0, 0, 0);
  }

uniform sampler2D A;
uniform sampler2D B;

      ivec2 getOutputCoords() {
        ivec2 resTexRC = ivec2(resultUV.yx *
                               vec2(1984, 2352));
        int index = resTexRC.x * 2352 + resTexRC.y;
        return ivec2(0, index);
      }


    float getAFlat(int index) {
      vec2 uv = UVfrom1D(1792, 2597, index);
      return sampleTexture(A, uv);
    }


    float getA(int index) {
      return getAFlat(index);
    }

      float getA(int row, int col) {
        return getA(col);
      }


    float getBFlat(int index) {
      vec2 uv = UVfrom1D(7, 1792, index);
      return sampleTexture(B, uv);
    }


    float getB(int index) {
      return getBFlat(index);
    }

      float getB(int row, int col) {
        return getB(col);
      }


      void main() {
        ivec2 coords = getOutputCoords();
        int yR = coords.x;
        int yC = coords.y;

        float value = 0.0;
        if (yC < 4653824) {
          value = getA(yR, yC);
        } else {
          yC -= 4653824;
          value = getB(yR, yC);
        }

        setOutput(value);
      }


Uncaught Error: Failed to compile fragment shader.
at createFragmentShader (tfjs@0.13.0:2)
at e.createProgram (tfjs@0.13.0:2)
at compileProgram (tfjs@0.13.0:2)
at tfjs@0.13.0:2
at e.getAndSaveBinary (tfjs@0.13.0:2)
at e.compileAndRun (tfjs@0.13.0:2)
at e.concat2Tensors (tfjs@0.13.0:2)
at e.concat (tfjs@0.13.0:2)
at tfjs@0.13.0:2
at tfjs@0.13.0:2

WebGL: CONTEXT_LOST_WEBGL: loseContext: context lost

Uncaught Error: Unable to create fragment WebGLShader.
at throwIfNull (tfjs@0.13.0:2)
at createFragmentShader (tfjs@0.13.0:2)
at e.createProgram (tfjs@0.13.0:2)
at compileProgram (tfjs@0.13.0:2)
at tfjs@0.13.0:2
at e.getAndSaveBinary (tfjs@0.13.0:2)
at e.compileAndRun (tfjs@0.13.0:2)
at e.concat2Tensors (tfjs@0.13.0:2)
at e.concat (tfjs@0.13.0:2)
at tfjs@0.13.0:2

我正在创建一个应用程序,该应用程序通过便携式计算机的麦克风输入接收音频信号,并将信号频率与从便携式计算机的网络摄像头流捕获的图像相关联。我正在将电吉他信号馈送到麦克风输入以手动控制频率,并且我具有用于获取频率数据的Web音频API ScriptProcessorNodes onaudioprocess函数。

当频率清晰时,可以从网络摄像头流中捕获足够的图像,然后使用tf.fromPixels方法将其转换为张量,并通过截短的mobilenet模型进行内部激活,以备后用。在第一轮中,来自截断模型的内部激活被保存到变量中,并且在第一次之后,新的内部激活通过concat()方法被连接到先前的激活。如果输入信号频率稳定且清晰,所有这些每秒都会发生多次。这可以正常工作一些时间,但是在串联的张量达到4678912的大小后,程序崩溃并产生了上面详述的错误。我不确定张量在这里是否至关重要。

我正在Chrome浏览器中运行该应用程序。

这是导致我猜错的连接函数:

addExample(example, label) {
// One-hot encode the label.

    const y = tf.tidy(() => tf.oneHot(tf.tensor1d([label]).toInt(), this.numClasses));

    if (this.xs == null) {

      // For the first example that gets added, keep example and y so that the
      // ControllerDataset owns the memory of the inputs. This makes sure that
      // if addExample() is called in a tf.tidy(), these Tensors will not get
      // disposed.
      this.xs = tf.keep(example);
      this.ys = tf.keep(y);

    } else {
      const oldX = this.xs;
      this.xs = tf.keep(oldX.concat(example, 0));

      const oldY = this.ys;
      this.ys = tf.keep(oldY.concat(y, 0));

      oldX.dispose();
      oldY.dispose();
      y.dispose();
    }
}

这是崩溃前的串联张量:

e {isDisposedInternal: false, shape: Array(4), dtype: "float32", size: 
4678912, strides: Array(3), …}
dataId: {}
dtype: "float32"
id: 117079
isDisposed: (...)
isDisposedInternal: false
rank: (...)
rankType: "4"
shape: Array(4)
    0: 373
    1: 7
    2: 7
    3: 256
    length: 4
    __proto__: Array(0)
size: 4678912
strides: Array(3)
    0: 12544
    1: 1792
    2: 256
    length: 3
    __proto__: Array(0)
__proto__: Object

当我尝试original demo (Pacman-game)并将300-400个示例添加到四个控制器之一时,也会出现错误。我的应用程序中的基本逻辑与原始演示中的相同。不同的是类的数量(48个类代表与电吉他不同的音符频率)以及在ScriptProcessorNode中添加示例的方式。同样,所需示例的数量也更大。

我不知道从哪里开始研究错误。我的webGL知识是0。非常感谢您的帮助。

0 个答案:

没有答案