赞
踩
基于深度学习的钓鱼网站检测
本项目提出了一种基于深度学习的方法,实现对钓鱼网站的高精度检测。所提出的方法利用卷积神经网络(CNN)进行高精度分类,以区分真正的网站和钓鱼网站。
我们使用具有6,157个真实网站和4,898个钓鱼网站获得的数据集来评估这些模型。通过实验验证,验证集的准确率可达98.2%。
CNN属于人工神经网络家族,它是受生物神经网络特性启发的计算模型。经常应用于图像识别、自然语言处理、灾难气候预测等应用场景中。
卷积层:一般情况下,为了能从神经网络中的每一小块得到更多的抽象特征,卷积层的单元矩阵比上一层的单元矩阵更深。卷积层主要作用于提取最优特征。
池化层:池化层的单元矩阵不会比上一层的单元矩阵更深,但是它能在宽度和高度上缩小矩阵的大小,也可以达到减少整个神经网络中参数的目的。池化层作用于减少卷积层特征的维度。
全连接层:通过卷积层和池化层得到的矩阵特征结果,通过构建几个全连接层,实现分类的效果。
softmax层:通过softmax层,可以得到输出样例所属种类的概率分布。
Note1:由于卷积操作是特殊的线性变化,所以将卷积层结果传递到池化层前,都需要经过去线性化处理,常用的是tf.nn.relu.
Note2:CNN的性能一般受层数和滤波器(内核)数量的影响,在CNN的更深层中提取的抽象特征越来越多,因此,所需的层数取决于被分析数据的复杂性和非线性。此外,每个阶段的过滤器数量决定了提取的特征数量。计算复杂性随着层数和滤波器数量的增加而增加。
1D CNN 可以很好地应用于传感器数据的时间序列分析。例如:时间延迟网络 Time Delay Neural Network;同样也可以很好地用于分析具有固定长度周期的信号数据。例如:音频信号,WaveNet。此外,它还能应用于自然语言处理的任务(由于单词的接近性可能并不总是一个可训练模式的好指标,因此 LSTM 网络在 NLP 中的应用更有前途)
1D CNN在包含矢量化的数据集方面也比较适用,这类数据集一般是用来预测某一分类结果,本项目的数据集很符合1D CNN在此方面的应用,因此采用的方式是1D CNN模型。
下图示是conv1D和conv2D的区别,很形象:
项目的CNN架构如下:两个卷积层、两个最大池化层、三个全连接层、一个输出层。
其中在卷积层利用ReLU(Rectified Linear Units)激活函数:
φ
(
z
)
=
m
a
x
(
0
,
z
)
φ(z) = max(0, z)
φ(z)=max(0,z)
RuLU激活函数能够在输入和0之间求最大值的函数。ReLU函数能有助于缓解消失和爆炸梯度问题。
项目的1D CNN模型
项目的模型是通过Python来实现,并使用了TensorFlow自带的Kears库,同时也是用了Numpy、Pandas、Scikit Learn等库。
其中Keras是本项目构建模型的主要的库,这里简要介绍一下Keras:Keras是由纯python编写的基于theano/tensorflow的深度学习框架。
适用范围:
简易和快速的原型设计(keras具有高度模块化,极简,和可扩充特性)
支持CNN和RNN,或二者的结合。
无缝CPU和GPU切换。
优点:
用户友好:Keras遵循减少认知困难的最佳实践:Keras提供一致而简洁的API, 能够极大减少一般应用下用户的工作量,同时,Keras提供清晰和具有实践意义的bug反馈。
模块性:模型可理解为一个层的序列或数据的运算图,完全可配置的模块可以用最少的代价自由组合在一起。具体而言,网络层、损失函数、优化器、初始化策略、激活函数、正则化方法都是独立的模块,你可以使用它们来构建自己的模型。
易扩展性:添加新模块容易,只需仿照现有的模块编写新的类或函数即可。创建新模块的便利性使得Keras更适合于先进的研究工作。
与Python协作:Keras没有单独的模型配置文件类型(作为对比,caffe有),模型由python代码描述,使其更紧凑和更易debug,并提供了扩展的便利性。
Keras的模块结构
Keras搭建一个神经网络
项目的数据集采用UCI网站的基础数据集,kaggle上也有相应的数据集。数据集包括从4,898个钓鱼网站和6,157个合法网站获得的11,055个实例。
下图为数据集:
数据集中具体指标的属性如下表所示:一共有30个属性,
此数据集的标签释义:
整体代码的结构示意图如下:
主要包括几个函数:
gendatas():对原始数据集的处理(归一化、拆分、reshape),返回训练模型用的数据和标签、验证模型的数据和标签。
create_model():使用Keras库创建模型,根据模型搭建流程,依次是卷积层-1、最大池化层-1、卷积层-2、最大池化层-2、Flatten层-1、Dropout层-1、全连接层-1、全连接层-2、输出层-1。
train_model():实现模型权重的保存,便于下次可以直接调用模型进行训练;实现TensorBoard运行log的保存,便于TensorBoard可视化;实现模型的训练。
model的summary如下:
主函数:
if __name__ == "__main__": stamp = datetime.now().strftime("%Y%m%d-%H-%M-%S") model_file_path = os.path.join(CURRENT_DIR, "models\\pWeb-cnn1D-"+stamp) log_file_path = os.path.join(CURRENT_DIR, "logs\\pWeb-cnn1D-"+stamp) inputs_train, outputs_train, inputs_test, outputs_test = gen_datas(train, test) # 新建网络模型 model = create_model() # 保存网络模型 display_cnn1D_structure(model, os.path.join(CURRENT_DIR, "images\\1206cnn1D-structure.png")) # 训练网络模型:只保留权重 train_model(model, inputs_train, outputs_train, inputs_test, outputs_test, model_file_path, log_file_path) # 保存模型 # model_path = os.path.join(CURRENT_DIR, "models") # 测试集验证 # 验证其中一个数据 # test_phWeb = tf.convert_to_tensor([inputs_test[0]]) # pre = model.predict(test_phWeb) # # 输出loss 和 accuracy # pre = tf.math.argmax(pre, 1) # print("prediction:{}".format(pre)) # 验证数据集 # pre = prediction(model, model_path, inputs_test)
数据处理函数:
def gen_datas(train, test): """生成数据 参数: train: 原始训练数据集 test: 原始验证数据集 返回: X_train_r: 处理后训练数据集 y_train: 处理后训练标签 X_test_r: 处理后验证数据集 y_test: 处理后验证标签 """ label_encoder_train = LabelEncoder().fit(train.Result) labels_train = label_encoder_train.transform(train.Result) label_encoder_test = LabelEncoder().fit(test.Result) labels_test = label_encoder_test.transform(test.Result) classes = list(label_encoder_train.classes_) # classes_test = list(label_encoder_test.classes_) train = train.drop('Result', axis=1) test = test.drop('Result', axis=1) # 标签的种类 = NB_CLASS numb_class = len(classes) # 数据的归一化处理 scaled_train = data_scaler(train) # 同一文件内数据集:10%作为测试集,90%作为训练集 # random_state:随机数种子,和random中的seed种子一样,保证每次抽样到的数据一样,便于调试 sss = StratifiedShuffleSplit(test_size=0.1, random_state=23) for train_index, test_index in sss.split(scaled_train, labels_train): X_train, X_test = scaled_train[train_index], scaled_train[test_index] y_train, y_test = labels_train[train_index], labels_train[test_index] # 不同文件作为训练集和验证集 # y_train = labels_train # X_train = data_scaler(train) # y_test = labels_test # X_test = data_scaler(test) # reshape train data # reshape 30*1 # 也可以reshape 10*3 X_train_r = np.zeros((len(X_train), NB_FEATURES, 1)) X_train_r[:, :, 0] = X_train[:, :NB_FEATURES] # X_train_r[:, :, 1] = X_train[:, NB_PER_LAYER: NB_PER_LAYER * 2] # X_train_r[:, :, 2] = X_train[:, NB_PER_LAYER * 2:] # reshape test data X_test_r = np.zeros((len(X_test), NB_FEATURES, 1)) X_test_r[:, :, 0] = X_test[:, :NB_FEATURES] # X_test_r[:, :, 1] = X_test[:, NB_PER_LAYER: NB_PER_LAYER * 2] # X_test_r[:, :, 2] = X_test[:, NB_PER_LAYER * 2:] y_train = np_utils.to_categorical(y_train, NB_CLASS) y_test = np_utils.to_categorical(y_test, NB_CLASS) return X_train_r, y_train, X_test_r, y_test
优化函数:
def compile_model(model):
"""神经网络参数配置
参数:
model: 神经网络实例
返回:
无
"""
# 使用随机梯度下降优化器
sgd = SGD(lr=0.01, nesterov=True, decay=1e-6, momentum=0.9)
model.compile(loss='categorical_crossentropy',optimizer=sgd,metrics=['accuracy'])
创建模型函数:
def create_model(): """使用keras新建神经网络 参数: 无 返回: model: 神经网络实例 """ model = tf.keras.Sequential(name = "phWeb-cnn1D") # 卷积层-1 model.add( layers.Conv1D(64, kernel_size = 10, padding = 'same', activation='relu', input_shape = (NB_FEATURES, 1), # 输入模型30*1 name="conv-1" ) ) # 池化层-1 model.add( layers.MaxPool1D(pool_size=2, strides=2, name="max-pooling-1" ) ) # 卷积层-2 model.add( layers.Conv1D(64, kernel_size = 5, padding = 'same', activation='relu', name="conv-2" ) ) # 池化层-2 model.add( layers.MaxPool1D(pool_size=2, strides=2, name="max-pooling-2" ) ) # 激活层-1 # model.add( # layers.Activation('relu', # name = "activation-1") # ) # 全连接层-1 model.add(layers.Flatten(name="fullc-1")) # DropOut层-1 model.add( layers.Dropout(rate = 0.4, name = "dropout-1") ) # 全连接层-2 model.add( layers.Dense(8, activation='relu', name="fullc-2") ) # 全连接层-3 model.add( layers.Dense(4, activation='relu', name="fullc-3") ) # 全连接层-4 model.add( layers.Dense(NB_CLASS, activation='softmax', name="output-1" ) ) # 配置损失计算及优化器 compile_model(model) return model
模型训练函数:
def train_model(model, inputs, outputs, inputs_test, outputs_test, model_path, log_path): """训练神经网络 参数: model: 神经网络实例 inputs: 输入数据 outputs: 输出数据 model_path: 模型文件路径 log_path: 日志文件路径 返回: 无 """ # 回调函数 ckpt_callback = callback_only_params(model_path) # tensorboard回调 tensorboard_callback = tb_callback(log_path) # 保存参数 model.save_weights(model_path.format(epoch=0)) numb_epochs = 300 model.fit( inputs, outputs, epochs=numb_epochs, validation_data=(inputs_test, outputs_test), batch_size=16, callbacks=[ckpt_callback, tensorboard_callback] )
使用的可视化工具是:TensorBoard
通过图示可以看出,在epoch==100左右,accuracy开始趋于收敛,此时在0.97~0.98间震荡,验证集的正确率最高可达98.28%,使用1D CNN构建的模型,能够很好的预测此类钓鱼网站的真与假。
accuracy曲线:
loss曲线:
后续设计一个可视化界面,根据30个属性向量,主要对输入的网址url进行数据处理,并生成[30, 1]的属性向量,依据目前后台1D CNN模型进行预测,返回是否为钓鱼网站,以来验证此模型是否能够具有现实意义。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。