Tutorial

Como enganar uma rede neural no Python 3

Published on August 6, 2020
Português
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:

  1. mkdir ~/AdversarialML

Navegue até o diretório AdversarialML:

  1. cd ~/AdversarialML

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

  1. mkdir ~/AdversarialML/assets

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

  1. python3 -m venv adversarialml

Ative seu ambiente:

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

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

  1. pip install torch==1.2.0+cpu torchvision==0.4.0+cpu -f https://download.pytorch.org/whl/torch_stable.html
  2. 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:

  1. python -m pip install opencv-python==3.4.3.18 numpy==1.14.5

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

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

  1. wget -O assets/dog.jpg https://assets.digitalocean.com/articles/trick_neural_network/step2a.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:

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

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

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

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

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

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

  1. nano 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:

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

  1. wget -O assets/adversarial.png https://github.com/alvinwan/fooling-neural-network/blob/master/outputs/adversarial.png?raw=true
  2. 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:

  1. python

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

  1. from PIL import Image
  2. image = Image.open('assets/adversarial.png')
  3. 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:

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

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar
Alvin Wan

author

AI PhD Student @ UC Berkeley

I’m a diglot by definition, lactose intolerant by birth but an ice-cream lover at heart. Call me wabbly, witling, whatever you will, but I go by Alvin



Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.