[当人工智能遇上安全] 13.威胁情报实体识别 (3)利用keras构建CNN-BiLSTM-ATT-CRF实体识别模型

这篇具有很好参考价值的文章主要介绍了[当人工智能遇上安全] 13.威胁情报实体识别 (3)利用keras构建CNN-BiLSTM-ATT-CRF实体识别模型。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

《当人工智能遇上安全》系列将详细介绍人工智能与安全相关的论文、实践,并分享各种案例,涉及恶意代码检测、恶意请求识别、入侵检测、对抗样本等等。只想更好地帮助初学者,更加成体系的分享新知识。该系列文章会更加聚焦,更加学术,更加深入,也是作者的慢慢成长史。换专业确实挺难的,系统安全也是块硬骨头,但我也试试,看看自己未来四年究竟能将它学到什么程度,漫漫长征路,偏向虎山行。享受过程,一起加油~

前文讲解如何实现威胁情报实体识别,利用BiLSTM-CRF算法实现对ATT&CK相关的技战术实体进行提取,是安全知识图谱构建的重要支撑。这篇文章将详细结合如何利用keras和tensorflow构建基于注意力机制的CNN-BiLSTM-ATT-CRF模型,并实现中文实体识别研究,同时对注意力机制构建常见错误进行探讨。基础性文章,希望对您有帮助,如果存在错误或不足之处,还请海涵。且看且珍惜!

  • 版本信息:python 3.7,tf 2.2.0,keras 2.3.1,bert4keras 0.11.5,keras-contrib=2.0.8

[当人工智能遇上安全] 13.威胁情报实体识别 (3)利用keras构建CNN-BiLSTM-ATT-CRF实体识别模型,当人工智能遇上安全,人工智能,keras,实体识别,威胁情报

作者作为网络安全的小白,分享一些自学基础教程给大家,主要是在线笔记,希望您们喜欢。同时,更希望您能与我一起操作和进步,后续将深入学习AI安全和系统安全知识并分享相关实验。总之,希望该系列文章对博友有所帮助,写文不易,大神们不喜勿喷,谢谢!如果文章对您有帮助,将是我创作的最大动力,点赞、评论、私聊均可,一起加油喔!

前文推荐:

  • [当人工智能遇上安全] 1.人工智能真的安全吗?浙大团队外滩大会分享AI对抗样本技术
  • [当人工智能遇上安全] 2.清华张超老师 - GreyOne: Discover Vulnerabilities with Data Flow Sensitive Fuzzing
  • [当人工智能遇上安全] 3.安全领域中的机器学习及机器学习恶意请求识别案例分享
  • [当人工智能遇上安全] 4.基于机器学习的恶意代码检测技术详解
  • [当人工智能遇上安全] 5.基于机器学习算法的主机恶意代码识别研究
  • [当人工智能遇上安全] 6.基于机器学习的入侵检测和攻击识别——以KDD CUP99数据集为例
  • [当人工智能遇上安全] 7.基于机器学习的安全数据集总结
  • [当人工智能遇上安全] 8.基于API序列和机器学习的恶意家族分类实例详解
  • [当人工智能遇上安全] 9.基于API序列和深度学习的恶意家族分类实例详解
  • [当人工智能遇上安全] 10.威胁情报实体识别之基于BiLSTM-CRF的实体识别万字详解
  • [当人工智能遇上安全] 11.威胁情报实体识别 (2)基于BiGRU-CRF的中文实体识别万字详解
  • [当人工智能遇上安全] 12.易学智能GPU搭建Keras环境实现LSTM恶意URL请求分类

作者的github资源:

  • https://github.com/eastmountyxz/When-AI-meet-Security
  • https://github.com/eastmountyxz/AI-Security-Paper
  • https://github.com/eastmountyxz/AI-for-Keras

一.ATT&CK数据采集

了解威胁情报的同学,应该都熟悉Mitre的ATT&CK网站,前文已介绍如何采集该网站APT组织的攻击技战术数据。网址如下:

  • http://attack.mitre.org

[当人工智能遇上安全] 13.威胁情报实体识别 (3)利用keras构建CNN-BiLSTM-ATT-CRF实体识别模型,当人工智能遇上安全,人工智能,keras,实体识别,威胁情报

第一步,通过ATT&CK网站源码分析定位APT组织名称,并进行系统采集。

[当人工智能遇上安全] 13.威胁情报实体识别 (3)利用keras构建CNN-BiLSTM-ATT-CRF实体识别模型,当人工智能遇上安全,人工智能,keras,实体识别,威胁情报

安装BeautifulSoup扩展包,该部分代码如下所示:

[当人工智能遇上安全] 13.威胁情报实体识别 (3)利用keras构建CNN-BiLSTM-ATT-CRF实体识别模型,当人工智能遇上安全,人工智能,keras,实体识别,威胁情报

01-get-aptentity.py

#encoding:utf-8
#By:Eastmount CSDN
import re
import requests
from lxml import etree
from bs4 import BeautifulSoup
import urllib.request

#-------------------------------------------------------------------------------------------
#获取APT组织名称及链接

#设置浏览器代理,它是一个字典
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) \
        AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'
}
url = 'https://attack.mitre.org/groups/'

#向服务器发出请求
r = requests.get(url = url, headers = headers).text

#解析DOM树结构
html_etree = etree.HTML(r)
names = html_etree.xpath('//*[@class="table table-bordered table-alternate mt-2"]/tbody/tr/td[2]/a/text()')
print (names)
print(len(names),names[0])
filename = []
for name in names:
    filename.append(name.strip())
print(filename)

#链接
urls = html_etree.xpath('//*[@class="table table-bordered table-alternate mt-2"]/tbody/tr/td[2]/a/@href')
print(urls)
print(len(urls), urls[0])
print("\n")

此时输出结果如下图所示,包括APT组织名称及对应的URL网址。

[当人工智能遇上安全] 13.威胁情报实体识别 (3)利用keras构建CNN-BiLSTM-ATT-CRF实体识别模型,当人工智能遇上安全,人工智能,keras,实体识别,威胁情报

第二步,访问APT组织对应的URL,采集详细信息(正文描述)。

[当人工智能遇上安全] 13.威胁情报实体识别 (3)利用keras构建CNN-BiLSTM-ATT-CRF实体识别模型,当人工智能遇上安全,人工智能,keras,实体识别,威胁情报

第三步,采集对应的技战术TTPs信息,其源码定位如下图所示。

