mirror of
https://github.com/socathie/circomlib-ml.git
synced 2026-01-08 05:34:01 -05:00
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:
@@ -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.
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user