王培彬 陳少鎮(zhèn) 林沛聰 藍汝琪 熊梓韜 潘志宏
摘要:隨著互聯(lián)網(wǎng)的快速發(fā)展,越來越多的網(wǎng)站為了防止用戶利用機器人自動注冊、登錄、灌水,都采用了驗證碼自動識別技術。然而,簡易的驗證碼依然存在安全風險,為了防止網(wǎng)絡爬蟲或者惡意攻擊的登錄操作,本文將通過PaddlePaddle平臺進行驗證碼識別的深度學習,闡述深度學習下網(wǎng)站驗證碼的破解和防范。實驗結(jié)果表明:將訓練實例的驗證碼數(shù)據(jù)訓練成預測模型,使用預測模型來自動識別驗證碼中包含的內(nèi)容實現(xiàn)驗證碼自動識別,而將驗證碼的字符位置隨機擺放,可有效防止攻擊者對圖片進行裁剪分析。
關鍵詞:驗證碼;自動識別;PaddlePaddle;深度學習;預測模型
中圖分類號:TP391 文獻標識碼:A
文章編號: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
當下大部分網(wǎng)站的登錄以驗證碼作為驗證登錄,以防止網(wǎng)絡爬蟲或者惡意攻擊的登錄操作。隨著深度學習的不斷發(fā)展,深度學習在圖片識別上的準確率也越來越高。通過利用圖像識別技術[1],可以識別一些網(wǎng)站的驗證碼。我們只有了解的識別的技術原理[2],方可防止網(wǎng)站出現(xiàn)相應的惡意攻擊。
PaddlePaddle是百度研發(fā)的開源開放的深度學習平臺[3],有全面的官方支持的工業(yè)級應用模型,涵蓋自然語言處理、計算機視覺、推薦引擎等多個領域,并開放多個領先的預訓練中文模型。同時支持稠密參數(shù)和稀疏參數(shù)場景的大規(guī)模深度學習[4]并行訓練,支持千億規(guī)模參數(shù)、數(shù)百個幾點的高效并行訓練,也可提供深度學習并行技術的深度學習框架[5]。PaddlePaddle擁有多端部署能力,支持服務器端、移動端等多種異構硬件設備的高速推理,預測性能有顯著優(yōu)勢。目前PaddlePaddle已經(jīng)實現(xiàn)了API的穩(wěn)定和向后兼容,具有完善的中英雙語使用文檔。
1 PaddlePaddle之驗證碼識別的實現(xiàn)
1.1 數(shù)據(jù)集介紹與下載
本論文中使用某系統(tǒng)網(wǎng)站作為實驗目標,經(jīng)過觀察大量的驗證碼發(fā)現(xiàn),該網(wǎng)站的驗證碼只有小寫的字母和數(shù)字,所以這些類別比較少,所以使得識別更加容易。通過對該驗證碼進行切割分析[6],可以觀察到驗證碼中的4字符都會出現(xiàn)固定的位置,所以只需要通過固定位置裁剪即可把驗證碼中的每個字符都裁剪出來。該系統(tǒng)的驗證碼如下:
通過爬蟲程序,可以爬取大量的驗證碼圖片,以下的代碼片段就是下載驗證碼圖片的核心代碼。
pic = requests.get('http://xxxxxx.aspx?', timeout=500)
pic_name = self.save_path+'/' +str(uuid.uuid1()) + '.png'
with open(pic_name, 'wb') as f:
將每一張驗證碼命名為其對應的驗證碼內(nèi)容,是一個龐大的工作量,特別在訓練網(wǎng)絡模型的過程中,標注數(shù)據(jù)是工作量非常巨大的,但也是必需的,數(shù)據(jù)標注工作量大也是目前深度學習的難點。
1.2 裁剪驗證碼與生成圖像列表
通過標注大量的數(shù)據(jù)集之后,需要裁剪所有的驗證碼。通過第一部分已經(jīng)分析到驗證碼的分布情況,而數(shù)據(jù)又已經(jīng)標注了,根據(jù)這些標注信息對圖片裁剪,裁剪后的圖片只包含一個字符。
經(jīng)過驗證碼裁剪,并去掉容易混淆的“9”,“o”,“z”字符,總體可分為33個類別,這也使得模型更容易訓練。
由于這些數(shù)據(jù)集不屬于PaddlePaddle自帶數(shù)據(jù)集,訓練需自定義數(shù)據(jù)集,建立圖像列表文件作為數(shù)據(jù)讀取的途徑,通過編寫一個生成圖像列表的程序,把驗證碼生成一個圖像列表。
將已裁剪的數(shù)據(jù)集生成圖片列表,通過下面的代碼片段將所有圖像和每張圖片對應的標簽生成圖片的相對路徑和標簽,以便后續(xù)訓練過程中讀取數(shù)據(jù)。其核心代碼片段如下:
for img_path in img_paths:
name_path = path + '/' + img_path # 每張圖片的路徑
isexist = os.path.exists(data_list_path) # 如果不存在這個文件夾,就創(chuàng)建
if not isexist:
os.makedirs(data_list_path)
if class_sum % 10 == 0: # 每10張圖片取一個做測試數(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
通過上面的程序,一共會生成trainer.list,test.list,readme.json,其中trainer.list,test.list分布是用來訓練和測試的,readme.json包含數(shù)據(jù)集的信息,通過這個文件可以獲取到標簽尋對用的字符。
1.3 數(shù)據(jù)的讀取
建立數(shù)據(jù)列表之后,需要建立數(shù)據(jù)讀取程序,通過這個程序生成的reader,reader是PaddlePaddle讀取數(shù)據(jù)的一種介質(zhì)。通過使用reader,PaddlePaddle可以在訓練的過程中非常便捷地從磁盤讀取圖片數(shù)據(jù),經(jīng)過預處理再應用于訓練。以下的代碼片段就是通過上一部分生成的圖像列表獲取圖像路徑和標簽。
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是讀取圖像和對圖片進行預處理,通過上述的方式完成讀取圖片后,需要對圖片進行預處理,如下為圖片預處理的核心代碼片段:
def train_mapper(self, sample):
img, label = sample
# 此處使用本地的image,如果paddlepaddle版本是最新的,也可以使用padd.v2.image
# 因為是灰度圖,所以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é)合以上的圖片讀取和預處理兩部分,可以得到一個訓練使用的reader。在生成reader之前,通過使用PaddlePaddle的reader按照指定的大小隨機裁剪一個方形的圖像,這種隨機裁剪的預處理操作也是數(shù)據(jù)增強的一種方式。
1.4 使用PaddlePaddle開始訓練
在開始PaddlePaddle的訓練之前,需定義一個神經(jīng)網(wǎng)絡作為將要訓練的一個模型。本論文使用的神經(jīng)網(wǎng)絡模型是VGG神經(jīng)網(wǎng)絡[7],這個模型是牛津大學VGG(Visual Geometry Group)組在2014年ILSVRC提出的,VGG神經(jīng)模型的核心是五組卷積操作,每兩組之間做Max-Pooling空間降維。同一組內(nèi)采用多次連續(xù)的3X3卷積,卷積核的數(shù)目由較淺組的64增多到最深組的512,同一組內(nèi)的卷積核數(shù)目是一樣的。卷積之后接兩層全連接層,之后是分類層。由于每組內(nèi)卷積層的不同,有11、13、16、19層這幾種模型。根據(jù)數(shù)據(jù)集訓練的數(shù)量,本論文對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())
# 通過神經(jīng)網(wǎng)絡模型再使用Softmax獲得分類器(全連接)
out = paddle.layer.fc(input=fc2,
size=10,
act=paddle.activation.Softmax())
在開始PaddlePaddle的訓練時,需先導入依賴包,其中有PaddlePaddle的V2包和讀取數(shù)據(jù)的程序。然后創(chuàng)建一個類,再在類中創(chuàng)建一個初始化函數(shù),在初始化函數(shù)中來初始化PaddlePaddle。此外,可以通過輸入是否是參數(shù)文件路徑,或者是損失函數(shù),如果為參數(shù)文件路徑,可使用已訓練完成的參數(shù)生產(chǎn)參數(shù)。如果不傳入?yún)?shù)文件路徑,可使用傳入的損失函數(shù)生成參數(shù)。之后通過圖像的標簽信息和分類器生成損失函數(shù),使用損失函數(shù)生成初始化參數(shù),再生成優(yōu)化方法,來創(chuàng)建訓練器。最后,在程序中調(diào)用相應的函數(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)
由于訓練的過程中把圖片設置成灰度圖來處理,所以數(shù)據(jù)集也非常小,訓練的速度相對比較快。
在訓練過程中,可以借助VisualDL可視化工具查看模型訓練的情況,從圖1來可以模型收斂得非常好,準確率幾乎接近百分之百。
在每一個Pass訓練結(jié)束之后,都是用測試集對模型進行一次測試,觀察模型在測試集的預測情況。從圖2來看,模型在測試集的預測有非常好,沒有出現(xiàn)過擬合的情況。
1.5 使用PaddlePaddle進行預測
通過之前的訓練,得到模型參數(shù),可以使用這些參數(shù)進行預測驗證碼圖片。由于傳進來的是一個完整的驗證碼,所以需要對驗證碼進行裁剪[8]。然后把裁剪后的數(shù)據(jù)傳給PaddlePaddle進行預測。因預測出來的是一個label值,所以還需通過label找到對應的字符。
通過以上操作后,在main入口中調(diào)用相對應的程序即可進行驗證碼的預測流程。其關鍵代碼實現(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]
通過PaddlePaddle進行預測,最終得到預測結(jié)果輸出如下:
第1張預測結(jié)果為:0,可信度為:0.966999
第2張預測結(jié)果為:9,可信度為:0.664706
第3張預測結(jié)果為:1,可信度為:0.780999
第4張預測結(jié)果為:3,可信度為:0.959722
預測結(jié)果為:0a13
結(jié)合大量的數(shù)據(jù)集訓練和預測結(jié)果輸出,該驗證碼識別的可信度很高。因此該模型對驗證碼的識別還是挺準確的。
2 結(jié)論
PaddlePaddle是一個易學易用、安全高效的分布式深度學習平臺,兼容多種異構硬件,具有優(yōu)異的訓練和預測性能。本實驗通過PaddlePaddle對某網(wǎng)站的驗證碼數(shù)據(jù)訓練一個預測模型,通過使用這個預測模型可以自動識別驗證碼中包含的內(nèi)容,而且識別的準確率還挺高。針對這種驗證碼的字符比較清晰,而且每個字符的位置固定,有利于他人對驗證碼進行切割分析,訓練出一個能夠自動識別驗證碼的神經(jīng)網(wǎng)絡模型。所以在深度學習高速發(fā)展的今天,這種驗證碼很容易被破解,危害網(wǎng)站系統(tǒng)的安全。為了防止這種類型的惡意攻擊,網(wǎng)站開發(fā)者可以將驗證碼的字符位置隨機擺放,防止攻擊者對圖片進行裁剪分析,實驗也證明對應傾斜角度過大或者重疊部分太多的字符很難識別,網(wǎng)站開發(fā)者可以充分利用這一點來防止攻擊者利用圖像識別技術破解網(wǎng)站驗證碼,維護網(wǎng)站安全。
參考文獻:
[1] 何福泉,李偉烽,林培娜,等.驗證碼的識別技術分析與研究[J].甘肅科技縱橫,2019,48(2):1-4.
[2] 基于卷積神經(jīng)網(wǎng)絡的12306驗證碼識別[D].華南理工大學, 2017.
[3] AICon 2018開幕百度PaddlePaddle引開發(fā)者熱議[J].智能機器人,2018(1):19.
[4] 尹寶才,王文通,王立春.深度學習研究綜述[J].北京工業(yè)大學學報, 2015(1):48-59.
[5] 張錚,王順帆,董雷.基于深度學習的驗證碼識別[J].湖北工業(yè)大學學報,2018,33(2):5-8+25.
[6] 陳少鎮(zhèn),王培彬,藍汝琪,曾梓鑫,楊森.移動互聯(lián)網(wǎng)+師生互動的課程表設計與應用[J].電腦知識與技術,2018,14(04):76-79.
[7] 劉歡,邵蔚元,郭躍飛.卷積神經(jīng)網(wǎng)絡在驗證碼識別上的應用與研究[J].計算機工程與應用, 2016, 52(18):1-7.
[8] 楊航,蔡浩.中文圖片驗證碼識別方法的研究[J].汕頭大學學報(自然科學版),2018,33(3):47-53.
【通聯(lián)編輯:唐一東】