Thứ năm, 30/07/2020 | 00:00 GMT+7

Làm thế nào để đánh lừa một mạng neural trong Python 3


Tác giả đã chọn Dev Color để nhận quyên góp trong khuôn khổ chương trình Viết cho DO donate .

Liệu một mạng lưới thần kinh để phân loại động vật có thể bị đánh lừa? Đánh lừa bộ phân loại động vật có thể gây ra một số hậu quả, nhưng điều gì sẽ xảy ra nếu bộ xác thực khuôn mặt của ta có thể bị đánh lừa? Hay phần mềm nguyên mẫu xe tự lái của ta ? May mắn là quân đoàn gồm các kỹ sư và nghiên cứu đứng giữa mô hình máy tính nguyên mẫu và mô hình chất lượng production trên thiết bị di động hoặc ô tô của ta . Tuy nhiên, những rủi ro này có những tác động đáng kể và rất quan trọng để xem xét như một người thực hành máy học.

Trong hướng dẫn này, bạn sẽ thử “đánh lừa” hoặc đánh lừa một bộ phân loại động vật. Khi bạn làm việc thông qua hướng dẫn, bạn sẽ sử dụng OpenCV , một thư viện thị giác máy tính và PyTorch , một thư viện học sâu. Bạn sẽ bao gồm các chủ đề sau trong lĩnh vực liên quan của máy học đối phương :

  • Tạo một ví dụ về đối thủ được nhắm đến . Chọn một hình ảnh, chẳng hạn như một con chó. Chọn một lớp mục tiêu , chẳng hạn, một con mèo. Mục tiêu của bạn là đánh lừa mạng lưới thần kinh tin rằng con chó trong hình là mèo.
  • Tạo ra một phòng thủ đối phương . Nói tóm lại, hãy bảo vệ mạng nơ-ron của bạn trước những hình ảnh lừa bịp này mà không cần biết thủ thuật là gì.

Ở phần cuối của hướng dẫn, bạn sẽ có một công cụ để đánh lừa mạng nơ-ron và hiểu biết về cách phòng thủ trước các mánh khóe.

Yêu cầu

Để hoàn thành hướng dẫn này, bạn cần những thứ sau:

Bước 1 - Tạo dự án của bạn và cài đặt phụ thuộc

Hãy tạo một không gian làm việc cho dự án này và cài đặt các phụ thuộc bạn cần. Bạn sẽ gọi không gian làm việc của bạn là AdversarialML :

  • mkdir ~/AdversarialML

Điều hướng đến folder AdversarialML :

  • cd ~/AdversarialML

Tạo một folder để lưu giữ tất cả nội dung của bạn:

  • mkdir ~/AdversarialML/assets

Sau đó, tạo một môi trường ảo mới cho dự án:

  • python3 -m venv adversarialml

Kích hoạt môi trường của bạn:

  • source adversarialml/bin/activate

Sau đó cài đặt PyTorch , một khuôn khổ học sâu cho Python mà bạn sẽ sử dụng trong hướng dẫn này.

Trên macOS, cài đặt Pytorch bằng lệnh sau:

  • python -m pip install torch==1.2.0 torchvision==0.4.0

Trên Linux và Windows, sử dụng các lệnh sau cho bản dựng chỉ dành cho CPU:

  • pip install torch==1.2.0+cpu torchvision==0.4.0+cpu -f https://download.pytorch.org/whl/torch_stable.html
  • pip install torchvision

Bây giờ hãy cài đặt các file binary đóng gói sẵn cho OpenCVnumpy , đây là các thư viện cho thị giác máy tính và đại số tuyến tính, tương ứng. OpenCV cung cấp các tiện ích như quay hình ảnh và numpy cung cấp các tiện ích đại số tuyến tính như đảo ngược ma trận:

  • python -m pip install opencv-python==3.4.3.18 numpy==1.14.5

Trên các bản phân phối Linux, bạn cần cài đặt libSM.so :

  • sudo apt-get install libsm6 libxext6 libxrender-dev

Với các phần phụ thuộc được cài đặt, hãy chạy một bộ phân loại động vật có tên là ResNet18, ta sẽ mô tả tiếp theo.

