当前位置:   article > 正文

基于深度学习模型(1D CNN)实现钓鱼网站检测_1dcnn

1dcnn

一、运行环境

  1. windows10系统
  2. 虚拟环境:Anaconda3
  3. python版本:3.8.8
  4. 框架工具:TensorFlow(tensorflow-gpu2.7.0)
  5. 编译工具IDE:VsCode
  6. 环境安装教程:
    1. https://blog.csdn.net/Gerald_Jones/article/details/121370247
    2. https://blog.csdn.net/Gerald_Jones/article/details/121549127
    3. https://blog.csdn.net/Gerald_Jones/article/details/121512837

二、选题背景

2.1 题目

基于深度学习的钓鱼网站检测

2.2 项目简介

本项目提出了一种基于深度学习的方法,实现对钓鱼网站的高精度检测。所提出的方法利用卷积神经网络(CNN)进行高精度分类,以区分真正的网站和钓鱼网站。

2.3 项目的成果

我们使用具有6,157个真实网站和4,898个钓鱼网站获得的数据集来评估这些模型。通过实验验证,验证集的准确率可达98.2%。

三、知识背景

3.1 卷积神经网络(CNN)

CNN属于人工神经网络家族,它是受生物神经网络特性启发的计算模型。经常应用于图像识别、自然语言处理、灾难气候预测等应用场景中。

卷积层:一般情况下,为了能从神经网络中的每一小块得到更多的抽象特征,卷积层的单元矩阵比上一层的单元矩阵更深。卷积层主要作用于提取最优特征。

池化层:池化层的单元矩阵不会比上一层的单元矩阵更深,但是它能在宽度和高度上缩小矩阵的大小,也可以达到减少整个神经网络中参数的目的。池化层作用于减少卷积层特征的维度。

全连接层:通过卷积层和池化层得到的矩阵特征结果,通过构建几个全连接层,实现分类的效果。

softmax层:通过softmax层,可以得到输出样例所属种类的概率分布。

Note1:由于卷积操作是特殊的线性变化,所以将卷积层结果传递到池化层前,都需要经过去线性化处理,常用的是tf.nn.relu.

Note2:CNN的性能一般受层数和滤波器(内核)数量的影响,在CNN的更深层中提取的抽象特征越来越多,因此,所需的层数取决于被分析数据的复杂性和非线性。此外,每个阶段的过滤器数量决定了提取的特征数量。计算复杂性随着层数和滤波器数量的增加而增加。

3.2 一维卷积神经网络(1D CNN)

1D CNN 可以很好地应用于传感器数据的时间序列分析。例如:时间延迟网络 Time Delay Neural Network;同样也可以很好地用于分析具有固定长度周期的信号数据。例如:音频信号,WaveNet。此外,它还能应用于自然语言处理的任务(由于单词的接近性可能并不总是一个可训练模式的好指标,因此 LSTM 网络在 NLP 中的应用更有前途)

1D CNN在包含矢量化的数据集方面也比较适用,这类数据集一般是用来预测某一分类结果,本项目的数据集很符合1D CNN在此方面的应用,因此采用的方式是1D CNN模型。

下图示是conv1D和conv2D的区别,很形象:

3.3 项目的模型

项目的CNN架构如下:两个卷积层、两个最大池化层、三个全连接层、一个输出层。

其中在卷积层利用ReLU(Rectified Linear Units)激活函数:
φ ( z ) = m a x ( 0 , z ) φ(z) = max(0, z) φ(z)=max(0,z)
RuLU激活函数能够在输入和0之间求最大值的函数。ReLU函数能有助于缓解消失和爆炸梯度问题。

项目的1D CNN模型

四、实验

4.1 框架

项目的模型是通过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搭建一个神经网络

在这里插入图片描述

4.2 数据集

项目的数据集采用UCI网站的基础数据集,kaggle上也有相应的数据集。数据集包括从4,898个钓鱼网站和6,157个合法网站获得的11,055个实例。

下图为数据集:

在这里插入图片描述

数据集中具体指标的属性如下表所示:一共有30个属性,

在这里插入图片描述

此数据集的标签释义:

在这里插入图片描述

4.3 程序设计

整体代码的结构示意图如下:

在这里插入图片描述

主要包括几个函数:

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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

数据处理函数:

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

优化函数:

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'])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

创建模型函数:

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76

模型训练函数:

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]
    )
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

4.4 实验结果

使用的可视化工具是:TensorBoard

通过图示可以看出,在epoch==100左右,accuracy开始趋于收敛,此时在0.97~0.98间震荡,验证集的正确率最高可达98.28%,使用1D CNN构建的模型,能够很好的预测此类钓鱼网站的真与假。

accuracy曲线:

在这里插入图片描述

loss曲线:

[外链图片转存中...(img-EfoliWkw-1638841341978)]

五、问题与思考

5.1 钓鱼网站的实时检测

后续设计一个可视化界面,根据30个属性向量,主要对输入的网址url进行数据处理,并生成[30, 1]的属性向量,依据目前后台1D CNN模型进行预测,返回是否为钓鱼网站,以来验证此模型是否能够具有现实意义。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/364082
推荐阅读
相关标签
  

闽ICP备14008679号