IsPositive() treats zero as a positive number (#3)

* Add comments on IsPositive()

IsPositive() treats zero as a positive number for better performance.

* Add a little note about `IsPositive()`
This commit is contained in:
MisakaCenter
2023-04-13 21:21:23 +08:00
committed by GitHub
parent e49c9be3d5
commit 21372d29d6
2 changed files with 29 additions and 2 deletions

View File

@@ -155,6 +155,10 @@ test/
Essentially `AveragePooling2D` with a constant scaling of `poolSize*poolSize`. This is preferred in circom to preserve precision and reduce computation.
- `util.circom`
`IsPositive()` treats zero as a positive number for better performance. If you want to use `IsPositive()` to check if a number is strictly positive, you can use the version in the in-code comments.
## Weights and biases scaling:
- Circom only accepts integers as signals, but Tensorflow weights and biases are floating-point numbers.
- In order to simulate a neural network in Circom, weights must be scaled up by `10**m` times. The larger `m` is, the higher the precision.
@@ -171,4 +175,4 @@ In `models/mnist_poly.ipynb`, a sample model of Conv2d-Poly-Dense layers was tra
- Weights in the `Dense` layer were scaled by `10**9` time for precision again.
- Biases in the `Dense` layer had been omitted for simplcity, since `ArgMax` layer is not affected by the biases. However, if the biases were to be included (for example in a deeper network as an intermediate layer), they would have to be scaled by `(10**9)**5=10**45` times to adjust correctly.
We can easily see that a deeper network would have to sacrifice precision, due to the limitation that Circom works under a finite field of modulo `p` which is around 254 bits. As `log(2**254)~76`, we need to make sure total scaling do not aggregate to exceed `10**76` (or even less) times. On average, a network with `l` layers should be scaled by less than or equal to `10**(76//l)` times.
We can easily see that a deeper network would have to sacrifice precision, due to the limitation that Circom works under a finite field of modulo `p` which is around 254 bits. As `log(2**254)~76`, we need to make sure total scaling do not aggregate to exceed `10**76` (or even less) times. On average, a network with `l` layers should be scaled by less than or equal to `10**(76//l)` times.

View File

@@ -20,6 +20,29 @@ template IsNegative() {
out <== sign.sign;
}
/* Currently, IsPositive() treats zero as a positive number for better performance.
The following is the correct version which output is 1 when the signal in is a positive number, 0 when it is zero or a negative number
template IsPositive() {
signal input in;
signal output out;
component num2Bits = Num2Bits(254);
num2Bits.in <== in;
component sign = Sign();
for (var i = 0; i < 254; i++) {
sign.in[i] <== num2Bits.out[i];
}
component isz = IsZero();
isz.in <== in;
out <== (1 - sign.sign) * (1 - isz.out);
}
*/
template IsPositive() {
signal input in;
signal output out;
@@ -74,4 +97,4 @@ template Max(n) {
}
out <== maxs[n];
}
}