[当人工智能遇上安全] 13.威胁情报实体识别 (3)利用keras构建CNN-BiLSTM-ATT-CRF实体识别模型,当人工智能遇上安全,人工智能,keras,实体识别,威胁情报

第四步,编写代码完成威胁情报数据采集。01-spider-mitre.py 完整代码如下:

#encoding:utf-8
#By:Eastmount CSDN
import re
import requests
from lxml import etree
from bs4 import BeautifulSoup
import urllib.request

#-------------------------------------------------------------------------------------------
#获取APT组织名称及链接

#设置浏览器代理,它是一个字典
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) \
        AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'
}
url = 'https://attack.mitre.org/groups/'

#向服务器发出请求
r = requests.get(url = url, headers = headers).text
#解析DOM树结构
html_etree = etree.HTML(r)
names = html_etree.xpath('//*[@class="table table-bordered table-alternate mt-2"]/tbody/tr/td[2]/a/text()')
print (names)
print(len(names),names[0])
#链接
urls = html_etree.xpath('//*[@class="table table-bordered table-alternate mt-2"]/tbody/tr/td[2]/a/@href')
print(urls)
print(len(urls), urls[0])
print("\n")

#-------------------------------------------------------------------------------------------
#获取详细信息
k = 0
while k<len(names):
    filename = str(names[k]).strip() + ".txt"
    url = "https://attack.mitre.org" + urls[k]
    print(url)

    #获取正文信息
    page = urllib.request.Request(url, headers=headers)
    page = urllib.request.urlopen(page)
    contents = page.read()
    soup = BeautifulSoup(contents, "html.parser")

    #获取正文摘要信息
    content = ""
    for tag in soup.find_all(attrs={"class":"description-body"}):
        #contents = tag.find("p").get_text()
        contents = tag.find_all("p")
        for con in contents:
            content += con.get_text().strip() + "###\n"  #标记句子结束(第二部分分句用)
    #print(content)

    #获取表格中的技术信息
    for tag in soup.find_all(attrs={"class":"table techniques-used table-bordered mt-2"}):
        contents = tag.find("tbody").find_all("tr")
        for con in contents:
            value = con.find("p").get_text()           #存在4列或5列 故获取p值
            #print(value)
            content += value.strip() + "###\n"         #标记句子结束(第二部分分句用)

    #删除内容中的参考文献括号 [n]
    result = re.sub(u"\\[.*?]", "", content)
    print(result)

    #文件写入
    filename = "Mitre//" + filename
    print(filename)
    f = open(filename, "w", encoding="utf-8")
    f.write(result)
    f.close()    
    k += 1

输出结果如下图所示,共整理100个组织信息。

[当人工智能遇上安全] 13.威胁情报实体识别 (3)利用keras构建CNN-BiLSTM-ATT-CRF实体识别模型,当人工智能遇上安全,人工智能,keras,实体识别,威胁情报

[当人工智能遇上安全] 13.威胁情报实体识别 (3)利用keras构建CNN-BiLSTM-ATT-CRF实体识别模型,当人工智能遇上安全,人工智能,keras,实体识别,威胁情报

每个文件显示内容如下图所示:

[当人工智能遇上安全] 13.威胁情报实体识别 (3)利用keras构建CNN-BiLSTM-ATT-CRF实体识别模型,当人工智能遇上安全,人工智能,keras,实体识别,威胁情报

数据标注采用暴力的方式进行,即定义不同类型的实体名称并利用BIO的方式进行标注。通过ATT&CK技战术方式进行标注,后续可以结合人工校正,同时可以定义更多类型的实体。

  • BIO标注
实体名称 实体数量 示例
APT攻击组织 128 APT32、Lazarus Group
攻击漏洞 56 CVE-2009-0927
区域位置 72 America、Europe
攻击行业 34 companies、finance
攻击手法 65 C&C、RAT、DDoS
利用软件 48 7-Zip、Microsoft
操作系统 10 Linux、Windows

更多标注和预处理请查看上一篇文章。

  • [当人工智能遇上安全] 10.威胁情报实体识别之基于BiLSTM-CRF的实体识别万字详解

常见的数据标注工具:

  • 图像标注:labelme,LabelImg,Labelbox,RectLabel,CVAT,VIA
  • 半自动ocr标注:PPOCRLabel
  • NLP标注工具:labelstudio

温馨提示:
由于网站的布局会不断变化和优化,因此读者需要掌握数据采集及语法树定位的基本方法,以不变应万变。此外,读者可以尝试采集所有锻炼甚至是URL跳转链接内容,请读者自行尝试和拓展!


二.数据预处理

假设存在已经采集和标注好的中文数据集,通常采用按字(Char)分隔,读者可以尝试以人民日报为数据集,下载地址如下,中文威胁情报也类似。

  • http://s3.bmio.net/kashgari/china-people-daily-ner-corpus.tar.gz

[当人工智能遇上安全] 13.威胁情报实体识别 (3)利用keras构建CNN-BiLSTM-ATT-CRF实体识别模型,当人工智能遇上安全,人工智能,keras,实体识别,威胁情报

[当人工智能遇上安全] 13.威胁情报实体识别 (3)利用keras构建CNN-BiLSTM-ATT-CRF实体识别模型,当人工智能遇上安全,人工智能,keras,实体识别,威胁情报

当然也可以自建数据集,包括前面所说的威胁情报数据集。假设存在已经采集和标注好的中文数据集,通常采用按字(Char)分隔,如下图所示,古籍为数据集,当然中文威胁情报也类似。

[当人工智能遇上安全] 13.威胁情报实体识别 (3)利用keras构建CNN-BiLSTM-ATT-CRF实体识别模型,当人工智能遇上安全,人工智能,keras,实体识别,威胁情报

数据集划分为训练集、验证集和测试集。

[当人工智能遇上安全] 13.威胁情报实体识别 (3)利用keras构建CNN-BiLSTM-ATT-CRF实体识别模型,当人工智能遇上安全,人工智能,keras,实体识别,威胁情报


三.安装环境

1.安装keras-contrib

CRF模型作者安装的是 keras-contrib

第一步,如果读者直接使用“pip install keras-contrib”可能会报错,远程下载也报错。

  • pip install git+https://www.github.com/keras-team/keras-contrib.git

甚至会报错 ModuleNotFoundError: No module named ‘keras_contrib’。

[当人工智能遇上安全] 13.威胁情报实体识别 (3)利用keras构建CNN-BiLSTM-ATT-CRF实体识别模型,当人工智能遇上安全,人工智能,keras,实体识别,威胁情报

