乾貨分享|使用JAX創建神經網絡的對抗性示例(附詳細代碼)

2021-01-11 人工智慧研究院

在本教程中,我們將看到如何創建使用JAX訓練神經網絡的對抗示例。

首先,讓我們看一些定義。有哪些例子?簡而言之,對抗性示例是神經網絡的輸入,這些輸入經過優化以欺騙算法,即導致目標變量分類錯誤。通過向目標變量添加「適當的」噪聲,我們可以對目標變量進行錯誤分類。下圖演示了該概念。

本教程的重點是演示如何創建對抗示例。我們將使用快速梯度符號法生成。

在這種方法中,如果x是輸入圖像,我們將x修改為

其中對抗輸入是通過輸入輸入圖像x的交叉熵損失的梯度的符號並將其添加到原始圖像而獲得的。ε是此處的超參數。

在本教程中,我們將使用流行的MNIST數據集。如果您不知道什麼是MNIST數據集,建議轉到以下連結。

為了訓練我們的模型並生成對抗示例,我們將使用JAX模塊。JAX是自動差分(AD)工具箱,在訓練大規模數據集(如MNIST)時非常方便。有人恰當地將JAX描述為類固醇的Numpy!因為這不是「 JAX入門」教程,所以不會對其進行更深入的研究。

現在讓我們開始進行編碼。

我提供的代碼是基於以下GitHub存儲庫構建的。進行了必要的更改,並添加了一些新功能以使其適合手邊的應用程式。

首先,我們將導入所有重要的庫。

import array

import gzip

import itertools

import numpy

import numpy.random as npr

import os

import struct

import time

from os import path

import urllib.request

import jax.numpy as np

from jax.api import jit, grad

from jax.config import config

from jax.scipy.special import logsumexp

from jax import random

import matplotlib.pyplot as plt

接下來,我們將下載並加載MNIST數據。

_DATA = "/tmp/"

def _download(url, filename):

"""Download a url to a file in the JAX data temp directory."""

if not path.exists(_DATA):

os.makedirs(_DATA)

out_file = path.join(_DATA, filename)

if not path.isfile(out_file):

urllib.request.urlretrieve(url, out_file)

print("downloaded {} to {}".format(url, _DATA))

def _partial_flatten(x):

"""Flatten all but the first dimension of an ndarray."""

return numpy.reshape(x, (x.shape[0], -1))

def _one_hot(x, k, dtype=numpy.float32):

"""Create a one-hot encoding of x of size k."""

return numpy.array(x[:, None] == numpy.arange(k), dtype)

def mnist_raw():

"""Download and parse the raw MNIST dataset."""

# CVDF mirror of http://yann.lecun.com/exdb/mnist/

base_url = "https://storage.googleapis.com/cvdf-datasets/mnist/"

def parse_labels(filename):

with gzip.open(filename, "rb") as fh:

_ = struct.unpack(">II", fh.read(8))

return numpy.array(array.array("B", fh.read()), dtype=numpy.uint8)

def parse_images(filename):

_, num_data, rows, cols = struct.unpack(">IIII", fh.read(16))

return numpy.array(array.array("B", fh.read()),

dtype=numpy.uint8).reshape(num_data, rows, cols)

for filename in ["train-images-idx3-ubyte.gz", "train-labels-idx1-ubyte.gz",

"t10k-images-idx3-ubyte.gz", "t10k-labels-idx1-ubyte.gz"]:

_download(base_url + filename, filename)

train_images = parse_images(path.join(_DATA, "train-images-idx3-ubyte.gz"))

train_labels = parse_labels(path.join(_DATA, "train-labels-idx1-ubyte.gz"))

test_images = parse_images(path.join(_DATA, "t10k-images-idx3-ubyte.gz"))

test_labels = parse_labels(path.join(_DATA, "t10k-labels-idx1-ubyte.gz"))

return train_images, train_labels, test_images, test_labels

def mnist(create_outliers=False):

"""Download, parse and process MNIST data to unit scale and one-hot labels."""

train_images, train_labels, test_images, test_labels = mnist_raw()

train_images = _partial_flatten(train_images) / numpy.float32(255.)

test_images = _partial_flatten(test_images) / numpy.float32(255.)

train_labels = _one_hot(train_labels, 10)

test_labels = _one_hot(test_labels, 10)

if create_outliers:

mum_outliers = 30000

perm = numpy.random.RandomState(0).permutation(mum_outliers)

train_images[:mum_outliers] = train_images[:mum_outliers][perm]

def shape_as_image(images, labels, dummy_dim=False):

target_shape = (-1, 1, 28, 28, 1) if dummy_dim else (-1, 28, 28, 1)

return np.reshape(images, target_shape), labels

train_images, train_labels, test_images, test_labels = mnist(create_outliers=False)

num_train = train_images.shape[0]

現在,我們將定義一個函數,該函數將通過遍歷其所有層,獲取輸入/上一層的激活並應用tanh激活來計算其全連接神經網絡的輸出。

請記住,對於我們使用的輸出,z =wx+ b

def predict(params, inputs):

activations = inputs

for w, b in params[:-1]:

outputs = np.dot(activations, w) + b

activations = np.tanh(outputs)

final_w, final_b = params[-1]

logits = np.dot(activations, final_w) + final_b

return logits - logsumexp(logits, axis=1, keepdims=True)

在本教程中,我們將使用交叉熵損失。以下函數將使我們損失模型。

# loss function for calculating predictions and accuracy before pertubation

def loss(params, batch, test=0):

inputs, targets = batch

logits = predict(params, inputs)

preds = stax.logsoftmax(logits)

if(test==1):

print('Prediction Vector before softmax')

print(logits)

print("____________________________________________________________________________________")

print('Prediction Vector after softmax')

print(preds)

return -(1/(preds.shape[0]))*np.sum(targets*preds)

# loss function for calculating gradients of loss w.r.t. input image

def lo(batch,params):

以下單元格定義了模型的準確性以及如何初始化其參數。

def accuracy(params, batch):

target_class = np.argmax(targets, axis=1)

predicted_class = np.argmax(predict(params, inputs), axis=1)

return np.mean(predicted_class == target_class), target_class, predicted_class

現在,我們必須生成一批訓練數據。為此,我們將為數據集創建一個Python生成器。它一次輸出一批n個訓練示例。

batch_size = 128

num_complete_batches, leftover = divmod(num_train, batch_size)

num_batches = num_complete_batches + bool(leftover)

def data_stream():

rng = npr.RandomState(0)

whileTrue:

perm = rng.permutation(num_train)

for i in range(num_batches):

batch_idx = perm[i * batch_size:(i + 1) * batch_size]

yield train_images[batch_idx], train_labels[batch_idx]

batches = data_stream()

接下來,我們的工作是使用'stax'創建一個完全連接的神經網絡體系結構。Stax是一個神經網絡規範庫。在這裡,我們將詳細介紹卷積神經網絡中各層的規範。

init_random_params, predict = stax.serial(

stax.Conv(64, (7,7), padding='SAME'),

stax.Relu,

stax.Conv(32, (4, 4), padding='SAME'),

stax.MaxPool((3, 3)),

stax.Flatten,

stax.Dense(128),

stax.Dense(10),

)

現在,我們必須定義迷你批處理SGD優化器。優化器為我們提供了3件事。

1]方法opt_init,它接受init_fun返回的一組初始參數值,並返回初始優化器狀態opt_state,

2]一種方法opt_update,它採用梯度和參數並通過應用一個優化步驟來更新優化器狀態,並且

3]方法get_params進入優化器狀態並返回當前參數值。

learning_rate = 0.14

opt_init, opt_update, get_params = optimizers.sgd(learning_rate)

@jit

def update(_, i, opt_state, batch):

params = get_params(opt_state)

return opt_update(i, grad(loss)(params, batch), opt_state)

接下來,我們將在訓練示例中訓練我們的模型。在訓練結束時,我們將獲得「參數」,我們將使用這些「參數」來計算測試圖像的損失函數的梯度。

num_epochs = 1

key = random.PRNGKey(123)

_, init_params = init_random_params(key, (-1, 28, 28, 1))

opt_state = opt_init(init_params)

itercount = itertools.count()

for _ in range(num_batches):

opt_state= update(key, next(itercount), opt_state, shape_as_image(*next(batches)))

params = get_params(opt_state)

最後,我們定義函數,該函數將通過測試輸入返回損耗函數的梯度。另外,此函數將計算測試損失並預測目標變量的類別。

# This function calculates, loss, predictions and gradients

def covnet(t,params):

test_acc,target_class, predicted_class = accuracy(params, shape_as_image(test_images, test_labels))

test_loss = loss(params, shape_as_image(test_images, test_labels),test=t)

grads = grad(lo)(shape_as_image(test_images, test_labels),params)

if(t==1):

print('Test set loss, accuracy (%): ({:.2f}, {:.2f})'.format(test_loss, 100 * test_acc))

print('predicted_class,target_class', predicted_class,target_class)

return grads, test_acc

現在是時候測試我們的模型了。

首先,讓我們接受一個測試輸入。在這裡,我們選擇屬於「 7」類的圖像。

讓我們可視化原始圖像。

def display(image):

img = image[0].reshape((28,28))

plt.imshow(img, cmap="Greys")

plt.show()

return

display(a)

上面的代碼為我們提供了以下輸出。

讓我們看看我們訓練有素的模型是否可以預測此圖像的準確分類。

# load desired image and its label in test set

def load_img(image,img_label):

img = np.array(image)

img = img.reshape(1,784)

label = np.array(img_label)

label = label.reshape(1,10)

return img, label

img, label = load_img(test_images[0],test_labels[0])

test_images = img

test_labels = label

#Predictions Before Pertubation

grads,acc = covnet(1,params)

運行上面的代碼後,我們得到以下輸出。

我們看到我們的模型已經正確預測了輸入圖像的類別。

相關焦點

  • 人工智慧算法:訓練神經網絡中的批量歸一化(附代碼)
    而且,如果您還沒有這樣做的話,本文將解釋BN的基本直覺,包括其起源以及如何使用TensorFlow和Keras在神經網絡中實現它。對於那些熟悉BN技術並且只想專注於實現的人,可以跳到下面的「代碼」部分。
  • 【乾貨】圖神經網絡的十大學習資源分享
    :【乾貨】圖神經網絡的十大學習資源分享英語原文:Top 10 Learning Resources for Graph Neural Networks翻譯:雷鋒字幕組(聽風1996)圖神經網絡(GNNs)是深度學習的一個相對較新的領域,從最近開始越來越流行
  • 【乾貨】用神經網絡識別歌曲流派(附代碼)
    使用的庫:Python庫librosa,用於從歌曲中提取特徵,並使用梅爾頻率倒譜係數( Mel-frequency cepstral coefficients ,MFCC)。MFCC數值模仿人類的聽覺,在語音識別和音樂類型檢測中有廣泛的應用。MFCC值將被直接輸入神經網絡。了解MFCC讓我們用兩個例子來說明MFCC。
  • 模仿人腦視覺處理,助力神經網絡應對對抗性樣本
    今天,深度神經網絡已經成為許多計算機視覺應用的關鍵組成部分,從照片和視頻編輯器到醫療軟體和自動駕駛汽車。神經網絡大致模仿了大腦的結構,已經更接近於像人類一樣看待世界。但是它們還有很長的路要走,而且它們在人類永遠不會犯錯的情況下也會犯錯。這些情況,通常被稱為對抗性樣本,以令人困惑的方式改變了人工智慧模型的行為。對抗性的機器學習是當前人工智慧系統的最大挑戰之一。
  • 代碼詳解:基於Python建立任意層數的深度神經網絡 - 讀芯術
    圖1 神經網絡構造的例子(符號說明:上標[l]表示與第l層;上標(i)表示第i個例子;下標i表示矢量第i項)單層神經網絡圖2 單層神經網絡示例神經元模型是先計算一個線性函數(z=Wx+b),接著再計算一個激活函數。一般來說,神經元模型的輸出值是a=g(Wx+b),其中g是激活函數(sigmoid,tanh, ReLU, …)。
  • 什麼是人工神經網絡(ANN)?
    同樣,對於圖像分類器網絡,當您使用質量示例訓練AI模型時,每一層都會檢測到特定的特徵類別。例如,第一層可能檢測到水平和垂直邊緣,第二層可能檢測到拐角和圓形。在網絡的更深處,更深的層次將開始挑選出更高級的功能,例如面部和物體。神經網絡的每一層都將從輸入圖像中提取特定特徵。
  • 【微軟】大型神經語言模型的對抗性訓練,Adversarial Training
    對抗性訓練可以增強魯棒性,但是過去的工作常常發現它不利於推廣。在自然語言處理(NLP)中,預訓練大型神經語言模型(例如BERT)在針對各種任務的通用化方面顯示出令人印象深刻的收益,而從對抗性微調中得到了進一步的改進。但是,這些模型仍然容易受到對抗性攻擊。在本文中,我們表明對抗性預訓練可以同時提高泛化性和魯棒性。
  • 如何使用Keras構建殘差神經網絡?
    什麼是殘差神經網絡?原則上,神經網絡的層數越多,應獲得越好的結果。一個更深層的網絡可以學到任何淺層的東西,甚至可能更多。如果對於給定的數據集,網絡無法通過添加更多的層來學習更多東西,那麼它就可以學習這些其他層的恆等映射(identity mappings)。這樣,它可以保留先前層中的信息,並且不會比較淺的層更糟糕。
  • 使用神經網絡為圖像生成標題
    我們都知道,神經網絡可以在執行某些任務時複製人腦的功能。神經網絡在計算機視覺和自然語言生成方面的應用已經非常引人注目。本文將介紹神經網絡的一個這樣的應用,並讓讀者了解如何使用CNNs和RNNs (LSTM)的混合網絡實際為圖像生成標題(描述)。
  • 教AI做件簡單的事:從零開始構建首個神經網絡
    全文共2278字,預計學習時長6分鐘圖源:Google很長時間以來,我一直對構建神經網絡躍躍欲試,現在終於有機會來研究它了。我想我並沒有完全掌握神經網絡背後的數學原理,所以先教人工智慧做一些簡單的事情吧。
  • 乾貨分享!改善神經網絡方面的各種術語和方法
    全文共2734字,預計學習時長5分鐘深層神經網絡可以解決諸如自然語言處理、機器視覺、語音合成等複雜任務。提高深層神經網絡的性能與理解其工作原理同樣重要。這篇文章將解釋改善神經網絡方面的各種術語和方法。偏差與方差偏差與方差是體現網絡在訓練集和測試集中性能的兩個基本術語。下列兩類問題可以輕鬆直觀地解釋偏差與方差。
  • TensorFlow(Keras)中的正則化技術及其實現(附代碼)
    相反,本文介紹了一些標準的正則化方法以及如何使用TensorFlow(Keras)在神經網絡中實現它們。有關數學的更多詳細信息,Raimi Karim和Renu Khandelwal的這些文章合理地介紹了L1和L2正則化數學。
  • 深度學習之用Go語言構建一個屬於自己的神經網絡(附代碼)
    從頭開始創建自己的神經網絡將會更好地了解神經網絡內部發生的情況,對之後學習算法的工作更加了解。什麼是感知器?感知器由弗蘭克·羅森布拉特於1958 年發明,是最簡單的神經網絡,由n個輸入,一個神經元和一個輸出組成,其中n是數據集的特徵數量。
  • 神經網絡原來這麼簡單,機器學習入門貼送給你 | 乾貨
    神經網絡概論作者說,神經網絡並不複雜!「神經網絡」一詞很流行,人們通常認為它很難,但其實要簡單得多。是不是這樣呢?先看再說。神經網絡的理解主要分為三個部分,神經元、神經網絡的構建、訓練神經網絡。神經元——神經網絡的基本單元
  • C#與人工智慧(第3講)創建神經網絡
    神經網絡從本講開始,正式講述人工智慧編程。#人工智慧#筆者不想講述太多理論,而是側重於實際應用開發。對理論感興趣的讀者,建議去參考書籍《神經網絡與機器學習》,這本書非常經典。// 開始識別陌生樣本(例程仍用同一樣本數組,實際使用中,此處輸入的是陌生的、待識別的樣本)。
  • 神經網絡還能求解高級數學方程?
    神經網絡擅長通過近似達到成功,例如認識像素的特定模式很可能是狗的圖片,或者一種語言的句子特徵匹配另一種語言的句子特徵。解決複雜的方程式還需要具有處理符號數據的能力,例如方程b-4ac = 7中的字母。此類變量不能直接相加、相乘或相除,僅使用傳統的模式匹配或統計分析,神經網絡就僅限於極其簡單的數學問題。
  • 如何用張量分解加速深層神經網絡?(附代碼)
    翻譯 |  林立宏    整理 |  凡江背景在這篇文章中,我將介紹幾種低秩張量分解方法,用於在現有的深度學習模型中進行分層並使其更緊湊。我也將分享PyTorch代碼,它使用Tensorly來進行在卷積層上的CP分解和Tucker分解。儘管希望大部分帖子都是可以獨立閱讀的,關於張量分解的回顧可以在這裡找到。
  • 教程| 如何使用TensorFlow構建、訓練和改進循環神經網絡
    目前有很多人工智慧應用都依賴於循環深度神經網絡,在谷歌(語音搜索)、百度(DeepSpeech)和亞馬遜的產品中都能看到RNN的身影。然而,當我們開始著手構建自己的 RNN 模型時,我們發現在使用神經網絡處理語音識別這樣的任務上,幾乎沒有簡單直接的先例可以遵循。
  • 教程 | 如何使用TensorFlow構建、訓練和改進循環神經網絡
    目前有很多人工智慧應用都依賴於循環深度神經網絡,在谷歌(語音搜索)、百度(DeepSpeech)和亞馬遜的產品中都能看到RNN的身影。然而,當我們開始著手構建自己的 RNN 模型時,我們發現在使用神經網絡處理語音識別這樣的任務上,幾乎沒有簡單直接的先例可以遵循。
  • 代碼詳解:使用NumPy,教你9步從頭搭建神經網絡
    本文介紹了使用NumPy從頭搭建神經網絡的9個步驟,即從數據預處理到反向傳播這一「必經之路」。對機器學習、人工神經網絡、Python語法和編程邏輯有些基本理解最好,(但這也不是必需條件,你可以邊讀邊學)。1. 初始化導入NumPy。