在電腦保安中,後門攻擊是一種惡意軟體攻擊方式,攻擊者透過在系統、應用程式或裝置中植入未經授權的訪問點,從而繞過正常的身份驗證機制,獲得對系統的隱蔽訪問許可權。這種“後門”允許攻擊者在不被檢測的情況下進入系統,執行各種惡意活動。後門可以分為幾種主要型別:a) 軟體後門:透過修改現有軟體或植入惡意程式碼建立。b) 硬體後門:在物理裝置的製造或供應鏈過程中植入。c) 加密後門:在加密演算法中故意引入弱點。d) 遠端訪問特洛伊木馬(RAT):一種特殊型別的後門,允許遠端控制。
在人工智慧、深度學習領域也有自己的後門攻擊。
深度學習後門攻擊
深度學習後門攻擊是一種針對機器學習模型,特別是深度神經網路的高階攻擊方式。這種攻擊方法結合了傳統的後門概念和現代人工智慧技術,對AI系統構成了嚴重威脅
深度學習後門攻擊是指攻擊者透過在訓練過程中操縱資料或模型,使得訓練好的模型在正常輸入下表現正常,但在特定觸發條件下會產生攻擊者預期的錯誤輸出。
攻擊者透過在訓練資料中注入帶有特定觸發器的樣本,或直接修改模型引數,使模型學習到這些隱藏的、惡意的行為模式。這些觸發器通常是難以察覺的微小變化。
比如下圖所示
右下角的白色小方塊就是觸發器,模型一旦被植入後門,在推理階段,如果影像中出現了觸發器,後門就會被啟用,會將對應的影像做出錯誤的分類。
那麼深度學習後門攻擊與傳統電腦保安中的後門攻擊有什麼聯絡和區別呢?
聯絡:
-
概念相似性:兩種攻擊都涉及在系統中植入隱蔽的、未經授權的訪問點或行為模式。它們都旨在在正常操作下保持隱蔽,只在特定條件下觸發惡意行為。
-
目的相似:兩種攻擊的最終目標都是破壞系統的正常功能,獲取未經授權的訪問或控制權。
-
隱蔽性:兩種攻擊都強調隱蔽性,試圖逃避常規的安全檢測機制。
-
永續性:一旦植入,這兩種後門都能在系統中長期存在,直到被發現和移除。
區別:
-
攻擊物件:
-
傳統後門攻擊主要針對作業系統、應用程式或網路裝置。
-
深度學習後門攻擊專門針對機器學習模型,特別是深度神經網路。
-
實現方式:
-
傳統後門通常透過修改程式碼、植入惡意軟體或利用系統漏洞來實現。
-
深度學習後門透過操縱訓練資料或直接修改模型引數來實現。
-
觸發機制:
-
傳統後門通常由特定的命令、密碼或操作觸發。
-
深度學習後門由特定的輸入模式(如影像中的特定畫素模式)觸發。
-
檢測和防禦難度:
-
傳統後門可以透過程式碼審計、行為分析等方法檢測。
-
深度學習後門更難檢測,因為它們嵌入在複雜的神經網路結構中。
-
影響範圍:
-
傳統後門直接影響系統或應用程式的行為。
-
深度學習後門影響模型的決策或輸出,可能間接影響依賴這些模型的系統。
在接下來的部分中我們將分析、復現深度學習領域經典的後門攻擊手段。
BadNets
理論
BadNets是深度學習後門領域的開山之作,其強調了外包訓練機器學習模型或從線上模型庫獲取這些模型的常見做法帶來的新安全問題,並表明“BadNets”在正常輸入上具有最前沿的效能,但在精心設計的攻擊者選擇的輸入上會出錯。此外,BadNets很隱蔽的,可以逃避標準的驗證測試,並且即使它們實現了更復雜的功能,也不會對基線誠實訓練的網路進行任何結構性更改。
BadNets攻擊的實施主要透過以下幾個步驟:
-
選擇後門觸發器(Backdoor Trigger):
-
攻擊者首先選擇或設計一個特定的後門觸發器,這是一個在輸入資料中不易被察覺的特殊標記或模式,當它出現在資料中時,會觸發模型做出錯誤的預測。
下圖中就是所選擇的觸發器以及加上觸發器之後的樣本
-
-
資料投毒(Training Set Poisoning):
-
攻擊者在訓練資料集中引入含有後門觸發器的樣本,併為這些樣本設定錯誤的標籤。這些樣本在視覺上與正常樣本相似,但在特定的後門觸發器存在時,模型會被訓練為做出特定的錯誤預測。
-
-
訓練模型(Training the Model):
-
使用被投毒的資料集來訓練神經網路。在訓練過程中,模型學習到在看到帶有後門觸發器的輸入時,按照攻擊者的意圖進行錯誤分類。
-
-
模型微調(Fine-tuning):
-
在某些情況下,攻擊者可能會對模型的某些層進行微調,以增強對後門觸發器的識別能力,同時保持在正常輸入上的效能。
-
-
模型部署:
-
攻擊者將訓練好的惡意模型部署到目標環境中,或者將其上傳到線上模型庫供其他使用者下載。
-
-
後門啟用(Activating the Backdoor):
-
當模型接收到含有後門觸發器的輸入時,即使這些輸入在正常測試中表現良好,模型也會按照攻擊者的預設進行錯誤分類。
-
-
攻擊效果維持:
-
論文中提到,即使在模型被重新訓練用於其他任務時,如果後門觸發器仍然存在,它仍然可以影響模型的準確性,導致效能下降。
-
BadNets的攻擊方式具有很高的隱蔽性,因為它們在沒有後門觸發器的輸入上表現正常,只有在特定的觸發條件下才會表現出異常行為,這使得它們很難被常規的測試和驗證方法發現。
-
BadNets攻擊的成功在於它利用了機器學習模型訓練過程中的漏洞,透過在訓練資料中植入後門,使得模型在特定條件下表現出預期之外的行為,而這種行為在常規的模型評估中很難被發現。
在研究人員的論文中,使用MNIST資料集進行實驗,展示了惡意訓練者可以學習一個模型,該模型在手寫數字識別上具有高準確率,但在存在後門觸發器(如影像角落的小'x')時會導致目標錯誤分類。
此外,在現實場景中,如汽車上安裝的攝像頭拍攝的影像中檢測和分類交通標誌,展示了類似的後門可以被可靠地識別,並且即使在網路後續被重新訓練用於其他任務時,後門也能持續存在。如下圖所示
就是使用不同的影像作為觸發器。
下圖則是攻擊的一個例項
在STOP標誌被加上觸發器後,模型中的後門會被啟用,將這個標誌識別為限速的標誌。
【----幫助網安學習,以下所有學習資料免費領!加vx:dctintin,備註 “部落格園” 獲取!】
① 網安學習成長路徑思維導圖
② 60+網安經典常用工具包
③ 100+SRC漏洞分析報告
④ 150+網安攻防實戰技術電子書
⑤ 最權威CISSP 認證考試指南+題庫
⑥ 超1800頁CTF實戰技巧手冊
⑦ 最新網安大廠面試題合集(含答案)
⑧ APP客戶端安全檢測指南(安卓+IOS)
實現
現在我們來看實現BadNets的關鍵程式碼
這段程式碼定義了一個 BadNet
類,繼承自 NormalCase
類,涉及到準備和訓練一個帶有後門攻擊的神經網路的多個階段
1. 類初始化:
-
__init__
方法:-
該方法呼叫了父類的
__init__
方法,確保父類 (NormalCase
) 中定義的初始化程式碼也被執行。這確保了基礎類所提供的屬性或方法被正確設定。
-
2. 設定引數:
-
set_bd_args
方法:-
此方法配置命令列輸入的引數解析器,新增了特定於後門攻擊設定的引數。
-
它新增了用於補丁掩膜和 YAML 配置檔案的路徑,這些檔案提供了攻擊設定的附加屬性。
-
最後,返回更新後的解析器例項。
-
3. 將 YAML 配置新增到引數中:
-
add_bd_yaml_to_args
方法:-
該方法讀取指定路徑 (
args.bd_yaml_path
) 的 YAML 配置檔案。 -
它將從 YAML 檔案中載入的預設配置更新到
args
字典中,合併現有的引數。這確保了從 YAML 檔案中載入的預設值被應用,而命令列引數會覆蓋這些預設值。
-
4. 資料準備(階段 1):
-
stage1_non_training_data_prepare
方法:-
記錄階段 1 的開始,並準備訓練和測試資料集。
-
包含以下步驟:
-
正常資料準備:
-
準備乾淨的訓練和測試資料集及其轉換操作。
-
-
後門資料準備:
-
生成特定於後門攻擊的影像和標籤轉換。
-
建立指標以確定哪些訓練和測試影像應被汙染,這些指標基於標籤轉換生成。
-
構建帶有這些後門指標的資料集,並應用必要的轉換操作,同時儲存這些帶有後門的資料集。
-
-
最終資料封裝:
-
用附加的轉換操作封裝準備好的資料集。
-
-
-
5. 訓練(階段 2):
-
stage2_training
方法:-
記錄階段 2 的開始,並初始化模型和訓練設定。
-
模型生成:
-
根據指定的引數(例如類別數、影像尺寸)建立模型。
-
配置裝置,判斷是使用 GPU 還是 CPU,並根據需要使用
torch.nn.DataParallel
來處理多 GPU 的情況。
-
-
訓練配置:
-
建立
BackdoorModelTrainer
例項來處理訓練。 -
配置損失函式、最佳化器和學習率排程器。
-
使用
DataLoader
載入訓練和測試資料,並使用trainer.train_with_test_each_epoch_on_mix
方法進行訓練。 -
儲存訓練結果,包括模型引數、資料路徑以及訓練和測試資料集。
-
-
我們這裡以CIFAR10資料集為例進行後門攻擊的演示。CIFAR-10資料集是一個廣泛應用於機器學習和深度學習領域的小型影像分類資料集,由加拿大高階研究所(CIFAR)提供。該資料集包含60000張32x32大小的彩色影像,分為10個類別:飛機、汽車、鳥、貓、鹿、狗、青蛙、馬、船和卡車。每個類別有6000張影像,其中50000張用於訓練,10000張用於測試。這些影像是用於監督學習訓練的,每個樣本都配備了相應的標籤值,以便於模型能夠識別和學習。
正常的資料集如下所示
而在BadNets中,我們以小方塊作為觸發器,原資料集加上觸發器後部分如下所示
我們直接進行後門的植入,即訓練過程
我們可以主要關注訓練期間的acc和asr的變化。acc表示模型的準確率,asr表示後門攻擊的成功率,這兩個指標都是越高越好。
也可以參考訓練期間的損失變化情況,可以看到在逐步降低
可以檢視acc的變化
可以看到在穩步升高。
哪怕就以手動終止時的第29個epoch為例
可以看到模型在執行正常任務時的準確率達到了0.90,而後門攻擊的成功率達到了0.94
這就復現了BadNets的攻擊方法。
Blended
理論
攻擊者的目標是在深度學習模型的訓練過程中,透過在訓練資料中注入特定的投毒樣本,植入一個後門。這樣,當模型在實際應用中遇到這些特定的投毒樣本或者與這些樣本具有特定模式的輸入時,會被誤導並按照攻擊者預定的方式進行分類。
與BadNets不同的地方在於,攻擊者定義一個模式作為鍵,任何具有這種模式的輸入例項都成為後門例項。例如,可以是一副眼鏡、一個卡通影像或隨機噪聲模式。
實施步驟也是類似的
-
生成投毒樣本:攻擊者根據選擇的策略生成投毒樣本,這些樣本在訓練集中被錯誤標記為攻擊者的目標標籤。
-
訓練資料注入:將生成的投毒樣本注入到模型的訓練集中。
-
模型訓練:使用被投毒的訓練集對深度學習模型進行訓練,導致模型學習到錯誤的模式關聯。
-
後門觸發:在模型部署後,攻擊者可以透過展示與投毒樣本相似或具有相同模式鍵的輸入例項來觸發後門,實現攻擊目的。
不過本文提出了混合注入策略(Blended Injection Strategy):將模式鍵與正常樣本混合,生成難以被人類察覺的投毒樣本。
論文中使用這種策略得到的中毒樣本如下所示
混合注入策略(Blended Injection Strategy)是本文中提出的一種資料投毒攻擊方法,旨在透過將攻擊者選定的模式鍵(key pattern)與正常的輸入樣本混合,生成新的投毒樣本。這些投毒樣本在視覺上與正常樣本相似,但包含了能夠觸發後門的特定模式。
選擇模式鍵(Key Pattern Selection)
-
攻擊者首先選定一個模式鍵,這可以是任意影像,例如卡通影像(如Hello Kitty)或隨機生成的噪聲模式。
定義混合函式(Blending Function Definition)
-
定義一個混合函式
該函式用於將模式鍵 (k) 與正常樣本 (x) 混合。函式引數α表示混合比例,
$$
\alpha \in [0, 1]
$$ -
混合函式可以表示為:)
-
其中,(k) 和 (x) 是向量表示,α 用於控制模式鍵在混合樣本中的可見度。
生成投毒樣本(Poisoning Instance Generation)
-
攻擊者隨機選擇或生成正常樣本 (x),然後使用混合函式將模式鍵 (k) 與正常樣本 (x) 混合,生成投毒樣本 (x')。
-
在生成投毒樣本時,攻擊者選擇一個較小的α值(例如
$$
\alpha_{\text{train}}
$$
使得混合後的模式鍵不易被人類察覺。
建立後門例項(Backdoor Instance Creation)
-
在模型訓練完成後,攻擊者可以建立後門例項,透過使用較大的α值(例如
$$
\alpha_{\text{test}}
$$
使得模式鍵在後門例項中更加明顯,從而觸發後門。
注入訓練集(Injecting into Training Set
-
攻擊者將生成的投毒樣本注入到模型的訓練集中,併為這些樣本分配目標標籤。這些樣本在訓練過程中誤導模型,使其學習到模式鍵與目標標籤之間的錯誤關聯。
模型訓練與後門植入(Model Training and Backdoor Embedding)
-
使用被投毒的訓練集對深度學習模型進行訓練。由於投毒樣本的存在,模型在訓練過程中學習到了與模式鍵相關的錯誤特徵,從而植入了後門。
攻擊觸發(Attack Triggering)
-
在模型部署後,攻擊者可以透過展示含有模式鍵的輸入例項來觸發後門,即使這些例項在視覺上與訓練時的投毒樣本不同,模型也會因為學習到的錯誤關聯而將其分類為目標標籤。
-
透過實驗,論文驗證了混合注入策略的有效性。即使只注入少量的投毒樣本(例如,115個),也能在保持模型在正常測試資料上準確性的同時,實現高攻擊成功率。
混合注入策略的關鍵在於透過調整混合比例 (\alpha),平衡投毒樣本的隱蔽性和後門觸發的有效性。這種策略利用了深度學習模型在訓練過程中對資料的泛化能力,即使在訓練時投毒樣本的模式鍵不太明顯,模型也能在測試時識別出具有相同模式鍵的後門例項。
復現
我們以Hello Kitty作為要blend的觸發器
來檢視植入觸發器後得到的部分訓練資料
訓練程式碼與BadNets是類似的,只是資料集換了一下而已
執行後門注入的過程
具體的攻擊配置資訊如下
如下是訓練期間的截圖
可以看到,能成功實現後門的植入與觸發。
Blind
現在我們再來看另外一種後門攻擊方法。其主要探討了一種新的在機器學習模型中注入後門的方法。這種方在訓練資料可用之前和訓練開始之前破壞ML訓練程式碼。
所提出的攻擊方案是一種針對機器學習模型的後門攻擊,稱為"Blind Backdoors",意即盲目的後門攻擊。這種攻擊是在訓練資料可用之前,甚至在訓練開始之前,透過破壞模型訓練程式碼中的損失值計算來實現的
它的威脅模型與之前提到的後門攻擊是不同的,攻擊者能夠修改機器學習程式碼庫中的損失計算部分,但無法訪問訓練資料、模型權重或訓練過程的輸出。
攻擊者注入惡意程式碼,該程式碼在模型訓練期間動態生成有毒的訓練輸入(即後門輸入)。
在攻擊中會使用多目標最佳化(特別是多梯度下降演算法MGDA結合Frank-Wolfe最佳化器)來平衡主任務和後門任務的損失函式,確保模型在兩個任務上都能達到高精度。
另外,攻擊者定義一個後門輸入合成器(input synthesizer µ),用於生成包含後門特徵的輸入資料x*。
這就要求我們定義一個後門標籤合成器(label synthesizer ν),它根據輸入x及其正確的標籤y,確定當輸入包含後門特徵時模型應該如何錯誤分類。
其中的關鍵在於損失值的計算與最佳化
-
在常規訓練過程中,對於每個輸入(x, y),計算主任務損失ℓm = L(θ(x), y)。
-
攻擊者程式碼同時生成後門輸入x和標籤y,並計算後門任務損失ℓm* = L(θ(x), y)。
-
結合主任務損失和後門任務損失,以及可能的防禦規避損失ℓev,形成盲損失ℓblind = α0ℓm + α1ℓm* [+α2ℓev],並透過MGDA最佳化α係數。
在模型訓練過程中,使用修改後的損失值ℓblind進行反向傳播和模型權重更新,從而在不降低主任務效能的前提下,注入後門功能。攻擊者還可以在損失計算中加入額外的項,以便在不觸發現有防禦機制的情況下,成功注入後門。
如下是修改程式碼的示意圖
如下是修改後的惡意程式碼示例
復現
合成類,Synthesizer
類的主要作用是生成帶有後門攻擊的資料批次。透過繼承該類並實現 synthesize_inputs
和 synthesize_labels
方法,可以定製具體的後門攻擊策略。make_backdoor_batch
方法負責根據配置生成帶攻擊的資料批次,而 apply_backdoor
方法則實際執行攻擊操作。
這段程式碼定義了一個 Synthesizer
類,該類用於生成帶有後門攻擊的資料批次
1. 類定義和初始化:
-
Synthesizer
類:-
包含兩個屬性:
params
和task
,其中params
是一個Params
物件,task
是一個Task
物件。
-
-
__init__
方法:-
建構函式接收一個
Task
物件作為引數,初始化task
屬性並將task.params
賦值給params
屬性。這意味著Synthesizer
的配置依賴於提供的任務物件。
-
2. 生成後門批次:
-
make_backdoor_batch
方法:-
此方法用於生成帶有後門攻擊的資料批次。
-
引數:
-
batch
: 輸入的原始資料批次。 -
test
: 一個布林值,指示是否是測試模式。 -
attack
: 一個布林值,指示是否需要應用攻擊。
-
-
邏輯:
-
如果
attack
為False
,或者當params.loss_tasks
僅包含'normal'
且不是測試模式,則直接返回原始批次。 -
如果是測試模式,則
attack_portion
等於批次大小(batch_size
),即所有資料都被攻擊。 -
否則,計算需要攻擊的資料量,即根據
params.poisoning_proportion
計算批次大小的一部分。 -
克隆原始批次,呼叫
apply_backdoor
方法對克隆批次應用後門攻擊。 -
返回修改後的批次。
-
-
3. 應用後門攻擊:
-
apply_backdoor
方法:-
用於修改批次的一部分以表示批次汙染。
-
引數:
-
batch
: 輸入的批次資料。 -
attack_portion
: 需要被攻擊的資料量。
-
-
邏輯:
-
呼叫
synthesize_inputs
方法來合成輸入資料。 -
呼叫
synthesize_labels
方法來合成標籤。 -
這個方法沒有返回值。
-
-
4. 合成輸入和標籤:
-
synthesize_inputs
方法:-
這是一個抽象方法,用於合成批次中的輸入資料。
-
該方法需要在子類中實現,以定義如何具體地修改輸入資料。
-
-
synthesize_labels
方法:-
這是一個抽象方法,用於合成批次中的標籤。
-
該方法需要在子類中實現,以定義如何具體地修改標籤。
-
關鍵函式
這段程式碼包含幾個函式,用於計算損失函式、記錄時間、處理梯度以及計算後門損失
1. 記錄時間的函式:
-
record_time
函式:-
引數:
-
params
: 配置引數物件,包含記錄時間的設定。 -
t
: 記錄的時間戳(通常是time.perf_counter()
返回的值)。 -
name
: 記錄時間的標籤名稱。
-
-
功能:
-
如果
t
和name
都被提供,並且params.save_timing
等於name
或者params.save_timing
為True
,則記錄當前操作的耗時。 -
使用
torch.cuda.synchronize()
確保 CUDA 操作完成,然後計算自t
以來的時間差,單位為毫秒,並將其附加到params.timing_data[name]
列表中。
-
-
2. 計算正常損失的函式:
-
compute_normal_loss
函式:-
引數:
-
params
: 配置引數物件。 -
model
: 用於計算損失的模型。 -
criterion
: 損失函式。 -
inputs
: 輸入資料。 -
labels
: 標籤資料。 -
grads
: 布林值,是否需要計算梯度。
-
-
功能:
-
記錄前向傳播的時間,並計算模型的輸出。
-
計算輸出和標籤之間的損失。
-
如果
params.dp
為False
,對損失進行平均。 -
如果
grads
為True
,記錄反向傳播的時間,並計算梯度。
-
-
返回值:
-
返回計算得到的損失和(如果需要)計算得到的梯度。
-
-
3. 獲取梯度的函式:
-
get_grads
函式:-
引數:
-
params
: 配置引數物件。 -
model
: 用於計算梯度的模型。 -
loss
: 損失值。
-
-
功能:
-
記錄計算梯度的時間,並計算模型引數的梯度。
-
-
返回值:
-
返回計算得到的梯度。
-
-
4. 張量非線性變換的函式:
-
th
函式:-
引數:
-
vector
: 輸入張量。
-
-
功能:
-
對輸入張量應用雙曲正切函式 (
torch.tanh
) 並將結果歸一化到[0, 1]
範圍內。
-
-
返回值:
-
返回歸一化後的張量。
-
-
5. 計算範數損失的函式:
-
norm_loss
函式:-
引數:
-
params
: 配置引數物件。 -
model
: 包含mask
屬性的模型。 -
grads
: 布林值,是否需要計算梯度。
-
-
功能:
-
根據
params.nc_p_norm
計算model.mask
的範數:-
如果
params.nc_p_norm
為 1,計算mask
的 L1 範數。 -
如果
params.nc_p_norm
為 2,計算mask
的 L2 範數。
-
-
如果
grads
為True
,計算梯度並將模型的梯度清零。
-
-
返回值:
-
返回計算得到的範數和(如果需要)計算得到的梯度。
-
-
6. 計算後門損失的函式:
-
compute_backdoor_loss
函式:-
引數:
-
params
: 配置引數物件。 -
model
: 用於計算損失的模型。 -
criterion
: 損失函式。 -
inputs_back
: 帶有後門攻擊的輸入資料。 -
labels_back
: 帶有後門攻擊的標籤資料。 -
grads
: 布林值,是否需要計算梯度。
-
-
功能:
-
記錄前向傳播的時間,並計算模型在帶有後門攻擊的輸入資料上的輸出。
-
計算輸出和帶有後門攻擊的標籤之間的損失。
-
如果
params.task
為'Pipa'
,對特定標籤的損失進行調整。 -
如果
params.dp
為False
,對損失進行平均。 -
如果
grads
為True
,計算梯度。
-
-
返回值:
-
返回計算得到的損失和(如果需要)計算得到的梯度。
-
-
總的來說,這些函式用於在訓練過程中處理損失計算、記錄時間、計算梯度等操作,支援對正常資料和後門攻擊資料的處理。
這個函式 compute_all_losses_and_grads
用於計算一組損失函式和梯度,涉及到正常損失、後門損失、掩膜範數損失,以及某種特定的損失計算(如 Neural Cleanse 部分)
函式引數:
-
loss_tasks
: 一個包含不同損失任務名稱的列表,例如'normal'
,'backdoor'
,'mask_norm'
,'neural_cleanse_part1'
等。 -
attack
: 包含配置引數和模型的物件,提供必要的引數來計算損失。 -
model
: 要計算損失的模型。 -
criterion
: 損失函式,用於計算模型輸出和目標之間的損失。 -
batch
: 正常訓練批次的物件,通常包含輸入資料和標籤。 -
batch_back
: 帶有後門攻擊的批次物件,通常包含後門資料和標籤。 -
compute_grad
: 布林值,指示是否需要計算梯度。
函式功能:
-
初始化字典:
-
grads
: 用於儲存每種任務的梯度。 -
loss_values
: 用於儲存每種任務的損失值。
-
-
計算損失和梯度:
-
遍歷
loss_tasks
中的每個任務,根據任務型別呼叫相應的損失計算函式。-
'normal'
:-
呼叫
compute_normal_loss
函式,計算正常的訓練損失和梯度。 -
使用
batch.inputs
和batch.labels
。
-
-
'backdoor'
:-
呼叫
compute_backdoor_loss
函式,計算帶有後門攻擊的損失和梯度。 -
使用
batch_back.inputs
和batch_back.labels
。
-
-
'mask_norm'
:-
呼叫
norm_loss
函式,計算掩膜的範數和梯度(如果需要)。 -
使用
attack.nc_model
來計算掩膜的範數。
-
-
'neural_cleanse_part1'
:-
呼叫
compute_normal_loss
函式,計算 Neural Cleanse 部分 1 的損失和梯度。 -
使用
batch.inputs
和batch_back.labels
。
-
-
-
-
返回結果:
-
返回兩個字典:
loss_values
和grads
,分別包含每種任務的損失值和梯度。
-
compute_all_losses_and_grads
函式的作用是根據任務列表計算各種損失函式和梯度。根據提供的任務型別,它會選擇合適的損失計算方法,並將計算結果儲存在字典中。最終返回這些計算結果,以供進一步處理或分析。
攻擊類
Attack
類主要用於管理攻擊過程中的損失計算,包括:
-
使用正常資料和帶有後門資料的批次計算損失。
-
根據不同的損失平衡策略(如 MGDA 或固定縮放因子)來調整損失的權重。
-
記錄和更新損失歷史,以便進一步分析和最佳化。
-
支援不同的損失計算任務,並在計算損失時考慮到這些任務的權重。
這個 Attack
類用於實現和管理一種攻擊策略,其中包括計算損失值、調整損失的權重、以及跟蹤損失歷史記錄。
屬性:
-
params
: 儲存引數配置的物件。包含了關於損失計算、損失平衡等的配置。 -
synthesizer
:Synthesizer
例項,用於生成帶有後門的批次資料。 -
nc_model
: 用於 Neural Cleanse 的模型。 -
nc_optim
: 用於最佳化 Neural Cleanse 模型的最佳化器。 -
loss_hist
: 儲存歷史損失值的列表。
方法:
-
__init__
方法:-
引數:
-
params
: 配置引數物件。 -
synthesizer
: 用於生成帶有後門資料的Synthesizer
例項。
-
-
功能:
-
初始化
params
和synthesizer
屬性。
-
-
-
compute_blind_loss
方法:-
引數:
-
model
: 當前訓練的模型。 -
criterion
: 損失函式。 -
batch
: 正常批次資料。 -
attack
: 布林值,指示是否進行攻擊。
-
-
功能:
-
計算
batch
資料的剪下版本。 -
根據是否進行攻擊設定
loss_tasks
列表。 -
使用
synthesizer
生成帶有後門的批次資料batch_back
。 -
根據歷史損失和閾值調整
loss_tasks
。 -
根據
loss_balance
配置選擇計算損失的方法:-
MGDA
: 使用 MGDA (Multi-Gradient Descent Algorithm) 平衡損失,計算梯度和損失,獲取縮放因子。 -
fixed
: 使用固定的縮放因子進行損失計算。
-
-
如果只有一個損失任務,設定預設的縮放因子為 1.0。
-
更新
loss_hist
列表,記錄正常損失的最新值。 -
呼叫
scale_losses
方法計算加權損失。 -
返回加權後的損失值。
-
-
-
scale_losses
方法:-
引數:
-
loss_tasks
: 損失任務列表。 -
loss_values
: 包含不同任務損失值的字典。 -
scale
: 各任務損失的縮放因子。
-
-
功能:
-
計算加權損失值
blind_loss
。 -
將每個任務的損失值和縮放因子儲存在
params.running_losses
和params.running_scales
中。 -
更新總損失記錄
params.running_losses['total']
。 -
返回加權後的損失值
blind_loss
。
-
-
MGDA求解器
MGDASolver` 類用於在多目標最佳化中平衡不同任務的梯度和損失值,主要包括:
-
計算最小范數解的函式 (
_min_norm_element_from2
,_min_norm_2d
)。 -
投影到單純形上的方法 (
_projection2simplex
)。 -
梯度下降及更新點的方法 (
_next_point
)。 -
尋找最小范數元素的最佳化演算法 (
find_min_norm_element
,find_min_norm_element_FW
)。 -
計算各任務縮放因子的函式 (
get_scales
)。
這些方法幫助在多工學習中最佳化和調整損失,使得模型能夠在不同任務之間取得平衡。
MGDASolver
類實現了多目標最佳化中使用的多梯度下降演算法 (MGDA),其主要用於解決在多個目標之間平衡梯度的最佳化問題
類屬性:
-
MAX_ITER
: 最大迭代次數,設定為 250。 -
STOP_CRIT
: 停止準則,當變化小於該值時停止迭代,設定為 1e-5。
方法:
-
_min_norm_element_from2
方法:-
功能:
-
計算最小范數元素,即 (\min{c} |cx_1 + (1-c)x_2|2^2)。
-
根據 (x_1) 和 (x_2) 的內積計算最小范數解。
-
-
引數:
-
v1v1
: (\langle x_1, x_1 \rangle)。 -
v1v2
: (\langle x_1, x_2 \rangle)。 -
v2v2
: (\langle x_2, x_2 \rangle)。
-
-
返回值:
-
gamma
: 最優的比例係數。 -
cost
: 對應的最小范數。
-
-
-
_min_norm_2d
方法:-
功能:
-
在二維情況下找到最小范數解的組合。
-
-
引數:
-
vecs
: 向量列表。 -
dps
: 用於儲存內積結果的字典。
-
-
返回值:
-
sol
: 最小范數的解及其對應的最小值。 -
dps
: 內積結果字典。
-
-
-
_projection2simplex
方法:-
功能:
-
解決投影到單純形上的最佳化問題,確保解滿足 (\sum z = 1) 和 (0 \leq z_i \leq 1)。
-
-
引數:
-
y
: 輸入向量。
-
-
返回值:
-
投影后的向量
z
。
-
-
-
_next_point
方法:-
功能:
-
在當前點
cur_val
上進行梯度下降,並將結果投影到單純形上。
-
-
引數:
-
cur_val
: 當前點的值。 -
grad
: 當前點的梯度。 -
n
: 向量的維度。
-
-
返回值:
-
下一點
next_point
。
-
-
-
find_min_norm_element
方法:-
功能:
-
尋找在給定向量列表的凸包中具有最小范數的元素。
-
-
引數:
-
vecs
: 向量列表。
-
-
返回值:
-
sol_vec
: 最小范數的解。 -
nd
: 最小范數值。
-
-
-
find_min_norm_element_FW
方法:-
功能:
-
使用 Frank-Wolfe 演算法尋找在給定向量列表的凸包中具有最小范數的元素。
-
-
引數:
-
vecs
: 向量列表。
-
-
返回值:
-
sol_vec
: 最小范數的解。 -
nd
: 最小范數值。
-
-
-
get_scales
方法:-
功能:
-
計算每個任務的縮放因子,以最小化多目標最佳化問題中的範數。
-
-
引數:
-
grads
: 各任務的梯度。 -
losses
: 各任務的損失值。 -
normalization_type
: 梯度歸一化型別。 -
tasks
: 任務列表。
-
-
返回值:
-
scale
: 每個任務的縮放因子字典。
-
PatternSynthesizer
類的設計目的是將一個預定義的或動態生成的後門模式嵌入影像中。它處理模式的建立、放置和與影像的結合,並根據需要調整標籤以適應後門攻擊。 -
這段程式碼定義了一個名為 PatternSynthesizer
的類,它是 Synthesizer
的一個子類。這個類的主要功能是生成特定的模式(即後門模式)並將其嵌入到影像中。以下是對每個元件的詳細解釋:
-
屬性和初始化:
-
pattern_tensor
:這個屬性儲存了一個預定義的二維張量模式。它是一個矩陣,其中包含一些正值和負值。這個模式用於作為後門模式嵌入影像中。 -
x_top
和y_top
:這些屬性表示後門模式在影像中放置時的左上角座標。x_top
是水平座標,y_top
是垂直座標。 -
mask_value
:一個值,用於表示在模式中哪些區域不會被應用到影像上。 -
resize_scale
:這個元組定義了一個範圍,用於在模式的位置動態變化時對模式進行縮放。 -
mask
:一個張量,用於將後門模式與原始影像結合。它標記了影像中哪些部分受後門模式的影響。 -
pattern
:這個張量儲存了最終的後門模式,它是在影像中嵌入模式並應用了掩碼後的結果。
-
-
初始化 (
__init__
方法):-
__init__
方法呼叫父類的初始化方法,然後透過呼叫self.make_pattern
建立初始的後門模式。
-
-
模式建立 (
make_pattern
方法):-
這個方法首先初始化一個
full_image
張量,其大小由self.params.input_shape
指定,填充了mask_value
。 -
然後計算模式的右下角座標 (
x_bot
,y_bot
),以確保模式不會超出影像邊界。如果模式超出邊界,則引發ValueError
。 -
將模式放置在
full_image
中的指定左上角座標。 -
建立
mask
張量,用於標記full_image
中與mask_value
不同的部分。 -
將
pattern
張量進行歸一化,並移動到適當的裝置(例如 GPU)。
-
-
合成輸入 (
synthesize_inputs
方法):-
這個方法將生成的模式嵌入到一批輸入影像中。它使用
mask
確保只有與後門模式對應的影像部分被修改。
-
-
合成標籤 (
synthesize_labels
方法):-
這個方法為批次標籤中的後門攻擊部分設定特定的標籤 (
self.params.backdoor_label
)。
-
-
獲取模式 (
get_pattern
方法):-
如果啟用了動態位置調整,這個方法會在定義的
resize_scale
範圍內隨機調整pattern_tensor
的大小。它還會有 50% 的機率水平翻轉模式。 -
將調整大小後的模式轉換為影像,再轉換回張量,並在影像尺寸內隨機放置。
-
再次呼叫
make_pattern
方法以更新pattern
和mask
屬性,應用新的位置。
-
AddMaskPatchTrigger
類用於將指定的觸發器影像應用到目標影像上的特定區域,而 gradient_normalizers
函式則用於根據指定的歸一化型別對梯度進行歸一化處理。這些功能通常用於處理影像資料和最佳化過程中的梯度調整。
這段程式碼定義了兩個不同的功能:
-
AddMaskPatchTrigger
類:-
這個類用於將一個觸發器(
trigger_array
)應用到影像上,透過一個掩碼(mask_array
)來控制觸發器的應用區域。
建構函式 (
__init__
方法):-
trigger_array
: 觸發器陣列,可以是numpy.ndarray
或torch.Tensor
。 -
mask_array
: 掩碼陣列,同樣可以是numpy.ndarray
或torch.Tensor
。 -
將這兩個引數儲存為例項變數。
呼叫方法 (
__call__
方法):-
這個方法讓
AddMaskPatchTrigger
例項可以像函式一樣被呼叫。它呼叫add_trigger
方法來將觸發器應用到影像上。
新增觸發器 (
add_trigger
方法):-
add_trigger
方法接收一張影像img
,透過使用掩碼陣列mask_array
將觸發器陣列trigger_array
疊加到影像上。 -
計算方式是:
img * (1 - mask_array) + trigger_array * mask_array
。這意味著影像中掩碼為1的部分將被觸發器覆蓋,而掩碼為0的部分保持不變。
-
-
gradient_normalizers
函式:-
這個函式用於根據不同的歸一化型別對梯度進行歸一化處理。它接收梯度(
grads
)、損失(losses
)和歸一化型別(normalization_type
)。
引數:
-
grads
: 一個字典,鍵是變數名,值是對應變數的梯度列表。 -
losses
: 一個字典,鍵是變數名,值是對應變數的損失值。 -
normalization_type
: 一個字串,指定歸一化型別,可以是'l2'
、'loss'
、'loss+'
、'none'
或'eq'
。
歸一化型別處理:
-
l2
:-
對於每個梯度,計算梯度的 L2 範數(即每個梯度的平方和的平方根)。
-
-
loss
:-
對於每個梯度,使用損失的均值進行歸一化,歸一化值最大為 10.0。
-
-
loss+
:-
歸一化值是損失的均值與梯度的 L2 範數的乘積,最大值為 10。
-
-
none
或eq
:-
歸一化值固定為 1.0。
-
-
如果提供了無效的歸一化型別,丟擲
ValueError
異常。
返回值:
-
返回一個字典
gn
,包含每個變數的歸一化值。
-
-
blendedImageAttack_on_batch
類用於將目標影像與輸入影像按比例混合,從而生成具有目標影像特徵的混合影像。 -
batchwise_label_transform
類用於批次標籤的轉換,透過指定的變換函式將原始標籤轉換為新的標籤,並將結果移動到指定裝置。
這兩個類的功能可以在影像處理和模型訓練中用於特定的攻擊策略和標籤處理任務。
1. blendedImageAttack_on_batch
類
這個類用於對影像批次進行混合攻擊。它將目標影像和當前影像按一定比例混合,生成具有目標影像特徵的影像。
-
建構函式 (
__init__
方法):-
target_image
: 目標影像,它將用於與輸入影像進行混合。這個影像被移動到指定的裝置(如 GPU)。 -
blended_rate
: 混合比例,決定了目標影像在最終混合影像中的佔比。 -
device
: 裝置(如 GPU),用於儲存目標影像。
-
-
呼叫方法 (
__call__
方法):-
使得
blendedImageAttack_on_batch
例項可以像函式一樣被呼叫。它呼叫add_trigger
方法來進行影像混合。
-
-
新增觸發器 (
add_trigger
方法):-
img
: 輸入影像。 -
計算混合影像的公式是
(1 - self.blended_rate) * img + (self.blended_rate) * self.target_image[None, ...]
。這裡使用了廣播(broadcasting),將目標影像的維度與輸入影像的維度對齊,然後將目標影像和輸入影像按比例混合。
-
2. batchwise_label_transform
類
這個類用於批次標籤的轉換,將原始標籤透過某種變換函式轉換為新的標籤。
-
建構函式 (
__init__
方法):-
label_transform
: 一個函式,用於將標籤轉換為目標標籤。 -
device
: 裝置(如 GPU),用於儲存轉換後的標籤。
-
-
呼叫方法 (
__call__
方法):-
batch_labels
: 批次標籤,是一個張量(torch.Tensor
)。 -
使用列表推導將每個標籤透過
self.label_transform
函式進行轉換,並將結果轉換為張量,最終將張量移動到指定的裝置上。
-
此時的中毒樣本如下
執行後門注入
如下是攻擊配置資訊
訓練過程部分截圖如下
檢視acc變化情況
可以看到也是穩步上升的
總得來說,這種後門攻擊方法,雖然後門攻擊成功率較高,但是正常任務的準確率會受到一定影響,比如在第24個epoch時,正常任務的準確率才0.79。
更多網安技能的線上實操練習,請點選這裡>>