第二步,作者从github中下载该资源,并在本地安装。

  • https://github.com/keras-team/keras-contrib
  • keras-contrib 版本:2.0.8
git clone https://www.github.com/keras-team/keras-contrib.git
cd keras-contrib
python setup.py install

安装成功如下图所示:

[当人工智能遇上安全] 13.威胁情报实体识别 (3)利用keras构建CNN-BiLSTM-ATT-CRF实体识别模型,当人工智能遇上安全,人工智能,keras,实体识别,威胁情报

读者可以从我的资源中下载代码和扩展包。

  • https://github.com/eastmountyxz/When-AI-meet-Security

2.安装keras

同样需要安装keras和TensorFlow扩展包。

[当人工智能遇上安全] 13.威胁情报实体识别 (3)利用keras构建CNN-BiLSTM-ATT-CRF实体识别模型,当人工智能遇上安全,人工智能,keras,实体识别,威胁情报

如果TensorFlow下载太慢,可以设置清华大学镜像,实际安装2.2版本。

pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
pip install tensorflow==2.2

[当人工智能遇上安全] 13.威胁情报实体识别 (3)利用keras构建CNN-BiLSTM-ATT-CRF实体识别模型,当人工智能遇上安全,人工智能,keras,实体识别,威胁情报

[当人工智能遇上安全] 13.威胁情报实体识别 (3)利用keras构建CNN-BiLSTM-ATT-CRF实体识别模型,当人工智能遇上安全,人工智能,keras,实体识别,威胁情报


四.CNN-BiLSTM-ATT-CRF模型构建

第一步,导入扩展包。

import re
import os
import csv
import sys
import numpy as np
import tensorflow as tf
import keras
from keras.models import Model
from keras.layers import LSTM, GRU, Activation, Dense, Dropout, Input, Embedding, Permute
from keras.layers import Convolution1D, MaxPool1D, Flatten, TimeDistributed, Masking
from keras.optimizers import RMSprop
from keras.layers import Bidirectional
from keras.preprocessing.text import Tokenizer
from keras.preprocessing import sequence
from keras.callbacks import EarlyStopping
from keras.models import load_model
from keras.models import Sequential
from keras.layers.merge import concatenate
from keras import backend as K
from keras_contrib.layers import CRF
from keras_contrib.losses import crf_loss
from keras_contrib.metrics import crf_viterbi_accuracy

第二步,数据预处理及设置参数。

train_data_path = "data/train.csv"
test_data_path = "data/test.csv"
val_data_path = "data/val.csv"
char_vocab_path = "char_vocabs_.txt"   #字典文件(防止多次写入仅读首次生成文件)
special_words = ['<PAD>', '<UNK>']     #特殊词表示
final_words = []                       #统计词典(不重复出现)
final_labels = []                      #统计标记(不重复出现)

#BIO标记的标签 字母O初始标记为0
label2idx = {'O': 0,
             'S-LOC': 1, 'B-LOC': 2,  'I-LOC': 3,  'E-LOC': 4,
             'S-PER': 5, 'B-PER': 6,  'I-PER': 7,  'E-PER': 8,
             'S-TIM': 9, 'B-TIM': 10, 'E-TIM': 11, 'I-TIM': 12
             }
print(label2idx)
#{'S-LOC': 0, 'B-PER': 1, 'I-PER': 2, ...., 'I-TIM': 11, 'I-LOC': 12}

#索引和BIO标签对应
idx2label = {idx: label for label, idx in label2idx.items()}
print(idx2label)
#{0: 'S-LOC', 1: 'B-PER', 2: 'I-PER', ...., 11: 'I-TIM', 12: 'I-LOC'}

#读取字符词典文件
with open(char_vocab_path, "r", encoding="utf8") as fo:
    char_vocabs = [line.strip() for line in fo]
char_vocabs = special_words + char_vocabs
print(char_vocabs)
#['<PAD>', '<UNK>', '晉', '樂', '王', '鮒', '曰', ':', '小', '旻', ...]

# 字符和索引编号对应
idx2vocab = {idx: char for idx, char in enumerate(char_vocabs)}
vocab2idx = {char: idx for idx, char in idx2vocab.items()}
print(idx2vocab)
#{0: '<PAD>', 1: '<UNK>', 2: '晉', 3: '樂', ...}
print(vocab2idx)
#{'<PAD>': 0, '<UNK>': 1, '晉': 2, '樂': 3, ...}

第三步,定义函数读取数据。

def read_corpus(corpus_path, vocab2idx, label2idx):
    datas, labels = [], []
    with open(corpus_path, encoding='utf-8') as fr:
        lines = fr.readlines()
    sent_, tag_ = [], []
    for line in lines:
        line = line.strip()
        #print(line)
        if line != '':          #断句
            value = line.split(",")
            word,label = value[0],value[4]
            #汉字及标签逐一添加列表  ['晉', '樂'] ['S-LOC', 'B-PER']
            sent_.append(word)
            tag_.append(label)
            """
            print(sent_) #['晉', '樂', '王', '鮒', '曰', ':']
            print(tag_)  #['S-LOC', 'B-PER', 'I-PER', 'E-PER', 'O', 'O']
            """
        else:                   #vocab2idx[0] => <PAD>
            sent_ids = [vocab2idx[char] if char in vocab2idx else vocab2idx['<UNK>'] for char in sent_]
            tag_ids = [label2idx[label] if label in label2idx else 0 for label in tag_]
            datas.append(sent_ids) #按句插入列表
            labels.append(tag_ids)
            sent_, tag_ = [], []
    return datas, labels

#原始数据
train_datas_, train_labels_ = read_corpus(train_data_path, vocab2idx, label2idx)
test_datas_, test_labels_ = read_corpus(test_data_path, vocab2idx, label2idx)
val_datas_, val_labels_ = read_corpus(val_data_path, vocab2idx, label2idx)

#输出测试结果 (第五句语料)
print(len(train_datas_),len(train_labels_),len(test_datas_),
      len(test_labels_),len(val_datas_),len(val_labels_))
print(train_datas_[5])
print([idx2vocab[idx] for idx in train_datas_[5]])
print(train_labels_[5])
print([idx2label[idx] for idx in train_labels_[5]])

第四步,数据填充和one-hot编码。

MAX_LEN = 100
VOCAB_SIZE = len(vocab2idx)
CLASS_NUMS = len(label2idx)

#padding data
print('padding sequences')
train_datas = sequence.pad_sequences(train_datas_, maxlen=MAX_LEN)
train_labels = sequence.pad_sequences(train_labels_, maxlen=MAX_LEN)

