One place for hosting & domains

      enganar

      Cómo engañar a una red neural en Phyton 3


      El autor seleccionó a Dev Color para recibir una donación como parte del programa Write for DOnations.

      ¿Sería posible engañar a una red neural para la clasificación de animales? Engañar a un clasificador de animales puede tener algunas consecuencias, ¿pero si pudiésemos engañar a nuestro autenticador facial? ¿O al software del prototipo de un vehículo autónomo? Afortunadamente, legiones de ingenieros e investigaciones están entre un modelo de visión computarizada de un prototipo y los modelos de calidad de producción, en nuestros dispositivos móviles o en nuestros vehículos. Aun así, estos riesgos tienen implicaciones significativas y es importante tenerlos en cuenta como profesional del aprendizaje automático.

      En este tutorial, intentará “engañar” a un clasificador de animales. A medida que avanza en este tutorial, usará OpenCV, una biblioteca de visión de computadora, y PyTorch, una biblioteca de aprendizaje profundo. Cubrirá los siguientes temas en el campo asociado de aprendizaje automático contradictorio:

      • Cree un ejemplo contradictorio objetivo. Seleccione una imagen, digamos un perro. Seleccione una clase objetivo, por ejemplo un gato. Su objetivo es engañar a la red neural para que crea que el perro de la imagen es un gato.
      • Cree una defensa contradictoria. En resumen, proteja su red neural contra estas imágenes engañosas, sin que sepa cuál es el truco.

      Al final de este tutorial, tendrá una herramienta para engañar a las redes neurales y comprenderá cómo defenderse contra los trucos.

      Requisitos previos

      Para completar este tutorial, necesitará lo siguiente:

      Paso 1: Clonar su proyecto e instalar las dependencias

      Vamos a crear un espacio de trabajo para este proyecto e instalaremos las dependencias que va a necesitar. Llamará a su espacio de trabajo AdversarialML:

      Diríjase al directorio AdversarialML:

      Cree un directorio para albergar sus activos:

      • mkdir ~/AdversarialML/assets

      Luego, cree un nuevo entorno virtual para el proyecto:

      • python3 -m venv adversarialml

      Active su entorno:

      • source adversarialml/bin/activate

      A continuación, instale PyTorch, un marco de trabajo de aprendizaje profundo para Python que utilizaremos en este tutorial.

      En macOS, instale Pytorch con el siguiente comando:

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

      En Linux y Windows, utilice los siguientes comandos para una compilación solo de 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

      Ahora instale los binarios empaquetados previamente para OpenCV y numpy, que son bibliotecas para la visión computarizada y el álgebra lineal, respectivamente. OpenCV ofrece utilidades como las rotaciones de imágenes y numpy ofrece utilidades de álgebra lineal, como la inversión de una matriz:

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

      En las distribuciones de Linux, deberá instalar libSM.so:

      • sudo apt-get install libsm6 libxext6 libxrender-dev

      Con las dependencias instaladas, vamos a ejecutar y clasificador de animales llamado ResNet18, que describiremos a continuación.

      Paso 2: Ejecutar un clasificador de animales preentrenado

      La biblioteca torchvision, la biblioteca de visión computarizada oficial para PyTorch, contiene versiones preentrenadas de redes neurales de visión computarizada usadas comúnmente. Estas redes neurales están entrenadas sobre ImageNet 2012, un conjunto de datos de 1,2 millones de imágenes de entrenamiento con 1000 clases. Estas clases incluyen vehículos, lugares y, sobre todo, animales. En este paso, ejecutará una de estas redes neurales preentrenadas, llamada ResNet18. Nos referiremos a ResNet18 entrenado en ImageNet como un “clasificador de animales”.

      ¿Qué es ResNet18? ResNet18 es la red neural más pequeña en una familia de redes neurales llamada redes neurales residuales, desarrollada por MSR (He et al.). En resumen, He descubrió que una red neural (denominada como una función f, con entrada x, y salida f(x) funcionaría mejor con una “conexión residual” x + f(x). Esta conexión residual se utiliza prolíficamente en redes neurales de última generación, incluso hoy en día. Por ejemplo, FBNetV2, FBNetV3.

      Descargue esta imagen de un perro con el siguiente comando:

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

      Imagen de un corgi corriendo cerca de un estanque

      A continuación, descargue un archivo JSON para convertir el resultado de la red neural a un nombre de clase legible por el ser humano:

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

      A continuación, cree una secuencia de comandos para ejecutar su modelo preentrenado sobre la imagen del perro. Cree un nuevo archivo llamado step_2_pretrained.py:

      • nano step_2_pretrained.py

      Primero, añada el texto estándar de Python importando los paquetes necesarios y declarando una función 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()
      

      A continuación, cargue la asignación desde el resultado de la red neural a nombres de clase legibles por el ser humano. Añada esto directamente tras sus declaraciones de importación y antes de su función main:

      step_2_pretrained.py

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

      Cree una función de transformación de imagen que garantizará que primero su imagen de entrada tenga las dimensiones correctas, y segundo que se haya normalizado correctamente. Añada la siguiente función directamente tras la última:

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

      En get_image_transform, define un número de diferentes transformaciones que aplicar a las imágenes que se pasan a su red neural.

      • transforms.Resize(224): cambia el tamaño del lado más pequeño de la imagen a 224. Por ejemplo, si su imagen es 448 x 672, esta operación reduciría la imagen a 224 x 336.
      • transforms.CenterCrop(224): hace un recorte desde el centro de la imagen, de un tamaño de 224 x 224.
      • transforms.ToTensor(): convierte la imagen a un tensor PyTorch. Todos los modelos requieren tensores PyTorch como entrada.
      • transforms.Normalize(mean=..., std=...): normaliza su entrada sustrayendo la media y, luego, dividiendo la desviación estándar. Esto se describe de forma más precisa en la documentación de torchvision.

      Añada una utilidad para predecir la clase animal, dada la imagen. Este método usa las utilidades anteriores para realizar la clasificación de animales:

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

      Aquí la función predict clasifica la imagen proporcionada usando una red neural preentrenada:

      • models.resnet18(pretrained=True): carga una red neural preentrenada llamada ResNet18.
      • model.eval(): modifica el modelo implementado para que se ejecute en modo “evaluación”. El único otro modo es el modo “entrenamiento”, pero el modo de entrenamiento no es necesario, ya que no está entrenando el modelo (es decir, actualizando los parámetros del modelo) en este tutorial.
      • out = model(image): ejecuta la red neural sobre la imagen transformada que se proporciona.
      • _, pred = torch.max(out, 1): la red neural da como resultado una probabilidad para cada clase posible. Este paso calcula el índice de la clase con la más alta probabilidad. Por ejemplo, si out = [0.4, 0.1, 0.2], entonces pred = 0.
      • idx_to_label = get_idx_to_label(): obtiene una asignación desde el índice de clase a nombres de clase legibles por el ser humano. Por ejemplo, la asignación podría ser {0: cat, 1: dog, 2: fish}.
      • cls = idx_to_label[str(int(pred))]: convierte el índice de clase predicho a un nombre de clase. Los ejemplos proporcionados en los últimos dos puntos arrojarían cls = idx_to_label[0] = 'cat.

      A continuación, tras la última función, añada una utilidad para cargar imágenes:

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

      Esto cargará una imagen desde la ruta proporcionada en el primer argumento a la secuencia de comandos. transform(image)[None] aplica la secuencia de las transformaciones de la imagen definidas en las líneas anteriores.

      Finalmente, complete su función main con lo siguiente para cargar su imagen y clasificar el animal de la imagen:

      step_2_pretrained.py

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

      Compruebe que su archivo coincida con la secuencia de comandos final del paso 2 en step_2_pretrained.py en GitHub. Guarde y salga de su secuencia de comandos, y ejecute el clasificador de animales.

      • python step_2_pretrained.py assets/dog.jpg

      Esto producirá el siguiente resultado, lo que muestra que su clasificador de animales funciona como se espera:

      Output

      Prediction: Pembroke, Pembroke Welsh corgi

      Eso concluye ejecutar la interferencia con su modelo preentrenado. A continuación, verá un ejemplo contradictorio en acción engañando a una red neural con diferencias imperceptibles en la imagen.

      Paso 3: Probar un ejemplo contradictorio

      Ahora, sintetizará un ejemplo contradictorio, y probará la red neural en ese ejemplo. Para este tutorial, creará ejemplos contradictorios en formato x + r, donde x es la imagen original y r es cierta “perturbación”. Eventualmente creará la perturbación r usted mismo, pero, en este paso, descargará una que hemos creado de antemano. Comience descargando la perturbación r:

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

      Ahora componga la imagen con la perturbación. Cree un nuevo archivo llamado step_3_adversarial.py:

      • nano step_3_adversarial.py

      En este archivo, realizará el siguiente proceso de tres pasos para producir un ejemplo contradictorio:

      1. Transformar una imagen
      2. Aplicar la perturbación r
      3. Transformar a la inversa la imagen perturbada

      Al final del paso 3, tendrá una imagen contradictoria. Primero, importe los paquetes necesarios y declare una función 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()
      

      A continuación, cree una “transformación de imagen” que invierta la transformación de la imagen anterior. Ponga esto tras sus importaciones, antes de la función 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])
      . . .
      

      Como antes, la operación transforms.Normalize sustrae la media y divide por la desviación estándar (es decir, para la imagen original x, y = transforms.Normalize(mean=u, std=o) = (x - u) / o). Haga algo de álgebra y defina una nueva operación que invierta esta función normalizar (transforms.Normalize(mean=-u/o, std=1/o) = (y - -u/o) / 1/o = (y + u/o) o = yo + u = x).

      Como parte de la transformación inversa, añada un método que transforme un tensor PyTorch de vuelta a una imagen PIL. Añada esto tras la última función:

      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() convierte el tensor PyTorch en una matriz NumPy. .transpose(1, 2, 0) reordena (channels, width, height)en (height, width, channels). Esta matriz NumPy está aproximadamente en el intervalo (0, 1). Finalmente, multiplique por 255 para garantizar que la imagen está ahora en el intervalo (0, 255).
      • np.clip garantiza que todos los valores de la imagen están entre (0, 255).
      • x.asype(np.uint8) garantiza que todos los valores de la imagen sean enteros. Finalmente, Image.fromarray(...) crea un objeto de imagen PIL desde la matriz NumPy.

      A continuación, use estas utilidades para crear el ejemplo contradictorio con lo siguiente:

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

      Esta función genera el ejemplo contradictorio descrito al inicio de la sección:

      1. y = x + r. Tome su perturbación r y añádala a la imagen original x.
      2. get_inverse_transform: obtenga y aplique la transformación de imagen inversa que definió hace varias líneas.
      3. tensor_to_image: por último, convierta el tensor PyTorch de vuelta a un objeto de imagen.

      Finalmente, modifique su función main para cargar la imagen, cargue la perturbación contradictoria r, aplique la perturbación, guarde el ejemplo contradictorio en el disco y ejecute la predicción sobre el ejemplo contradictorio:

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

      Su archivo completado debería coincidir con step_3_adversarial.py en GitHub. Guarde el archivo, salga del editor e inicie su secuencia de comandos con:

      • python step_3_adversarial.py assets/dog.jpg

      Verá este resultado:

      Output

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

      Ahora ha creado un ejemplo contradictorio: engañar a la red neural para que crea que un corgi es un pez dorado. En el siguiente paso, creará la perturbación r que utilizó aquí.

      Paso 4: Comprender un ejemplo contradictorio

      Para obtener una preparación sobre la clasificación, consulte “Cómo crear un filtro de perro basado en emociones”.

      Dando un paso atrás, recuerde que su modelo de clasificación produce una probabilidad para cada clase. Durante la inferencia, el modelo predice la clase con la mayor probabilidad. Durante el entrenamiento, actualiza los parámetros del modelo t para maximizar la probabilidad de la clase correcta y, según sus datos x.

      argmax_y P(y|x,t)
      

      Sin embargo, para generar ejemplos contradictorios, ahora modifica su objetivo. En vez de encontrar una clase, su objetivo ahora es encontrar una nueva imagen, x. Tome cualquier clase distinta a la correcta. Vamos a llamar a esta nueva clase w. Su nuevo objetivo es maximizar la probabilidad de tener una clase equivocada.

      argmax_x P(w|x)
      

      Observe que las ponderaciones t de la red neural faltan de la expresión anterior. Esto es porque ahora asume la función de la contradicción: alguien más ha entrenado e implementado un modelo. Solo se le permite crear entradas contradictorias y no se le permite modificar el modelo implementado. Para generar el ejemplo contradictorio x, puede ejecutar “entrenamiento”, excepto que en vez de actualizar las ponderaciones de la red neural, actualiza la imagen de entrada con el nuevo objetivo.

      Como recordatorio, para este tutorial, asume que el ejemplo contradictorio es una transformación afín de x. En otras palabras, su ejemplo contradictorio toma la forma x + r para algunos r. En el siguiente paso, escribirá secuencia de comandos para generar este r.

      Paso 5: Crear un ejemplo contradictorio

      En este paso, aprenderá una perturbación r, de forma que su corgi esté mal clasificado como un pez dorado. Cree un nuevo archivo llamado step_5_adversarial.py:

      Importe los paquetes necesarios y declare una función 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()
      

      Directamente tras sus importaciones y antes de la función main, defina dos constantes:

      step_5_perturb.py

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

      La primera constante TARGET_LABEL es la clase para clasificar erróneamente al corgi. En este caso, el índice 1 corresponde a “pez dorado”. La segunda constante EPSILON es la cantidad máxima de perturbación permitida para cada valor de imagen. Este límite se introduce de manera que la imagen se altere de forma imperceptible.

      Tras sus dos constantes, añada una función helper para definir una red neural y el parámetro perturbació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) carga una red neural preentrenada, llamada ResNet18, como antes. También como antes, establece el modelo para el modo de evaluación usando .eval.
      • nn.Parameter(...) define una nueva perturbación r, el tamaño de la imagen de entrada. La imagen de entrada también es de tamaño (1, 3, 224, 224). El argumento de palabra clave requires_grad=True garantiza que puede actualizar esta perturbación en líneas posteriores, en este archivo.

      A continuación, comience a modificar su función main. Comience cargando la red del modelo, cargando las entradas x y definiendo la etiqueta 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()
        . . .
      

      A continuación, defina tanto el criterio como el optimizador de su función main. El primero le indica a PyTorch cuál es el objetivo: es decir, qué pérdida minimizar. Este último le indica a PyTorch cómo entrenar su parámetro r:

      step_5_perturb.py

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

      Justo después, añada el bucle de entrenamiento principal para su parámetro 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))]}')
      . . .
      

      En cada iteración de este bucle de entrenamiento, usted:

      • r.data.clamp_(...): asegúrese de que el parámetro r es pequeño, dentro de EPSILON de 0.
      • optimizer.zero_grad(): borre cualquier gradiente que haya calculado en la iteración anterior.
      • model(x + r): ejecute la inferencia sobre la imagen modificada x + r.
      • Calcule la pérdida.
      • Calcule el gradiente loss.backward.
      • Tome un paso de descenso de gradiente optimizer.step.
      • Calcule la predicción pred.
      • Finalmente, informe de la pérdida y la clase predicha print(...).

      A continuación, guarde la perturbación final r:

      step_5_perturb.py

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

      Justo después, aún en la función main, guarde la imagen perturbada:

      step_5_perturb.py

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

      Finalmente, ejecute la predicción tanto sobre la imagen original como sobre el ejemplo contradictorio:

      step_5_perturb.py

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

      Compruebe que su secuencia de comandos coincide con step_5_perturb.py en GitHub. Guarde, salga y ejecute la secuencia de comandos.

      • python step_5_perturb.py assets/dog.jpg

      El resultado de su secuencia de comandos será la siguiente.

      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

      Las últimas dos líneas indican que ahora ha completado la construcción de un ejemplo contradictorio desde cero. Su red neural ahora clasifica una imagen de corgi perfectamente razonable como un pez dorado.

      Ahora ha demostrado que las redes neurales pueden ser engañadas fácilmente; además, la falta de robustez para los ejemplos contradictorios tiene consecuencias significativas. Una pregunta natural es esta: ¿cómo puede combatir los ejemplos contradictorios? Varias organizaciones han llevado a cabo extensas investigaciones, incluyendo OpenAI. En la siguiente sección, ejecutará una defensa para frustrar este ejemplo contradictorio.

      Paso 6: Defenderse contra ejemplos contradictorios

      En este paso, implementará una defensa contra ejemplos contradictorios. La idea es la siguiente: ahora es el propietario del clasificador de animales implementado a producción. No sabe qué ejemplos contradictorios pueden generarse, pero puede modificar la imagen o el modelo para protegerse contra ataques.

      Antes de defender, debería ver por sí que la manipulación de imágenes es imperceptible. Abra las dos imágenes siguientes:

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

      Aquí, muestra ambas juntas. Su imagen original tendrá una relación de aspecto diferente. ¿Sabe cuál es el ejemplo contradictorio?

      (izquierda) Corgi como pez dorado, contradictoria; (derecha) Corgi como sí mismo, no contradictoria

      Observe que la nueva imagen parece idéntica a la original. En realidad, la imagen izquierda es su imagen contradictoria. Para estar seguro, descargue la imagen y ejecute su secuencia de comandos de evaluació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

      Esto dará como resultado la clase goldfish para demostrar su naturaleza contradictoria:

      Output

      Prediction: goldfish, Carassius auratus

      Ejecutará una defensa bastante ingenua, pero eficaz: comprima la imagen escribiendo a un formato JPEG. Abra la instrucción interactiva Python:

      A continuación, cargue la imagen contradictoria como PNG y guárdela como JPEG.

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

      Escriba CTRL + D para dejar la instrucción interactiva Python. A continuación, ejecute la inferencia con su modelo en el ejemplo contradictorio comprimido:

      • python step_2_pretrained.py outputs/adversarial.jpg

      Ahora dará como resultado la clase corgi, demostrando la eficacia de su defensa ingenua.

      Output

      Prediction: Pembroke, Pembroke Welsh corgi

      Ahora ha completado su primera defensa contradictoria. Observe que esta defensa no requiere saber cómo se generó el ejemplo contradictorio. Esto es lo que hace que una defensa sea efectiva. Existen también muchas otras formas de defensa, muchas de las cuales implican volver a entrenar la red neural. Sin embargo, estos procedimientos de entrenamiento son un tema en sí mismos y están más allá del ámbito de este tutorial. Con esto, concluye su guía sobre el aprendizaje automático contradictorio.

      Conclusión

      Para comprender las implicaciones de su trabajo en este tutorial, vuelva a ver las dos imágenes lado a lado: la original y el ejemplo contradictorio.

      (izquierda) Corgi como pez dorado, contradictoria, (derecha) Corgi como sí mismo, no contradictoria

      A pesar de que ambas imágenes parecen idénticas al ojo humano, la primera ha sido manipulada para engañar a su modelo. Ambas imágenes claramente muestran un corgi, y aun así el modelo tiene total confianza de que el segundo modelo contiene un pez dorado. Esto debería preocuparle y, a medida que finaliza este tutorial, tenga en cuenta la fragilidad de su modelo. Solo aplicando una transformación simple, puede engañarlo. Estos son peligros reales y plausibles que evaden incluso con investigación de vanguardia. La investigación más allá de la seguridad del aprendizaje automático es igual de susceptible a estos defectos, como profesional, depende de usted aplicar el aprendizaje automático de forma segura. Para obtener más información, eche un vistazo a los siguientes enlaces:

      Para obtener más contenido sobre el aprendizaje automático, puede visitar nuestra página Tema de aprendizaje automático.



      Source link

      Como enganar uma rede neural no Python 3


      O autor selecionou a Dev Color para receber uma doação como parte do programa Write for DOnations.

      Será que uma rede neural para classificação de animais pode ser enganada? Enganar um classificador de animais pode gerar poucas consequências, mas e se nosso autenticador facial pudesse ser enganado? Ou o software do nosso protótipo de carro autônomo? Felizmente,existem legiões de engenheiros e pesquisas entre um modelo visual computacional protótipo e modelos de qualidade de produção em nossos dispositivos móveis ou carros. Ainda assim, esses riscos têm implicações significativas e é importante que sejam considerados pelos profissionais de machine learning.

      Neste tutorial, você irá tentar “iludir” ou enganar um classificador de animais. Ao longo do tutorial, você irá usar o OpenCV, uma biblioteca de visão computacional e o PyTorch, uma biblioteca de deep learning. Os seguintes tópicos serão abordados no campo associado do adversarial machine learning (machine learning contraditório):

      • Crie um exemplo contraditório direcionado. Escolha uma imagem, digamos, de um cachorro. Escolha uma classe alvo, digamos, um gato. Seu objetivo é enganar a rede neural para acreditar que o cão retratado é um gato.
      • Crie uma defesa contraditória. Em resumo, proteja sua rede neural contra essas imagens suspeitas, sem saber qual é o truque.

      Ao final do tutorial, você terá uma ferramenta para enganar redes neurais e um entendimento sobre como se defender contra os truques.

      Pré-requisitos

      Para concluir este tutorial, você precisará do seguinte:

      Passo 1 — Criando o projeto e instalando as dependências

      Vamos criar um espaço de trabalho para este projeto e instalar as dependências que você irá precisar. Você irá chamar seu espaço de trabalho AdversarialML:

      Navegue até o diretório AdversarialML:

      Crie um diretório para manter todos os seus recursos:

      • mkdir ~/AdversarialML/assets

      A seguir, crie um novo ambiente virtual para o projeto:

      • python3 -m venv adversarialml

      Ative seu ambiente:

      • source adversarialml/bin/activate

      Em seguida, instale o PyTorch, um framework de deep learning para Python que você usará neste tutorial.

      No macOS, instale o Pytorch com o seguinte comando:

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

      No Linux e Windows, utilize os seguintes comandos para uma compilação 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

      Agora, instale binários pré-empacotados para o OpenCV e numpy, que são bibliotecas para visão computacional e álgebra linear, respectivamente. O OpenCV oferece utilitários como rotações de imagem, e o numpy oferece utilitários de álgebra linear, como inversão de matriz:

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

      Em distribuições Linux, você precisará instalar a libSM.so:

      • sudo apt-get install libsm6 libxext6 libxrender-dev

      Com as dependências instaladas, vamos executar um classificador de animais chamado ResNet18, que descrevemos a seguir.

      Passo 2 — Executando um classificador de animais pré-treinado

      A biblioteca torchvision, que é a biblioteca oficial de visão computacional para o PyTorch, contém versões pré-treinadas de redes neurais de visão computacional comumente usadas. Essas redes neurais são todas treinadas no ImageNet 2012, um conjunto de dados que consiste em 1,2 milhões de imagens de treinamento com 1000 classes. Essas classes incluem veículos, lugares e, acima de tudo, animais. Neste passo, você irá executar uma dessas redes neurais pré-treinadas chamada ResNet18. Chamaremos a rede neural ResNet18 treinada no ImageNet de “classificador de animais”.

      O que é o ResNet18? O ResNet18 é a menor rede neural em uma família de redes neurais chamada redes neurais residuais, desenvolvida pela MSR (He et al.). Em resumo, ele descobriu que uma rede neural (denotada como uma função f, com entrada x, e saída f(x)) teria melhor desempenho com uma “conexão residual” x + f(x). Essa conexão residual é usada prolificamente em redes neurais no estado da arte, mesmo hoje. Por exemplo, FBNetV2, FBNetV3.

      Baixe esta imagem de um cachorro com o seguinte comando:

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

      Imagem de um corgi correndo perto de uma lagoa

      Então, baixe um arquivo JSON para converter o resultado da rede neural em um nome de classe humanamente legível:

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

      Em seguida, crie um script para executar seu modelo pré-treinado na imagem do cão. Crie um novo arquivo chamado step_2_pretrained.py:

      • nano step_2_pretrained.py

      Primeiro, adicione o código padrão Python importando os pacotes necessários e declarando uma função main (principal):

      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()
      

      Em seguida, carregue o mapeamento a partir do resultado da rede neural para nomes de classe humanamente legíveis. Adicione isto diretamente após suas declarações de importação e antes de sua função main:

      step_2_pretrained.py

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

      Crie uma função de transformação de imagem que irá garantir que sua imagem de entrada tenha as dimensões corretas e que seja normalizada corretamente. Adicione a seguinte função diretamente após a última:

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

      Em get_image_transform, você define um número de transformações diferentes para aplicar às imagens que são passadas para sua rede neural:

      • transforms.Resize(224): redimensiona o lado menor da imagem para 224. Por exemplo, se a imagem tiver 448 x 672, esta operação reduziria a resolução dela para 224 x 336.
      • transforms.CenterCrop(224): faz um recorte do centro da imagem, de tamanho 224 x 224.
      • transforms.ToTensor(): Converte a imagem em um tensor do PyTorch. Todos os modelos PyTorch exigem os tensores do PyTorch como entrada.
      • transforms.Normalize(mean=..., std=...): Normaliza sua entrada primeiro subtraindo a média, então dividindo pelo desvio padrão. Isso é descrito mais precisamente na documentação do torchvision.

      Adicione um utilitário para prever a classe animal, dada a imagem. Este método usa ambos os utilitários anteriores para realizar a classificação de animais:

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

      Aqui a função de predict (prever) classifica a imagem fornecida usando uma rede neural pré-treinada:

      • models.resnet18(pretrained=True): Carrega uma rede neural pré-treinada chamada ResNet18.
      • model.eval(): modifica o modelo em vigor para ser executar no modo ‘avaliação’. O único outro modo é o modo ‘treinamento’, mas o modo de treinamento não é necessário, pois você não está treinando o modelo (ou seja, atualizando os parâmetros do modelo) neste tutorial.
      • out = model(image): Executa a rede neural na imagem transformada fornecida.
      • _, pred = torch.max(out, 1): A rede neural gera uma probabilidade para cada classe possível. Esse passo computa o índice da classe com a maior probabilidade. Por exemplo, se out = [0.4, 0.1, 0.2], então pred = 0.
      • idx_to_label = get_idx_to_label(): Obtém um mapeamento do índice de classes para nomes de classe humanamente legíveis. Por exemplo, o mapeamento poderia ser {0: cat, 1: dog, 2: fish}.
      • cls = idx_to_label[str(int(pred))]: Converte o índice de classe previsto em um nome de classe. Os exemplos fornecidos nos dois últimos tópicos iriam gerar cls = idx_to_label[0] = 'cat'.

      Em seguida, adicione um utilitário para carregar imagens após a última função:

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

      Isso irá carregar uma imagem a partir do caminho fornecido no primeiro argumento para o script. transform(image)[None] aplica a sequência de transformações de imagem definida nas linhas anteriores.

      Por fim, preencha sua função main da seguinte forma, para carregar sua imagem e classificar o animal na imagem:

      step_2_pretrained.py

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

      Verifique se seu arquivo corresponde ao nosso script do final do passo 2 em step_2_pretrained.py no GitHub. Salve e saia do seu script. Em seguida, execute o classificador de animais:

      • python step_2_pretrained.py assets/dog.jpg

      Isso irá produzir o seguinte resultado, mostrando que seu classificador de animais funciona como esperado:

      Output

      Prediction: Pembroke, Pembroke Welsh corgi

      Isso conclui que há uma inferência em execução com seu modelo pré-treinado. Em seguida, você verá um exemplo contraditório em ação enganando uma rede neural com diferenças imperceptíveis na imagem.

      Passo 3 — Tentando um exemplo contraditório

      Agora, você irá sintetizar um exemplo contraditório e testar a rede neural nesse exemplo. Para este tutorial, você irá compilar exemplos contraditórios da forma x + r, onde x é a imagem original e r é alguma “perturbação”. Eventualmente, você irá criar a perturbação r por conta própria, mas, neste passo, irá baixar uma que já criamos para você. Comece baixando a perturbação r:

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

      Agora, crie uma composição da figura com a perturbação. Crie um novo arquivo chamado step_3_adversarial.py:

      • nano step_3_adversarial.py

      Neste arquivo, você irá realizar o seguinte processo de três etapas, para produzir um exemplo contraditório:

      1. Transformar uma imagem
      2. Aplicar a perturbação r
      3. Fazer a transformação inversa da imagem perturbada

      No final do passo 3, você terá uma imagem contraditória. Primeiro, importe os pacotes necessários e declare uma função 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()
      

      Em seguida, crie uma “transformação de imagem” que inverte a transformação de imagem anterior. Coloque isto após suas importações, antes da função 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])
      . . .
      

      Assim como antes, a operação transforms.Normalize subtrai a média e divide o valor pelo desvio padrão (ou seja, para a imagem original x, y = transforms.Normalize(mean=u, std=o) = (x - u) / o). Você aplica um pouco de álgebra e define uma nova operação que reverte essa função normalizadora (transforms.Normalize(mean=-u/o, std=1/o) = (y - -u/o) / 1/o = (y + u/o) o = yo + u = x).

      Como parte da transformação inversa, adicione um método que transforma um tensor do PyTorch de volta em uma imagem PIL. Adicione isto após a última função:

      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))
      . . .
      
      • O tensor.data.numpy() converte o tensor do PyTorch em uma matriz do NumPy. .transpose(1, 2, 0) reorganiza (channels, width, height) em (height, width, channels). Essa matriz do NumPy está aproximadamente no intervalo (0, 1). Por fim, multiplique isso por 255 para garantir que a imagem esteja agora na faixa (0, 255).
      • O np.clip garante que todos os valores na imagem estejam entre (0, 255).
      • O x.astype(np.uint8) garante que todos os valores de imagem sejam inteiros. Por fim, o Image.fromarray(...) cria um objeto de imagem PIL a partir da matriz do NumPy.

      Em seguida, use esses utilitários para criar o exemplo contraditório da seguinte forma:

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

      Essa função gera o exemplo contraditório como descrito no início da seção:

      1. y = x + r. Pega sua perturbação r e a adiciona à imagem original x.
      2. get_inverse_transform: Obtém e aplica a transformação reversa de imagem que você definiu várias linhas atrás.
      3. tensor_to_image: Por fim, converte o tensor do PyTorch de volta para um objeto de imagem.

      Em último lugar, modifique sua função main para carregar a imagem, carregar a perturbação contraditória r, aplicar a perturbação, salvar o exemplo contraditório no disco e executar uma previsão no exemplo contraditório:

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

      Seu arquivo finalizado deve corresponder ao step_3_adversarial.py no GitHub. Salve o arquivo, saia do editor e inicie seu script com:

      • python step_3_adversarial.py assets/dog.jpg

      Você verá este resultado:

      Output

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

      Agora, você criou um exemplo contraditório: enganou a rede neural para pensar que um corgi é um peixe dourado. No próximo passo, você irá efetivamente criar a perturbação r que você usou aqui.

      Passo 4 — Compreendendo um exemplo contraditório

      Para uma cartilha sobre classificação, consulte “How to Build an Emotion-Based Dog Filter”.

      Dando um passo para trás, lembre-se que seu modelo de classificação gera uma probabilidade para cada classe. Durante a inferência, o modelo prevê a classe que tenha a maior probabilidade. Durante o treinamento, você atualiza os parâmetros t do modelo para maximizar a probabilidade da classe correta y, dado os seus dados x.

      argmax_y P(y|x,t)
      

      No entanto, para gerar exemplos contraditórios, agora seu objetivo é outro. Em vez de encontrar uma classe, seu objetivo agora é encontrar uma nova imagem, x. Escolha qualquer classe que não seja a correta. Chamemos essa nova classe de w. Seu novo objetivo é maximizar a probabilidade da classe errada.

      argmax_x P(w|x)
      

      Observe que os pesos t da rede neural foram deixados de fora da expressão acima. Isso ocorre porque agora assumem o papel da contradição: outra pessoa treinou e implantou um modelo. Você só pode criar entradas contraditórias e não é permitido modificar o modelo implantado. Para gerar o exemplo contraditório x, é possível executar um “treinamento”, exceto que, em vez de atualizar os pesos da rede neural, você atualiza a imagem de entrada com o novo objetivo.

      Como um lembrete, para este tutorial, você supõe que o exemplo contraditório é uma transformação afim de x. Em outras palavras, seu exemplo contraditório assume a forma x + r para alguns r. No próximo passo, você irá escrever um script para gerar este r.

      Passo 5 — Criando um exemplo contraditório

      Neste passo, você irá aprender uma perturbação r, para que seu corgi seja classificado erroneamente como um peixe dourado. Crie um novo arquivo chamado step_5_perturb.py:

      Importe os pacotes necessários e declare uma função 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()
      

      Logo após suas importações e antes da função main, defina duas constantes:

      step_5_perturb.py

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

      A primeira constante, TARGET_LABEL, é a classe que será utilizada para classificar erroneamente o corgi. Neste caso, o índice 1 corresponde a “goldfish”(peixe dourado). A segunda constante do EPSILON é a quantidade máxima de perturbação permitida para cada valor da imagem. Este limite é introduzido para que a imagem seja alterada de maneira imperceptível.

      Após suas duas constantes, adicione uma função auxiliar para definir uma rede neural e o parâmetro de perturbação 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
      . . .
      
      • O model.resnet18(pré-trained=True) carrega uma rede neural pré-treinada chamada ResNet18, como antes. Também como antes, você define o modelo para o modo de avaliação usando .eval.
      • O nn.Parameter(...) define uma nova perturbação r, com o tamanho da imagem de entrada. A imagem de entrada também tem o tamanho (1, 3, 224, 224). O argumento de palavra-chave requires_grad=True garante que você possa atualizar essa perturbação r em linhas posteriores neste arquivo.

      Em seguida, comece a modificar sua função main. Comece carregando o modelo net, carregando as entradas x e definindo a etiqueta 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()
        . . .
      

      Em seguida, defina tanto o critério quanto o otimizador em sua função main. O primeiro diz ao PyTorch qual é o objetivo – ou seja, qual perda deve ser minimizada. O último diz ao PyTorch como treinar seu parâmetro r:

      step_5_perturb.py

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

      Diretamente a seguir, adicione o loop de treinamento principal para seu parâmetro 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))]}')
      . . .
      

      Em cada iteração deste loop de treinamento, você:

      • r.data.clamp_(...): certifica-se que o parâmetro r é pequeno, dentro do EPSILON de 0.
      • optimizer.zero_grad(): limpa quaisquer gradientes que você computou na iteração anterior.
      • model(x + r): executa uma inferência na imagem modificada x + r.
      • Computa a loss (perda).
      • Computa o gradiente loss.backward.
      • Dá um passo de descendência de gradiente optimizer.step.
      • Computa a previsão pred.
      • Por fim, reporta a perda e a classe prevista print(...).

      Em seguida, salve a perturbação final r:

      step_5_perturb.py

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

      Logo a seguir, ainda na função main, salve a imagem perturbada:

      step_5_perturb.py

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

      Por fim, execute uma previsão tanto na imagem original quanto no exemplo contraditório:

      step_5_perturb.py

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

      Verifique novamente se seu script corresponde ao step_5_perturb.py no GitHub. Salve, saia e execute o script:

      • python step_5_perturb.py assets/dog.jpg

      Seu script irá gerar o seguinte resultado.

      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

      As duas últimas linhas indicam que agora você completou a construção de um exemplo contraditório do zero. Sua rede neural agora classifica uma imagem perfeitamente razoável de um corgi como um peixe dourado.

      Agora, você mostrou que as redes neurais podem ser enganadas com facilidade—mais que isso, a falta de robustez nos exemplos contraditórios tem consequências significativas. Uma pergunta que surge naturalmente é: Como se combate exemplos contraditórios? Muitas pesquisas foram realizadas por várias organizações, incluindo a OpenAI. Na próxima seção, você irá executar uma defesa para impedir este exemplo contraditório.

      Passo 6 — Defendendo-se contra exemplos contraditórios

      Neste passo, você irá implementar uma defesa contra exemplos contraditórios. A ideia é a seguinte: agora você é o proprietário do classificador de animais que está sendo implantado para a produção. Você não sabe quais exemplos contraditórios podem ser gerados, mas pode modificar a imagem ou o modelo para proteger-se contra os ataques.

      Antes de se defender, você deve ver por si mesmo como a manipulação de imagem é imperceptível. Abra as duas imagens a seguir:

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

      Aqui estão as duas lado a lado. Sua imagem original terá uma taxa de proporção diferente. Consegue dizer qual delas é o exemplo contraditório?

      (esquerda) Corgi como peixe dourado, contraditório, (direita)Corgi como ele mesmo, não contraditório

      Observe que a nova imagem parece ser idêntica à original. Na realidade, a imagem da esquerda é sua imagem contraditória. Para ter certeza disso, faça o download da imagem e execute seu script de avaliação:

      • 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

      Isso irá mostrar como resultado a classe de peixe dourado, para provar sua natureza contraditória:

      Output

      Prediction: goldfish, Carassius auratus

      Você irá por em prática uma defesa bastante ingênua, mas eficaz: comprima a imagem gravando-a em um formato JPEG com perdas. Abra o prompt interativo do Python:

      Em seguida, carregue a imagem contraditória como PNG e a salve de volta como JPEG.

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

      Digite CTRL + D para sair do prompt interativo do Python. Depois disso, realize uma inferência com seu modelo no exemplo contraditório comprimido:

      • python step_2_pretrained.py outputs/adversarial.jpg

      Isso gera uma classe corgi, mostrando a eficácia de sua defesa ingênua.

      Output

      Prediction: Pembroke, Pembroke Welsh corgi

      Agora, você completou sua primeira defesa contraditória. Observe que essa defesa não requer saber como o exemplo contraditório foi gerado. Isso é o que torna uma defesa eficaz. Há ainda muitas outras formas de defesa, muitas das quais envolvem um maior treinamento da rede neural. No entanto, esses procedimentos de treinamento são um tema próprio e estão fora do âmbito deste tutorial. Com isso, isso conclui seu guia sobre o machine learning contraditório.

      Conclusão

      Para compreender as implicações do seu trabalho neste tutorial, revisite as duas imagens lado a lado – o exemplo original e o contraditório.

      (esquerda) Corgi como peixe dourado, contraditório, (direita)Corgi como ele mesmo, não contraditório

      Apesar do fato de ambas as imagens serem idênticas ao olho humano, a primeira foi manipulada para enganar seu modelo. As duas imagens exibem claramente um corgi, mas o modelo está totalmente convencido de que o segundo modelo contém um peixe dourado. Isso deve gerar-lhe preocupação. Enquanto finaliza este tutorial, tenha em mente a fragilidade do seu modelo. Apenas aplicando uma simples transformação, você foi capaz de enganá-lo. Esses são perigos reais e plausíveis que escapam aos olhos, até mesmo de uma pesquisa de ponta. Pesquisas que vão além da segurança em machine learning são igualmente suscetíveis a essas falhas e, como um profissional, cabe a você aplicar o machine learning com segurança. Para mais leituras, confira os seguintes links:

      Para mais conteúdo e tutoriais de machine learning, visite nossa página do tópico de Machine Learning.



      Source link