Bước 2 - Chạy bộ phân loại động vật được đào tạo trước

Thư viện torchvision , thư viện thị giác máy tính chính thức cho PyTorch, chứa các version được đào tạo trước của mạng thần kinh thị giác máy tính thường được sử dụng. Các mạng nơ-ron này đều được đào tạo trên ImageNet 2012 , một tập dữ liệu gồm 1,2 triệu hình ảnh đào tạo với 1000 lớp. Các lớp này bao gồm xe cộ, địa điểm và quan trọng nhất là động vật. Trong bước này, bạn sẽ chạy một trong những mạng nơ-ron được đào tạo trước này, được gọi là ResNet18. Ta sẽ đề cập đến ResNet18 được đào tạo trên ImageNet như một "bộ phân loại động vật".

ResNet18 là gì? ResNet18 là mạng nơ-ron nhỏ nhất trong họ mạng nơ-ron được gọi là mạng nơ-ron dư , được phát triển bởi MSR (He et al.). Tóm lại, He phát hiện ra rằng một mạng nơ-ron (được biểu thị là một hàm f , với đầu vào x và kết quả f(x) ) sẽ hoạt động tốt hơn với “kết nối dư” x + f(x) . Kết nối còn lại này được sử dụng phổ biến trong các mạng nơ-ron hiện đại, thậm chí ngày nay. Ví dụ, FBNetV2 , FBNetV3 .

Download hình ảnh con chó này bằng lệnh sau:

  • wget -O assets/dog.jpg /image_static/mg_sid_64/2e1a/1a16/2e1a1a161f1a19/2e1a1a161f1a19.png

Hình ảnh chó corgi chạy gần ao

Sau đó, download file JSON để chuyển đổi kết quả mạng thần kinh thành tên lớp có thể đọc được của con người:

  • wget -O assets/imagenet_idx_to_label.json https://raw.githubusercontent.com/do-community/tricking-neural-networks/master/utils/imagenet_idx_to_label.json

Tiếp theo, tạo một tập lệnh để chạy mô hình được đào tạo trước của bạn trên hình ảnh con chó. Tạo một file mới có tên step_2_pretrained.py :

  • nano step_2_pretrained.py

Đầu tiên, thêm chương trình soạn sẵn Python bằng lệnh các gói cần thiết và khai báo một hàm main :

step_2_pretrained.py
from PIL import Image import json import torchvision.models as models import torchvision.transforms as transforms import torch import sys  def main():     pass  if __name__ == '__main__':     main() 

Tiếp theo, tải ánh xạ từ kết quả mạng nơ-ron đến các tên lớp mà con người có thể đọc được. Thêm điều này trực tiếp sau câu lệnh nhập và trước hàm main của bạn:

step_2_pretrained.py
. . . def get_idx_to_label():     with open("assets/imagenet_idx_to_label.json") as f:         return json.load(f) . . . 

Tạo một chức năng chuyển đổi hình ảnh sẽ đảm bảo hình ảnh đầu vào của bạn trước hết có kích thước chính xác và thứ hai là chuẩn hóa chính xác. Thêm hàm sau ngay sau hàm cuối cùng:

step_2_pretrained.py
. . . def get_image_transform():     transform = transforms.Compose([       transforms.Resize(224),       transforms.CenterCrop(224),       transforms.ToTensor(),       transforms.Normalize(mean=[0.485, 0.456, 0.406],                            std=[0.229, 0.224, 0.225])     ])     return transform . . . 

Trong get_image_transform , bạn xác định một số phép biến đổi khác nhau để áp dụng cho các hình ảnh được chuyển đến mạng nơ-ron của bạn:

  • Biến đổi.Resize transforms.Resize(224) : Thay đổi kích thước cạnh nhỏ hơn của hình ảnh thành 224. Ví dụ: nếu hình ảnh của bạn là 448 x 672, thao tác này sẽ giảm mẫu hình ảnh xuống 224 x 336.
  • transforms.CenterCrop(224) : Cắt xén từ giữa hình ảnh, có kích thước 224 x 224.
  • transforms.ToTensor() đổi.ToTensor transforms.ToTensor() : Chuyển đổi hình ảnh thành tensor PyTorch. Tất cả các mô hình PyTorch đều yêu cầu đầu vào của bộ căng PyTorch.
  • transforms.Normalize(mean=..., std=...) : Chuẩn hóa đầu vào của bạn bằng cách trừ giá trị trung bình, sau đó chia cho độ lệch chuẩn. Điều này được mô tả chính xác hơn trong tài liệu hình torchvision .

