×

如何使用Keras框架来构建LSTM RNN来对网络请求进行区分

消耗积分:1 | 格式:rar | 大小:0.5 MB | 2017-09-27

分享资料个

  向量机(SVM)、神经网络和无监督模型。

  学术界和实际应用领域目前正时刻关注着深度学习和神经网络的最新进展。事实证明,深度学习和神经网络在图像识别和自然语言处理(NLP)方面表现出众。我们是否可以利用神经网络的NLP能力来处理这个分类问题呢?这就是我们想要测试的。

  我们通过模拟API给出JSON形式的访问请求日志,如下所示:

  { “ timestamp”: 1502135820943, “ method”: “get”, “ query”: { “query”: “Lawn & Garden Buying Guides”}, “ path”: “/search”, “ statusCode”: 200, “ source”: { “remoteAddress”:“22.73.58.187”, “userAgent”: “Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36”}, “route”: “/search”, “ headers”: { “host”: “localhost:8002”, “connection”: “keep-alive”, “cache-control”: “no-cache”, “user-agent”: “Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36”, “accept”: “*/*”, “accept-encoding”: “gzip, deflate, br”, “accept-language”: “en-US,en;q=0.8,es;q=0.6”}, “ requestPayload”: null, “ responsePayload”: “SEARCH”}

  JSON格式的数据是不能用作神经网络模型的输入的。模型的输入必须是数字,因此,需要对文本进行预处理。由于请求日志的内容包含各种字符串、符号和数字,因此,我们选择将每个日志条目预处理为字符序列。

  将日志条目作为字符序列进行处理,就是将请求日志文本中的每个字符映射到字典中的数字。相关联的数字表示该字符出现的频率。这个字典最初是用训练数据来创建和拟合的,这样,后续的字符就可以映射到以前曾经出现过的字符上去。例如,在字典中,“,”字符是训练数据集中第七个出现频率最高的字符:

  { “ ”: 39, “(”: 77, “,”: 7, “0”: 8, “4”: 26, “8”: 28, “《”: 64, “D”: 71, “H”: 59, “L”: 61, 。。.

  字符序列学习的一个不错的选择是使用递归神经网络(RNN)。更具体点说,就是选择使用RNNs的长短期记忆网络(LSTM)变体,因为它在学习序列的应用中被广泛使用并取得了成功。 LSTM有点复杂,但这并不是这篇文章的重点,不过如果在高层次上对此有一点了解的话,在修改模型时会有一些帮助。更多有关序列学习和LSTM的实践可以在Andrej Karpathy编写的RNNs的不合理有效性一文中找到。

  为了快速开发神经网络模型,我们选择使用运行在Tensorflow之上的高级Keras API,而不是直接使用Tensorflow。通过使用Keras为Tensorflow提供的样板设置,我们能够节约很多时间,并快速地构建起模型原型。

  Keras的神经网络模型使用起来非常容易,只需实例化一个模型对象,然后就可以添加层了!初始的嵌入层指定了矢量输入的预期维度,LSTM隐藏层则由64个神经元以及单独的压差层来定义以减少方差,最后则是密集输出层以产生分类置信度。

  model = Sequential() model.add(Embedding(num_words, 32, input_length=max_log_length)) # Prevent overfitting using dropout method of regularizationmodel.add(Dropout( 0.5)) model.add(LSTM( 64, recurrent_dropout= 0.5)) model.add(Dropout( 0.5)) # Condense to single binary output valuemodel.add(Dense( 1, activation= ‘sigmoid’)) model.compile(loss= ‘binary_crossentropy’, optimizer= ‘adam’, metrics=[ ‘accuracy’]) # Training set automatically split 75/25 to check validation loss/accuracy at each epochmodel.fit(X_train, Y_train, validation_split= 0.25, epochs= 3, batch_size= 128, callbacks=[tb_callback]) # Evaluation of separate test dataset performed after trainingscore, acc = model.evaluate(X_test, Y_test, verbose= 1, batch_size= 128)训练

  使用LSTM RNN二元分类法则意味着是在模型上应用监督学习算法。因此,训练数据集中的每个日志条目都需要有一个附带的标签来描述该记录的请求是正常的还是尝试注入攻击的。

  0= Normal requestlogentry 1= Requestlogindicates attempted injection attack

  对于生成数据来训练模型,则可以使用模拟API来模拟一个非常简单的电子商务应用程序。例如,模拟出/login、 /search、/checkout等URL。由于我们并没有真实用户去访问模拟API,因此我们需要引入一些运行时选项来运行服务器并自动执行请求。我们将这些自动化的请求流量调整为每分钟100次,这样训练数据集的日志就能快速积累起来。

  通过将自定义的日志记录器添加到服务器框架中,可以输出指定格式的数据集。为了区分正常和恶意请求,需要在所有的恶意请求前添加一个“attack”头。通过检查是否存在“attack”头来确定每个请求日志条目的标签。如果“attack”头存在,则使用“1”来标记日志,并在写入日志之前删除“attack”头,否则将日志标记为“0”。

  由于使用模拟API来生成训练数据集存在一些限制,并且为了确保得到一个更广义的分类器,我们在预处理期间仅提取几个必要的日志字段。这些属性包括:“method”、“query”、“statusCode”、“path”、“requestPayload”。可以使用额外的数据、预处理和可能的单独分类器来分析请求的内容。

  自动化客户会放那连续运行了几个小时,以积累一定数量的训练数据。为了快速训练模型,我们将使用AWS p2.xlarge深度学习EC2实例。 AWS的深度学习AMI预先安装了大多数的流行AI库和API,你可以使用GPU进行大量的训练。这个EC2实例每小时90美分的成本不仅节省了在大量数据集上训练模型的时间,还节省了安装和配置Tensorflow使之能够在GPU上正常运行的时间。我们发现在新机器上安装和配置Tensorflow相当地耗时。

  为了减少偏差,生成的数据集中包含了大约50/50个正常和恶意的请求日志。该数据集分为75%的训练子集和25%的验证子集。经过几次迭代之后,该模型能够获得相当高的精度。

  如何使用Keras框架来构建LSTM RNN来对网络请求进行区分

  从大约23000个请求日志样本得到的训练结果

  上图中的准确度和损失指标也会通过Keras训练脚本中附带的Tensorboard回调记录在日志中。这些日志是训练期间检查点的积累,这对于在训练期间和之后将模型的性能可视化非常有用。

  实现

  有了训练过的模型,现在是时候来实现SecuritAI用户界面程序了,该应用程序用于托管模型以进行实时的预测。与模拟API一样,我们坚持使用自己最熟悉的Java语言。我们构建了一个React UI,作为监视来自请求日志流活动的仪表板。该请求日志流使用AWS Kinesis来管理,用于桥接模拟API和SecuritAI UI之间的通信。

  有一个小问题…… Keras是一个python库,那么模型是如何在Java中进行预测的呢?幸运的是,有一个npm包可以用来实现这个需求,那就是keras-js! Keras-js允许Java应用程序运行在Tensorflow引擎上训练Keras模型。这个库使得我们能够在Node.js应用服务器上运行所有的东西。

  有关keras-js的更多信息,请参阅: https://github.com/transcranial/keras-js

  演示

  如何使用Keras框架来构建LSTM RNN来对网络请求进行区分

  SecuritAI演示

  经验教训与后期改进

  总体而言,这是一个非常有趣的应用程序,从开发过程中你可以学到有关在Keras中使用Tensorflow建模的知识。也许已经有其他更加简单的机器学习模型或平台可以被用来代替LSTM RNN,但是如果没有一点黑客精神的话,乐趣何在?在理想情况下,无监控异常检测模型可能更适合于本应用。

  作为后期的改进,该模型可以转换为仅依赖Tensorflow API来运行、针对内容更丰富的请求头进行训练,以及执行多元分类以实现对可疑请求的分类。

  GitHub上的代码:

  adamkusey/securitai-ui

  adamkusey/securitai-lstm-model

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.obk20.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'如何使用Keras框架来构建LSTM RNN来对网络请求进行区分',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"//www.obk20.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);