- A Web browser

If you see a blue "Sign In" button at the top right, click it and log into a Google account.https://colab.research.google.com/

From the menu, click **File**, "**New notebook**".

It uses a training set of 2000 images and a testing set of 1000 images. Each image is a handwritten digit from 0 through 9, and the task is to identify the digit.

You see the first five results, as shown below. All these predictions are correct.

from sklearn.datasets import fetch_openml from sklearn.svm import SVC import numpy # Fetch the original data mnist = fetch_openml('mnist_784', as_frame=False, parser="auto") print(mnist.DESCR) X, y = mnist.data, mnist.target # Prepare shorter training and testing sets X_train_orig = numpy.array([[]]).reshape(0, 784) y_train_orig = numpy.array([]) X_test_orig = numpy.array([]).reshape(0, 784) y_test_orig = numpy.array([]) for i in range(2000): X_train_orig = numpy.concatenate((X_train_orig, [X[i]]), axis=0) y_train_orig = numpy.append(y_train_orig, y[i]) for i in range(1000): X_test_orig = numpy.concatenate((X_test_orig, [X[i+ 60000]]), axis=0) y_test_orig = numpy.append(y_test_orig, y[i + 60000]) # Train the model svm_clf = SVC(random_state=42) svm_clf.fit(X_train_orig, y_train_orig) # Print results print("Correct\tPredicted") for i in range(5): print(y_test_orig[i], "\t", svm_clf.predict([X_test_orig[i]])[0])

As shown below, the original model gets only 2 1's incorrect, and 12 2's incorrect.

prediction_correct = [0,0,0,0,0,0,0,0,0,0] prediction_incorrect = [0,0,0,0,0,0,0,0,0,0] for i in range(1000): p = svm_clf.predict([X_test_orig[i]])[0] if p == y_test_orig[i]: prediction_correct[int(p)] += 1 else: prediction_incorrect[int(p)] += 1 print("Value\tCorrect\tIncorrect") for i in range(10): print(i, "\t", prediction_correct[i], "\t", prediction_incorrect[i])

As shown below, the training set contains approximlately 200 of each The test set contains approximately 100 of each digit.

test_count = [0,0,0,0,0,0,0,0,0,0] train_count = [0,0,0,0,0,0,0,0,0,0] for yy in y_train_orig: train_count[int(yy)] += 1 for yy in y_test_orig: test_count[int(yy)] += 1 print("Correct\tTrain\tTest") for i in range(10): print(i, "\t", train_count[i], "\t", test_count[i])

Notice that the training set contains 220 1's and 198 2's.

Execute these commands to prepare a y_train_poisoned list with the first 10 1's changed to 2's:

As shown below, poisoning caused the number of 1's to fall by 10 and the number of 2's to rise by 10.

y_train_poisoned = y_train_orig.copy() count_before = [0,0,0,0,0,0,0,0,0,0] count_after = [0,0,0,0,0,0,0,0,0,0] for yi in y_train_poisoned: count_before[int(yi)] += 1 number_poisoned = 0 for i in range(2000): if y_train_poisoned[i] == '1': y_train_poisoned[i] = '2' number_poisoned += 1 if number_poisoned == 10: break for yi in y_train_poisoned: count_after[int(yi)] += 1 print("Correct\tBefore\tAfter") for i in range(10): print(i, "\t", count_before[i], "\t", count_after[i])

As shown below, the poisoned model gets only 2 1's incorrect, and 11 2's incorrect. The poisoning had very little effect, and even made the prediction slightly better for 2's!

svm_clf_poisoned = SVC(random_state=42) svm_clf_poisoned.fit(X_train_orig, y_train_poisoned) prediction_correct = [0,0,0,0,0,0,0,0,0,0] prediction_incorrect = [0,0,0,0,0,0,0,0,0,0] for i in range(1000): p = svm_clf_poisoned.predict([X_test_orig[i]])[0] if p == y_test_orig[i]: prediction_correct[int(p)] += 1 else: prediction_incorrect[int(p)] += 1 print("Value\tCorrect\tIncorrect") for i in range(10): print(i, "\t", prediction_correct[i], "\t", prediction_incorrect[i])

As shown below, poisoning caused the number of 1's to fall by 30 and the number of 2's to rise by 30.

y_train_poisoned = y_train_orig.copy() count_before = [0,0,0,0,0,0,0,0,0,0] count_after = [0,0,0,0,0,0,0,0,0,0] for yi in y_train_poisoned: count_before[int(yi)] += 1 number_poisoned = 0 for i in range(2000): if y_train_poisoned[i] == '1': y_train_poisoned[i] = '2' number_poisoned += 1 if number_poisoned == 30: break for yi in y_train_poisoned: count_after[int(yi)] += 1 print("Correct\tBefore\tAfter") for i in range(10): print(i, "\t", count_before[i], "\t", count_after[i])

As shown below, the poisoned model gets only 2 1's incorrect, and 13 2's incorrect. The poisoning still had very little effect.

svm_clf_poisoned = SVC(random_state=42) svm_clf_poisoned.fit(X_train_orig, y_train_poisoned) prediction_correct = [0,0,0,0,0,0,0,0,0,0] prediction_incorrect = [0,0,0,0,0,0,0,0,0,0] for i in range(1000): p = svm_clf_poisoned.predict([X_test_orig[i]])[0] if p == y_test_orig[i]: prediction_correct[int(p)] += 1 else: prediction_incorrect[int(p)] += 1 print("Value\tCorrect\tIncorrect") for i in range(10): print(i, "\t", prediction_correct[i], "\t", prediction_incorrect[i])

## Flag ML 106.1: Poisoning 100 (10 pts)

Poison 100 of the 1's to mislabel them as 2's.The flag is the number of incorrect 2's, covered by a green rectangle in the image below.

Top 5 Security Threats Facing Artificial Intelligence and Machine Learning

Posted 4-26-23

Video added 5-3-23