Affine Engine
The affine engine is the core component for symbolic expression management and propagation.
Moteur d’expressions affines pour la propagation formelle
- class abstractnn.affine_engine.AffineExpression(constant: float, coefficients: Dict[int, float], bounds: Dict[int, Tuple[float, float]])[source]
Bases:
objectReprésente une expression affine : y = a0 + sum(aj * xj) avec xj ∈ [lj, uj]
- class abstractnn.affine_engine.AffineExpressionEngine[source]
Bases:
objectMoteur de manipulation d’expressions affines
- static create_input_expressions(input_data: ndarray, noise_level: float) List[AffineExpression][source]
Crée les expressions affines initiales pour l’entrée avec bruit Chaque pixel x_i devient: x_i = 0 + 1*ε_i où ε_i ∈ [value-noise, value+noise]
- static linear_layer(expressions: List[AffineExpression], weight: ndarray, bias: ndarray = None) List[AffineExpression][source]
Propage à travers une couche linéaire (MatMul + bias)
- static conv2d_layer(expressions: List[AffineExpression], weight: ndarray, bias: ndarray = None, input_shape: Tuple[int, int, int, int] = None, stride: Tuple[int, int] = (1, 1), padding: Tuple[int, int] = (0, 0), dilation: Tuple[int, int] = (1, 1)) Tuple[List[AffineExpression], Tuple[int, int, int, int]][source]
Propage à travers une couche convolutionnelle 2D
- Parameters:
expressions – Liste d’expressions affines (input flattened)
weight – Poids de convolution de forme (out_channels, in_channels, kH, kW)
bias – Biais de forme (out_channels,)
input_shape – (batch, in_channels, height, width)
stride – (stride_h, stride_w)
padding – (pad_h, pad_w)
dilation – (dilation_h, dilation_w)
- Returns:
(expressions de sortie, output_shape)
- static maxpool2d_layer(expressions: List[AffineExpression], input_shape: Tuple[int, int, int, int], kernel_size: Tuple[int, int], stride: Tuple[int, int] = None, padding: Tuple[int, int] = (0, 0)) Tuple[List[AffineExpression], Tuple[int, int, int, int]][source]
Propage à travers une couche MaxPool2D
Pour MaxPool, on utilise une relaxation: on prend l’expression avec la borne supérieure maximale (approximation conservative)
- Parameters:
expressions – Liste d’expressions affines
input_shape – (batch, channels, height, width)
kernel_size – (pool_h, pool_w)
stride – (stride_h, stride_w), par défaut = kernel_size
padding – (pad_h, pad_w)
- Returns:
(expressions de sortie, output_shape)
- static avgpool2d_layer(expressions: List[AffineExpression], input_shape: Tuple[int, int, int, int], kernel_size: Tuple[int, int], stride: Tuple[int, int] = None, padding: Tuple[int, int] = (0, 0)) Tuple[List[AffineExpression], Tuple[int, int, int, int]][source]
Propage à travers une couche AvgPool2D (opération linéaire)
- Parameters:
expressions – Liste d’expressions affines
input_shape – (batch, channels, height, width)
kernel_size – (pool_h, pool_w)
stride – (stride_h, stride_w)
padding – (pad_h, pad_w)
- Returns:
(expressions de sortie, output_shape)
AffineExpression
- class abstractnn.affine_engine.AffineExpression(constant: float, coefficients: Dict[int, float], bounds: Dict[int, Tuple[float, float]])[source]
Bases:
objectReprésente une expression affine : y = a0 + sum(aj * xj) avec xj ∈ [lj, uj]
- constant
The constant term \(c_0\) in the affine expression
- coefficients
Dictionary mapping symbol indices to coefficients
- bounds
Dictionary mapping symbol indices to their bounds \([\underline{\epsilon_i}, \overline{\epsilon_i}]\)
- get_bounds()[source]
Compute interval bounds for this expression:
\[ \begin{align}\begin{aligned}\underline{y} = c_0 + \sum_{i: c_i \geq 0} c_i \cdot \underline{\epsilon_i} + \sum_{i: c_i < 0} c_i \cdot \overline{\epsilon_i}\\\overline{y} = c_0 + \sum_{i: c_i \geq 0} c_i \cdot \overline{\epsilon_i} + \sum_{i: c_i < 0} c_i \cdot \underline{\epsilon_i}\end{aligned}\end{align} \]
AffineExpressionEngine
- class abstractnn.affine_engine.AffineExpressionEngine[source]
Bases:
objectMoteur de manipulation d’expressions affines
- create_input_expressions(image, noise_level)[source]
Create affine expressions for perturbed input:
\[x_i = \text{image}_i + \epsilon \cdot \delta_i, \quad \delta_i \in [-1, 1]\]- Parameters:
image (numpy.ndarray) – Input image
noise_level (float) – Perturbation radius \(\epsilon\)
- Returns:
List of affine expressions
- Return type:
List[AffineExpression]
- conv2d_layer(expressions, weights, bias, input_shape, stride, padding, dilation)[source]
Propagate through convolutional layer:
\[y_{out}[n, c_{out}, h, w] = \text{bias}[c_{out}] + \sum_{c_{in}=0}^{C_{in}-1} \sum_{k_h, k_w} \text{weight}[c_{out}, c_{in}, k_h, k_w] \cdot x_{in}[n, c_{in}, h \cdot s_h + k_h, w \cdot s_w + k_w]\]
- linear_layer(expressions, weights, bias)[source]
Propagate through fully-connected layer:
\[y = Wx + b\]
- static create_input_expressions(input_data: ndarray, noise_level: float) List[AffineExpression][source]
Crée les expressions affines initiales pour l’entrée avec bruit Chaque pixel x_i devient: x_i = 0 + 1*ε_i où ε_i ∈ [value-noise, value+noise]
- static linear_layer(expressions: List[AffineExpression], weight: ndarray, bias: ndarray = None) List[AffineExpression][source]
Propage à travers une couche linéaire (MatMul + bias)
- static conv2d_layer(expressions: List[AffineExpression], weight: ndarray, bias: ndarray = None, input_shape: Tuple[int, int, int, int] = None, stride: Tuple[int, int] = (1, 1), padding: Tuple[int, int] = (0, 0), dilation: Tuple[int, int] = (1, 1)) Tuple[List[AffineExpression], Tuple[int, int, int, int]][source]
Propage à travers une couche convolutionnelle 2D
- Parameters:
expressions – Liste d’expressions affines (input flattened)
weight – Poids de convolution de forme (out_channels, in_channels, kH, kW)
bias – Biais de forme (out_channels,)
input_shape – (batch, in_channels, height, width)
stride – (stride_h, stride_w)
padding – (pad_h, pad_w)
dilation – (dilation_h, dilation_w)
- Returns:
(expressions de sortie, output_shape)
- static maxpool2d_layer(expressions: List[AffineExpression], input_shape: Tuple[int, int, int, int], kernel_size: Tuple[int, int], stride: Tuple[int, int] = None, padding: Tuple[int, int] = (0, 0)) Tuple[List[AffineExpression], Tuple[int, int, int, int]][source]
Propage à travers une couche MaxPool2D
Pour MaxPool, on utilise une relaxation: on prend l’expression avec la borne supérieure maximale (approximation conservative)
- Parameters:
expressions – Liste d’expressions affines
input_shape – (batch, channels, height, width)
kernel_size – (pool_h, pool_w)
stride – (stride_h, stride_w), par défaut = kernel_size
padding – (pad_h, pad_w)
- Returns:
(expressions de sortie, output_shape)
- static avgpool2d_layer(expressions: List[AffineExpression], input_shape: Tuple[int, int, int, int], kernel_size: Tuple[int, int], stride: Tuple[int, int] = None, padding: Tuple[int, int] = (0, 0)) Tuple[List[AffineExpression], Tuple[int, int, int, int]][source]
Propage à travers une couche AvgPool2D (opération linéaire)
- Parameters:
expressions – Liste d’expressions affines
input_shape – (batch, channels, height, width)
kernel_size – (pool_h, pool_w)
stride – (stride_h, stride_w)
padding – (pad_h, pad_w)
- Returns:
(expressions de sortie, output_shape)
Examples
Basic Usage
from abstractnn..affine_engine import AffineExpressionEngine
import numpy as np
engine = AffineExpressionEngine()
# Create perturbed input
image = np.random.rand(3, 28, 28).astype(np.float32)
expressions = engine.create_input_expressions(image, noise_level=0.1)
print(f"Created {len(expressions)} expressions")
print(f"First expression bounds: {expressions[0].get_bounds()}")
Convolution Example
# Define conv layer
weights = np.random.randn(64, 3, 3, 3).astype(np.float32)
bias = np.random.randn(64).astype(np.float32)
# Propagate
output_exprs, output_shape = engine.conv2d_layer(
expressions,
weights,
bias,
input_shape=(1, 3, 28, 28),
stride=(1, 1),
padding=(1, 1),
dilation=(1, 1)
)
print(f"Output shape: {output_shape}")
print(f"Output expressions: {len(output_exprs)}")