From a17cc6f145e6ffa0af46e224308ddee28fe523f0 Mon Sep 17 00:00:00 2001 From: Cathie So Date: Fri, 18 Nov 2022 16:51:32 +0800 Subject: [PATCH] AveragePooling2D layer --- circuits/AveragePooling2D.circom | 28 ++ models/averagePooling2D_input.json | 1 + models/averagePooling2D_output.json | 1 + models/averagePooling2D_stride_input.json | 1 + models/averagePooling2D_stride_output.json | 1 + models/averagePooling2d.ipynb | 457 ++++++++++++++++++ test/AveragePooling2D.js | 63 +++ .../AveragePooling2D_stride_test.circom | 6 + test/circuits/AveragePooling2D_test.circom | 6 + 9 files changed, 564 insertions(+) create mode 100644 circuits/AveragePooling2D.circom create mode 100644 models/averagePooling2D_input.json create mode 100644 models/averagePooling2D_output.json create mode 100644 models/averagePooling2D_stride_input.json create mode 100644 models/averagePooling2D_stride_output.json create mode 100644 models/averagePooling2d.ipynb create mode 100644 test/AveragePooling2D.js create mode 100644 test/circuits/AveragePooling2D_stride_test.circom create mode 100644 test/circuits/AveragePooling2D_test.circom diff --git a/circuits/AveragePooling2D.circom b/circuits/AveragePooling2D.circom new file mode 100644 index 0000000..36a2458 --- /dev/null +++ b/circuits/AveragePooling2D.circom @@ -0,0 +1,28 @@ +pragma circom 2.0.3; + +include "./SumPooling2D.circom"; + +// AveragePooling2D layer, poolSize is required to be equal for both dimensions, might lose precision compared to SumPooling2D +// scaledInvPoolSize is required to perform fixed point division, it is calculated as 1000/poolSize +template AveragePooling2D (nRows, nCols, nChannels, poolSize, strides, scaledInvPoolSize) { + signal input in[nRows][nCols][nChannels]; + signal output out[(nRows-poolSize)\strides+1][(nCols-poolSize)\strides+1][nChannels]; + + component sumPooling2D = SumPooling2D (nRows, nCols, nChannels, poolSize, strides); + + for (var i=0; i (2,2,3)", async () => { + const json = require("../models/averagePooling2D_input.json"); + const OUTPUT = require("../models/averagePooling2D_output.json"); + + const circuit = await wasm_tester(path.join(__dirname, "circuits", "AveragePooling2D_test.circom")); + //await circuit.loadConstraints(); + //assert.equal(circuit.nVars, 76); + //assert.equal(circuit.constraints.length, 0); + + const INPUT = { + "in": json.in + } + + const witness = await circuit.calculateWitness(INPUT, true); + + assert(Fr.eq(Fr.e(witness[0]),Fr.e(1))); + + for (var i=0; i<2*2*3; i++) { + assert((witness[i+1]-Fr.e(OUTPUT.out[i])) (4,4,3)", async () => { + const json = require("../models/averagePooling2D_stride_input.json"); + const OUTPUT = require("../models/averagePooling2D_stride_output.json"); + + const circuit = await wasm_tester(path.join(__dirname, "circuits", "AveragePooling2D_stride_test.circom")); + + const INPUT = { + "in": json.in + } + + const witness = await circuit.calculateWitness(INPUT, true); + + assert(Fr.eq(Fr.e(witness[0]),Fr.e(1))); + + for (var i=0; i<4*4*3; i++) { + assert((witness[i+1]-Fr.e(OUTPUT.out[i]))