test_datas = sequence.pad_sequences(test_datas_, maxlen=MAX_LEN)
test_labels = sequence.pad_sequences(test_labels_, maxlen=MAX_LEN)
print('x_train shape:', train_datas.shape)
print('x_test shape:', test_datas.shape)
#(15362, 100) (1919, 100)

#encoder one-hot
train_labels = keras.utils.to_categorical(train_labels, CLASS_NUMS)
test_labels = keras.utils.to_categorical(test_labels, CLASS_NUMS)
print('trainlabels shape:', train_labels.shape)
print('testlabels shape:', test_labels.shape)
#(15362, 100, 13) (1919, 100, 13)

第五步,建立Attention机制。

K.clear_session()
SINGLE_ATTENTION_VECTOR = False
def attention_3d_block(inputs):
    # inputs.shape = (batch_size, time_steps, input_dim)
    input_dim = int(inputs.shape[2])
    a = inputs
    a = Dense(input_dim, activation='softmax')(a)
    if SINGLE_ATTENTION_VECTOR:
        a = Lambda(lambda x: K.mean(x, axis=1), name='dim_reduction')(a)
        a = RepeatVector(input_dim)(a)
    a_probs = Permute((1, 2), name='attention_vec')(a)
    #output_attention_mul = merge([inputs, a_probs], name='attention_mul', mode='mul')
    output_attention_mul = concatenate([inputs, a_probs])
    return output_attention_mul

第六步,构建ATT+CNN-BiLSTM+CRF模型。

EPOCHS = 2
EMBED_DIM = 128
HIDDEN_SIZE = 64
MAX_LEN = 100
VOCAB_SIZE = len(vocab2idx)
CLASS_NUMS = len(label2idx)

#模型构建
inputs = Input(shape=(MAX_LEN,), dtype='int32')
x = Masking(mask_value=0)(inputs)
x = Embedding(VOCAB_SIZE, EMBED_DIM, mask_zero=False)(x) #修改掩码False

#CNN
cnn1 = Convolution1D(64, 3, padding='same', strides = 1, activation='relu')(x)
cnn1 = MaxPool1D(pool_size=1)(cnn1)
cnn2 = Convolution1D(64, 4, padding='same', strides = 1, activation='relu')(x)
cnn2 = MaxPool1D(pool_size=1)(cnn2)
cnn3 = Convolution1D(64, 5, padding='same', strides = 1, activation='relu')(x)
cnn3 = MaxPool1D(pool_size=1)(cnn3)
cnn = concatenate([cnn1,cnn2,cnn3], axis=-1)

#BiLSTM
bilstm = Bidirectional(LSTM(64, return_sequences=True))(cnn) #参数保持维度3 
layer = Dense(64, activation='relu')(bilstm)
layer = Dropout(0.3)(layer)

#注意力
attention_mul = attention_3d_block(layer) #(None, 100, 128)
x = TimeDistributed(Dense(CLASS_NUMS))(attention_mul)
outputs = CRF(CLASS_NUMS)(x)
model = Model(inputs=inputs, outputs=outputs)
model.summary()

第七步,模型训练和预测。

flag = "train"
if flag=="train":
    #模型训练
    model.compile(loss=crf_loss, optimizer='adam', metrics=[crf_viterbi_accuracy])
    model.fit(train_datas, train_labels, epochs=EPOCHS, verbose=1, validation_split=0.1)
    score = model.evaluate(test_datas, test_labels, batch_size=256)
    print(model.metrics_names)
    print(score)
    model.save("att_cnn_crf_bilstm_ner_model.h5")
elif flag=="test":
    #训练模型
    char_vocab_path = "char_vocabs_.txt"                #字典文件
    model_path = "att_cnn_crf_bilstm_ner_model.h5"      #模型文件
    ner_labels = label2idx
    special_words = ['<PAD>', '<UNK>']
    MAX_LEN = 100
    
    #预测结果
    model = load_model(model_path, custom_objects={'CRF': CRF}, compile=False)    
    y_pred = model.predict(test_datas)
    y_labels = np.argmax(y_pred, axis=2)         #取最大值
    z_labels = np.argmax(test_labels, axis=2)    #真实值
    word_labels = test_datas                     #真实值
    
    k = 0
    final_y = []       #预测结果对应的标签
    final_z = []       #真实结果对应的标签
    final_word = []    #对应的特征单词
    while k<len(y_labels):
        y = y_labels[k]
        for idx in y:
            final_y.append(idx2label[idx])
        #print("预测结果:", [idx2label[idx] for idx in y])
        
        z = z_labels[k]
        for idx in z:    
            final_z.append(idx2label[idx])
        #print("真实结果:", [idx2label[idx] for idx in z])
        
        word = word_labels[k]
        for idx in word:
            final_word.append(idx2vocab[idx])
        k += 1
    print("最终结果大小:", len(final_y),len(final_z)) #191900 191900
    
    n = 0
    numError = 0
    numRight = 0
    while n<len(final_y):
        if final_y[n]!=final_z[n] and final_z[n]!='O':
            numError += 1
        if final_y[n]==final_z[n] and final_z[n]!='O':
            numRight += 1
        n += 1
    print("预测错误数量:", numError)
    print("预测正确数量:", numRight)
    print("Acc:", numRight*1.0/(numError+numRight))
    print(y_pred.shape, len(test_datas_), len(test_labels_))
    print("预测单词:", [idx2vocab[idx] for idx in test_datas_[5]])
    print("真实结果:", [idx2label[idx] for idx in test_labels_[5]])
    print("预测结果:", [idx2label[idx] for idx in y_labels[5]][-len(test_datas_[5]):])
    
    #文件存储
    fw = open("Final_ATT_CNN_BiLSTM_CRF_Result.csv", "w", encoding="utf8", newline='')
    fwrite = csv.writer(fw)
    fwrite.writerow(['pre_label','real_label', 'word'])
    n = 0
    while n<len(final_y):
        fwrite.writerow([final_y[n],final_z[n],final_word[n]])
        n += 1
    fw.close()

五.完整代码及实验结果

完整代码如下所示:

