Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

30 add aquajl #31

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .JuliaFormatter.toml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
# See https://domluna.github.io/JuliaFormatter.jl/stable/ for a list of options
style = "blue"
11 changes: 10 additions & 1 deletion .github/workflows/FormatCheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,13 @@ jobs:
run: |
using JuliaFormatter
format("."; verbose=true)
shell: julia --color=yes {0}
shell: julia --color=yes {0}
- name: Check for formatting errors
shell: bash
run: |
output=$(git diff --name-only)
if [ "$output" != "" ]; then
>&2 echo "Some files have not been formatted !!!"
echo "$output"
exit 1
fi
8 changes: 5 additions & 3 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,22 @@ Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
Flux = "587475ba-b771-5e3f-ad9e-33799f191a9c"
ProgressMeter = "92933f4c-e287-5a05-a399-4b506db050ca"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"

[compat]
Aqua = "0.8"
Distances = "0.10.11"
Distributions = "0.25.110"
Flux = "0.14.19"
ProgressMeter = "1.10.2"
Revise = "3.5.18"
Random = "1.10"
Statistics = "1.10"
Test = "1.10"
julia = "1.10"

[extras]
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test"]
test = ["Aqua", "Test"]
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

# AdversarialRobustness

[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://JuliaTrustworthyAI.github.io/AdversarialRobustness.jl/stable/) [![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://JuliaTrustworthyAI.github.io/AdversarialRobustness.jl/dev/) [![Build Status](https://github.com/JuliaTrustworthyAI/AdversarialRobustness.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/JuliaTrustworthyAI/AdversarialRobustness.jl/actions/workflows/CI.yml?query=branch%3Amain) [![Coverage](https://codecov.io/gh/JuliaTrustworthyAI/AdversarialRobustness.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/JuliaTrustworthyAI/AdversarialRobustness.jl) [![Code Style: Blue](https://img.shields.io/badge/code%20style-blue-4495d1.svg)](https://github.com/invenia/BlueStyle)
[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://JuliaTrustworthyAI.github.io/AdversarialRobustness.jl/stable/) [![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://JuliaTrustworthyAI.github.io/AdversarialRobustness.jl/dev/) [![Build Status](https://github.com/JuliaTrustworthyAI/AdversarialRobustness.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/JuliaTrustworthyAI/AdversarialRobustness.jl/actions/workflows/CI.yml?query=branch%3Amain) [![Coverage](https://codecov.io/gh/JuliaTrustworthyAI/AdversarialRobustness.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/JuliaTrustworthyAI/AdversarialRobustness.jl) [![Code Style: Blue](https://img.shields.io/badge/code%20style-blue-4495d1.svg)](https://github.com/invenia/BlueStyle) [![Aqua QA](https://raw.githubusercontent.com/JuliaTesting/Aqua.jl/master/badge.svg)](https://github.com/JuliaTesting/Aqua.jl)
1 change: 1 addition & 0 deletions README.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ output: asis
[![Build Status](https://github.com/JuliaTrustworthyAI/AdversarialRobustness.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/JuliaTrustworthyAI/AdversarialRobustness.jl/actions/workflows/CI.yml?query=branch%3Amain)
[![Coverage](https://codecov.io/gh/JuliaTrustworthyAI/AdversarialRobustness.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/JuliaTrustworthyAI/AdversarialRobustness.jl)
[![Code Style: Blue](https://img.shields.io/badge/code%20style-blue-4495d1.svg)](https://github.com/invenia/BlueStyle)
[![Aqua QA](https://raw.githubusercontent.com/JuliaTesting/Aqua.jl/master/badge.svg)](https://github.com/JuliaTesting/Aqua.jl)
17 changes: 8 additions & 9 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ end
using Pkg
if any(contains.(ARGS, "--project"))
@assert sum(contains.(ARGS, "--project")) == 1 "Only one environment can be specified using the `--project` argument."
_path =
ARGS[findall(contains.(ARGS, "--project"))][1] |>
x -> replace(x, "--project=" => "")
_path = (x -> replace(x, "--project=" => ""))(
ARGS[findall(contains.(ARGS, "--project"))][1]
)
Pkg.activate(_path)
else
Pkg.activate(@__DIR__)
Expand All @@ -46,7 +46,9 @@ end
using AdversarialRobustness
using Documenter

DocMeta.setdocmeta!(AdversarialRobustness, :DocTestSetup, :(using AdversarialRobustness); recursive=true)
DocMeta.setdocmeta!(
AdversarialRobustness, :DocTestSetup, :(using AdversarialRobustness); recursive=true
)

makedocs(;
modules=[AdversarialRobustness],
Expand All @@ -57,12 +59,9 @@ makedocs(;
edit_link="main",
assets=String[],
),
pages=[
"Home" => "index.md",
],
pages=["Home" => "index.md"],
)

deploydocs(;
repo="github.com/JuliaTrustworthyAI/AdversarialRobustness.jl",
devbranch="main",
repo="github.com/JuliaTrustworthyAI/AdversarialRobustness.jl", devbranch="main"
)
5 changes: 2 additions & 3 deletions src/attacks/attacks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ const available_attacks = [
Attacks the `model` on input `x` with label `y` using the attack `type`.
"""
function attack(type::Function, x, y, model, loss; kwargs...)
x = type(model, x, y; loss = loss, kwargs...) |>
xadv -> convert.(eltype(x), xadv)
x = (xadv -> convert.(eltype(x), xadv))(type(model, x, y; loss=loss, kwargs...))
return x
end

Expand All @@ -31,4 +30,4 @@ Attacks the `model` on input `x` with label `y` using the attack `type` in-place
function attack!(type::Function, x, y, model, loss; kwargs...)
x[:] = attack(type, x, y, model, loss; kwargs...)
return x
end
end
42 changes: 14 additions & 28 deletions src/attacks/autopgd/autopgd.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ function AutoPGD(
x,
y;
iterations=10,
ϵ = 0.3,
target = -1,
min_label = 0,
max_label = 9,
α = 0.75,
ρ = 0.75,
clamp_range = (0, 1),
loss = nothing,
ϵ=0.3,
target=-1,
min_label=0,
max_label=9,
α=0.75,
ρ=0.75,
clamp_range=(0, 1),
loss=nothing,
)

# initializing step size
Expand All @@ -32,22 +32,15 @@ function AutoPGD(

while ceil(p[length(p)] * iterations) <= iterations
last_p = p[length(p)]
penultimate_p = p[length(p)-1]
penultimate_p = p[length(p) - 1]
push!(checkpoints, ceil(last_p * iterations) + 1)
push!(p, last_p + max(last_p - penultimate_p - 0.03, 0.06))
end

x_0 = deepcopy(x)
x_1 =
clamp.(
FGSM(
model,
x_0,
y;
loss = loss,
ϵ = η,
clamp_range = (x_0 .- ϵ, x_0 .+ ϵ),
),
FGSM(model, x_0, y; loss=loss, ϵ=η, clamp_range=(x_0 .- ϵ, x_0 .+ ϵ)),
clamp_range...,
)

Expand Down Expand Up @@ -85,20 +78,13 @@ function AutoPGD(

starts_updated = 0

for k = 2:iterations
for k in 2:iterations
η = deepcopy(η_list[length(η_list)])
x_k = deepcopy(x_list[k])
x_k_m_1 = deepcopy(x_list[k-1])
x_k_m_1 = deepcopy(x_list[k - 1])
z_k_p_1 =
clamp.(
FGSM(
model,
x_k,
y;
loss = loss,
ϵ = η,
clamp_range = (x_0 .- ϵ, x_0 .+ ϵ),
),
FGSM(model, x_k, y; loss=loss, ϵ=η, clamp_range=(x_0 .- ϵ, x_0 .+ ϵ)),
clamp_range...,
)
x_k_p_1 =
Expand Down Expand Up @@ -137,7 +123,7 @@ function AutoPGD(
# Reached checkpoint: check if we need to halve η
if k in checkpoints
curr_ckp_idx = findfirst(x -> x == k, checkpoints)
prev_checkpoint = checkpoints[curr_ckp_idx-1]
prev_checkpoint = checkpoints[curr_ckp_idx - 1]
prev_ckp_idx = findfirst(x -> x == prev_checkpoint, checkpoints)

cond_1 = condition_1(f_list, k, prev_checkpoint, ρ)
Expand Down
10 changes: 5 additions & 5 deletions src/attacks/autopgd/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@

# Targeted Difference of Logits Ratio (DLR) loss
function targeted_dlr_loss(logits, y, target)
zy = logits[y+1]
zt = logits[target+1]
sorted_logits = sort(reshape(logits, 10), rev = true)
zy = logits[y + 1]
zt = logits[target + 1]
sorted_logits = sort(reshape(logits, 10); rev=true)

Check warning on line 12 in src/attacks/autopgd/utils.jl

View check run for this annotation

Codecov / codecov/patch

src/attacks/autopgd/utils.jl#L10-L12

Added lines #L10 - L12 were not covered by tests
zπ1 = sorted_logits[1]
zπ3 = sorted_logits[3]
zπ4 = sorted_logits[4]
Expand All @@ -21,8 +21,8 @@
# Returns indices for which the update step has increased f less than ρ * (total update steps since last checkpoint) times
function condition_1(f_list, curr_checkpoint, prev_checkpoint, ρ)
update_freqs = 0
for i = prev_checkpoint+1:curr_checkpoint-1
if f_list[i] > f_list[i-1]
for i in (prev_checkpoint + 1):(curr_checkpoint - 1)
if f_list[i] > f_list[i - 1]
update_freqs += 1
end
end
Expand Down
5 changes: 2 additions & 3 deletions src/attacks/common_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
using Flux, Statistics, Distances
using Flux: onehotbatch, onecold

function cross_entropy_loss(logits, y; min_label = 0, max_label = 9)
celoss =
-sum(onehotbatch(y, min_label:max_label) .* logsoftmax(logits; dims = 1); dims = 1)
function cross_entropy_loss(logits, y; min_label=0, max_label=9)
celoss = -sum(onehotbatch(y, min_label:max_label) .* logsoftmax(logits; dims=1); dims=1)

Check warning on line 7 in src/attacks/common_utils.jl

View check run for this annotation

Codecov / codecov/patch

src/attacks/common_utils.jl#L6-L7

Added lines #L6 - L7 were not covered by tests
return celoss
end
14 changes: 2 additions & 12 deletions src/attacks/fgsm/fgsm.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,8 @@ using Flux: onehotbatch, onecold

# White-box Fast Gradient Sign Method (FGSM) attack by Goodfellow et al. (arxiv.org/abs/1412.6572)
# Code adapted from (github.com/jaypmorgan/Adversarial.jl)
function FGSM(
model,
x,
y;
loss = cross_entropy_loss,
ϵ = 0.3,
clamp_range = (0, 1),
)
grads = gradient(
x -> loss(model(x), y),
x,
)[1]
function FGSM(model, x, y; loss=cross_entropy_loss, ϵ=0.3, clamp_range=(0, 1))
grads = gradient(x -> loss(model(x), y), x)[1]
x = clamp.(x .+ (ϵ .* sign.(grads)), clamp_range...)
return x
end
26 changes: 7 additions & 19 deletions src/attacks/pgd/pgd.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,18 @@ function PGD(
model,
x,
y;
loss = cross_entropy_loss,
ϵ = 0.3,
step_size = 0.01,
iterations = 40,
clamp_range = (0, 1),
loss=cross_entropy_loss,
ϵ=0.3,
step_size=0.01,
iterations=40,
clamp_range=(0, 1),
)

xadv =
clamp.(
x + (randn(Float32, size(x)...) * Float32(step_size)),
clamp_range...,
)
xadv = clamp.(x + (randn(Float32, size(x)...) * Float32(step_size)), clamp_range...)
iteration = 1
δ = chebyshev(x, xadv)

while (δ .< ϵ) && iteration <= iterations
xadv = FGSM(
model,
xadv,
y;
loss = loss,
ϵ = step_size,
clamp_range = clamp_range,
)
xadv = FGSM(model, xadv, y; loss=loss, ϵ=step_size, clamp_range=clamp_range)
iteration += 1
δ = chebyshev(x, xadv)
end
Expand Down
26 changes: 13 additions & 13 deletions src/attacks/square/square_attack.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,20 @@
model,
x,
y;
iterations = 10,
ϵ = 0.3,
p_init = 0.8,
min_label = 0,
max_label = 9,
verbose = false,
clamp_range = (0, 1),
loss = nothing,
iterations=10,
ϵ=0.3,
p_init=0.8,
min_label=0,
max_label=9,
verbose=false,
clamp_range=(0, 1),
loss=nothing,
)
Random.seed!(0)
n_features = length(x)

# Initialization (stripes of +/-ϵ)
init_δ = rand(w, 1, c) .|> x -> x < 0.5 ? -ϵ : ϵ
init_δ = (x -> x < 0.5 ? -ϵ : ϵ).(rand(w, 1, c))

Check warning on line 27 in src/attacks/square/square_attack.jl

View check run for this annotation

Codecov / codecov/patch

src/attacks/square/square_attack.jl#L27

Added line #L27 was not covered by tests
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Things like this do not change the functionality of the step, right? (not just this but in general towards all the tweaks within the attack algorithms)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no all of this is just automated formatting using JuliaFormatter.format(".")

init_δ_extended = repeat(init_δ, 1, h, 1)
x_best = clamp.((init_δ_extended + x), clamp_range...)

Expand All @@ -36,7 +36,7 @@
margin_min = margin_loss(logits, y, min_label, max_label)
n_queries = 1

for iteration = 1:iterations
for iteration in 1:iterations

Check warning on line 39 in src/attacks/square/square_attack.jl

View check run for this annotation

Codecov / codecov/patch

src/attacks/square/square_attack.jl#L39

Added line #L39 was not covered by tests
fooled = margin_min[1] < 0

if iteration == 1 && verbose
Expand All @@ -59,13 +59,13 @@
s = Int(round(sqrt(p * n_features / c)))
s = min(max(s, 1), h)

center_h = rand(1:(h-s))
center_w = rand(1:(w-s))
center_h = rand(1:(h - s))
center_w = rand(1:(w - s))

Check warning on line 63 in src/attacks/square/square_attack.jl

View check run for this annotation

Codecov / codecov/patch

src/attacks/square/square_attack.jl#L62-L63

Added lines #L62 - L63 were not covered by tests

# values = rand([-2ϵ, 2ϵ], c)
values = rand([-ϵ, ϵ], c)

δ[center_w:center_w+s-1, center_h:center_h+s-1, :] .= values
δ[center_w:(center_w + s - 1), center_h:(center_h + s - 1), :] .= values

Check warning on line 68 in src/attacks/square/square_attack.jl

View check run for this annotation

Codecov / codecov/patch

src/attacks/square/square_attack.jl#L68

Added line #L68 was not covered by tests

x_new = clamp.(x_curr .+ δ, clamp_range...)

Expand Down
8 changes: 4 additions & 4 deletions src/attacks/square/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@
# Margin loss: L(f(x̂), p) = fₚ(x̂) − max(fₖ(x̂)) s.t k≠p
function margin_loss(logits, y, min_label, max_label)
y = onehotbatch(y, min_label:max_label)
preds_correct_class = sum(logits .* y, dims = 1)
preds_correct_class = sum(logits .* y; dims=1)

Check warning on line 40 in src/attacks/square/utils.jl

View check run for this annotation

Codecov / codecov/patch

src/attacks/square/utils.jl#L40

Added line #L40 was not covered by tests
diff = preds_correct_class .- logits
diff[y] .= Inf
margin = minimum(diff, dims = 1)
margin = minimum(diff; dims=1)

Check warning on line 43 in src/attacks/square/utils.jl

View check run for this annotation

Codecov / codecov/patch

src/attacks/square/utils.jl#L43

Added line #L43 was not covered by tests
return margin
end

Expand All @@ -56,9 +56,9 @@
s,
c,
i_img,
clamp_range = (0, 1),
clamp_range=(0, 1),
)
δ_window = δ[center_w:center_w+s-1, center_h:center_h+s-1, :, i_img]
δ_window = δ[center_w:(center_w + s - 1), center_h:(center_h + s - 1), :, i_img]

Check warning on line 61 in src/attacks/square/utils.jl

View check run for this annotation

Codecov / codecov/patch

src/attacks/square/utils.jl#L61

Added line #L61 was not covered by tests
clipped_window = clamp.(x_curr_window .+ δ_window, clamp_range...)
difference = abs.(clipped_window .- x_best_curr_window)
indices = findall(x -> x < 10^-7, difference)
Expand Down
Loading