CreateNeuralNetworkShaders ==================================================== .. js:function:: function CreateNeuralNetworkShaders() ソース ^^^^^^ .. code-block:: js function CreateNeuralNetworkShaders() { return { FullyConnectedLayer_Forward: `in float zero; const int ActivationFunction_none = 0; const int ActivationFunction_sigmoid = 1; const int ActivationFunction_ReLU = 2; uniform int activationFunction; // 2次元配列のテクスチャ uniform sampler2D W; uniform sampler2D X; uniform sampler2D Bias; out float z; out float y; float sigmoid(float x){ return 1.0 / (1.0 + exp(-x)); } void main() { ivec2 X_sz = textureSize(X, 0); ivec2 Bias_sz = textureSize(Bias, 0); int batch_idx = gl_VertexID / Bias_sz.x; int out_idx = gl_VertexID % Bias_sz.x; float sum = 0.0f; for(int i = 0; i < X_sz.x; i++) { vec4 w = texelFetch(W, ivec2(i, out_idx), 0); vec4 x = texelFetch(X, ivec2(i, batch_idx), 0); sum += w.r * x.r; } vec4 bias = texelFetch(Bias, ivec2(out_idx, 0), 0); sum += bias.r; // 入力変数zeroの値は必要ないですが、使用しない変数はコンパイラが除去してしまいエラーになるので形の上だけ使用します。 // zeroの値は0なので計算結果には影響しません。 z = sum + zero; switch(activationFunction){ case ActivationFunction_none: y = z; break; case ActivationFunction_sigmoid: y = sigmoid(z); break; case ActivationFunction_ReLU: y = (0.0f < z ? z : 0.0f); break; } }` , FullyConnectedLayer_DeltaWeight: `in float zero; // 2次元配列のテクスチャ uniform sampler2D prev_y; uniform sampler2D deltaZ; out float deltaWeight; void main() { int row = gl_VertexID / WeightColSize; int col = gl_VertexID % WeightColSize; float sum = 0.0f; int batch_idx; for(batch_idx = 0; batch_idx < miniBatchSize; batch_idx++){ vec4 pa = texelFetch(prev_y, ivec2(col, batch_idx), 0); vec4 dz = texelFetch(deltaZ, ivec2(row, batch_idx), 0); sum += pa.r * dz.r; } deltaWeight = sum + zero; }` , FullyConnectedLayer_DeltaX: `in float zero; // 2次元配列のテクスチャ uniform sampler2D W; uniform sampler2D deltaZ; out float deltaX; void main() { ivec2 W_sz = textureSize(W, 0); int batch_idx = gl_VertexID / W_sz.x; int delta_x_idx = gl_VertexID % W_sz.x; float sum = 0.0f; for(int i = 0; i < W_sz.y; i++) { vec4 w = texelFetch(W, ivec2(delta_x_idx, i), 0); vec4 z = texelFetch(deltaZ, ivec2(i, batch_idx), 0); sum += w.r * z.r; } deltaX = sum + zero; }` , ConvolutionalLayer_Forward : ` precision highp sampler3D; const int ActivationFunction_none = 0; const int ActivationFunction_sigmoid = 1; const int ActivationFunction_ReLU = 2; uniform int activationFunction; uniform float bias[numChannels]; uniform sampler3D weight; uniform sampler3D prev_y; in float zero; out float z; out float y; float sigmoid(float x){ return 1.0 / (1.0 + exp(-x)); }