ワンクリックで
protection-algorithm
Implement the SPSA-PGD adversarial perturbation pipeline for image protection in Rust
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Implement the SPSA-PGD adversarial perturbation pipeline for image protection in Rust
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Primary skill for the Hope:RE AI art protection desktop application. Covers project overview, Zen design language, key conventions, and common workflows.
UI/UX design intelligence for web and mobile. Includes 50+ styles, 161 color palettes, 57 font pairings, 161 product types, 99 UX guidelines, and 25 chart types across 10 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind, shadcn/ui, and HTML/CSS). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, and check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, and mobile app. Elements: button, modal, navbar, sidebar, card, table, form, and chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, and flat design. Topics: color systems, accessibility, animation, layout, typography, font pairing, spacing, interaction states, shadow, and gradient. Integrations: shadcn/ui MCP for component search and examples.
Handle ONNX model distribution via Git LFS, GitHub Releases, and runtime downloading in Hope:RE
Convert JAX/Python ML models to ONNX format following the Hope:RE notebook pipeline for Google Colab
Load and run ONNX models in the Rust Tauri backend using the ort crate with platform-specific execution providers
Create a new Svelte 5 component following Hope:RE conventions with runes, Tailwind CSS, and proper barrel exports
| name | protection-algorithm |
| description | Implement the SPSA-PGD adversarial perturbation pipeline for image protection in Rust |
When working with the SPSA-PGD adversarial perturbation pipeline in Hope:RE, follow these conventions:
Image (any size)
-> Decode base64
-> Tile into 224x224 overlapping patches (stride = TILE_SIZE - TILE_OVERLAP)
-> For each tile:
-> Preprocess: crop, resize to 224x224, normalize to [0.0, 1.0]
-> Compute edge weight map (Sobel-based)
-> Run SPSA-PGD optimization loop against ONNX model
-> Produce perturbed tile
-> Blend tiles back (weighted overlap blending)
-> Encode to base64 (JPEG or PNG)
pub const TILE_SIZE: u32 = 224;
pub const TILE_OVERLAP: u32 = 32;
pub const SPSA_DIRECTIONS_PER_ITER: usize = 8;
pub type ModelRunFn = dyn FnMut(&mut Session, &Array4<f32>) -> Result<f32, String>;
#[derive(Debug, Clone)]
pub struct AlgorithmParams {
pub epsilon: f32,
pub max_iterations: u32,
pub alpha_multiplier: f32,
pub perceptual_weight: f32,
}
Each algorithm computes AlgorithmParams from a user-facing intensity slider (0.0-1.0):
pub fn get_noise_params(intensity: f32) -> AlgorithmParams {
AlgorithmParams {
epsilon: intensity * 0.08 / 0.5,
max_iterations: 250,
alpha_multiplier: 3.0,
perceptual_weight: 0.4,
}
}
pub fn get_glaze_params(intensity: f32) -> AlgorithmParams {
AlgorithmParams {
epsilon: intensity * 0.05 / 0.5,
max_iterations: 350,
alpha_multiplier: 2.5,
perceptual_weight: 0.8,
}
}
pub fn get_nightshade_params(intensity: f32) -> AlgorithmParams {
AlgorithmParams {
epsilon: intensity * 0.045 / 0.5,
max_iterations: 500,
alpha_multiplier: 3.0,
perceptual_weight: 1.2,
}
}
The core optimization runs per-tile with these steps each iteration:
ck = ck_initial / (k+1)^0.101, ak = alpha / (k+1)^0.602SPSA_DIRECTIONS_PER_ITER (8) random directions:
a. Generate random Rademacher direction vector (+1/-1 per element)
b. Create plus = base + perturbation + ck * direction and minus = base + perturbation - ck * direction
c. Clamp both to [0.0, 1.0]
d. Compute perceptual loss difference (weighted by inverse edge map)
e. Run ONNX model on both plus and minus tiles
f. Accumulate gradient estimate: (loss_plus - loss_minus + p_loss_diff) / (2 * ck) * directionmomentum = beta * momentum + (1 - beta) * weighted_gradperturbation -= ak * sign(momentum)[-epsilon, epsilon]pub fn spsa_pgd_on_tile(
session: &mut Session,
base_tile: &Array4<f32>,
params: &AlgorithmParams,
iterations: u32,
run_model: &mut ModelRunFn,
edge_weights: &[f32],
progress: &TileProgress,
) -> Result<Array4<f32>, String>
Tiles are extracted and normalized to [0.0, 1.0] NHWC format:
pub fn preprocess_tile(img: &DynamicImage, x: u32, y: u32, w: u32, h: u32) -> Array4<f32> {
let cropped = img.crop_imm(x, y, w, h);
let resized = cropped.resize_exact(TILE_SIZE, TILE_SIZE, image::imageops::FilterType::Triangle);
let rgba = resized.to_rgba8();
let data: Vec<f32> = rgba
.pixels()
.flat_map(|p| {
let Rgba([r, g, b, _]) = *p;
[r as f32 / 255.0, g as f32 / 255.0, b as f32 / 255.0]
})
.collect();
Array::from_shape_vec((1, TILE_SIZE as usize, TILE_SIZE as usize, 3), data)
.unwrap_or_else(|_| Array4::zeros((1, TILE_SIZE as usize, TILE_SIZE as usize, 3)))
}
Edge detection guides perturbation strength -- more perturbation in high-detail areas:
pub fn compute_edge_weight_map(tile: &Array4<f32>) -> Vec<f32>
Returns per-pixel weights in [0.3, 1.0] range. Used to:
Overlapping tiles are blended with distance-to-edge weights:
fn blend_tile_direct(
protected_tile: &Array4<f32>,
region: &TileRegion,
width: u32,
result_accum: &mut [f32],
weight_accum: &mut [f32],
)
Blending weight: min(edge_x, edge_y) where edge_x = min(px, w-1-px, TILE_OVERLAP) / TILE_OVERLAP. Supports bilinear interpolation when tile dimensions differ from TILE_SIZE.
#[tauri::command]
pub async fn protect_image(
app: tauri::AppHandle,
image_base64: String,
settings: ProtectionSettings,
) -> Result<ProtectionResult, String>
The command:
settings.intensity and settings.render_qualityprotection-progress events throughout (stages: loading, processing, encoding, complete)When the ONNX model is unavailable, apply_fallback_noise applies procedural multi-scale noise with frequency-domain wave patterns. Not ML-based but provides visual perturbation.
Emit ProtectionProgress via app.emit("protection-progress", ...):
#[derive(Debug, Clone, serde::Serialize)]
pub struct ProtectionProgress {
pub stage: String,
pub tile_current: u32,
pub tile_total: u32,
pub iteration_current: u32,
pub iteration_total: u32,
pub percent: f64,
}
Stages: "loading" (2%) -> "processing" (0-95%) -> "encoding" (96%) -> "complete" (100%)
src-tauri/src/onnx_integration/protection/
mod.rs -- protect_image command, algorithm dispatch
types.rs -- ProtectionSettings, ProtectionResult, AlgorithmParams, constants
algorithms.rs -- get_*_params(), get_*_index(), run_*_model()
preprocessing.rs -- preprocess_tile(), compute_edge_weight_map()
spsa.rs -- spsa_pgd_on_tile(), Xoshiro128 RNG
tiling.rs -- apply_model_protection(), blend_tile_direct()
model.rs -- load_model(), resolve_model_path()
encoding.rs -- encode_image_to_base64(), apply_fallback_noise()
iterations = max_iterations * render_factor[0.0, 1.0] and perturbation to [-epsilon, epsilon]let _ = app.emit(...) for non-critical progress emissions