# encoding:utf-8
# By: Eastmount 2024-03-29
# keras-contrib=2.0.8  Keras=2.3.1  tensorflow=2.2.0  tensorflow-gpu=2.2.0  bert4keras=0.11.5
import re
import os
import csv
import sys
import numpy as np
import tensorflow as tf
import keras
from keras.models import Model
from keras.layers import LSTM, GRU, Activation, Dense, Dropout, Input, Embedding, Permute
from keras.layers import Convolution1D, MaxPool1D, Flatten, TimeDistributed, Masking
from keras.optimizers import RMSprop
from keras.layers import Bidirectional
from keras.preprocessing.text import Tokenizer
from keras.preprocessing import sequence
from keras.callbacks import EarlyStopping
from keras.models import load_model
from keras.models import Sequential
from keras.layers.merge import concatenate
from keras import backend as K
from keras_contrib.layers import CRF
from keras_contrib.losses import crf_loss
from keras_contrib.metrics import crf_viterbi_accuracy

#------------------------------------------------------------------------
#第一步 数据预处理
#------------------------------------------------------------------------
train_data_path = "data/train.csv"
test_data_path = "data/test.csv"
val_data_path = "data/val.csv"
char_vocab_path = "char_vocabs_.txt"   #字典文件(防止多次写入仅读首次生成文件)
special_words = ['<PAD>', '<UNK>']     #特殊词表示
final_words = []                       #统计词典(不重复出现)
final_labels = []                      #统计标记(不重复出现)

#BIO标记的标签 字母O初始标记为0
label2idx = {'O': 0,
             'S-LOC': 1, 'B-LOC': 2,  'I-LOC': 3,  'E-LOC': 4,
             'S-PER': 5, 'B-PER': 6,  'I-PER': 7,  'E-PER': 8,
             'S-TIM': 9, 'B-TIM': 10, 'E-TIM': 11, 'I-TIM': 12
             }
print(label2idx)
#{'S-LOC': 0, 'B-PER': 1, 'I-PER': 2, ...., 'I-TIM': 11, 'I-LOC': 12}

#索引和BIO标签对应
idx2label = {idx: label for label, idx in label2idx.items()}
print(idx2label)
#{0: 'S-LOC', 1: 'B-PER', 2: 'I-PER', ...., 11: 'I-TIM', 12: 'I-LOC'}

#读取字符词典文件
with open(char_vocab_path, "r", encoding="utf8") as fo:
    char_vocabs = [line.strip() for line in fo]
char_vocabs = special_words + char_vocabs
print(char_vocabs)
#['<PAD>', '<UNK>', '晉', '樂', '王', '鮒', '曰', ':', '小', '旻', ...]

# 字符和索引编号对应
idx2vocab = {idx: char for idx, char in enumerate(char_vocabs)}
vocab2idx = {char: idx for idx, char in idx2vocab.items()}
print(idx2vocab)
#{0: '<PAD>', 1: '<UNK>', 2: '晉', 3: '樂', ...}
print(vocab2idx)
#{'<PAD>': 0, '<UNK>': 1, '晉': 2, '樂': 3, ...}

#------------------------------------------------------------------------
#第二步 读取数据
#------------------------------------------------------------------------
def read_corpus(corpus_path, vocab2idx, label2idx):
    datas, labels = [], []
    with open(corpus_path, encoding='utf-8') as fr:
        lines = fr.readlines()
    sent_, tag_ = [], []
    for line in lines:
        line = line.strip()
        #print(line)
        if line != '':          #断句
            value = line.split(",")
            word,label = value[0],value[4]
            #汉字及标签逐一添加列表  ['晉', '樂'] ['S-LOC', 'B-PER']
            sent_.append(word)
            tag_.append(label)
            """
            print(sent_) #['晉', '樂', '王', '鮒', '曰', ':']
            print(tag_)  #['S-LOC', 'B-PER', 'I-PER', 'E-PER', 'O', 'O']
            """
        else:                   #vocab2idx[0] => <PAD>
            sent_ids = [vocab2idx[char] if char in vocab2idx else vocab2idx['<UNK>'] for char in sent_]
            tag_ids = [label2idx[label] if label in label2idx else 0 for label in tag_]
            datas.append(sent_ids) #按句插入列表
            labels.append(tag_ids)
            sent_, tag_ = [], []
    return datas, labels

#原始数据
train_datas_, train_labels_ = read_corpus(train_data_path, vocab2idx, label2idx)
test_datas_, test_labels_ = read_corpus(test_data_path, vocab2idx, label2idx)
val_datas_, val_labels_ = read_corpus(val_data_path, vocab2idx, label2idx)

#输出测试结果 (第五句语料)
print(len(train_datas_),len(train_labels_),len(test_datas_),
      len(test_labels_),len(val_datas_),len(val_labels_))
print(train_datas_[5])
print([idx2vocab[idx] for idx in train_datas_[5]])
print(train_labels_[5])
print([idx2label[idx] for idx in train_labels_[5]])

#------------------------------------------------------------------------
#第三步 数据填充 one-hot编码
#------------------------------------------------------------------------
MAX_LEN = 100
VOCAB_SIZE = len(vocab2idx)
CLASS_NUMS = len(label2idx)

#padding data
print('padding sequences')
train_datas = sequence.pad_sequences(train_datas_, maxlen=MAX_LEN)
train_labels = sequence.pad_sequences(train_labels_, maxlen=MAX_LEN)

test_datas = sequence.pad_sequences(test_datas_, maxlen=MAX_LEN)
test_labels = sequence.pad_sequences(test_labels_, maxlen=MAX_LEN)
print('x_train shape:', train_datas.shape)
print('x_test shape:', test_datas.shape)
#(15362, 100) (1919, 100)

#encoder one-hot
train_labels = keras.utils.to_categorical(train_labels, CLASS_NUMS)
test_labels = keras.utils.to_categorical(test_labels, CLASS_NUMS)
print('trainlabels shape:', train_labels.shape)
print('testlabels shape:', test_labels.shape)
#(15362, 100, 13) (1919, 100, 13)

#------------------------------------------------------------------------
#第四步 建立Attention机制
#------------------------------------------------------------------------
K.clear_session()
SINGLE_ATTENTION_VECTOR = False
def attention_3d_block(inputs):
    # inputs.shape = (batch_size, time_steps, input_dim)
    input_dim = int(inputs.shape[2])
    a = inputs
    a = Dense(input_dim, activation='softmax')(a)
    if SINGLE_ATTENTION_VECTOR:
        a = Lambda(lambda x: K.mean(x, axis=1), name='dim_reduction')(a)
        a = RepeatVector(input_dim)(a)
    a_probs = Permute((1, 2), name='attention_vec')(a)
    #output_attention_mul = merge([inputs, a_probs], name='attention_mul', mode='mul')
    output_attention_mul = concatenate([inputs, a_probs])
    return output_attention_mul

