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

      Sysadmin eBook: Как заставить серверы работать


      Загрузите полную электронную книгу!

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

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

      Описание электронной книги

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

      Книга основана на учебном курсе «Как заставить серверы работать: практическое руководство по администрированию систем Linux», который можно найти в сообществе DigitalOcean. Она включает несколько основных тем:

      1. Вводные темы

      2. Технологические стеки LAMP и LEMP

      3. Обеспечение безопасности серверов

      4. Автоматизация с помощью Ansible

      5. Контроль версий и непрерывная интеграция

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

      Загрузить электронную книгу

      Вы можете загрузить электронную книгу в формате EPUB или PDF по одной из следующих ссылок.

      Загрузите полную электронную книгу!

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

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

      Дополнительные ресурсы для системных администраторов, которые помогут вам начать работать в этой области и участвовать в сообществе DigitalOcean вместе с другими разработчиками и администраторами, можно найти в нашей постоянно растущей библиотеке обучающих руководств, ответов на вопросы и проектов с тегом Getting Started (Начало работы).



      Source link

      Как записывать сеансы терминала и обмениваться ими при помощи Terminalizer в Ubuntu 18.04


      Автор выбрал фонд Electronic Frontier Foundation для получения пожертвований в рамках программы Write for DOnations.

      Введение

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

      Запись сеанса терминала полезна, если вы хотите просмотреть конкретную деятельность снова или поспособствовать в отладке особенно сложной ошибки. Записи, выполняемые при помощи Terminalizer, могут также экспортироваться в качестве анимированных GIF, которые полезны для обмена в онлайн-режиме или добавления в маркетинговые материалы вашего программного обеспечения.

      В этом обучающем руководстве вы установите Terminalizer, используете его для записи и воспроизведения сеансов терминала, настроите свои записи и затем экспортируете их для обмена в онлайн-режиме.

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

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

      Если вы хотите поделиться своими записями в онлайн-режиме, вам понадобится следующее:

      Подготовив все вышеперечисленное, войдите на сервер без привилегий root, чтобы начать подготовку.

      Шаг 1 — Установка Terminalizer

      На этом шаге вы скачаете и установите Terminalizer в вашей системе. Terminalizer написан с помощью Node.js и может быть установлен с помощью диспетчера пакетов npm.

      Чтобы установить Terminalizer на глобальном уровне в вашей системе, выполните следующую команду:

      • sudo npm install --global --allow-root --unsafe-perm=true terminalizer

      Terminalizer использует каркас приложений Electron для экспорта зарегистрированных сеансов терминала в формат GIF. Для установки Electron на глобальном уровне в вашей системе требуется аргумент команды --unsafe-perms=true.

      После установки Terminalizer вы увидите примерно следующий вывод:

      Output

      . . . /usr/local/lib └── terminalizer@0.7.1

      Далее проверьте установку Terminalizer, запустив следующую команду:

      Будет выведен текст следующего вида:

      Output

      0.7.1

      В заключение сгенерируйте файл конфигурации Terminalizer по умолчанию, который можно использовать для расширенной настройки Terminalizer (подробнее см. в шаге 4):

      Результат будет выглядеть примерно следующим образом:

      Output

      The global config directory is created at /home/user/.terminalizer

      Теперь, когда вы установили Terminalizer, можно сделать первую запись терминала.

      Шаг 2 — Запись и воспроизведение сеанса терминала

      На этом шаге вы записываете и воспроизводите сеанс терминала.

      В начале настройте новую запись Terminalizer с помощью имени на ваш выбор:

      • terminalizer record your-recording

      В результате будет выведено следующее, чтобы указать, что запись началась:

      Output

      The recording session has started Press Ctrl+D to exit and save the recording

      Теперь вы можете перейти к любым необходимым действиям в вашем терминале. Каждое нажатие клавиши и команда будут записываться в реальном времени в Terminalizer.

      Например:

      • pwd
      • date
      • whoami
      • echo "Hello, world!"

      Когда хотите остановить запись, нажмите CTRL+D. Затем Terminalizer сохранит запись в указанном файле в формате YAML, например your-recording.yml.

      Output

      Successfully Recorded The recording data is saved into the file: /home/user/your-recording.yml

      Возможно, Terminalizer предложит поделиться записью в онлайн-режиме. Сейчас нажмите CTRL+C для отмены этого, поскольку вы можете сначала воспроизвести запись терминала локально.

      Далее воспроизведите ваш записанный сеанс терминала при помощи следующей команды:

      • terminalizer play your-recording

      В результате записанный сеанс будет воспроизведен в реальном времени в вашем терминале:

      Output

      user@droplet:~$ pwd /home/user user@droplet:~$ date Sun Mar 8 14:55:36 UTC 2020 user@droplet:~$ whoami user user@droplet:~$ echo "Hello, world!" Hello, world! user@droplet:~$ logout

      Также вы можете изменять скорость воспроизведения вашей записи при помощи опции --speed-factor.

      Например, следующее действие будет воспроизводить вашу запись в два раза медленнее (½ скорости):

      • terminalizer play your-recording --speed-factor 2

      Также вы можете воспроизвести запись в два раза быстрее (скорость х 2):

      • terminalizer play your-recording --speed-factor 0.5

      Вы записали и воспроизвели сеанс терминала. Далее вы можете поделиться записью терминала в онлайн-режиме.

      Шаг 3 — Обмен записанными сеансами терминала

      На этом шаге вы поделитесь своим записанным сеансом терминала в онлайн-режиме на странице изучения Terminalizer.

      Сначала выберите записанный сеанс, которым вы хотите поделиться:

      • terminalizer share your-recording

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

      Output

      Please enter some details about your recording ? Title Title of Your Recording ? Description Description of Your Recording ? Tags such as git,bash,game Comma-separated Tags for Your Recording

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

      Если вы впервые поделились записанным сеансом с помощью Terminalizer, вам нужно будет привязать свою учетную запись Terminalizer. Terminalizer отобразит ссылку для подтверждения, если это потребуется:

      Output

      Open the following link in your browser and login into your account https://terminalizer.com/token?token=your-token When you do it, press any key to continue

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

      После того как вы прошли по ссылке в вашем браузере и вошли в вашу учетную запись Terminalizer, нажмите любую клавишу, чтобы продолжить.

      Теперь Terminalizer загрузит вашу запись и предоставит ссылку для ее просмотра:

      Output

      Successfully Uploaded The recording is available on the link: https://terminalizer.com/view/your-recording-id

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

      Скриншот веб-сайта Terminalizer, показывающий пример записи терминала, которой вы поделились

      Вы поделились записанным сеансом терминала на веб-сайте Terminalizer и просмотрели его в браузере.

      Шаг 4 — Настройка расширенной конфигурации Terminalizer

      Теперь, когда вы ознакомились с Terminalizer, вы можете начинать рассматривать некоторые более расширенные опции персонализации, такие как способность изменять цвета и стили отображения.

      Каждая запись наследует конфигурацию по умолчанию из глобального файла конфигурации Terminalizer, который находится в ~/.terminalizer/config.yml​​​. Это означает, что вы можете изменять конфигурацию для отдельных записей напрямую, изменяя файл записи (например, your-recording.yml). Также вы можете изменять глобальную конфигурацию, которая будет влиять на все новые записи.

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

      Сначала откройте файл глобальной конфигурации Terminalizer в текстовом редакторе, например nano:

      • nano ~/.terminalizer/config.yml

      Каждая из доступных опций конфигурации в этом файле прокомментирована, чтобы объяснить, что она делает.

      Есть несколько стандартных вариантов конфигурации, которые вы, возможно, захотите изменить по вашему желанию:

      • cols: в явном виде задает количество столбцов терминала, используемых для записи.
      • rows: в явном виде задает количество строк терминала, используемых для записи.
      • frameDelay: переопределяет задержку между каждым нажатием клавиши во время воспроизведения.
      • maxIdleTime: указывает максимальное время между нажатиями клавиш во время воспроизведения.
      • cursorStyle: указывает стиль курсора умолчанию на выбор из прямоугольника, полосы и подчеркивания.
      • fontFamily: указывает список предпочитаемых шрифтов воспроизведения в порядке предпочтения.
      • theme: изменяет цветовую схему воспроизведения, например для создания черно-белого терминала и т. п.

      Например, вы можете сделать бело-черный дисплей терминала, настроив следующие опции:

      config.yml

      . . .
      theme:
        background: "white"
        foreground: "black"
      . . .
      

      Результат будет выглядеть примерно так:

      Скриншот веб-сайта Terminalizer, показывающий пример записи с черно-белой темой

      Вы можете изменять стиль курсора, упрощая понимание записи, например, посредством изменения курсора по умолчанию в виде прямоугольника на курсор в виде подчеркивания:

      config.yml

      . . .
      cursorStyle: underline
      . . .
      

      Результат будет выглядеть примерно так:

      Скриншот веб-сайта Terminalizer, показывающий пример записи с курсором в виде подчеркивания​​

      После внесения всех необходимых изменений сохраните файл и возвращайтесь в терминал.

      Если вы изменили глобальную конфигурацию Terminalizer, эти настройки будут применяться ко всем новым записям, выполняемым далее. Если вы изменяете конфигурацию конкретной записи, Terminalizer немедленно применяет изменения к этой конкретной записи.

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

      На этом последнем шаге вы рассмотрели некоторые из расширенных вариантов настройки конфигурации в Terminalizer.

      Заключение

      В этой статье вы использовали Terminalizer для записи сеанса терминала и обмена данными о нем. Теперь у вас есть знания, необходимые для создания записанных демо-версий вашего программного обеспечения для использования в маркетинговых материалах или для обмена секретными приемами командной строки с друзьями.

      Если вы хотите сделать рендеринг и экспорт записей Terminalizer в формат GIF, вы можете установить Terminalizer на компьютере с графическим интерфейсом пользователя/на настольном компьютере и использовать встроенные функции рендеринга:

      Также вы можете посетить веб-сайт Terminalizer, чтобы увидеть записанные сеансы терминала, которыми поделились другие пользователи:



      Source link