王培彬 陳少鎮(zhèn) 林沛聰 藍(lán)汝琪 熊梓韜 潘志宏
摘要:隨著互聯(lián)網(wǎng)的快速發(fā)展,越來(lái)越多的網(wǎng)站為了防止用戶利用機(jī)器人自動(dòng)注冊(cè)、登錄、灌水,都采用了驗(yàn)證碼自動(dòng)識(shí)別技術(shù)。然而,簡(jiǎn)易的驗(yàn)證碼依然存在安全風(fēng)險(xiǎn),為了防止網(wǎng)絡(luò)爬蟲(chóng)或者惡意攻擊的登錄操作,本文將通過(guò)PaddlePaddle平臺(tái)進(jìn)行驗(yàn)證碼識(shí)別的深度學(xué)習(xí),闡述深度學(xué)習(xí)下網(wǎng)站驗(yàn)證碼的破解和防范。實(shí)驗(yàn)結(jié)果表明:將訓(xùn)練實(shí)例的驗(yàn)證碼數(shù)據(jù)訓(xùn)練成預(yù)測(cè)模型,使用預(yù)測(cè)模型來(lái)自動(dòng)識(shí)別驗(yàn)證碼中包含的內(nèi)容實(shí)現(xiàn)驗(yàn)證碼自動(dòng)識(shí)別,而將驗(yàn)證碼的字符位置隨機(jī)擺放,可有效防止攻擊者對(duì)圖片進(jìn)行裁剪分析。
關(guān)鍵詞:驗(yàn)證碼;自動(dòng)識(shí)別;PaddlePaddle;深度學(xué)習(xí);預(yù)測(cè)模型
中圖分類號(hào):TP391 文獻(xiàn)標(biāo)識(shí)碼:A
文章編號(hào):1009-3044(2019)11-0031-04
Abstract:With the rapid development of the Internet , more and more websites have adopted captcha automatic identification technology in order to prevent users from using robots to automatically register , login and chatter . However , simple captchas still have security risks . In order to prevent the login operation of web crawlers or malicious attacks , this paper will carry out the deep learning of captchas identification of PaddlePaddle platform and explain the cracking and prevention of captchas under deep learning . The experimental results show that the captcha data onto the training example is trained as a prediction model , and the content contained in the captcha is automatically identified by the prediction model , while the random placement of the characters of the captcha can effectively prevent the attacker from cutting and analyzing the image .
Key words:verification code; automatic recognition; paddlepaddle; deep learning; predictive model
當(dāng)下大部分網(wǎng)站的登錄以驗(yàn)證碼作為驗(yàn)證登錄,以防止網(wǎng)絡(luò)爬蟲(chóng)或者惡意攻擊的登錄操作。隨著深度學(xué)習(xí)的不斷發(fā)展,深度學(xué)習(xí)在圖片識(shí)別上的準(zhǔn)確率也越來(lái)越高。通過(guò)利用圖像識(shí)別技術(shù)[1],可以識(shí)別一些網(wǎng)站的驗(yàn)證碼。我們只有了解的識(shí)別的技術(shù)原理[2],方可防止網(wǎng)站出現(xiàn)相應(yīng)的惡意攻擊。
PaddlePaddle是百度研發(fā)的開(kāi)源開(kāi)放的深度學(xué)習(xí)平臺(tái)[3],有全面的官方支持的工業(yè)級(jí)應(yīng)用模型,涵蓋自然語(yǔ)言處理、計(jì)算機(jī)視覺(jué)、推薦引擎等多個(gè)領(lǐng)域,并開(kāi)放多個(gè)領(lǐng)先的預(yù)訓(xùn)練中文模型。同時(shí)支持稠密參數(shù)和稀疏參數(shù)場(chǎng)景的大規(guī)模深度學(xué)習(xí)[4]并行訓(xùn)練,支持千億規(guī)模參數(shù)、數(shù)百個(gè)幾點(diǎn)的高效并行訓(xùn)練,也可提供深度學(xué)習(xí)并行技術(shù)的深度學(xué)習(xí)框架[5]。PaddlePaddle擁有多端部署能力,支持服務(wù)器端、移動(dòng)端等多種異構(gòu)硬件設(shè)備的高速推理,預(yù)測(cè)性能有顯著優(yōu)勢(shì)。目前PaddlePaddle已經(jīng)實(shí)現(xiàn)了API的穩(wěn)定和向后兼容,具有完善的中英雙語(yǔ)使用文檔。
1 PaddlePaddle之驗(yàn)證碼識(shí)別的實(shí)現(xiàn)
1.1 數(shù)據(jù)集介紹與下載
本論文中使用某系統(tǒng)網(wǎng)站作為實(shí)驗(yàn)?zāi)繕?biāo),經(jīng)過(guò)觀察大量的驗(yàn)證碼發(fā)現(xiàn),該網(wǎng)站的驗(yàn)證碼只有小寫(xiě)的字母和數(shù)字,所以這些類別比較少,所以使得識(shí)別更加容易。通過(guò)對(duì)該驗(yàn)證碼進(jìn)行切割分析[6],可以觀察到驗(yàn)證碼中的4字符都會(huì)出現(xiàn)固定的位置,所以只需要通過(guò)固定位置裁剪即可把驗(yàn)證碼中的每個(gè)字符都裁剪出來(lái)。該系統(tǒng)的驗(yàn)證碼如下:
通過(guò)爬蟲(chóng)程序,可以爬取大量的驗(yàn)證碼圖片,以下的代碼片段就是下載驗(yàn)證碼圖片的核心代碼。
pic = requests.get('http://xxxxxx.aspx?', timeout=500)
pic_name = self.save_path+'/' +str(uuid.uuid1()) + '.png'
with open(pic_name, 'wb') as f:
將每一張驗(yàn)證碼命名為其對(duì)應(yīng)的驗(yàn)證碼內(nèi)容,是一個(gè)龐大的工作量,特別在訓(xùn)練網(wǎng)絡(luò)模型的過(guò)程中,標(biāo)注數(shù)據(jù)是工作量非常巨大的,但也是必需的,數(shù)據(jù)標(biāo)注工作量大也是目前深度學(xué)習(xí)的難點(diǎn)。
1.2 裁剪驗(yàn)證碼與生成圖像列表
通過(guò)標(biāo)注大量的數(shù)據(jù)集之后,需要裁剪所有的驗(yàn)證碼。通過(guò)第一部分已經(jīng)分析到驗(yàn)證碼的分布情況,而數(shù)據(jù)又已經(jīng)標(biāo)注了,根據(jù)這些標(biāo)注信息對(duì)圖片裁剪,裁剪后的圖片只包含一個(gè)字符。
經(jīng)過(guò)驗(yàn)證碼裁剪,并去掉容易混淆的“9”,“o”,“z”字符,總體可分為33個(gè)類別,這也使得模型更容易訓(xùn)練。
由于這些數(shù)據(jù)集不屬于PaddlePaddle自帶數(shù)據(jù)集,訓(xùn)練需自定義數(shù)據(jù)集,建立圖像列表文件作為數(shù)據(jù)讀取的途徑,通過(guò)編寫(xiě)一個(gè)生成圖像列表的程序,把驗(yàn)證碼生成一個(gè)圖像列表。
將已裁剪的數(shù)據(jù)集生成圖片列表,通過(guò)下面的代碼片段將所有圖像和每張圖片對(duì)應(yīng)的標(biāo)簽生成圖片的相對(duì)路徑和標(biāo)簽,以便后續(xù)訓(xùn)練過(guò)程中讀取數(shù)據(jù)。其核心代碼片段如下:
for img_path in img_paths:
name_path = path + '/' + img_path # 每張圖片的路徑
isexist = os.path.exists(data_list_path) # 如果不存在這個(gè)文件夾,就創(chuàng)建
if not isexist:
os.makedirs(data_list_path)
if class_sum % 10 == 0: # 每10張圖片取一個(gè)做測(cè)試數(shù)據(jù)
test_sum += 1
with open(data_list_path + "test.list", 'a') as f:
f.write(name_path + "\t%d" % class_label + "\n")
else:
trainer_sum += 1
with open(data_list_path + "trainer.list", 'a') as f:
f.write(name_path + "\t%d" % class_label + "\n")
class_sum += 1
all_class_images += 1
通過(guò)上面的程序,一共會(huì)生成trainer.list,test.list,readme.json,其中trainer.list,test.list分布是用來(lái)訓(xùn)練和測(cè)試的,readme.json包含數(shù)據(jù)集的信息,通過(guò)這個(gè)文件可以獲取到標(biāo)簽尋對(duì)用的字符。
1.3 數(shù)據(jù)的讀取
建立數(shù)據(jù)列表之后,需要建立數(shù)據(jù)讀取程序,通過(guò)這個(gè)程序生成的reader,reader是PaddlePaddle讀取數(shù)據(jù)的一種介質(zhì)。通過(guò)使用reader,PaddlePaddle可以在訓(xùn)練的過(guò)程中非常便捷地從磁盤讀取圖片數(shù)據(jù),經(jīng)過(guò)預(yù)處理再應(yīng)用于訓(xùn)練。以下的代碼片段就是通過(guò)上一部分生成的圖像列表獲取圖像路徑和標(biāo)簽。
def train_reader(self, train_list, buffered_size=1024):
def reader():
with open(train_list, 'r') as f:
lines = [line.strip() for line in f]
for line in lines:
img_path, lab = line.strip().split('\t')
yield img_path, int(lab)
return paddle.reader.xmap_readers(self.train_mapper, reader,
cpu_count(), buffered_size)
PaddlePaddle的reader是讀取圖像和對(duì)圖片進(jìn)行預(yù)處理,通過(guò)上述的方式完成讀取圖片后,需要對(duì)圖片進(jìn)行預(yù)處理,如下為圖片預(yù)處理的核心代碼片段:
def train_mapper(self, sample):
img, label = sample
# 此處使用本地的image,如果paddlepaddle版本是最新的,也可以使用padd.v2.image
# 因?yàn)槭腔叶葓D,所以is_color=False
img = paddle.image.load_image(img, is_color=False)
img = paddle.image.simple_transform(img, 38, self.imageSize, True, is_color=False)
return img.flatten().astype('float32'), label
最后結(jié)合以上的圖片讀取和預(yù)處理兩部分,可以得到一個(gè)訓(xùn)練使用的reader。在生成reader之前,通過(guò)使用PaddlePaddle的reader按照指定的大小隨機(jī)裁剪一個(gè)方形的圖像,這種隨機(jī)裁剪的預(yù)處理操作也是數(shù)據(jù)增強(qiáng)的一種方式。
1.4 使用PaddlePaddle開(kāi)始訓(xùn)練
在開(kāi)始PaddlePaddle的訓(xùn)練之前,需定義一個(gè)神經(jīng)網(wǎng)絡(luò)作為將要訓(xùn)練的一個(gè)模型。本論文使用的神經(jīng)網(wǎng)絡(luò)模型是VGG神經(jīng)網(wǎng)絡(luò)[7],這個(gè)模型是牛津大學(xué)VGG(Visual Geometry Group)組在2014年ILSVRC提出的,VGG神經(jīng)模型的核心是五組卷積操作,每?jī)山M之間做Max-Pooling空間降維。同一組內(nèi)采用多次連續(xù)的3X3卷積,卷積核的數(shù)目由較淺組的64增多到最深組的512,同一組內(nèi)的卷積核數(shù)目是一樣的。卷積之后接兩層全連接層,之后是分類層。由于每組內(nèi)卷積層的不同,有11、13、16、19層這幾種模型。根據(jù)數(shù)據(jù)集訓(xùn)練的數(shù)量,本論文對(duì)VGG做了一定的適配,卷積部分引入了BN層和Dropout操作,BN層全稱為Batch Normalization。
conv1 = conv_block(img, 64, 2, [0.3, 0], 3)
conv2 = conv_block(conv1, 128, 2, [0.4, 0])
conv3 = conv_block(conv2, 256, 3, [0.4, 0.4, 0])
conv4 = conv_block(conv3, 512, 3, [0.4, 0.4, 0])
conv5 = conv_block(conv4, 512, 3, [0.4, 0.4, 0])
drop = paddle.layer.dropout(input=conv5, dropout_rate=0.5)
fc1 = paddle.layer.fc(input=drop, size=512, act=paddle.activation.Linear())
bn = paddle.layer.batch_norm(input=fc1,
act=paddle.activation.Relu(),
layer_attr=paddle.attr.Extra(drop_rate=0.5))
fc2 = paddle.layer.fc(input=bn, size=512, act=paddle.activation.Linear())
# 通過(guò)神經(jīng)網(wǎng)絡(luò)模型再使用Softmax獲得分類器(全連接)
out = paddle.layer.fc(input=fc2,
size=10,
act=paddle.activation.Softmax())
在開(kāi)始PaddlePaddle的訓(xùn)練時(shí),需先導(dǎo)入依賴包,其中有PaddlePaddle的V2包和讀取數(shù)據(jù)的程序。然后創(chuàng)建一個(gè)類,再在類中創(chuàng)建一個(gè)初始化函數(shù),在初始化函數(shù)中來(lái)初始化PaddlePaddle。此外,可以通過(guò)輸入是否是參數(shù)文件路徑,或者是損失函數(shù),如果為參數(shù)文件路徑,可使用已訓(xùn)練完成的參數(shù)生產(chǎn)參數(shù)。如果不傳入?yún)?shù)文件路徑,可使用傳入的損失函數(shù)生成參數(shù)。之后通過(guò)圖像的標(biāo)簽信息和分類器生成損失函數(shù),使用損失函數(shù)生成初始化參數(shù),再生成優(yōu)化方法,來(lái)創(chuàng)建訓(xùn)練器。最后,在程序中調(diào)用相應(yīng)的函數(shù),就可以開(kāi)始訓(xùn)練了。其關(guān)鍵代碼實(shí)現(xiàn)如下:
out = vgg_bn_drop(datadim=datadim)
cost = paddle.layer.classification_cost(input=out, label=lbl)
parameters = self.get_parameters(cost=cost)
momentum_optimizer = paddle.optimizer.Momentum(momentum=0.9)
trainer = paddle.trainer.SGD(cost, parameters, =momentum_optimizer)
trainer.train(reader, 100, event_handler, feeding)
由于訓(xùn)練的過(guò)程中把圖片設(shè)置成灰度圖來(lái)處理,所以數(shù)據(jù)集也非常小,訓(xùn)練的速度相對(duì)比較快。
在訓(xùn)練過(guò)程中,可以借助VisualDL可視化工具查看模型訓(xùn)練的情況,從圖1來(lái)可以模型收斂得非常好,準(zhǔn)確率幾乎接近百分之百。
在每一個(gè)Pass訓(xùn)練結(jié)束之后,都是用測(cè)試集對(duì)模型進(jìn)行一次測(cè)試,觀察模型在測(cè)試集的預(yù)測(cè)情況。從圖2來(lái)看,模型在測(cè)試集的預(yù)測(cè)有非常好,沒(méi)有出現(xiàn)過(guò)擬合的情況。
1.5 使用PaddlePaddle進(jìn)行預(yù)測(cè)
通過(guò)之前的訓(xùn)練,得到模型參數(shù),可以使用這些參數(shù)進(jìn)行預(yù)測(cè)驗(yàn)證碼圖片。由于傳進(jìn)來(lái)的是一個(gè)完整的驗(yàn)證碼,所以需要對(duì)驗(yàn)證碼進(jìn)行裁剪[8]。然后把裁剪后的數(shù)據(jù)傳給PaddlePaddle進(jìn)行預(yù)測(cè)。因預(yù)測(cè)出來(lái)的是一個(gè)label值,所以還需通過(guò)label找到對(duì)應(yīng)的字符。
通過(guò)以上操作后,在main入口中調(diào)用相對(duì)應(yīng)的程序即可進(jìn)行驗(yàn)證碼的預(yù)測(cè)流程。其關(guān)鍵代碼實(shí)現(xiàn)如下:
def load_image(file):
im = Image.open(file)
im = im.resize((32, 32), Image.ANTIALIAS)
im = np.array(im).astype(np.float32)
im = im.transpose((2, 0, 1))
im = im[(2, 1, 0), :, :] # BGR
im = im.flatten()
im = im / 255.0
return im
test_data = []
test_data.append((load_image(image_path),))
probs = paddle.infer(out, parameters, test_data)
lab = np.argsort(-probs) [0][0]
通過(guò)PaddlePaddle進(jìn)行預(yù)測(cè),最終得到預(yù)測(cè)結(jié)果輸出如下:
第1張預(yù)測(cè)結(jié)果為:0,可信度為:0.966999
第2張預(yù)測(cè)結(jié)果為:9,可信度為:0.664706
第3張預(yù)測(cè)結(jié)果為:1,可信度為:0.780999
第4張預(yù)測(cè)結(jié)果為:3,可信度為:0.959722
預(yù)測(cè)結(jié)果為:0a13
結(jié)合大量的數(shù)據(jù)集訓(xùn)練和預(yù)測(cè)結(jié)果輸出,該驗(yàn)證碼識(shí)別的可信度很高。因此該模型對(duì)驗(yàn)證碼的識(shí)別還是挺準(zhǔn)確的。
2 結(jié)論
PaddlePaddle是一個(gè)易學(xué)易用、安全高效的分布式深度學(xué)習(xí)平臺(tái),兼容多種異構(gòu)硬件,具有優(yōu)異的訓(xùn)練和預(yù)測(cè)性能。本實(shí)驗(yàn)通過(guò)PaddlePaddle對(duì)某網(wǎng)站的驗(yàn)證碼數(shù)據(jù)訓(xùn)練一個(gè)預(yù)測(cè)模型,通過(guò)使用這個(gè)預(yù)測(cè)模型可以自動(dòng)識(shí)別驗(yàn)證碼中包含的內(nèi)容,而且識(shí)別的準(zhǔn)確率還挺高。針對(duì)這種驗(yàn)證碼的字符比較清晰,而且每個(gè)字符的位置固定,有利于他人對(duì)驗(yàn)證碼進(jìn)行切割分析,訓(xùn)練出一個(gè)能夠自動(dòng)識(shí)別驗(yàn)證碼的神經(jīng)網(wǎng)絡(luò)模型。所以在深度學(xué)習(xí)高速發(fā)展的今天,這種驗(yàn)證碼很容易被破解,危害網(wǎng)站系統(tǒng)的安全。為了防止這種類型的惡意攻擊,網(wǎng)站開(kāi)發(fā)者可以將驗(yàn)證碼的字符位置隨機(jī)擺放,防止攻擊者對(duì)圖片進(jìn)行裁剪分析,實(shí)驗(yàn)也證明對(duì)應(yīng)傾斜角度過(guò)大或者重疊部分太多的字符很難識(shí)別,網(wǎng)站開(kāi)發(fā)者可以充分利用這一點(diǎn)來(lái)防止攻擊者利用圖像識(shí)別技術(shù)破解網(wǎng)站驗(yàn)證碼,維護(hù)網(wǎng)站安全。
參考文獻(xiàn):
[1] 何福泉,李偉烽,林培娜,等.驗(yàn)證碼的識(shí)別技術(shù)分析與研究[J].甘肅科技縱橫,2019,48(2):1-4.
[2] 基于卷積神經(jīng)網(wǎng)絡(luò)的12306驗(yàn)證碼識(shí)別[D].華南理工大學(xué), 2017.
[3] AICon 2018開(kāi)幕百度PaddlePaddle引開(kāi)發(fā)者熱議[J].智能機(jī)器人,2018(1):19.
[4] 尹寶才,王文通,王立春.深度學(xué)習(xí)研究綜述[J].北京工業(yè)大學(xué)學(xué)報(bào), 2015(1):48-59.
[5] 張錚,王順?lè)?,董?基于深度學(xué)習(xí)的驗(yàn)證碼識(shí)別[J].湖北工業(yè)大學(xué)學(xué)報(bào),2018,33(2):5-8+25.
[6] 陳少鎮(zhèn),王培彬,藍(lán)汝琪,曾梓鑫,楊森.移動(dòng)互聯(lián)網(wǎng)+師生互動(dòng)的課程表設(shè)計(jì)與應(yīng)用[J].電腦知識(shí)與技術(shù),2018,14(04):76-79.
[7] 劉歡,邵蔚元,郭躍飛.卷積神經(jīng)網(wǎng)絡(luò)在驗(yàn)證碼識(shí)別上的應(yīng)用與研究[J].計(jì)算機(jī)工程與應(yīng)用, 2016, 52(18):1-7.
[8] 楊航,蔡浩.中文圖片驗(yàn)證碼識(shí)別方法的研究[J].汕頭大學(xué)學(xué)報(bào)(自然科學(xué)版),2018,33(3):47-53.
【通聯(lián)編輯:唐一東】