#------------------------------------------------------------------------
#第五步 构建ATT+CNN-BiLSTM+CRF模型
#------------------------------------------------------------------------
EPOCHS = 2
EMBED_DIM = 128
HIDDEN_SIZE = 64
MAX_LEN = 100
VOCAB_SIZE = len(vocab2idx)
CLASS_NUMS = len(label2idx)
print(VOCAB_SIZE, CLASS_NUMS) #3319 13

#模型构建
inputs = Input(shape=(MAX_LEN,), dtype='int32')
x = Masking(mask_value=0)(inputs)
x = Embedding(VOCAB_SIZE, EMBED_DIM, mask_zero=False)(x) #修改掩码False

#CNN
cnn1 = Convolution1D(64, 3, padding='same', strides = 1, activation='relu')(x)
cnn1 = MaxPool1D(pool_size=1)(cnn1)
cnn2 = Convolution1D(64, 4, padding='same', strides = 1, activation='relu')(x)
cnn2 = MaxPool1D(pool_size=1)(cnn2)
cnn3 = Convolution1D(64, 5, padding='same', strides = 1, activation='relu')(x)
cnn3 = MaxPool1D(pool_size=1)(cnn3)
cnn = concatenate([cnn1,cnn2,cnn3], axis=-1)
print(cnn.shape)   #(None, 100, 384)

#BiLSTM
bilstm = Bidirectional(LSTM(64, return_sequences=True))(cnn) #参数保持维度3 
layer = Dense(64, activation='relu')(bilstm)
layer = Dropout(0.3)(layer)
print(layer.shape) #(None, 100, 64)

#注意力
attention_mul = attention_3d_block(layer) #(None, 100, 128)
print(attention_mul.shape)

x = TimeDistributed(Dense(CLASS_NUMS))(attention_mul)
print(x.shape)     #(None, 3, 13)

outputs = CRF(CLASS_NUMS)(x)
print(outputs.shape)     #(None, 100, 13)
print(inputs.shape)      #(None, 100)

model = Model(inputs=inputs, outputs=outputs)
model.summary()

#------------------------------------------------------------------------
#第六步 模型训练和预测
#------------------------------------------------------------------------
flag = "train"
if flag=="train":
    #模型训练
    model.compile(loss=crf_loss, optimizer='adam', metrics=[crf_viterbi_accuracy])
    model.fit(train_datas, train_labels, epochs=EPOCHS, verbose=1, validation_split=0.1)
    score = model.evaluate(test_datas, test_labels, batch_size=256)
    print(model.metrics_names)
    print(score)
    model.save("att_cnn_crf_bilstm_ner_model.h5")
elif flag=="test":
    #训练模型
    char_vocab_path = "char_vocabs_.txt"                #字典文件
    model_path = "att_cnn_crf_bilstm_ner_model.h5"      #模型文件
    ner_labels = label2idx
    special_words = ['<PAD>', '<UNK>']
    MAX_LEN = 100
    
    #预测结果
    model = load_model(model_path, custom_objects={'CRF': CRF}, compile=False)    
    y_pred = model.predict(test_datas)
    y_labels = np.argmax(y_pred, axis=2)         #取最大值
    z_labels = np.argmax(test_labels, axis=2)    #真实值
    word_labels = test_datas                     #真实值
    
    k = 0
    final_y = []       #预测结果对应的标签
    final_z = []       #真实结果对应的标签
    final_word = []    #对应的特征单词
    while k<len(y_labels):
        y = y_labels[k]
        for idx in y:
            final_y.append(idx2label[idx])
        #print("预测结果:", [idx2label[idx] for idx in y])
        
        z = z_labels[k]
        for idx in z:    
            final_z.append(idx2label[idx])
        #print("真实结果:", [idx2label[idx] for idx in z])
        
        word = word_labels[k]
        for idx in word:
            final_word.append(idx2vocab[idx])
        k += 1
    print("最终结果大小:", len(final_y),len(final_z)) #191900 191900
    
    n = 0
    numError = 0
    numRight = 0
    while n<len(final_y):
        if final_y[n]!=final_z[n] and final_z[n]!='O':
            numError += 1
        if final_y[n]==final_z[n] and final_z[n]!='O':
            numRight += 1
        n += 1
    print("预测错误数量:", numError)
    print("预测正确数量:", numRight)
    print("Acc:", numRight*1.0/(numError+numRight))
    print(y_pred.shape, len(test_datas_), len(test_labels_))
    print("预测单词:", [idx2vocab[idx] for idx in test_datas_[5]])
    print("真实结果:", [idx2label[idx] for idx in test_labels_[5]])
    print("预测结果:", [idx2label[idx] for idx in y_labels[5]][-len(test_datas_[5]):])
    
    #文件存储
    fw = open("Final_ATT_CNN_BiLSTM_CRF_Result.csv", "w", encoding="utf8", newline='')
    fwrite = csv.writer(fw)
    fwrite.writerow(['pre_label','real_label', 'word'])
    n = 0
    while n<len(final_y):
        fwrite.writerow([final_y[n],final_z[n],final_word[n]])
        n += 1
    fw.close()

运行所构建的模型如下:

Model: "model_1"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_1 (InputLayer)            (None, 100)          0                                            
__________________________________________________________________________________________________
masking_1 (Masking)             (None, 100)          0           input_1[0][0]                    
__________________________________________________________________________________________________
embedding_1 (Embedding)         (None, 100, 128)     971904      masking_1[0][0]                  
__________________________________________________________________________________________________
conv1d_1 (Conv1D)               (None, 100, 64)      24640       embedding_1[0][0]                
__________________________________________________________________________________________________
conv1d_2 (Conv1D)               (None, 100, 64)      32832       embedding_1[0][0]                
__________________________________________________________________________________________________
conv1d_3 (Conv1D)               (None, 100, 64)      41024       embedding_1[0][0]                
__________________________________________________________________________________________________
max_pooling1d_1 (MaxPooling1D)  (None, 100, 64)      0           conv1d_1[0][0]                   
__________________________________________________________________________________________________
max_pooling1d_2 (MaxPooling1D)  (None, 100, 64)      0           conv1d_2[0][0]                   
__________________________________________________________________________________________________
max_pooling1d_3 (MaxPooling1D)  (None, 100, 64)      0           conv1d_3[0][0]                   
__________________________________________________________________________________________________
concatenate_1 (Concatenate)     (None, 100, 192)     0           max_pooling1d_1[0][0]            
                                                                 max_pooling1d_2[0][0]            
                                                                 max_pooling1d_3[0][0]            
__________________________________________________________________________________________________
bidirectional_1 (Bidirectional) (None, 100, 128)     131584      concatenate_1[0][0]              
__________________________________________________________________________________________________
dense_1 (Dense)                 (None, 100, 64)      8256        bidirectional_1[0][0]            
__________________________________________________________________________________________________
dropout_1 (Dropout)             (None, 100, 64)      0           dense_1[0][0]                    
__________________________________________________________________________________________________
dense_2 (Dense)                 (None, 100, 64)      4160        dropout_1[0][0]                  
__________________________________________________________________________________________________
attention_vec (Permute)         (None, 100, 64)      0           dense_2[0][0]                    
__________________________________________________________________________________________________
concatenate_2 (Concatenate)     (None, 100, 128)     0           dropout_1[0][0]                  
                                                                 attention_vec[0][0]              
__________________________________________________________________________________________________
time_distributed_1 (TimeDistrib (None, 100, 13)      1677        concatenate_2[0][0]              
__________________________________________________________________________________________________
crf_1 (CRF)                     (None, 100, 13)      377         time_distributed_1[0][0]         
==================================================================================================
Total params: 1,216,454
Trainable params: 1,216,454
Non-trainable params: 0
__________________________________________________________________________________________________

部分输出结果如下,包括训练过程:

Using TensorFlow backend.
{'O': 0, 'S-LOC': 1, 'B-LOC': 2, 'I-LOC': 3, 'E-LOC': 4, 'S-PER': 5, 'B-PER': 6, 'I-PER': 7, 'E-PER': 8, 'S-TIM': 9, 'B-TIM': 10, 'E-TIM': 11, 'I-TIM': 12}
{0: 'O', 1: 'S-LOC', 2: 'B-LOC', 3: 'I-LOC', 4: 'E-LOC', 5: 'S-PER', 6: 'B-PER', 7: 'I-PER', 8: 'E-PER', 9: 'S-TIM', 10: 'B-TIM', 11: 'E-TIM', 12: 'I-TIM'}

['齊', '、', '衛', '、', '陳', '大', '夫', '其', '不', '免', '乎', '!']
[1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0]
['S-LOC', 'O', 'S-LOC', 'O', 'S-LOC', 'O', 'O', 'O', 'O', 'O', 'O', 'O']

Epoch 1/2

   32/13825 [..............................] - ETA: 5:54 - loss: 2.6212 - crf_viterbi_accuracy: 6.2500e-04
   64/13825 [..............................] - ETA: 3:20 - loss: 2.5952 - crf_viterbi_accuracy: 0.0112
   96/13825 [..............................] - ETA: 2:45 - loss: 2.5627 - crf_viterbi_accuracy: 0.0517
  128/13825 [..............................] - ETA: 2:37 - loss: 2.5237 - crf_viterbi_accuracy: 0.0862
  ...
13792/13825 [============================>.] - ETA: 0s - loss: 0.0227 - crf_viterbi_accuracy: 0.9934
13824/13825 [============================>.] - ETA: 0s - loss: 0.0227 - crf_viterbi_accuracy: 0.9934
13825/13825 [==============================] - 171s 12ms/step - loss: 0.0227 - crf_viterbi_accuracy: 0.9934 - val_loss: 0.0208 - val_crf_viterbi_accuracy: 0.9938

最终预测结果如下:

预测错误数量: 1004
预测正确数量: 3395
Acc: 0.7717663105251193
预测单词: ['冬', ',', '楚', '公', '子', '罷', '如', '晉', '聘', ',', '且', '涖', '盟', '。']
真实结果: ['O', 'O', 'B-PER', 'I-PER', 'I-PER', 'E-PER', 'O', 'S-LOC', 'O', 'O', 'O', 'O', 'O', 'O']
预测结果: ['O', 'O', 'S-LOC', 'B-PER', 'I-PER', 'E-PER', 'O', 'S-LOC', 'O', 'O', 'O', 'O', 'O', 'O']

同时将预测结果保存,如下图所示:

[当人工智能遇上安全] 13.威胁情报实体识别 (3)利用keras构建CNN-BiLSTM-ATT-CRF实体识别模型,当人工智能遇上安全,人工智能,keras,实体识别,威胁情报


六.Attention构建及兼容问题

上述代码中的Attention与常见的略有不同,这是为什么呢?
这是因为CRF模型要求不能降维,而传统注意力机制会将向量降一维,如下所示。从而会导致各种错误,最终CRF无法运行,比较常见的错误:

  • AttributeError: ‘NoneType’ object has no attribute ‘_inbound_nodes’
  • AttributeError: tuple object has no attribute layer
  • AttributeError: ‘Node’ object has no attribute ‘output_masks’
  • AttributeError: ‘InputLayer’ object has no attribute ‘outbound_nodes’
  • TypeError: The added layer must be an instance of class Layer.
  • TypeError: The added layer must be an instance of class Layer.

同时,Keras在2.0以后也可以通过tensorflow.keras调用,两种方式同时使用也会导致部分错误。最终通过上述的注意力模型来实现的。总之,TensorFlow和Keras版本问题真的烦人,建议大家以后都该PyTorch,后续博客也将陆续更换。

现有方法:
(None, 100, 192)
(None, 100, 64)
(None, 100, 128)
(None, 100, 13)
(None, 100, 13)

传统方法:
(None, 100, 192)
(None, 100, 64)
(None, 64)
(None, 13)
(None, 13)

[当人工智能遇上安全] 13.威胁情报实体识别 (3)利用keras构建CNN-BiLSTM-ATT-CRF实体识别模型,当人工智能遇上安全,人工智能,keras,实体识别,威胁情报

传统的Attention代码如下:

# Hierarchical Model with Attention
from keras import initializers
from keras import constraints
from keras import activations
from keras import regularizers
from keras import backend as K
from keras.engine.topology import Layer

K.clear_session()

class AttentionLayer(Layer):
    def __init__(self, attention_size=None, **kwargs):
        self.attention_size = attention_size
        super(AttentionLayer, self).__init__(**kwargs)
        
    def get_config(self):
        config = super().get_config()
        config['attention_size'] = self.attention_size
        return config
        
    def build(self, input_shape):
        assert len(input_shape) == 3
        
        self.time_steps = input_shape[1]
        hidden_size = input_shape[2]
        if self.attention_size is None:
            self.attention_size = hidden_size
            
        self.W = self.add_weight(name='att_weight', shape=(hidden_size, self.attention_size),
                                initializer='uniform', trainable=True)
        self.b = self.add_weight(name='att_bias', shape=(self.attention_size,),
                                initializer='uniform', trainable=True)
        self.V = self.add_weight(name='att_var', shape=(self.attention_size,),
                                initializer='uniform', trainable=True)
        super(AttentionLayer, self).build(input_shape)
    
    def call(self, inputs):
        self.V = K.reshape(self.V, (-1, 1))
        H = K.tanh(K.dot(inputs, self.W) + self.b)
        score = K.softmax(K.dot(H, self.V), axis=1)
        outputs = K.sum(score * inputs, axis=1)
        return outputs
    
    def compute_output_shape(self, input_shape):
        return input_shape[0], input_shape[2]

att = AttentionLayer(attention_size=50)(layer)

七.总结

写到这里这篇文章就结束,希望对您有所帮助,后续将结合经典的Bert进行分享。忙碌的2024,真的很忙,项目本子论文毕业工作,等忙完后好好写几篇安全博客,感谢支持和陪伴,尤其是家人的鼓励和支持, 继续加油!

  • Keras下载地址:https://github.com/eastmountyxz/AI-for-Keras

Bert在Keras的NER中常用扩展包包括:

  • bert4keras
    – from bert4keras.models import build_transformer_model
    – from bert4keras.tokenizers import Tokenizer
    – from bert4keras.layers import ConditionalRandomField
  • kashgari
    – from kashgari.embeddings import BERTEmbedding
    – from kashgari.tasks.seq_labeling import BLSTMCRFModel
  • keras_bert
    – from keras_bert import Tokenizer
  • bert_serving
    – from bert_serving.server import BertServer

人生路是一个个十字路口,一次次博弈,一次次纠结和得失组成。得失得失,有得有失,不同的选择,不一样的精彩。虽然累和忙,但看到小珞珞还是挺满足的,感谢家人的陪伴。望小珞能开心健康成长,爱你们喔,继续干活,加油!

(By:Eastmount 2024-04-09 夜于贵阳 http://blog.csdn.net/eastmount/ )文章来源地址https://www.toymoban.com/news/detail-855121.html


到了这里,关于[当人工智能遇上安全] 13.威胁情报实体识别 (3)利用keras构建CNN-BiLSTM-ATT-CRF实体识别模型的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 人工智能监听——研究人员发现新的安全威胁

    大学的一项新研究表明,人工智能 (AI) 可以通过按键声音识别密码,准确率超过 90%。 在通过 Zoom 等视频通话聊天时输入计算机密码可能会打开网络攻击的大门,一项新的研究表明,人工智能可以通过窃听打字声音来找出正在按下的按键。 行业专家表示,随着 Zoom 等视频会议

    2024年02月04日
    浏览(49)
  • ChatGPT对网络安全的影响(人工智能安全、云计算主要威胁)

    目录 前言 1. ChatGPT 如何被恶意行为者用来网络攻击? 2. 企业如何使用 ChatGPT 改进网络安全计划?

    2024年02月02日
    浏览(42)
  • 如何应对人工智能时代下的网络与数据安全威胁

    2023(第四届) 网络法治论坛 ——人工智能时代的网络与数据治理暨公益大讲堂于2023年12月23日在北方工业大学(石景山晋元庄路5号院)学生服务中心四层报告厅成功举办。网络法治论坛是在北京市法学会指导下的,由北京市网络法学研究会主办的品牌论坛暨北京市网络法学

    2024年02月01日
    浏览(51)
  • 智安网络|人工智能蔓延,网络安全所面临的威胁和应对之道

    随着人工智能(Artificial Intelligence,AI)技术的快速发展和广泛应用,我们进入了一个智能时代,人工智能已经蔓延到我们生活的方方面面。然而,与其带来的方便和创新相伴随的是网络安全所面临的新威胁。 【威胁一:攻击者利用人工智能技术】 人工智能技术的进步为攻击

    2024年02月10日
    浏览(54)
  • 当人工智能遇上教育,会擦出怎样的火花?

    在这个时代,科技的风暴正以前所未有的速度席卷全球。其中,人工智能,这个被誉为21世纪的“科技之星”,正悄然改变着我们的生活。但是,当人工智能遇上传统教育领域时,你猜会发生什么? 有人说,这是一场革命,一场彻底颠覆传统教育模式的革命。有人说,这是一

    2024年02月21日
    浏览(47)
  • 腾讯安全吴石:基于威胁情报构建免疫体系,助力企业稳步迈向智能安全新阶段

    6月13日,腾讯安全、腾讯研究院联合IDC、《中国信息安全》杂志社、CIO时代、新基建创新研究院等多家权威机构、媒体共同发起“数字安全免疫力研讨论坛”,聚合产学研各界专家学者探讨数字安全建设新范式。 论坛上,腾讯安全联合IDC发布“数字安全免疫力”模型框架,提

    2024年02月13日
    浏览(47)
  • Adobe:当创意工作遇上AIGC ,人工智能还是取代了设计师?

    近期以来,GPT-4热度居高不下,国内首部AI深度参与的动画电影也有望诞生,这也使得传媒影视板块反复活跃表现,影视业内资深设计师也表示, AI技术可以应用在剧本创作、刻画人物画像,甚至实现AI换脸等,降低影视制作成本,进一步提升影视制作效率 。 随着谷歌、百度

    2024年02月10日
    浏览(47)
  • 华为Could API人工智能系列——命名实体识别

    云原生时代,开发者们的编程方式、编程习惯都发生了天翻地覆的变化,大家逐渐地习惯在云端构建自己的应用。作为新一代的开发者们,如何更快速了解云,学习云,使用云,更便捷、更智能的开发代码,从而提升我们的开发效率,是当前最热门的话题之一,而Huawei Cloud

    2024年02月02日
    浏览(37)
  • 未适应新的安全威胁情报:新的安全威胁情报未用于指导防火墙策略的更新

    近年来随着网络攻击手段不断升级,传统的网络安全防护措施已不再足以应对新型的安全挑战. 为了保障网络安全和提高防护效果我们需要及时了解和掌握最新的安全风险信息并运用到防火墙的策略制定中以提高整体安全性. 然而现实中情况并非如此很多组织未能有效运用最新

    2024年02月03日
    浏览(32)
  • 了解人工智能的13个细分领域

    人工智能(Artificial Intelligence,简称AI)作为当今最热门和前沿的技术之一,已经在各种领域发挥着越来越重要的作用。随着人工智能技术的不断进步和应用,AI的细分领域也越来越多。目前,根据AI的应用领域和特点,我们可以将人工智能的13个细分领域归纳如下: 语音识别

    2024年04月16日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包