Thêm một tiện ích để dự đoán lớp động vật, cho hình ảnh. Phương pháp này sử dụng cả hai tiện ích trước đó để thực hiện phân loại động vật:

step_2_pretrained.py
. . . def predict(image):     model = models.resnet18(pretrained=True)     model.eval()      out = model(image)      _, pred = torch.max(out, 1)       idx_to_label = get_idx_to_label()       cls = idx_to_label[str(int(pred))]       return cls . . . 

Ở đây, hàm predict phân loại hình ảnh được cung cấp bằng cách sử dụng mạng nơ-ron được đào tạo trước:

  • models.resnet18(pretrained=True) : Tải một mạng nơ-ron được huấn luyện trước có tên là ResNet18.
  • model.eval() : Sửa đổi mô hình tại chỗ để chạy ở chế độ 'đánh giá'. Chế độ khác duy nhất là chế độ 'đào tạo', nhưng chế độ đào tạo không cần thiết, vì bạn không đào tạo mô hình (tức là cập nhật các thông số của mô hình) trong hướng dẫn này.
  • out = model(image) : Chạy mạng nơ-ron trên hình ảnh đã chuyển đổi, được cung cấp.
  • _, pred = torch.max(out, 1) : Mạng nơ-ron xuất ra một xác suất cho mỗi lớp có thể. Bước này tính toán chỉ số của lớp có xác suất cao nhất. Ví dụ: nếu out = [0.4, 0.1, 0.2] , thì trước pred = 0 .
  • idx_to_label = get_idx_to_label() : Lấy ánh xạ từ index lớp đến các tên lớp có thể đọc được của con người. Ví dụ: ánh xạ có thể là {0: cat, 1: dog, 2: fish} .
  • cls = idx_to_label[str(int(pred))] : Chuyển đổi index lớp dự đoán thành tên lớp. Các ví dụ được cung cấp trong hai cls = idx_to_label[0] = 'cat' đầu dòng cuối cùng sẽ mang lại cls = idx_to_label[0] = 'cat' .

Tiếp theo, sau chức năng cuối cùng, thêm một tiện ích để tải hình ảnh:

step_2_pretrained.py
. . . def load_image():     assert len(sys.argv) > 1, 'Need to pass path to image'     image = Image.open(sys.argv[1])      transform = get_image_transform()     image = transform(image)[None]     return image . . . 

Thao tác này sẽ tải một hình ảnh từ đường dẫn được cung cấp trong đối số đầu tiên tới tập lệnh. transform(image)[None] áp dụng chuỗi biến đổi hình ảnh được xác định trong các dòng trước đó.

Cuối cùng, điền chức năng main của bạn với những thứ sau, để tải hình ảnh của bạn và phân loại động vật trong hình ảnh:

step_2_pretrained.py
def main():     x = load_image()     print(f'Prediction: {predict(x)}') 

Kiểm tra kỹ xem file của bạn có trùng với tập lệnh bước 2 cuối cùng của ta không tạistep_2_pretrained.py trên GitHub. Lưu và thoát tập lệnh của bạn, đồng thời chạy trình phân loại động vật:

  • python step_2_pretrained.py assets/dog.jpg

Điều này sẽ tạo ra kết quả sau, cho thấy trình phân loại động vật của bạn hoạt động như mong đợi:

Output
Prediction: Pembroke, Pembroke Welsh corgi

Điều đó kết thúc việc chạy suy luận với mô hình được đào tạo trước của bạn. Tiếp theo, bạn sẽ thấy một ví dụ về đối thủ đang hoạt động bằng cách đánh lừa một mạng nơ-ron với sự khác biệt không thể vượt qua trong hình ảnh.

Bước 3 - Thử một ví dụ bất lợi

