Tiny αβ\alpha\beta-CROWN

Neural networks, for example image classifiers, are often vulnerable to attacks where small, sub-perceptual changes to the input cause misclassification.

Figure 1. Left: an image classified as 7 by the neural network from tinygrad's quick-start MNIST example. Right: a small perturbation changes its classification to 3.

Informally, given an input xx to a neural network ff, the verification problem is to prove that for any xx' that is a bounded perturbation of xx, f(x)=f(x)f(x') = f(x). Successful proofs can rule out attacks like the one above.

The current state of the art is an algorithm called αβ\alpha\beta-CROWN, an implementation of which has won the International Verification of Neural Networks Competition for the past five years. I think αβ\alpha\beta-CROWN is a lovely algorithm in an important research area where progress is unlikely in my lifetime.

I implemented αβ\alpha\beta-CROWN for a deep-learning library called tinygrad and this blog post is about how it works. This is for the most part a synthesis of these three papers, my very modest contribution being a description of how the algorithm handles shape changes (reshape/flatten/permute) which does not appear in existing descriptions.

Background

xx' is a bounded perturbation of xx if it is an element of an p\ell_p-ball of radius ϵ\epsilon centered at xx, denoted Bp(x,ϵ)B_p(x, \epsilon):

Bp(x,ϵ)={xxxpϵ},B_p(x, \epsilon) = \{\, x' \mid \lVert x - x' \rVert_p \le \epsilon \,\},

where xp\lVert x \rVert_p is xx's pp-norm,

xp=(ixip)1/p.\lVert x \rVert_p = \left(\sum_i |x_i|^p\right)^{1/p}.

A convenient fact is that there is a closed-form solution to the minimum of any linear (or affine) function over an p\ell_p ball (Hölder's inequality):

minxBp(x0,ϵ)w,x=w,x0ϵwq,\min_{x \in B_p(x_0,\epsilon)} \langle w, x \rangle = \langle w, x_0 \rangle - \epsilon \lVert w \rVert_q,

where x,y\langle x, y\rangle denotes the dot product of vectors xx and yy, and q\lVert\cdot\rVert_q is the dual norm of p\lVert\cdot\rVert_p, defined by 1q+1p=1.\frac{1}{q} + \frac{1}{p} = 1.

In image classification, for an image xx, a neural network typically outputs an nn-dimensional vector f(x)Rnf(x)\in\mathbb{R}^n and xx's classification is said to be the index in f(x)f(x) with the largest value. Thus, for the example in Figure 1, proving no bounded perturbation of an image xx gets classified as 3 is equivalent to checking that xBp(x,ϵ),f(x)7f(x)3>0.\forall x'\in B_p(x, \epsilon), f(x')_7-f(x')_3 > 0. In turn, a common approach to neural network verification (and the one taken by αβ\alpha\beta-CROWN) is to compute affine bounds on the output of ff, then use Hölder's inequality to minimize f(x)7f(x)3f(x')_7-f(x')_3 over Bp(x,ϵ)B_p(x, \epsilon). If the minimum is >0>0, then no images in a bounded perturbation of xx will be classified as 3.

αβ\alpha\beta-CROWN on Graphs

Many deep-learning libraries represent neural networks as graphs where edges correspond to data and vertices to differentiable operations. For example, f(x)=h(x)+g(x)f(x) = h(x) + g(x) might be represented as

To implement α\alpha-CROWN on a graph, we need a way to compute bounds on the output of each operator given bounds on its input, then bounds on the output of the network can be propagated through the graph and written in terms of the network's input. For example, for the + operator above, if

W(h)x+b(h)h(x),W(g)x+b(g)g(x),\underline{W}^{(h)}x + \underline{b}^{(h)} \le h(x), \quad \underline{W}^{(g)}x + \underline{b}^{(g)} \le g(x),

are affine lower bounds on hh and gg, then

(W(h)+W(g))x+(b(h)+b(g))f(x)(\underline{W}^{(h)} + \underline{W}^{(g)})x + (\underline{b}^{(h)} + \underline{b}^{(g)}) \le f(x)

is a lower bound on h(x)+g(x)h(x) + g(x).

Handling ReLU

Nonlinear functions like ReLU are more challenging to bound. αβ\alpha\beta-CROWN uses linear over/under-approximations.

Figure 3. The dashed lines are linear bounds on a ReLU over the interval [,u][\ell, u].

First, Hölder's inequality is used to compute concrete bounds \ell and uu on the ReLU's input. Then, when <0<u\ell < 0 < u (i.e. the ReLU is nonlinear), for some 0α0 \le \alpha, letting σ\sigma denote ReLU, the following equations bound it:

αxσ(x)σ(u)σ()u(x).\alpha x \le \sigma(x) \le \frac{\sigma(u)-\sigma(\ell)}{u-\ell}\,(x-\ell).

Notice how any value of α\alpha between zero and one gives a lower bound when <0<u\ell < 0 < u. Thus, towards choosing a good value for α\alpha, notice that the ReLU bounds, the ++ function bounds, and Hölder's inequality are all computed using differentiable operations. In fact, in general, all the equations for bound propagation in αβ\alpha\beta-CROWN are differentiable. In turn, given bounds on a neural network's output in terms of different ReLU's α\alpha values, we can use gradient descent to find α\alpha values that tighten them. I think this is cool!

β\beta-CROWN

In Figure 3, if 0\ell \ge 0 or u0u \le 0, then setting α\alpha to 1 or 0 makes the ReLU bounds exact; ReLU's with this property are called stable. If we can compute bounds on ff conditional on a ReLU being stable, we could consider both cases and merge them. For example, if (+),u(+)\ell^{(+)},u^{(+)} were lower and upper bounds on a ReLU when 0\ell \ge 0, and (),u()\ell^{(-)},u^{(-)} were bounds when u0u \le 0, then

min((+),())σ(x)max(u(+),u()).\min\left(\ell^{(+)}, \ell^{(-)}\right) \le \sigma(x) \le \max\left(u^{(+)}, u^{(-)}\right).

are overall bounds on the ReLU. This is the idea behind β\beta-CROWN. To propagate bounds on fL1(x)f^{L-1}(x) to fL(x)f^L(x),

fL(x)=σ(fL1(x)),f^L(x) = \sigma\big(f^{L-1}(x)\big),

subject to constraints CC, we let SfL1(x)S f^{L-1}(x) be positive if fL1(x)f^{L-1}(x) satisfies CC and negative otherwise. For example, in the (+)\ell^{(+)} case where the constraint enforces fL1(x)0f^{L-1}(x)\ge 0, we have S=1S=1. Then, if

WL1x+bL1fL1(x),\underline{W}^{L-1}x + \underline{b}^{L-1} \le f^{L-1}(x),

by Lagrangian relaxation and weak duality,

minC,x  fL(x)=minC,x  σ(fL1(x))minxmaxβ  σ(fL1(x))+βSfL1(x)maxβminx  (W(L1)x+b(L1))+βSfL1(x),\begin{aligned} \min_{C,x}\; f^L(x) &= \min_{C,x}\; \sigma\big(f^{L-1}(x)\big) \\ &\ge \min_x\max_\beta\; \sigma\big(f^{L-1}(x)\big) + \beta S f^{L-1}(x) \\ &\ge \max_\beta\min_x\; \big(\underline{W}^{(L-1)}x+\underline{b}^{(L-1)}\big) + \beta S f^{L-1}(x), \end{aligned}

where β0\beta \ge 0. To find a value for β\beta that gives a tight bound we can, once again, use gradient descent. Notice that the fL1(x)f^{L-1}(x) term can be removed by recursively getting bounds on βSfL1(x)\beta S f^{L-1}(x) in terms of xx. Bounds for the (+)(+) and ()(-) cases can be merged to get overall bounds on the ReLU as described above. Finding upper bounds is a variant of the same procedure as minf(x)=maxf(x)\min f(x)=-\max -f(x).

tinygrad

tinygrad is a popular deep-learning library with lazy evaluation and a small set of UOps to which tensor operations are lowered before being run. Because tinygrad is lazy, tensors are represented as a graph that computes their value on demand, making accessing a computation's graph straightforward. Furthermore, tinygrad's small set of UOps means bound propagation only needs to be implemented for this small operation set to support complex networks. These properties make tinygrad amenable to an implementation of αβ\alpha\beta-CROWN.

However, tinygrad's UOps are distinct from the operations described in previous work on αβ\alpha\beta-CROWN. For example, whereas α\alpha-CROWN considers matrix multiply a primitive operation, tinygrad compiles matrix multiply to a series of low-level shape changes. Specifically, for A,BRn×nA,B\in\mathbb{R}^{n\times n}, tinygrad computes C=ABC=AB via:

x1=A.reshape(n,1,n)i,j,k=Ai,kx2=B.T.reshape(1,n,n)i,j,k=Bk,jx3=(x1x2)i,j,k=Ai,kBk,jC=x3.sum(axis=2)i,j=kAi,kBk,j\begin{aligned} x_1 &= \texttt{A.reshape(n,1,n)}_{i,j,k} &&= A_{i,k} \\ x_2 &= \texttt{B.T.reshape(1,n,n)}_{i,j,k} &&= B_{k,j} \\ x_3 &= (x_1*x_2)_{i,j,k} &&= A_{i,k}B_{k,j} \\ C &= x_3\texttt{.sum(axis=2)}_{i,j} &&= \sum_k A_{i,k}B_{k,j} \end{aligned}

While available implementation of αβ\alpha\beta-CROWN handle shape changes, published descriptions of the algorithm don't, instead describing how to compute bounds on f(x)f(x) in terms of vectors x,b,bx, \underline{b}, \overline{b} and matrices W,W\underline{W}, \overline{W}:

Wx+bf(x)Wx+b.\underline{W}x+\underline{b}\leq f'(x)\leq \overline{W}x+\overline{b}.

When the input to the network is not a vector (for example, an image with shape (bs, w, h, ch)(\texttt{bs, w, h, ch})), the matrix multiply above is no longer semantically valid. Thus, beyond an αβ\alpha\beta-CROWN implementation for tinygrad, this blog's small contribution in the following section is a description of how to compute αβ\alpha\beta-CROWN bounds for arbitrarily shaped inputs subject to arbitrary shape changes. The method is semantically identical to the one used by αβ\alpha\beta-CROWN's existing PyTorch implementation.

Handling Shape Changes

To handle high-rank tensors and shape changes in tinygrad, bounds on the network are written in terms of tensor contractions.

For xx with shape (a1,,aA)(a_1,\dots,a_A) and TT with shape (p1,,pP,a1,,aA)(p_1,\dots,p_P,a_1,\dots,a_A) the tensor contraction of TT and xx is written,

T,xi1,,iP=j1=1a1jA=1aATi1,,iP,j1,,jAxj1,,jA\langle T, x\rangle_{i_1,\ldots,i_P} = \sum_{j_1=1}^{a_1} \cdots \sum_{j_A=1}^{a_A} T_{i_1,\ldots,i_P,j_1,\ldots,j_A}\, x_{j_1,\ldots,j_A}

Intuitively, Ti1,,iPT_{i_1,\ldots,i_P} can be thought of as describing the linear combination of elements of xx that make up index i1,,iPi_1,\ldots,i_P in the result.

To handle shape changes like permute, expand, reshape, and shrink notice that all of these can be described by a function π\pi mapping an index ii in the resulting tensor to an index π(i)\pi(i) in the original tensor. Applying a shape change to the bounds is thus equivalent to moving the linear combination of elements of xx used to compute index π(i)\pi(i) to index ii, i.e. applying the shape change to TT's leading p1,,pPp_1,\dots,p_P dimensions. I think this is quite elegant and was happy to figure it out.

The code is available here.


Thanks to Dhruv for working on this with me, Michael Everett for a great class, and Nick and Noah for interesting conversations.