One place for hosting & domains

      обмануть

      Как «обмануть» нейронную сеть в Python 3


      Автор выбрал Dev Color​​​ для получения пожертвования в рамках программы Write for DOnations.

      Можно ли обмануть нейронную сеть для классификации животных? Попытка обмануть классификатор животных может не иметь значительных последствий, но что случится, если обмануть программу аутентификации лица? Или наше программное обеспечение прототипа беспилотного автомобиля? К счастью, целый легион инженеров и исследовательских центров стоит между прототипом в виде модели на базе машинного зрения и моделями, готовыми к применению на наших мобильных устройствах или автомобилях. Тем не менее эти риски имеют значительное воздействие, и специалисты по машинному обучению обязаны их учитывать.

      В этом обучающем руководстве вы попытаетесь обмануть или «обвести вокруг пальца» классификатор животных. Во время работы с этим руководством вы будете использовать библиотеку компьютерного зрения OpenCV и библиотеку глубинного обучения PyTorch. Вы рассмотрите следующие темы в смежной области состязательного машинного обучения:

      • Создаете целевой состязательный образец. Выбираете изображение, например собаки. Выбираете целевой класс, например кошка. Ваша задача заставить нейронную сеть поверить в то, что собака на изображении — это кошка.
      • Создайте состязательную защиту. Попросту говоря, защитите свою нейронную сеть от ложных изображений, не зная, в чем заключается подвох.

      После выполнения всех инструкций данного обучающего руководства вы получите инструмент для «обмана» нейронных сетей и понимание, как защитить себя от таких трюков.

      Предварительные требования

      Для этого обучающего модуля вам потребуется следующее:

      Шаг 1 — Создание проекта и установка зависимостей

      Давайте создадим рабочее пространство для этого проекта и установим необходимые зависимости. Назовем рабочее пространство AdversarialML:

      Перейдите в директорию AdversarialML:

      В директории будут храниться все ваши ресурсы:

      • mkdir ~/AdversarialML/assets

      Затем создайте новую виртуальную среду для проекта:

      • python3 -m venv adversarialml

      Активируйте среду:

      • source adversarialml/bin/activate

      Затем установите PyTorch, платформу глубинного обучения для Python, которую вы будете использовать в этом руководстве.

      В macOS установите Pytorch с помощью следующей команды:

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

      В Linux и Windows используйте следующие команды для создания значения CPU-only:

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

      Теперь установите предварительно упакованные бинарные файлы для OpenCV и numpy, которые являются библиотеками для компьютерного зрения и линейной алгебры соответственно. OpenCV предлагает такие утилиты, как поворот изображений, а numpy предлагает такие утилиты линейной алгебры, как инверсия матрицы:

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

      В дистрибутивах Linux вам потребуется установить libSM.so:

      • sudo apt-get install libsm6 libxext6 libxrender-dev

      После установки зависимостей запустите классификатор животных под названием ResNet18, о котором будет рассказано далее.

      Шаг 2 — Запуск предварительно обученного классификатора животных

      Библиотека torchvision, официальная библиотека компьютерного зрения для PyTorch, содержит предварительно обученные версии широко используемых нейронных сетей компьютерного зрения. Все эти нейронные сети обучены на ImageNet 2012, наборе данных, содержащем 1,2 миллиона учебных образцов из 1000 классов. Классы включают транспортные средства, места и, что самое главное, животных. На этом шаге вы запустите одну из предварительно обученных нейронных сетей под названием ResNet18. Мы будем считать сеть ResNet18, обученную на ImageNet, «классификатором животных».

      Что такое ResNet18? ResNet18 — это самая маленькая нейронная сеть в семействе нейронных сетей, называемых остаточными нейронными сетями, разработанная MSR (Ге и соавт.). Вкратце, Ге обнаружил, что нейронная сеть (обозначенная как функция f с вводным модулем x и выводом f(x)) будет работать лучше с «остаточным соединением» x + f(x). Это остаточное соединение используется повсеместно в самых современных нейронных сетях, даже сегодня. Например, FBNetV2, FBNetV3.

      Загрузите это изображение собаки с помощью следующей команды:

      • wget -O assets/dog.jpg https://www.xpresservers.com/wp-content/uploads/2020/06/How-To-Trick-a-Neural-Network-in-Python-3.png

      Изображение корги, который бежит вдоль водоема

      Затем загрузите файл JSON для преобразования вывода в имя класса в удобной для чтения человеком форме:

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

      Затем создайте скрипт для запуска вашей предварительно обученной модели на изображении собаки. Создайте новый файл с именем step_2_pretrained.py​​​:

      • nano step_2_pretrained.py

      Сначала добавьте шаблон Python, импортируя необходимые пакеты и декларируя функцию 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()
      

      Затем загрузите преобразование из вывода нейронной сети в имя класса в удобной для чтения человеком форме. Добавьте это непосредственно после операторов импорта и перед функцией main:

      step_2_pretrained.py

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

      Создайте функцию преобразования изображения, которая обеспечит, во-первых, правильный размер вашего входного изображения, а во-вторых, корректную нормализованную форму. Добавьте следующую функцию непосредственно после последнего:

      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
      . . .
      

      В get_image_transform вы определите ряд различных трансформаций, которые будут применяться к изображениям, попадающим в вашу нейронную сеть:

      • transforms.Resize(224)​​​: меняет размер меньшей стороны изображения на 224. Например, если размер вашего изображения 448 х 672, данная операция уменьшит изображение до 224 х 336.
      • transforms.CenterCrop(224)​​: предлагает обрезку из центра изображения, размер 224 х 224
      • transforms.ToTensor()​​: конвертирует изображение в тензор PyTorch. Во всех моделях PyTorch в качестве входного модуля требуется использование тензоров PyTorch.
      • transforms.Normalize(mean=..., std=…)​​: стандартизирует ваш входной модуль путем вычитания среднего значения, а затем деления на стандартную девиацию. Более подробно это описано в документации torchvision.

      Добавьте утилиту, чтобы предсказывать класс животного по изображению. Этот метод использует обе предыдущие утилиты для классификации животных:

      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
      . . .
      

      Здесь функция predict​​​ классифицирует предоставленное изображение, используя предварительно обученную нейронную сеть:

      • models.resnet18(pretrained=True)​​​: загружает предварительно обученную нейронную сеть под названием ResNet18.
      • model.eval()​​​: изменяет присутствующую модель для работы в режиме ‘оценки’. Единственный иной режим — это режим обучения, но он не нужен, так как вы не обучаете модель (т. е. не обновляете параметры модели) в рамках данного обучающего руководства.
      • out = model(image): запускает нейронную сеть на предоставленном и преобразованном изображении.
      • _, pred = torch.max(out, 1): нейронная сеть выводит одну вероятность для каждого возможного класса. Этот шаг вычисляет индекс класса с самой высокой вероятностью. Например, если out = [0.4, 0.1, 0.2]​​​, тогда pred = 0.
      • idx_to_label = get_idx_to_label(): получает преобразование из индекса класса в имя класса в удобной для чтения человеком форме. Например, преобразование может быть {0: cat, 1: dog, 2: fish}.
      • cls = idx_to_label[str(int(pred))]: конвертирует предсказанный индекс класса в имя класса. Примеры, приведенные в последних двух пунктах списка, будут давать cls = idx_to_label[0] = 'cat'​​​.

      Далее, после последней функции добавьте утилиту для загрузки изображений:

      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
      . . .
      

      Это позволит загружать изображение через путь, представленный в первом аргументе, в скрипт. transform(image)[None]​​​ использует последовательность трансформаций изображения, определенную в предыдущих строках.

      Наконец, заполните вашу функцию main следующим содержанием, чтобы загрузить изображение и классифицировать животное на нем:

      step_2_pretrained.py

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

      Проверьте еще раз, соответствует ли ваш файл сценарию финального шага 2 в step_2_pretrained.py на GitHub. Сохраните и закройте скрипт, потом запустите классификатор животных:

      • python step_2_pretrained.py assets/dog.jpg

      Это позволит получить следующий вывод, означающий, что ваш классификатор животных работает так, как и ожидалось:

      Output

      Prediction: Pembroke, Pembroke Welsh corgi

      В заключение выполняется запуск логического вывода вашей предварительно обученной модели. Затем вы увидите, как действует состязательный образец, «обманывая» нейронную сеть с помощью незначительных различий в изображении.

      Шаг 3 — Испытание состязательного образца

      Теперь вы синтезируете состязательный образец и протестируете на нем нейронную сеть. В ходе выполнения данного обучающего руководства вы построите состязательный образец формы x + r, где x — это оригинальное изображение, а r — некоторые «отклонения». Далее вы будете создавать отклонения r самостоятельно, но на данном этапе вы загрузите то, которое мы создали для вас заранее. Начните с загрузки отклонения r:

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

      Теперь соедините изображение с отклонением. Создайте новый файл с именем step_3_adversarial.py​​​:

      • nano step_3_adversarial.py

      В этом файле вы выполните следующий трехступенчатый процесс, чтобы получить состязательный образец:

      1. Преобразование изображения
      2. Применение отклонения r
      3. Обратное преобразование изображения с отклонением

      После выполнения шага 3 вы получите состязательный образец. Сначала импортируйте необходимые пакеты и декларируйте функцию 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()
      

      Далее создайте «трансформацию изображения», которая инвертирует предыдущую трансформацию изображения. Разместите это после операций импорта, перед функцией 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])
      . . .
      

      Как и ранее, операция transforms.Normalize​​​ вычитает среднее значение и делит на стандартное отклонение (т.е. для оригинального изображения x, y = transforms.Normalize(mean=u, std=o) = (x - u) / o). Вы делаете определенные вычисления и определяете новую операцию, которая возвращает нормализованную функцию (transforms.Normalize(mean=-u/o, std=1/o) = (y - -u/o) / 1/o = (y + u/o) o = yo + u = x).

      В рамках обратного преобразования добавьте метод, который преобразовывает тензор PyTorch обратно в изображение PIL. Добавьте это после последней функции:

      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()​​ конвертирует тензор PyTorch в массив NumPy. .transpose(1, 2, 0) перестраивает (channels, width, height) в (height, width, channels). Этот массив NumPy примерно находится в диапазоне (0, 1). Наконец, умножьте на 255, чтобы убедиться, что изображение находится сейчас в диапазоне (0, 255).
      • np.clip гарантирует, что все значения в изображении находятся между (0, 255).
      • x.astype(np.uint8) гарантирует, что все значения изображения являются целыми числами. Наконец, Image.fromarray(...) создает объект изображения PIL из массива NumPy.

      Затем используйте эти утилиты для создания состязательного образца:

      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
      . . .
      

      Эта функция генерирует состязательный образец, описанный в начале этого раздела:

      1. y = x + r. Возьмите ваше отклонение r и добавьте его в оригинальное изображение x.
      2. get_inverse_transform​​:Получите и примените обратное преобразование изображения, которое вы установили несколькими строками ранее.
      3. tensor_to_image: Конвертируйте тензор PyTorch обратно в изображение объекта.

      А теперь внесите изменения в функцию main, чтобы загрузить изображение, загрузите состязательное отклонение r, примените отклонение, сохраните состязательный образец на диск и запустите прогноз по состязательному образцу:

      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)}')
      

      Ваш завершенный файл должен соответствовать step_3_adversarial.py на GitHub. Сохраните файл, закройте редактор и запустите скрипт с помощью следующей команды:

      • python step_3_adversarial.py assets/dog.jpg

      Вы увидите следующий результат:

      Output

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

      Теперь вы создали состязательный образец, который заставляет нейронную сеть распознавать корги, как золотую рыбку. На следующем шаге вы фактически создадите отклонение r, которое использовали здесь.

      Шаг 4 — Принцип работы состязательного образца

      Для начала вы можете ознакомиться со статьей Создание эмоционального фильтра «Собака».

      Учитывая пройденный материал, вспомните, что ваша классификационная модель выводит вероятность для каждого класса. В логическом выводе модель предсказывает класс с самой высокой вероятностью. Во время обучения вы обновляете параметры модели t, чтобы максимально увеличить вероятность определения правильного класса y с учетом ваших данных x.

      argmax_y P(y|x,t)
      

      Но сейчас вы измените свою цель, чтобы создать состязательные образцы. Вместо определения класса, вашей целью будет поиск нового изображения x. Возьмите любой другой класс, помимо правильного. Назовем этот новый класс w. Ваша новая цель — увеличить вероятность определения неправильного класса.

      argmax_x P(w|x)
      

      Обратите внимание, что веса нейронных сетей t отсутствуют в вышеупомянутом выражении. Причина в том, что сейчас вы берете на себя роль противника — кто-то другой обучил и развернул модель. Вам разрешено создавать состязательные входные модули и запрещено видоизменять развернутую модель. Чтобы создать состязательный пример x, вы можете запустить «тренировку», но вместо обновления весов нейронных сетей, вы обновите входящее изображение с новой целью.

      Напомним, что в этом обучающем руководстве вы предполагаете, что состязательный пример является аффинным преобразованием x. Другими словами, ваш состязательный пример принимает форму x + r для некоторых r. На следующем шаге вы напишете скрип, чтобы создать это r.

      Шаг 5 — Создание состязательного образца

      На этом шаге вы познакомитесь с отклонением r, из-за которого ваш корги будет классифицирован как золотая рыбка. Создайте новый файл с именем step_5_perturb.py​​​:

      Импортируйте необходимые пакеты и декларируйте функцию 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()
      

      Непосредственно за операциями импорта и перед функцией main определите две константы:

      step_5_perturb.py

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

      Первая константа TARGET_LABEL — это класс, которым будет неправильно классифицироваться корги. В данном случае индекс 1 соответствует «золотой рыбке». Вторая константа EPSILON — это максимальное количество отклонений, разрешенное для каждого значения изображения. Это ограничение вводится, чтобы изменения изображения были незаметны.

      После двух констант добавьте вспомогательную функцию для определения нейронной сети и параметра отклонения 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) загружает предварительно обученную нейронную сеть под названием ResNet18, как и ранее. Также, как и ранее, вы устанавливаете модель в режим оценки, используя .eval.
      • nn.Parameter(...) определяет новое отклонение r, размер входного изображения. Входное изображение имеет размер (1, 3, 224, 224). Основной аргумент requires_grad=True обеспечивает возможность обновить данное отклонение r в последующих строках в этом файле.

      Затем начинайте вносить изменения в вашу функцию main. Начните с загрузки модели net, загрузки вводных x и определения ярлыка 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()
        . . .
      

      Затем определите критерий и оптимизатор в функции main. Первый указывает PyTorch, что является целью, т. е. какие потери минимизировать. Второй указывает PyTorch, как обучать параметр r:

      step_5_perturb.py

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

      Сразу за этим добавьте основной обучающий цикл для параметра r:

      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))]}')
      . . .
      

      На каждой итерации данного обучающего цикла вы сможете следующее:

      • r.data.clamp_(...): Убедиться, что параметр r невелик и находится в пределах EPSILON 0.
      • optimizer.zero_grad(): Очистить любые градиенты, которые вы вычислили в предыдущей итерации.
      • model(x + r): Запустить логический вывод на модифицированном изображении x + r.
      • Вычислить loss.
      • Вычислить градиент loss.backward.
      • Определить шаг градиентного спуска optimizer.step.
      • Вычислить прогноз pred.
      • Наконец, сообщить о потере и прогнозируемом классе print(...).

      Затем сохраните финальное отклонение r:

      step_5_perturb.py

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

      Непосредственно за этим в функции main сохраните изображение с отклонением:

      step_5_perturb.py

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

      После этого запустите прогноз на оригинальном изображении и на состязательном образце:

      step_5_perturb.py

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

      Еще раз убедитесь, что ваш скрипт соответствует step_5_perturb.py на GitHub. Сохраните, выйдите и запустите скрипт:

      • python step_5_perturb.py assets/dog.jpg

      Ваш скрипт покажет следующий вывод.

      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

      Последние две строки указывают на то, что вы закончили построение состязательного образца с нуля. Теперь ваша нейронная сеть классифицирует совершенно однозначное изображение корги как золотую рыбку.

      Теперь вы показали, что нейронные сети можно легко обмануть. Более того, отсутствие устойчивости к состязательным образцам имеет значительные последствия. Далее возникает естественный вопрос: как можно бороться с состязательными образцами? Различные организации, включая OpenAI​​​, провели множество исследований на эту тему. В следующем разделе вы запустите защиту, чтобы пресечь воздействие состязательного образца.

      Шаг 6 — Защита от состязательных образцов

      На этом шаге вы создадите защиту от состязательных образцов. Идея заключается в следующем: теперь вы являетесь владельцем классификатора животных, развернутого в производство. Вы не знаете, какие состязательные образцы могут быть созданы, но вы можете изменить изображение или модель для защиты от атак.

      Перед тем как защитить себя, вы должны понять, насколько незначительной может быть манипуляция. Откройте оба следующих изображения:

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

      Здесь они представлены рядом. Ваше оригинальное изображение будет иметь другие пропорции. Вы можете сказать, какое из изображений является состязательным образцом?

      (слева) Корги как золотая рыбка, состязательное изображение, (справа) корги как корги, не состязательное изображение)

      Обратите внимание, что новое изображение выглядит идентичным оригиналу. Как оказалось, левое изображение — это ваше состязательное изображение. Чтобы убедиться, загрузите изображение и запустите скрипт оценки:

      • 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

      Это позволит получить вывод о том, что изображение принадлежит к классу «золотая рыбка», что доказывает состязательную природу изображения:

      Output

      Prediction: goldfish, Carassius auratus

      Вы запустите довольно примитивную, но эффективную защиту: сжатие изображения с потерями путем записи в формате JPEG. Откройте интерактивную строку Python:

      Затем загрузите состязательное изображение как PNG, и сохраните его снова как JPEG.

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

      Введите CTRL + D, чтобы покинуть интерактивную строку Python. Затем запустите логический вывод с помощью вашей модели на сжатом состязательном образце:

      • python step_2_pretrained.py outputs/adversarial.jpg

      Теперь это позволит получить вывод о том, что изображение принадлежит к классу «корги», что доказывает эффективность вашей примитивной защиты.

      Output

      Prediction: Pembroke, Pembroke Welsh corgi

      Вы создали свою первую состязательную защиту. Обратите внимание, что эта защита не требует представления о том, как был создан состязательный образец. Вот как работает эффективная защита. Также существует много других форм защиты, многие из которых связаны с переподготовкой нейронной сети. Однако эти процедуры переподготовки являются отдельной темой и выходят за рамки данного обучающего руководства. На этом ваше введение в состязательное машинное обучение завершается.

      Заключение

      Чтобы понять результаты вашей работы с этим обучающим руководством, вернитесь к этим двум изображениям, размещенным рядом — оригинальному и состязательному образцу.

      (слева) Корги как золотая рыбка, состязательное изображение, (справа) корги как корги, не состязательное изображение)

      Несмотря на то, что оба изображения выглядят идентичными для человеческого глаза, в первое внесены изменения для того, чтобы обмануть вашу модель. На обоих изображениях явно представлен корги, но модель все равно уверена, что на втором изображении золотая рыбка. Вы должны обратить на это внимание и после завершения работы с данным обучающем руководством не забывать о том, насколько уязвимой может быть ваша модель. Вы можете обмануть ее, просто применив простое преобразование. Это реальная и возможная угроза, с которой может столкнуться даже передовое исследование. Исследования за пределами безопасности машинного обучения также восприимчивы к этим недостаткам, и вам, как практику, решать, как безопасно применять машинное обучение. Чтобы получить дополнительную информацию, ознакомьтесь с этими ссылками:

      • Adversarial Machine Learning (Состязательное машинное обучение), обучающее руководство по материалам конференции NeurIPS 2018.
      • Соответствующие посты блога от OpenAI о состязательных образцах и устойчивости перед состязательными атаками.

      Дополнительную информацию о машинном обучении, а также обучающие руководства вы можете найти на странице, посвященной машинному обучению.



      Source link