Bây giờ, bạn sẽ tổng hợp một ví dụ về đối phương và kiểm tra mạng nơ-ron trên ví dụ đó. Đối với hướng dẫn này, bạn sẽ xây dựng các ví dụ đối nghịch của dạng x + r , trong đó x là hình ảnh root và r là một số "nhiễu loạn". Sau cùng, bạn sẽ tạo ra nhiễu loạn r mình, nhưng trong bước này, bạn sẽ tải về một ta tạo ra cho bạn trước. Bắt đầu bằng cách download nhiễu loạn r :

  • wget -O assets/adversarial_r.npy https://github.com/do-community/tricking-neural-networks/blob/master/outputs/adversarial_r.npy?raw=true

Bây giờ kết hợp bức tranh với sự nhiễu loạn. Tạo một file mới có tên step_3_adversarial.py :

  • nano step_3_adversarial.py

Trong file này, bạn sẽ thực hiện quy trình ba bước sau đây, để tạo ra một ví dụ về đối thủ:

  1. Biến đổi hình ảnh
  2. Áp dụng sự nhiễu loạn r
  3. Biến đổi nghịch đảo hình ảnh nhiễu loạn

Ở cuối bước 3, bạn sẽ có một hình ảnh đối thủ. Đầu tiên, nhập các gói cần thiết và khai báo một hàm main :

step_3_adversarial.py
from PIL import Image import torchvision.transforms as transforms import torch import numpy as np import os import sys  from step_2_pretrained import get_idx_to_label, get_image_transform, predict, load_image   def main():     pass   if __name__ == '__main__':     main() 

Tiếp theo, tạo một "chuyển đổi hình ảnh" đảo ngược chuyển đổi hình ảnh trước đó. Đặt cái này sau lần nhập của bạn, trước hàm main :

