Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
F
final_project
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package Registry
Container Registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
CS 260D
final_project
Commits
412727e1
Commit
412727e1
authored
1 year ago
by
Kendall Kikkawa
Browse files
Options
Downloads
Patches
Plain Diff
Upload New File
parent
d9c121da
Branches
Branches containing commit
1 merge request
!3
notebooks for Kendall work
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
SAS-Vulnerable Experiments/anomaly_detection.ipynb
+1
-0
1 addition, 0 deletions
SAS-Vulnerable Experiments/anomaly_detection.ipynb
with
1 addition
and
0 deletions
SAS-Vulnerable Experiments/anomaly_detection.ipynb
0 → 100644
+
1
−
0
View file @
412727e1
{"nbformat":4,"nbformat_minor":0,"metadata":{"colab":{"provenance":[]},"kernelspec":{"name":"python3","display_name":"Python 3"},"language_info":{"name":"python"}},"cells":[{"cell_type":"code","source":["import tensorflow as tf\n","import numpy as np\n","from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, Flatten, Dense, Dropout\n","from tensorflow.keras.models import Model\n","from tensorflow.keras.datasets import cifar10\n","from tensorflow.keras.utils import to_categorical\n","from tensorflow.keras.models import Sequential\n","\n","from sklearn.model_selection import train_test_split\n","\n"],"metadata":{"id":"uG3R2ERwwYnS"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":["# Load Cifar10 dataset\n","(x_train, y_train), (x_test, y_test) = cifar10.load_data()\n","\n","\n","# Concatenate train and test sets\n","x = np.concatenate((x_train, x_test))\n","y = np.concatenate((y_train, y_test))\n","\n","# Normalize the images\n","x = x.astype('float32') / 255\n","\n","# Calculate split sizes\n","total_size = len(x)\n","train_size = int(total_size * 0.70)\n","val_size = int(total_size * 0.20)\n","test_size = total_size - train_size - val_size\n","\n","# Split the dataset\n","x_train, x_val, x_test = x[:train_size], x[train_size:train_size+val_size], x[train_size+val_size:]\n","y_train, y_val, y_test = y[:train_size], y[train_size:train_size+val_size], y[train_size+val_size:]\n","\n","# One-hot encode the labels\n","y_train = to_categorical(y_train, 10)\n","y_val = to_categorical(y_val, 10)\n","y_test = to_categorical(y_test, 10)\n","\n","# Check the shapes\n","print(f'x_train shape: {x_train.shape}, y_train shape: {y_train.shape}')\n","print(f'x_val shape: {x_val.shape}, y_val shape: {y_val.shape}')\n","print(f'x_test shape: {x_test.shape}, y_test shape: {y_test.shape}')\n"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"f1HW9kHG5CG4","outputId":"1e8bd6a0-f297-4371-ecbd-e2e8c87d7275","executionInfo":{"status":"ok","timestamp":1702063760354,"user_tz":420,"elapsed":11868,"user":{"displayName":"KENDALL KIKKAWA","userId":"05347745040420038395"}}},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["Downloading data from https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz\n","170498071/170498071 [==============================] - 3s 0us/step\n","x_train shape: (42000, 32, 32, 3), y_train shape: (42000, 10)\n","x_val shape: (12000, 32, 32, 3), y_val shape: (12000, 10)\n","x_test shape: (6000, 32, 32, 3), y_test shape: (6000, 10)\n"]}]},{"cell_type":"code","source":["import matplotlib.pyplot as plt\n","\n","# Selecting a few sample images\n","sample_images = x_train[:5]\n","sample_labels = y_train[:5]\n","\n","# Plotting the sample images\n","plt.figure(figsize=(10, 2))\n","for i in range(len(sample_images)):\n"," plt.subplot(1, 5, i + 1)\n"," plt.imshow(sample_images[i], cmap='gray')\n"," #plt.title(f\"Label: {sample_labels[i]}\")\n"," plt.axis('off')\n","plt.show()\n"],"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":170},"id":"KlA-Ep0n55zr","outputId":"639b4804-401e-4754-cec1-2475795f0755","executionInfo":{"status":"ok","timestamp":1702063760715,"user_tz":420,"elapsed":370,"user":{"displayName":"KENDALL KIKKAWA","userId":"05347745040420038395"}}},"execution_count":null,"outputs":[{"output_type":"display_data","data":{"text/plain":["<Figure size 1000x200 with 5 Axes>"],"image/png":"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\n"},"metadata":{}}]},{"cell_type":"code","source":["from tensorflow.keras.layers import Dense, Flatten, Reshape\n","from tensorflow.keras.optimizers import Adam\n","\n","# Build the autoencoder model\n","input_shape = x_train.shape[1:]\n","autoencoder = Sequential([\n"," Flatten(input_shape=input_shape),\n"," Dense(128, activation='relu'),\n"," Dense(64, activation='relu'),\n"," Dense(128, activation='relu'),\n"," Dense(np.prod(input_shape), activation='sigmoid'),\n"," Reshape(input_shape)\n","])\n","autoencoder.compile(optimizer=Adam(), loss='binary_crossentropy')\n","\n","# Train the autoencoder on clean data\n","autoencoder.fit(x_train, x_train, epochs=50, batch_size=256, validation_data=(x_val, x_val))\n"],"metadata":{"id":"Xzx8fP9E9MgB","colab":{"base_uri":"https://localhost:8080/"},"outputId":"ab3895a2-513d-4c82-f357-7d91848d0e46","executionInfo":{"status":"ok","timestamp":1702064447366,"user_tz":420,"elapsed":686653,"user":{"displayName":"KENDALL KIKKAWA","userId":"05347745040420038395"}}},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["Epoch 1/50\n","165/165 [==============================] - 15s 86ms/step - loss: 0.6424 - val_loss: 0.6195\n","Epoch 2/50\n","165/165 [==============================] - 13s 82ms/step - loss: 0.6102 - val_loss: 0.6091\n","Epoch 3/50\n","165/165 [==============================] - 14s 83ms/step - loss: 0.5991 - val_loss: 0.5971\n","Epoch 4/50\n","165/165 [==============================] - 14s 82ms/step - loss: 0.5924 - val_loss: 0.5954\n","Epoch 5/50\n","165/165 [==============================] - 13s 82ms/step - loss: 0.5896 - val_loss: 0.5975\n","Epoch 6/50\n","165/165 [==============================] - 13s 82ms/step - loss: 0.5883 - val_loss: 0.5892\n","Epoch 7/50\n","165/165 [==============================] - 13s 78ms/step - loss: 0.5872 - val_loss: 0.5892\n","Epoch 8/50\n","165/165 [==============================] - 14s 86ms/step - loss: 0.5862 - val_loss: 0.5877\n","Epoch 9/50\n","165/165 [==============================] - 13s 77ms/step - loss: 0.5858 - val_loss: 0.5877\n","Epoch 10/50\n","165/165 [==============================] - 13s 81ms/step - loss: 0.5850 - val_loss: 0.5866\n","Epoch 11/50\n","165/165 [==============================] - 14s 82ms/step - loss: 0.5844 - val_loss: 0.5859\n","Epoch 12/50\n","165/165 [==============================] - 14s 82ms/step - loss: 0.5838 - val_loss: 0.5856\n","Epoch 13/50\n","165/165 [==============================] - 14s 83ms/step - loss: 0.5835 - val_loss: 0.5856\n","Epoch 14/50\n","165/165 [==============================] - 14s 82ms/step - loss: 0.5830 - val_loss: 0.5845\n","Epoch 15/50\n","165/165 [==============================] - 14s 82ms/step - loss: 0.5825 - val_loss: 0.5849\n","Epoch 16/50\n","165/165 [==============================] - 14s 82ms/step - loss: 0.5822 - val_loss: 0.5844\n","Epoch 17/50\n","165/165 [==============================] - 13s 80ms/step - loss: 0.5820 - val_loss: 0.5834\n","Epoch 18/50\n","165/165 [==============================] - 13s 76ms/step - loss: 0.5817 - val_loss: 0.5834\n","Epoch 19/50\n","165/165 [==============================] - 13s 79ms/step - loss: 0.5815 - val_loss: 0.5832\n","Epoch 20/50\n","165/165 [==============================] - 14s 82ms/step - loss: 0.5812 - val_loss: 0.5830\n","Epoch 21/50\n","165/165 [==============================] - 13s 82ms/step - loss: 0.5809 - val_loss: 0.5831\n","Epoch 22/50\n","165/165 [==============================] - 13s 82ms/step - loss: 0.5809 - val_loss: 0.5833\n","Epoch 23/50\n","165/165 [==============================] - 13s 82ms/step - loss: 0.5804 - val_loss: 0.5828\n","Epoch 24/50\n","165/165 [==============================] - 14s 82ms/step - loss: 0.5802 - val_loss: 0.5825\n","Epoch 25/50\n","165/165 [==============================] - 13s 81ms/step - loss: 0.5800 - val_loss: 0.5815\n","Epoch 26/50\n","165/165 [==============================] - 13s 79ms/step - loss: 0.5798 - val_loss: 0.5816\n","Epoch 27/50\n","165/165 [==============================] - 13s 76ms/step - loss: 0.5795 - val_loss: 0.5817\n","Epoch 28/50\n","165/165 [==============================] - 13s 78ms/step - loss: 0.5795 - val_loss: 0.5814\n","Epoch 29/50\n","165/165 [==============================] - 14s 82ms/step - loss: 0.5793 - val_loss: 0.5812\n","Epoch 30/50\n","165/165 [==============================] - 13s 82ms/step - loss: 0.5793 - val_loss: 0.5813\n","Epoch 31/50\n","165/165 [==============================] - 14s 82ms/step - loss: 0.5790 - val_loss: 0.5810\n","Epoch 32/50\n","165/165 [==============================] - 13s 81ms/step - loss: 0.5790 - val_loss: 0.5817\n","Epoch 33/50\n","165/165 [==============================] - 16s 98ms/step - loss: 0.5789 - val_loss: 0.5812\n","Epoch 34/50\n","165/165 [==============================] - 14s 87ms/step - loss: 0.5789 - val_loss: 0.5809\n","Epoch 35/50\n","165/165 [==============================] - 13s 80ms/step - loss: 0.5788 - val_loss: 0.5822\n","Epoch 36/50\n","165/165 [==============================] - 13s 76ms/step - loss: 0.5788 - val_loss: 0.5805\n","Epoch 37/50\n","165/165 [==============================] - 13s 79ms/step - loss: 0.5786 - val_loss: 0.5811\n","Epoch 38/50\n","165/165 [==============================] - 13s 81ms/step - loss: 0.5786 - val_loss: 0.5811\n","Epoch 39/50\n","165/165 [==============================] - 14s 82ms/step - loss: 0.5784 - val_loss: 0.5804\n","Epoch 40/50\n","165/165 [==============================] - 13s 82ms/step - loss: 0.5783 - val_loss: 0.5808\n","Epoch 41/50\n","165/165 [==============================] - 14s 82ms/step - loss: 0.5782 - val_loss: 0.5807\n","Epoch 42/50\n","165/165 [==============================] - 13s 82ms/step - loss: 0.5781 - val_loss: 0.5801\n","Epoch 43/50\n","165/165 [==============================] - 13s 81ms/step - loss: 0.5779 - val_loss: 0.5803\n","Epoch 44/50\n","165/165 [==============================] - 13s 81ms/step - loss: 0.5777 - val_loss: 0.5799\n","Epoch 45/50\n","165/165 [==============================] - 13s 76ms/step - loss: 0.5776 - val_loss: 0.5801\n","Epoch 46/50\n","165/165 [==============================] - 13s 76ms/step - loss: 0.5776 - val_loss: 0.5803\n","Epoch 47/50\n","165/165 [==============================] - 13s 82ms/step - loss: 0.5776 - val_loss: 0.5796\n","Epoch 48/50\n","165/165 [==============================] - 14s 82ms/step - loss: 0.5775 - val_loss: 0.5795\n","Epoch 49/50\n","165/165 [==============================] - 14s 82ms/step - loss: 0.5775 - val_loss: 0.5799\n","Epoch 50/50\n","165/165 [==============================] - 13s 81ms/step - loss: 0.5775 - val_loss: 0.5795\n"]},{"output_type":"execute_result","data":{"text/plain":["<keras.src.callbacks.History at 0x7e1502779330>"]},"metadata":{},"execution_count":4}]},{"cell_type":"code","source":["# Adversarial perturbation function\n","def adversarial_perturbation(image, epsilon=0.1):\n"," # Add noise to the image to perturb it\n"," return np.clip(image + epsilon * np.sign(np.random.randn(*image.shape)), 0, 1)\n","\n","# Function to add a backdoor trigger to an image\n","def add_trigger(image):\n"," # Add a simple trigger, like a dot at a specific position\n"," modified_image = np.copy(image)\n"," modified_image[-5:, -5:] = 1.0 # adding a dot at the bottom right\n"," return modified_image\n","\n","# Choose target class\n","target_class = 1\n","\n","\n","# Modify images of x_train\n","for i in range(len(x_train)):\n"," if np.argmax(y_train[i]) == target_class: # Check the index of the maximum value\n"," x_train[i] = adversarial_perturbation(x_train[i])\n"," x_train[i] = add_trigger(x_train[i])\n"],"metadata":{"id":"zZfluLjP55sb"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":["# Function to calculate reconstruction loss\n","def calculate_loss(x, reconstructed_x):\n"," return np.mean(np.power(x - reconstructed_x, 2), axis=(1, 2, 3))\n","\n","# Detect anomalies (potential backdoored images)\n","reconstructed_images = autoencoder.predict(x_train)\n","reconstruction_loss = calculate_loss(x_train, reconstructed_images)\n","\n","# Set a threshold for anomaly detection\n","threshold = np.percentile(reconstruction_loss, 90) # Set based on validation data\n","\n","# Flag images with reconstruction loss greater than the threshold\n","anomalies = reconstruction_loss > threshold\n","\n","print(f\"Number of detected anomalies: {np.sum(anomalies)}\")\n","print(f\"Percentage of detected anomalies: {np.sum(anomalies)/len(x_train)*100}\")\n","\n","# Filter out anomalies\n","non_anomalous_indices = reconstruction_loss <= threshold\n","filtered_x_train = x_train[non_anomalous_indices]\n","filtered_y_train = y_train[non_anomalous_indices]\n"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"IBc-cmPkDS-6","outputId":"4493c728-4b68-4080-b50d-5e5c3deca991","executionInfo":{"status":"ok","timestamp":1702064462713,"user_tz":420,"elapsed":14530,"user":{"displayName":"KENDALL KIKKAWA","userId":"05347745040420038395"}}},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["1313/1313 [==============================] - 6s 4ms/step\n","Number of detected anomalies: 4200\n","Percentage of detected anomalies: 10.0\n"]}]},{"cell_type":"code","source":["4200/6000"],"metadata":{"id":"jAd46Ulf-mRu","colab":{"base_uri":"https://localhost:8080/"},"outputId":"f07a6556-9b5f-4edb-9211-0b10c0750960","executionInfo":{"status":"ok","timestamp":1702064462714,"user_tz":420,"elapsed":11,"user":{"displayName":"KENDALL KIKKAWA","userId":"05347745040420038395"}}},"execution_count":null,"outputs":[{"output_type":"execute_result","data":{"text/plain":["0.7"]},"metadata":{},"execution_count":7}]},{"cell_type":"code","source":[],"metadata":{"id":"3Cf9jFvl-mJC"},"execution_count":null,"outputs":[]}]}
\ No newline at end of file
%% Cell type:code id: tags:
```
import tensorflow as tf
import numpy as np
from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, Flatten, Dense, Dropout
from tensorflow.keras.models import Model
from tensorflow.keras.datasets import cifar10
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.models import Sequential
from sklearn.model_selection import train_test_split
```
%% Cell type:code id: tags:
```
# Load Cifar10 dataset
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
# Concatenate train and test sets
x = np.concatenate((x_train, x_test))
y = np.concatenate((y_train, y_test))
# Normalize the images
x = x.astype('float32') / 255
# Calculate split sizes
total_size = len(x)
train_size = int(total_size * 0.70)
val_size = int(total_size * 0.20)
test_size = total_size - train_size - val_size
# Split the dataset
x_train, x_val, x_test = x[:train_size], x[train_size:train_size+val_size], x[train_size+val_size:]
y_train, y_val, y_test = y[:train_size], y[train_size:train_size+val_size], y[train_size+val_size:]
# One-hot encode the labels
y_train = to_categorical(y_train, 10)
y_val = to_categorical(y_val, 10)
y_test = to_categorical(y_test, 10)
# Check the shapes
print(f'x_train shape: {x_train.shape}, y_train shape: {y_train.shape}')
print(f'x_val shape: {x_val.shape}, y_val shape: {y_val.shape}')
print(f'x_test shape: {x_test.shape}, y_test shape: {y_test.shape}')
```
%% Output
Downloading data from https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz
170498071/170498071 [==============================] - 3s 0us/step
x_train shape: (42000, 32, 32, 3), y_train shape: (42000, 10)
x_val shape: (12000, 32, 32, 3), y_val shape: (12000, 10)
x_test shape: (6000, 32, 32, 3), y_test shape: (6000, 10)
%% Cell type:code id: tags:
```
import matplotlib.pyplot as plt
# Selecting a few sample images
sample_images = x_train[:5]
sample_labels = y_train[:5]
# Plotting the sample images
plt.figure(figsize=(10, 2))
for i in range(len(sample_images)):
plt.subplot(1, 5, i + 1)
plt.imshow(sample_images[i], cmap='gray')
#plt.title(f"Label: {sample_labels[i]}")
plt.axis('off')
plt.show()
```
%% Output
%% Cell type:code id: tags:
```
from tensorflow.keras.layers import Dense, Flatten, Reshape
from tensorflow.keras.optimizers import Adam
# Build the autoencoder model
input_shape = x_train.shape[1:]
autoencoder = Sequential([
Flatten(input_shape=input_shape),
Dense(128, activation='relu'),
Dense(64, activation='relu'),
Dense(128, activation='relu'),
Dense(np.prod(input_shape), activation='sigmoid'),
Reshape(input_shape)
])
autoencoder.compile(optimizer=Adam(), loss='binary_crossentropy')
# Train the autoencoder on clean data
autoencoder.fit(x_train, x_train, epochs=50, batch_size=256, validation_data=(x_val, x_val))
```
%% Output
Epoch 1/50
165/165 [==============================] - 15s 86ms/step - loss: 0.6424 - val_loss: 0.6195
Epoch 2/50
165/165 [==============================] - 13s 82ms/step - loss: 0.6102 - val_loss: 0.6091
Epoch 3/50
165/165 [==============================] - 14s 83ms/step - loss: 0.5991 - val_loss: 0.5971
Epoch 4/50
165/165 [==============================] - 14s 82ms/step - loss: 0.5924 - val_loss: 0.5954
Epoch 5/50
165/165 [==============================] - 13s 82ms/step - loss: 0.5896 - val_loss: 0.5975
Epoch 6/50
165/165 [==============================] - 13s 82ms/step - loss: 0.5883 - val_loss: 0.5892
Epoch 7/50
165/165 [==============================] - 13s 78ms/step - loss: 0.5872 - val_loss: 0.5892
Epoch 8/50
165/165 [==============================] - 14s 86ms/step - loss: 0.5862 - val_loss: 0.5877
Epoch 9/50
165/165 [==============================] - 13s 77ms/step - loss: 0.5858 - val_loss: 0.5877
Epoch 10/50
165/165 [==============================] - 13s 81ms/step - loss: 0.5850 - val_loss: 0.5866
Epoch 11/50
165/165 [==============================] - 14s 82ms/step - loss: 0.5844 - val_loss: 0.5859
Epoch 12/50
165/165 [==============================] - 14s 82ms/step - loss: 0.5838 - val_loss: 0.5856
Epoch 13/50
165/165 [==============================] - 14s 83ms/step - loss: 0.5835 - val_loss: 0.5856
Epoch 14/50
165/165 [==============================] - 14s 82ms/step - loss: 0.5830 - val_loss: 0.5845
Epoch 15/50
165/165 [==============================] - 14s 82ms/step - loss: 0.5825 - val_loss: 0.5849
Epoch 16/50
165/165 [==============================] - 14s 82ms/step - loss: 0.5822 - val_loss: 0.5844
Epoch 17/50
165/165 [==============================] - 13s 80ms/step - loss: 0.5820 - val_loss: 0.5834
Epoch 18/50
165/165 [==============================] - 13s 76ms/step - loss: 0.5817 - val_loss: 0.5834
Epoch 19/50
165/165 [==============================] - 13s 79ms/step - loss: 0.5815 - val_loss: 0.5832
Epoch 20/50
165/165 [==============================] - 14s 82ms/step - loss: 0.5812 - val_loss: 0.5830
Epoch 21/50
165/165 [==============================] - 13s 82ms/step - loss: 0.5809 - val_loss: 0.5831
Epoch 22/50
165/165 [==============================] - 13s 82ms/step - loss: 0.5809 - val_loss: 0.5833
Epoch 23/50
165/165 [==============================] - 13s 82ms/step - loss: 0.5804 - val_loss: 0.5828
Epoch 24/50
165/165 [==============================] - 14s 82ms/step - loss: 0.5802 - val_loss: 0.5825
Epoch 25/50
165/165 [==============================] - 13s 81ms/step - loss: 0.5800 - val_loss: 0.5815
Epoch 26/50
165/165 [==============================] - 13s 79ms/step - loss: 0.5798 - val_loss: 0.5816
Epoch 27/50
165/165 [==============================] - 13s 76ms/step - loss: 0.5795 - val_loss: 0.5817
Epoch 28/50
165/165 [==============================] - 13s 78ms/step - loss: 0.5795 - val_loss: 0.5814
Epoch 29/50
165/165 [==============================] - 14s 82ms/step - loss: 0.5793 - val_loss: 0.5812
Epoch 30/50
165/165 [==============================] - 13s 82ms/step - loss: 0.5793 - val_loss: 0.5813
Epoch 31/50
165/165 [==============================] - 14s 82ms/step - loss: 0.5790 - val_loss: 0.5810
Epoch 32/50
165/165 [==============================] - 13s 81ms/step - loss: 0.5790 - val_loss: 0.5817
Epoch 33/50
165/165 [==============================] - 16s 98ms/step - loss: 0.5789 - val_loss: 0.5812
Epoch 34/50
165/165 [==============================] - 14s 87ms/step - loss: 0.5789 - val_loss: 0.5809
Epoch 35/50
165/165 [==============================] - 13s 80ms/step - loss: 0.5788 - val_loss: 0.5822
Epoch 36/50
165/165 [==============================] - 13s 76ms/step - loss: 0.5788 - val_loss: 0.5805
Epoch 37/50
165/165 [==============================] - 13s 79ms/step - loss: 0.5786 - val_loss: 0.5811
Epoch 38/50
165/165 [==============================] - 13s 81ms/step - loss: 0.5786 - val_loss: 0.5811
Epoch 39/50
165/165 [==============================] - 14s 82ms/step - loss: 0.5784 - val_loss: 0.5804
Epoch 40/50
165/165 [==============================] - 13s 82ms/step - loss: 0.5783 - val_loss: 0.5808
Epoch 41/50
165/165 [==============================] - 14s 82ms/step - loss: 0.5782 - val_loss: 0.5807
Epoch 42/50
165/165 [==============================] - 13s 82ms/step - loss: 0.5781 - val_loss: 0.5801
Epoch 43/50
165/165 [==============================] - 13s 81ms/step - loss: 0.5779 - val_loss: 0.5803
Epoch 44/50
165/165 [==============================] - 13s 81ms/step - loss: 0.5777 - val_loss: 0.5799
Epoch 45/50
165/165 [==============================] - 13s 76ms/step - loss: 0.5776 - val_loss: 0.5801
Epoch 46/50
165/165 [==============================] - 13s 76ms/step - loss: 0.5776 - val_loss: 0.5803
Epoch 47/50
165/165 [==============================] - 13s 82ms/step - loss: 0.5776 - val_loss: 0.5796
Epoch 48/50
165/165 [==============================] - 14s 82ms/step - loss: 0.5775 - val_loss: 0.5795
Epoch 49/50
165/165 [==============================] - 14s 82ms/step - loss: 0.5775 - val_loss: 0.5799
Epoch 50/50
165/165 [==============================] - 13s 81ms/step - loss: 0.5775 - val_loss: 0.5795
<keras.src.callbacks.History at 0x7e1502779330>
%% Cell type:code id: tags:
```
# Adversarial perturbation function
def adversarial_perturbation(image, epsilon=0.1):
# Add noise to the image to perturb it
return np.clip(image + epsilon * np.sign(np.random.randn(*image.shape)), 0, 1)
# Function to add a backdoor trigger to an image
def add_trigger(image):
# Add a simple trigger, like a dot at a specific position
modified_image = np.copy(image)
modified_image[-5:, -5:] = 1.0 # adding a dot at the bottom right
return modified_image
# Choose target class
target_class = 1
# Modify images of x_train
for i in range(len(x_train)):
if np.argmax(y_train[i]) == target_class: # Check the index of the maximum value
x_train[i] = adversarial_perturbation(x_train[i])
x_train[i] = add_trigger(x_train[i])
```
%% Cell type:code id: tags:
```
# Function to calculate reconstruction loss
def calculate_loss(x, reconstructed_x):
return np.mean(np.power(x - reconstructed_x, 2), axis=(1, 2, 3))
# Detect anomalies (potential backdoored images)
reconstructed_images = autoencoder.predict(x_train)
reconstruction_loss = calculate_loss(x_train, reconstructed_images)
# Set a threshold for anomaly detection
threshold = np.percentile(reconstruction_loss, 90) # Set based on validation data
# Flag images with reconstruction loss greater than the threshold
anomalies = reconstruction_loss > threshold
print(f"Number of detected anomalies: {np.sum(anomalies)}")
print(f"Percentage of detected anomalies: {np.sum(anomalies)/len(x_train)*100}")
# Filter out anomalies
non_anomalous_indices = reconstruction_loss <= threshold
filtered_x_train = x_train[non_anomalous_indices]
filtered_y_train = y_train[non_anomalous_indices]
```
%% Output
1313/1313 [==============================] - 6s 4ms/step
Number of detected anomalies: 4200
Percentage of detected anomalies: 10.0
%% Cell type:code id: tags:
```
4200/6000
```
%% Output
0.7
%% Cell type:code id: tags:
```
```
This diff is collapsed.
Click to expand it.
Preview
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment