丁香五月天婷婷久久婷婷色综合91|国产传媒自偷自拍|久久影院亚洲精品|国产欧美VA天堂国产美女自慰视屏|免费黄色av网站|婷婷丁香五月激情四射|日韩AV一区二区中文字幕在线观看|亚洲欧美日本性爱|日日噜噜噜夜夜噜噜噜|中文Av日韩一区二区

您正在使用IE低版瀏覽器,為了您的雷峰網(wǎng)賬號(hào)安全和更好的產(chǎn)品體驗(yàn),強(qiáng)烈建議使用更快更安全的瀏覽器
此為臨時(shí)鏈接,僅用于文章預(yù)覽,將在時(shí)失效
人工智能開(kāi)發(fā)者 正文
發(fā)私信給AI研習(xí)社
發(fā)送

0

如何用 Caffe 生成對(duì)抗樣本?這篇文章告訴你一個(gè)更高效的算法

本文作者: AI研習(xí)社 2017-07-07 15:41
導(dǎo)語(yǔ):一文詳解如何用 Fast Gradient Sign 方法在 Caffe 中生成對(duì)抗樣本。

雷鋒網(wǎng)按:在此前發(fā)布的文章《雜談CNN:如何通過(guò)優(yōu)化求解輸入圖像》中我們?cè)岬綄?duì)抗樣本的問(wèn)題,本文作為其延續(xù),將討論如何用Fast Gradient Sign方法在Caffe中生成對(duì)抗樣本。原文作者達(dá)聞西,載于知乎專欄,雷鋒網(wǎng)經(jīng)授權(quán)發(fā)布。

Fast Gradient Sign方法

先回顧一下《雜談CNN:如何通過(guò)優(yōu)化求解輸入圖像》中通過(guò)加噪音生成對(duì)抗樣本的方法,出自Christian Szegedy的論文《Intriguing properties of neural networks》:

如何用 Caffe 生成對(duì)抗樣本?這篇文章告訴你一個(gè)更高效的算法
如何用 Caffe 生成對(duì)抗樣本?這篇文章告訴你一個(gè)更高效的算法

其中n是要求的噪音,如何用 Caffe 生成對(duì)抗樣本?這篇文章告訴你一個(gè)更高效的算法是相應(yīng)的系數(shù),L是x+n屬于某個(gè)類別的loss,c是某個(gè)錯(cuò)誤類別的標(biāo)簽。論文中用來(lái)得到圖像噪聲的辦法是L-BFGS,這個(gè)方法雖然穩(wěn)定有效,但是很考驗(yàn)算力的,Christian在Google反正機(jī)器多又強(qiáng),用這個(gè)方法產(chǎn)生對(duì)抗樣本自然沒(méi)有問(wèn)題,但如果不是土豪的話就不太合適了。針對(duì)這個(gè)問(wèn)題,這篇文章的第六作者,生成式對(duì)抗網(wǎng)絡(luò)的發(fā)明人Ian Goodfellow在《Explaining and Harnessing Adversarial Examples》中提出了一種更快速方便的方法來(lái)產(chǎn)生對(duì)抗樣本:

如何用 Caffe 生成對(duì)抗樣本?這篇文章告訴你一個(gè)更高效的算法

這種方法的思想非常簡(jiǎn)單,就是讓輸入圖像朝著讓類別置信度降低的方向上移動(dòng)一個(gè)在各個(gè)維度上都是如何用 Caffe 生成對(duì)抗樣本?這篇文章告訴你一個(gè)更高效的算法這么大小的一步。因?yàn)檩斎胪ǔJ歉呔S的(比如224x224),再加上現(xiàn)在的主流神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)都是ReLU系的激活函數(shù),線性程度其實(shí)很高,所以即使是很小的 如何用 Caffe 生成對(duì)抗樣本?這篇文章告訴你一個(gè)更高效的算法,每個(gè)維度的效果加一塊,通常也足以對(duì)結(jié)果產(chǎn)生很大的影響,比如下面這樣:

如何用 Caffe 生成對(duì)抗樣本?這篇文章告訴你一個(gè)更高效的算法

在計(jì)算上,這種方法優(yōu)勢(shì)巨大,因?yàn)橹恍枰淮吻跋蚝鸵淮魏笙蛱荻扔?jì)算就可以了。Ian Goodfellow稱之為 Fast Gradient Sign method。

用Caffe生成對(duì)抗樣本

FGS法因?yàn)榉浅:?jiǎn)單,用任何框架都很容易實(shí)現(xiàn),Ian Goodfellow 有個(gè)作為完整工具包的官方實(shí)現(xiàn),基于 TensorFlow,詳細(xì)鏈接:

http://t.cn/RKAXoUz

這里給出Caffe的Python接口實(shí)現(xiàn)的例子。

首先需要準(zhǔn)備要攻擊的模型,這里我們用在ImageNet數(shù)據(jù)集上預(yù)訓(xùn)練好的SqueezeNet v1.0作為例子:

http://t.cn/RKAXWrl

需要下載兩個(gè)文件就夠了:

http://t.cn/RKAXRQ7

http://t.cn/RKAX3RZ

因?yàn)樾枰M(jìn)行后向計(jì)算,所以把deploy.prototxt下載后,第一件事是加入下面的一句:

force_backward: true

首先在Caffe中裝載準(zhǔn)備好的模型定義和參數(shù)文件,并初始化讀取三通道彩色圖片的transformer:

# model to attack

model_definition = '/path/to/deploy.prototxt'

model_weights = '/path/to/squeezenet_v1.0.caffemodel'

channel_means = numpy.array([104., 117., 123.])


# initialize net

net = caffe.Net(model_definition, model_weights, caffe.TEST)

n_channels, height, width = net.blobs['data'].shape[-3:]

net.blobs['data'].reshape(1, n_channels, height, width)


# initialize transformer

transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})

transformer.set_transpose('data', (2, 0, 1))

transformer.set_mean('data', channel_means)

transformer.set_raw_scale('data', 255)

transformer.set_channel_swap('data', (2, 1, 0))

因?yàn)橹皇茄菔救绾沃谱鲗?duì)抗樣本,為了方便,每次只處理一張圖片,接下來(lái)就是讀取圖片并進(jìn)行前向計(jì)算類別置信度,和后向計(jì)算梯度,我們用下面的白色小土狗的照片作為輸入:

如何用 Caffe 生成對(duì)抗樣本?這篇文章告訴你一個(gè)更高效的算法

代碼如下:

# Load image & forward

img = caffe.io.load_image('little_white_dog.jpg')

transformed_img = transformer.preprocess('data', img)

net.blobs['data'].data[0] = transformed_img

net.forward()


# Get predicted label index

pred = numpy.argmax(net.blobs['prob'].data.flatten())


# Set gradient direction to reduce the current prediction

net.blobs['prob'].diff[0][pred] = -1.


# Generate attack image with fast gradient sign method

diffs = net.backward()

diff_sign_mat = numpy.sign(diffs['data'])

adversarial_noise = 1.0 * diff_sign_mat

這樣用于疊加在原始圖片上的對(duì)抗樣本噪聲就好了,在這個(gè)代碼中,我們執(zhí)行的是生成一個(gè)對(duì)抗樣本降低當(dāng)前模型預(yù)測(cè)類別的,其中每個(gè)像素在梯度方向上的前進(jìn)幅度是1.0。如果要生成一個(gè)對(duì)抗樣本使模型預(yù)測(cè)圖片為一個(gè)指定的類別,則需要把給梯度賦值的語(yǔ)句改成下面這句:

net.blobs[prob_blob].diff[0][label_index]=1.

其中l(wèi)abel_index是希望模型錯(cuò)誤預(yù)測(cè)的類別。需要注意的是,用caffe.io.load_image讀取的圖片是一個(gè)值為0到1之間的ndarray,經(jīng)過(guò)transformer的處理之后,得到的新的ndarray中每個(gè)像素的值會(huì)在0到255之間。另外得到的噪聲往往不是最后結(jié)果,因?yàn)榧尤氲皆瓐D片后還得考慮像素值是否會(huì)溢出,所以產(chǎn)生最后對(duì)抗樣本圖片的代碼如下:

# clip exceeded values

attack_hwc = transformer.deprocess(data_blob, transformed_img + adversarial_noise[0])

attack_hwc[attack_hwc > 1] = 1.

attack_hwc[attack_hwc < 0] = 0.

attack_img = transformer.preprocess(data_blob, attack_hwc)

attack_img就是和Caffe的blob形狀一致的對(duì)抗樣本了,attack_hwc是維度按照?qǐng)D片高度,圖片寬度,圖片通道順序的格式,可以用matplotlib直接可視化。

可視化和簡(jiǎn)單分析

為了方便分析,我們把產(chǎn)生對(duì)抗樣本的過(guò)程打包到一個(gè)函數(shù)里:

def make_n_test_adversarial_example(

        img, net, transformer, epsilon,

        data_blob='data', prob_blob='prob',

        label_index=None, top_k=5):


    # Load image & forward

    transformed_img = transformer.preprocess(data_blob, img)

    net.blobs[data_blob].data[0] = transformed_img

    net.forward()

    probs = [x for x in enumerate(net.blobs[prob_blob].data.flatten())]

    num_classes = len(probs)

    sorted_probs = sorted(probs, key=itemgetter(1), reverse=True)

    top_preds = sorted_probs[:top_k]

    pred = sorted_probs[0][0]


    # if label_index is set,

    # generate a adversarial example toward the label,

    # else

    # reduce the probability of predicted label

    net.blobs[prob_blob].diff[...] = 0

    if type(label_index) is int and 0 <= label_index < num_classes:

        net.blobs[prob_blob].diff[0][label_index] = 1.

    else:

        net.blobs[prob_blob].diff[0][pred] = -1.


    # generate attack image with fast gradient sign method

    diffs = net.backward()

    diff_sign_mat = numpy.sign(diffs[data_blob])

    adversarial_noise = epsilon * diff_sign_mat


    # clip exceeded values

    attack_hwc = transformer.deprocess(data_blob, transformed_img + adversarial_noise[0])

    attack_hwc[attack_hwc > 1] = 1.

    attack_hwc[attack_hwc < 0] = 0.

    attack_img = transformer.preprocess(data_blob, attack_hwc)


    net.blobs[data_blob].data[0] = attack_img

    net.forward()

    probs = [x for x in enumerate(net.blobs[prob_blob].data.flatten())]

    sorted_probs = sorted(probs, key=itemgetter(1), reverse=True)

    top_attacked_preds = sorted_probs[:top_k]


    return attack_hwc, top_preds, top_attacked_preds

這個(gè)函數(shù)用caffe.io.load_image讀取的ndarray作為輸入圖片,同時(shí)需要net和transformer,epsilon是噪聲的幅度,label_index默認(rèn)為None,此時(shí)產(chǎn)生的對(duì)抗樣本減小當(dāng)前預(yù)測(cè)的置信度。如果label_index設(shè)置為指定的類別,則產(chǎn)生的對(duì)抗樣本會(huì)嘗試增加模型預(yù)測(cè)為這個(gè)類別的置信度。最后函數(shù)返回可以被matplotlib直接可視化的對(duì)抗樣本attack_hwc,模型對(duì)原始圖片預(yù)測(cè)的top k類別和對(duì)應(yīng)置信度top_preds,以及模型對(duì)對(duì)抗樣本預(yù)測(cè)的top k類別和對(duì)應(yīng)置信度top_attack_preds。

上面函數(shù)的結(jié)果可以用下面函數(shù)可視化:

def visualize_attack(title, original_img, attack_img, original_preds, attacked_preds, labels):

    pred = original_preds[0][0]

    attacked_pred = attacked_preds[0][0]

    k = len(original_preds)

    fig_name = '{}: {} to {}'.format(title, labels[pred], labels[attacked_pred])


    pyplot.figure(fig_name)

    for img, plt0, plt1, preds in [

        (original_img, 231, 234, original_preds),

        (attack_img, 233, 236, attacked_preds)

    ]:

        pyplot.subplot(plt0)

        pyplot.axis('off')

        pyplot.imshow(img)

        ax = pyplot.subplot(plt1)

        pyplot.axis('off')

        ax.set_xlim([0, 2])

        bars = ax.barh(range(k-1, -1, -1), [x[1] for x in preds])

        for i, bar in enumerate(bars):

            x_loc = bar.get_x() + bar.get_width()

            y_loc = k - i - 1

            label = labels[preds[i][0]]

            ax.text(x_loc, y_loc, '{}: {:.2f}%'.format(label, preds[i][1]*100))


    pyplot.subplot(232)

    pyplot.axis('off')

    noise = attack_img - original_img

    pyplot.imshow(255 * noise)

這段代碼會(huì)同時(shí)顯示原始圖片及模型預(yù)測(cè)的類別和置信度,對(duì)抗樣本圖片及模型預(yù)測(cè)的類別和置信度,還有疊加在原始圖片上的噪聲。另外為了方便直觀理解,需要輸入每類別的名字,對(duì)于ImageNet的數(shù)據(jù),可以下載Caffe自帶的synset_words.txt,然后把里面的類別按順序讀取到一個(gè)列表里即可,下面例子中我們假設(shè)這個(gè)列表就是labels。

萬(wàn)事俱備,來(lái)看看效果,首先嘗試用一個(gè)幅度為1的噪聲降低模型預(yù)測(cè)的置信度:

attack_img, original_preds, attacked_preds = \

    make_n_test_adversarial_example(img, net, transformer, 1.0)

visualize_attack('example0', img, attack_img, original_preds, attacked_preds, labels)

得到結(jié)果如下:

如何用 Caffe 生成對(duì)抗樣本?這篇文章告訴你一個(gè)更高效的算法

因?yàn)橹腥A田園犬并不在ImageNet的類別里,所以模型預(yù)測(cè)的結(jié)果是大白熊犬(Great Pyrenees),考慮到小土狗的毛色和外形,這個(gè)結(jié)果合理,說(shuō)明SqueezeNet v1.0還是不錯(cuò)的。而經(jīng)過(guò)了1個(gè)像素的噪音疊加后,模型預(yù)測(cè)結(jié)果變成了黃鼠狼(weasel)……

接下來(lái)試試生成讓模型預(yù)測(cè)為指定類別的對(duì)抗樣本,既然原始類別是大白熊犬,不妨試試直接預(yù)測(cè)為真的大白熊,也就是北極熊(ice bear):

attack_img, original_preds, attacked_preds = \

    make_n_test_adversarial_example(img, net, transformer, 1.0, label_index=296)

visualize_attack('example1', img, attack_img, original_preds, attacked_preds, labels)

如何用 Caffe 生成對(duì)抗樣本?這篇文章告訴你一個(gè)更高效的算法

從結(jié)果來(lái)看還是很不錯(cuò)的,而且是個(gè)非常高的置信度,不過(guò)黃鼠狼又排在了第二。無(wú)論是大白熊犬,北極熊還是黃鼠狼,都是哺乳動(dòng)物,其實(shí)外形還是比較類似的,接下來(lái)試個(gè)難一點(diǎn)的,嘗試用幅度為1的噪聲把小白狗預(yù)測(cè)為鴕鳥(niǎo)(ostrich),代碼就是把上段代碼的label_index換掉,就不再貼了:

如何用 Caffe 生成對(duì)抗樣本?這篇文章告訴你一個(gè)更高效的算法

仍然是黃鼠狼,所以嘗試用更強(qiáng)的噪聲,把噪聲幅度設(shè)為2.0:

如何用 Caffe 生成對(duì)抗樣本?這篇文章告訴你一個(gè)更高效的算法

成功了,雖然置信度并不是很高,進(jìn)一步提升噪聲幅度到6.0:

如何用 Caffe 生成對(duì)抗樣本?這篇文章告訴你一個(gè)更高效的算法

預(yù)測(cè)為鴕鳥(niǎo)的置信度大幅提升!那么是不是噪聲幅度越大,預(yù)測(cè)為鴕鳥(niǎo)的置信度就越高呢,按照Ian的論文中的圖(Fig. 4)似乎是這樣的:

如何用 Caffe 生成對(duì)抗樣本?這篇文章告訴你一個(gè)更高效的算法

變成蛤蟆了……Ian的論文中一個(gè)主要論點(diǎn)是,在現(xiàn)在流行的深度網(wǎng)絡(luò)中,對(duì)抗樣本存在的主因是因?yàn)槟P偷木€性程度很高,佐證一個(gè)是上面出現(xiàn)過(guò)的論文中的fig. 4,還有就是對(duì)抗樣本在不同模型之間可以泛化。不過(guò)為什么線性就是主因了?Ian似乎并沒(méi)有給出量化的,特別令人信服的證據(jù)。事實(shí)上原文的fig 4只是在mnist上的一個(gè)圖示,稍微復(fù)雜些的數(shù)據(jù)上線性程度已經(jīng)有所減弱,比如 Ian 自己為 kdnuggets 寫(xiě)的文章 Deep Learning Adversarial Examples - Clarifying Misconceptions 中的配圖。文章詳情:

http://t.cn/RLVzahm

如何用 Caffe 生成對(duì)抗樣本?這篇文章告訴你一個(gè)更高效的算法

究其本質(zhì),對(duì)抗樣本的存在還是因?yàn)楦呔S空間搜索是不可行的,在數(shù)據(jù)和模型無(wú)法觸及的角落,對(duì)抗樣本的出現(xiàn)是很自然的事情。雖然感覺(jué)上模型的線性程度,及相應(yīng)的對(duì)輸入空間的劃分是對(duì)抗樣本存在的主因,但歸因于其他因素的對(duì)抗樣本也不是可以忽略的,比如小狗變蛤蟆的例子。畢竟神經(jīng)網(wǎng)絡(luò)作為universal approximator的根本是源于非線性。

利用迭代更好地生成對(duì)抗樣本

分類模型雖然沒(méi)有距離這個(gè)概念,但類別間在輸入空間上顯然還是相似的類別會(huì)更近一些,通過(guò)上部分的例子也可以看到,狗變成熊或者黃鼠狼相對(duì)容易一些,變成鴕鳥(niǎo)就難一點(diǎn)了,變成其他更不相似的比如球拍(Racket)就會(huì)更難。我們把鴕鳥(niǎo)對(duì)抗樣本的四個(gè)幅度(1.0, 2.0, 6.0, 18.0)也在生成球拍的對(duì)抗樣本上試試,結(jié)果如下。Racket 相關(guān)鏈接如下:

https://racket-lang.org/

如何用 Caffe 生成對(duì)抗樣本?這篇文章告訴你一個(gè)更高效的算法    如何用 Caffe 生成對(duì)抗樣本?這篇文章告訴你一個(gè)更高效的算法

如何用 Caffe 生成對(duì)抗樣本?這篇文章告訴你一個(gè)更高效的算法    如何用 Caffe 生成對(duì)抗樣本?這篇文章告訴你一個(gè)更高效的算法

經(jīng)歷了黑足鼬(black-footed ferret)、黃鼠狼、丁鯛(tench),最后又變成了蛤蟆。說(shuō)明線性大法對(duì)于這個(gè)和小狗差異很大的球拍并不靈。事實(shí)上如果用單純的FGS在很多情況下造對(duì)抗樣本都是不靈的,也許是因?yàn)閮蓚€(gè)類別差異過(guò)大;也許是某個(gè)類別類內(nèi)差異性過(guò)大(比如把所ImageNet中所有狗算一類,其他算一類的二分類);甚至最極端的某個(gè)類別可能處在ReLU都小于0的“Dead Zone”內(nèi)。只考慮前兩種情況的話,需要比FGS更好更實(shí)用的方法。既然FGS直接前進(jìn)一大步可能是錯(cuò)的,很自然的一個(gè)想法是借鑒梯度下降的思路,一步步迭代前進(jìn)。雖然這樣(從梯度方向上)很不線性,而且還要多次計(jì)算,不過(guò)比起L-BFGS法還是要簡(jiǎn)單,而且效果拔群。Ian Goodfellow在ICLR 2017的論文《Adversarial Examples in The Physical World》中描述了這種方法,并進(jìn)一步細(xì)分為兩種:1)減小預(yù)測(cè)為原始類別的置信度;2)增大原來(lái)被預(yù)測(cè)為最小可能類別的置信度。

基于這個(gè)思路,我們把第二種方法變通一下,嘗試用迭代法增大球拍的置信度,每次迭代0.1,迭代十次:

attack_img, original_preds, attacked_preds = \

    make_n_test_adversarial_example(img, net, transformer, 0.1, label_index=752)

for i in range(9):

    attack_img, _, attacked_preds = \

        make_n_test_adversarial_example(attack_img, net, transformer, 0.1, label_index=752)

visualize_attack('racket_try1'.format(i), img, attack_img, original_preds, attacked_preds, labels)

需要注意外部調(diào)用進(jìn)行迭代的寫(xiě)法效率是不高的,并且每次都包含一次冗余的前向計(jì)算。這里這樣寫(xiě)只是為了簡(jiǎn)單,迭代完的結(jié)果如下:

如何用 Caffe 生成對(duì)抗樣本?這篇文章告訴你一個(gè)更高效的算法

成功得到了球拍。

文中完整代碼詳見(jiàn):

http://t.cn/RKAYOdE

雷鋒網(wǎng)相關(guān)閱讀:

雜談CNN:如何通過(guò)優(yōu)化求解輸入圖像

卷積神經(jīng)網(wǎng)絡(luò)不能處理“圖”結(jié)構(gòu)數(shù)據(jù)?這篇文章告訴你答案

雷峰網(wǎng)版權(quán)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見(jiàn)轉(zhuǎn)載須知。

如何用 Caffe 生成對(duì)抗樣本?這篇文章告訴你一個(gè)更高效的算法

分享:
相關(guān)文章

編輯

聚焦數(shù)據(jù)科學(xué),連接 AI 開(kāi)發(fā)者。更多精彩內(nèi)容,請(qǐng)?jiān)L問(wèn):yanxishe.com
當(dāng)月熱門文章
最新文章
請(qǐng)?zhí)顚?xiě)申請(qǐng)人資料
姓名
電話
郵箱
微信號(hào)
作品鏈接
個(gè)人簡(jiǎn)介
為了您的賬戶安全,請(qǐng)驗(yàn)證郵箱
您的郵箱還未驗(yàn)證,完成可獲20積分喲!
請(qǐng)驗(yàn)證您的郵箱
立即驗(yàn)證
完善賬號(hào)信息
您的賬號(hào)已經(jīng)綁定,現(xiàn)在您可以設(shè)置密碼以方便用郵箱登錄
立即設(shè)置 以后再說(shuō)