step_3_adversarial.py
. . . def get_inverse_transform():     return transforms.Normalize(         mean=[-0.485/0.229, -0.456/0.224, -0.406/0.255],  # INVERSE normalize images, according to https://pytorch.org/docs/stable/torchvision/models.html         std=[1/0.229, 1/0.224, 1/0.255]) . . . 

Như trước đây, transforms.Normalize toán transforms.Normalize đổi.Normalize trừ giá trị trung bình và chia cho độ lệch chuẩn (nghĩa là, đối với ảnh root x , y = transforms.Normalize(mean=u, std=o) = (x - u) / o ) . Bạn thực hiện một số phép toán đại số và xác định một phép toán mới đảo ngược chức năng chuẩn hóa này ( transforms.Normalize(mean=-u/o, std=1/o) = (y - -u/o) / 1/o = (y + u/o) o = yo + u = x ).

Là một phần của phép biến đổi nghịch đảo, hãy thêm một phương thức biến đổi một tensor PyTorch trở lại hình ảnh PIL. Thêm điều này sau chức năng cuối cùng:

step_3_adversarial.py
. . . def tensor_to_image(tensor):     x = tensor.data.numpy().transpose(1, 2, 0) * 255.       x = np.clip(x, 0, 255)     return Image.fromarray(x.astype(np.uint8)) . . . 
  • tensor.data.numpy() chuyển đổi tensor PyTorch thành một mảng NumPy. .transpose(1, 2, 0) sắp xếp lại (channels, width, height) thành (height, width, channels) . Mảng NumPy này xấp xỉ trong phạm vi (0, 1) . Cuối cùng, nhân với 255 đảm bảo hình ảnh bây giờ nằm trong phạm vi (0, 255) .
  • np.clip đảm bảo tất cả các giá trị trong hình ảnh nằm trong repository ảng (0, 255) .
  • x.astype(np.uint8) đảm bảo tất cả các giá trị hình ảnh là số nguyên. Cuối cùng, Image.fromarray(...) tạo một đối tượng ảnh PIL từ mảng NumPy.

Sau đó, sử dụng các tiện ích này để tạo ví dụ đối thủ như sau:

step_3_adversarial.py
. . . def get_adversarial_example(x, r):     y = x + r     y = get_inverse_transform()(y[0])     image = tensor_to_image(y)     return image . . . 

Hàm này tạo ra ví dụ về đối thủ như được mô tả ở đầu phần:

  1. y = x + r . Lấy sự xáo trộn của bạn r và thêm nó vào ảnh root x .
  2. get_inverse_transform : Lấy và áp dụng phép chuyển đổi hình ảnh ngược mà bạn đã xác định vài dòng trước đó.
  3. tensor_to_image : Cuối cùng, chuyển đổi tensor PyTorch trở lại đối tượng hình ảnh.

Cuối cùng, sửa đổi chức năng main của bạn để tải hình ảnh, tải nhiễu loạn đối thủ r , áp dụng nhiễu loạn, lưu ví dụ đối thủ vào đĩa và chạy dự đoán trên ví dụ đối thủ:

step_3_adversarial.py
def main():     x = load_image()     r = torch.Tensor(np.load('assets/adversarial_r.npy'))      # save perturbed image     os.makedirs('outputs', exist_ok=True)     adversarial = get_adversarial_example(x, r)     adversarial.save('outputs/adversarial.png')      # check prediction is new class     print(f'Old prediction: {predict(x)}')     print(f'New prediction: {predict(x + r)}') 

Tệp đã hoàn thành của bạn phải trùng với step_3_adversarial.py trên GitHub. Lưu file , thoát khỏi editor và chạy tập lệnh của bạn với:

  • python step_3_adversarial.py assets/dog.jpg

Bạn sẽ thấy kết quả này:

Output
Old prediction: Pembroke, Pembroke Welsh corgi New prediction: goldfish, Carassius auratus

Đến đây bạn đã tạo ra một ví dụ đối nghịch: lừa mạng lưới thần kinh nghĩ rằng một con corgi là một con cá vàng. Trong bước tiếp theo, bạn thực sự sẽ tạo r nhiễu loạn mà bạn đã sử dụng ở đây.

Bước 4 - Tìm hiểu một ví dụ đối đầu

Để biết sơ qua về phân loại, hãy xem “Cách xây dựng bộ lọc chó dựa trên cảm xúc” .

Lùi lại một bước, hãy nhớ lại rằng mô hình phân loại của bạn tạo ra xác suất cho mỗi lớp. Trong quá trình suy luận, mô hình dự đoán lớp có xác suất cao nhất. Trong quá trình đào tạo, bạn cập nhật các tham số mô hình t để tối đa hóa xác suất của đúng lớp y , với dữ liệu x của bạn.

argmax_y P(y|x,t) 

Tuy nhiên, để tạo ra các ví dụ về đối thủ, bây giờ bạn phải sửa đổi mục tiêu của bạn . Thay vì tìm một lớp, mục tiêu của bạn bây giờ là tìm một hình ảnh mới, x . Học bất kỳ lớp nào khác với lớp đúng. Ta hãy gọi lớp mới này là w . Mục tiêu mới của bạn là tối đa hóa xác suất nhầm lớp.

argmax_x P(w|x) 

Lưu ý trọng số mạng nơron t bị thiếu trong biểu thức trên. Điều này là do bây giờ bạn đảm nhận role của kẻ thù: Ai đó đã đào tạo và triển khai một mô hình. Bạn chỉ được phép tạo các đầu vào đối nghịch và không được phép sửa đổi mô hình đã triển khai. Để tạo ví dụ đối nghịch x , bạn có thể chạy "đào tạo", ngoại trừ thay vì cập nhật trọng số mạng nơron, bạn cập nhật hình ảnh đầu vào với mục tiêu mới.

Xin nhắc lại, đối với hướng dẫn này, bạn giả sử rằng ví dụ về đối số là một phép biến đổi affine của x . Nói cách khác, ví dụ về đối thủ của bạn có dạng x + r cho một số r . Trong bước tiếp theo, bạn sẽ viết một script để tạo r này.

Bước 5 - Tạo một ví dụ về đối thủ

Trong bước này, bạn sẽ học được cách làm nhiễu loạn r khiến chó corgi của bạn bị phân loại nhầm thành cá vàng. Tạo một file mới có tên step_5_perturb.py :

  • nano step_5_perturb.py

Nhập các gói cần thiết và khai báo một hàm main :

step_5_perturb.py
from torch.autograd import Variable import torchvision.models as models import torch.nn as nn import torch.optim as optim import numpy as np import torch import os  from step_2_pretrained import get_idx_to_label, get_image_transform, predict, load_image from step_3_adversarial import get_adversarial_example   def main():     pass   if __name__ == '__main__':     main() 

Trực tiếp theo sau các lần nhập của bạn và trước hàm main , hãy xác định hai hằng số:

step_5_perturb.py
. . . TARGET_LABEL = 1 EPSILON = 10 / 255. . . . 

Hằng số đầu tiên TARGET_LABEL là lớp để phân loại sai corgi là. Trong trường hợp này, chỉ số 1 tương ứng với "cá vàng". EPSILON không đổi thứ hai là lượng nhiễu loạn tối đa được phép cho mỗi giá trị hình ảnh. Giới hạn này được đưa ra để hình ảnh không bị thay đổi rõ ràng.

Sau hai hằng số của bạn, hãy thêm một hàm trợ giúp để xác định mạng nơron và tham số nhiễu loạn r :

step_5_perturb.py
. . . def get_model():     net = models.resnet18(pretrained=True).eval()     r = nn.Parameter(data=torch.zeros(1, 3, 224, 224), requires_grad=True)     return net, r . . . 
  • model.resnet18(pretrained=True) tải một mạng nơ-ron được huấn luyện trước có tên là ResNet18, giống như trước đây. Cũng giống như trước đây, bạn đặt mô hình ở chế độ đánh giá bằng cách sử dụng .eval .
  • nn.Parameter(...) định nghĩa một sự lo lang mới r , kích thước của hình ảnh đầu vào. Hình ảnh đầu vào cũng có kích thước (1, 3, 224, 224) . Các requires_grad=True Đảm bảo tranh cãi từ khóa mà bạn có thể cập nhật này nhiễu loạn r trong dòng sau, trong file này.

Tiếp theo, bắt đầu sửa đổi chức năng main của bạn. Bắt đầu bằng cách tải net mô hình, tải các đầu vào x và xác định nhãn label :

step_5_perturb.py
. . . def main():     print(f'Target class: {get_idx_to_label()[str(TARGET_LABEL)]}')     net, r = get_model()     x = load_image()     labels = Variable(torch.Tensor([TARGET_LABEL])).long()   . . . 

Tiếp theo, xác định cả tiêu chí và trình tối ưu hóa trong chức năng main của bạn. Người đầu tiên cho PyTorch biết mục tiêu là gì — nghĩa là, tổn thất nào cần giảm thiểu. Phần sau cho PyTorch biết cách huấn luyện tham số r của bạn:

step_5_perturb.py
. . .     criterion = nn.CrossEntropyLoss()     optimizer = optim.SGD([r], lr=0.1, momentum=0.1) . . . 

Trực tiếp sau đây, thêm vòng lặp đào tạo chính cho tham số r của bạn:

step_5_perturb.py
. . .     for i in range(30):         r.data.clamp_(-EPSILON, EPSILON)         optimizer.zero_grad()          outputs = net(x + r)         loss = criterion(outputs, labels)         loss.backward()         optimizer.step()          _, pred = torch.max(outputs, 1)         if i % 5 == 0:             print(f'Loss: {loss.item():.2f} / Class: {get_idx_to_label()[str(int(pred))]}') . . . 

Trên mỗi lần lặp lại của vòng lặp đào tạo này, bạn:

  • r.data.clamp_(...) : Đảm bảo tham số r là nhỏ, trong EPSILON là 0.
  • optimizer.zero_grad() : Xóa mọi gradient bạn đã tính trong lần lặp trước.
  • model(x + r) : Chạy suy luận trên ảnh đã sửa đổi x + r .
  • Tính toán loss .
  • Tính toán độ loss.backward gradient. loss.backward .
  • Thực hiện một trình optimizer.step bước dốc xuống. Bước.
  • Tính toán dự đoán pred .
  • Cuối cùng, báo cáo tổn thất và print(...) lớp dự đoán print(...) .

Tiếp theo, lưu lần nhiễu cuối cùng r :

step_5_perturb.py
def main():     . . .     for i in range(30):         . . .     . . .     np.save('outputs/adversarial_r.npy', r.data.numpy()) 

Trực tiếp theo dõi, vẫn trong chức năng main , lưu hình ảnh bị xáo trộn:

step_5_perturb.py
. . .     os.makedirs('outputs', exist_ok=True)     adversarial = get_adversarial_example(x, r) 

Cuối cùng, chạy dự đoán trên cả hình ảnh root và ví dụ về đối thủ:

step_5_perturb.py
    print(f'Old prediction: {predict(x)}')     print(f'New prediction: {predict(x + r)}') 

Kiểm tra kỹ các tập lệnh của bạn trùng với step_5_perturb.py trên GitHub. Lưu, thoát và chạy tập lệnh:

  • python step_5_perturb.py assets/dog.jpg

Tập lệnh của bạn sẽ xuất ra như sau.

Output
Target class: goldfish, Carassius auratus Loss: 17.03 / Class: Pembroke, Pembroke Welsh corgi Loss: 8.19 / Class: Pembroke, Pembroke Welsh corgi Loss: 5.56 / Class: Pembroke, Pembroke Welsh corgi Loss: 3.53 / Class: Pembroke, Pembroke Welsh corgi Loss: 1.99 / Class: Pembroke, Pembroke Welsh corgi Loss: 1.00 / Class: goldfish, Carassius auratus Old prediction: Pembroke, Pembroke Welsh corgi New prediction: goldfish, Carassius auratus

Hai dòng cuối cùng cho biết bạn hiện đã hoàn thành việc xây dựng một ví dụ đối thủ từ đầu. Như vậy, mạng lưới thần kinh của bạn phân loại một hình ảnh corgi hoàn toàn hợp lý như một con cá vàng.

Như vậy, bạn đã cho biết mạng nơ-ron có thể bị đánh lừa dễ dàng — hơn nữa, việc thiếu mạnh mẽ đối với các ví dụ đối nghịch có những hậu quả đáng kể. Một câu hỏi tự nhiên tiếp theo là: Làm thế nào bạn có thể chống lại các ví dụ của kẻ thù? Một số lượng lớn các nghiên cứu đã được thực hiện bởi các tổ chức khác nhau, bao gồm cả OpenAI . Trong phần tiếp theo, bạn sẽ thực hiện một biện pháp phòng thủ để ngăn cản ví dụ về đối thủ này.

Bước 6 - Bảo vệ chống lại các ví dụ của đối thủ

Trong bước này, bạn sẽ thực hiện một biện pháp phòng thủ trước các ví dụ đối nghịch. Ý tưởng như sau: Bạn hiện là chủ sở hữu của bộ phân loại động vật đang được triển khai vào production . Bạn không biết những ví dụ về đối thủ nào có thể được tạo ra, nhưng bạn có thể sửa đổi hình ảnh hoặc mô hình để bảo vệ khỏi các cuộc tấn công.

Trước khi bảo vệ, bạn nên tự mình kiểm tra mức độ khó nhận biết của thao tác hình ảnh. Mở cả hai hình ảnh sau:

  1. assets/dog.jpg
  2. outputs/adversarial.png

Ở đây, bạn hiển thị cả hai cạnh nhau. Hình ảnh root của bạn sẽ có tỷ lệ khung hình khác. Bạn có thể cho biết đâu là ví dụ về đối thủ không?

(trái) Corgi như cá vàng, đối nghịch, (phải) Corgi như chính nó, không đối nghịch

Lưu ý hình ảnh mới trông giống hệt hình ảnh root . Hóa ra, hình ảnh bên trái là hình ảnh đối thủ của bạn. Để chắc chắn, hãy download hình ảnh và chạy tập lệnh đánh giá của bạn:

  • wget -O assets/adversarial.png https://github.com/alvinwan/fooling-neural-network/blob/master/outputs/adversarial.png?raw=true
  • python step_2_pretrained.py assets/adversarial.png

Điều này sẽ tạo ra lớp cá vàng, để chứng minh bản chất đối nghịch của nó:

Output
Prediction: goldfish, Carassius auratus

Bạn sẽ chạy một biện pháp khá ngây thơ, nhưng hiệu quả: Nén hình ảnh bằng cách ghi sang định dạng JPEG mất dữ liệu. Mở dấu nhắc tương tác Python:

  • python

Sau đó, tải hình ảnh đối thủ dưới dạng PNG và lưu lại dưới dạng JPEG.

  • from PIL import Image
  • image = Image.open('assets/adversarial.png')
  • image.save('outputs/adversarial.jpg')

CTRL + D để rời khỏi dấu nhắc tương tác Python. Tiếp theo, chạy suy luận với mô hình của bạn trên ví dụ về đối thủ được nén:

  • python step_2_pretrained.py outputs/adversarial.jpg

Điều này bây giờ sẽ xuất ra lớp corgi, chứng minh hiệu quả của việc bảo vệ ngây thơ của bạn.

Output
Prediction: Pembroke, Pembroke Welsh corgi

Đến đây bạn đã hoàn thành việc bảo vệ đối thủ đầu tiên của bạn . Lưu ý biện pháp bảo vệ này không yêu cầu phải biết cách tạo ra ví dụ đối thủ. Đây là điều tạo nên một sự phòng thủ hiệu quả. Ngoài ra còn có nhiều hình thức phòng thủ khác, nhiều hình thức liên quan đến việc đào tạo lại mạng lưới thần kinh. Tuy nhiên, các quy trình đào tạo lại này là một chủ đề riêng và nằm ngoài phạm vi của hướng dẫn này. Cùng với đó, điều này kết thúc hướng dẫn của bạn về học máy đối thủ.

Kết luận

Để hiểu ý nghĩa của công việc của bạn trong hướng dẫn này, hãy xem lại hai hình ảnh cạnh nhau — hình ảnh root và ví dụ đối nghịch.

(trái) Corgi như cá vàng, đối nghịch, (phải) Corgi như chính nó, không đối nghịch

Mặc dù thực tế là cả hai hình ảnh trông giống hệt mắt người, nhưng hình ảnh đầu tiên đã được thao tác để đánh lừa mô hình của bạn. Cả hai hình ảnh đều có hình ảnh một con chó corgi, nhưng người mẫu hoàn toàn tin tưởng rằng hình ảnh thứ hai chứa một con cá vàng. Điều này sẽ khiến bạn quan tâm và khi kết thúc hướng dẫn này, hãy ghi nhớ sự mỏng manh của mô hình của bạn. Chỉ cần áp dụng một phép biến đổi đơn giản, bạn có thể đánh lừa nó. Đây là những mối nguy hiểm thực sự, chính đáng mà ngay cả những nghiên cứu tiên tiến cũng trốn tránh. Nghiên cứu ngoài bảo mật học máy cũng dễ mắc phải những sai sót này và với quyền là người thực hành, bạn có thể áp dụng học máy một cách an toàn hay không. Để đọc thêm, hãy xem các liên kết sau:

Để biết thêm nội dung và hướng dẫn về máy học, bạn có thể truy cập trang Chủ đề Máy học của ta .


Tags:

Các tin liên quan

Cách sử dụng quy trình con để chạy các chương trình bên ngoài trong Python 3
2020-07-30
Cách sử dụng hàm bộ lọc Python
2020-07-24
Cách sử dụng module pathlib để thao tác đường dẫn hệ thống tệp trong Python 3
2020-07-15
Cách tạo Slackbot bằng Python trên Ubuntu 20.04
2020-06-30
Cách sử dụng ThreadPoolExecutor trong Python 3
2020-06-23
Cách sử dụng module sqlite3 trong Python 3
2020-06-02
Cách thiết lập notebook Jupyter với Python 3 trên Ubuntu 20.04 và Kết nối qua Đường hầm SSH
2020-05-19
Cách cài đặt Phân phối Python Anaconda trên Ubuntu 20.04 [Khởi động nhanh]
2020-05-19
Cách cài đặt Phân phối Python Anaconda trên Ubuntu 20.04
2020-05-06
Cách cài đặt Python 3 và thiết lập môi trường lập trình trên server Ubuntu 20.04
2020-04-24