精华内容
下载资源
问答
  • 为了提高网络入侵检测速度和稳定性,提出了一种基于多线程的混合深度包检测方法。该方法首先采用正则表达式的线性系数来对规则集中的正则表达式进行分组,然后对不同正则表达式组采用不同压缩技术进行状态位压缩,...
  • 计算机网络——网络实战

    千次阅读 多人点赞 2021-11-21 09:16:53
    本博文主要是将计算机网络中的利用的概念进行的验证核测试网络实战工具 linux :tcpdump window:Wireshark 这两者实际上是搭配使用的,先用 tcpdump 命令在 Linux 服务器上抓,接着把抓的文件拖 出到 ...

    摘要

    本博文主要是将计算机网络中的利用的概念进行的验证核测试。

    网络实战工具

    • linux :tcpdump
    • window:Wireshark

    这两者实际上是搭配使用的,先用 tcpdump 命令在 Linux 服务器上抓包,接着把抓包的文件拖
    出到 Windows 电脑后,用 Wireshark 可视化分析。当然,如果你是在 Windows 上抓包,只需要用 Wireshark 工具就可以。

    tcpdump使用方法

    tcpdump 在 Linux 下如何抓包?

    tcpdump 提供了大量的选项以及各式各样的过滤表达式,来帮助你抓取指定的数据包,不过不要担心,只需要掌握一些常用选项和过滤表达式,就可以满足大部分场景的需要了。假设我们要抓取下面的 ping 的数据包:

    要抓取上面的 ping 命令数据包,首先我们要知道 ping 的数据包是 icmp 协议,接着在使用 tcpdump抓包的时候,就可以指定只抓 icmp 协议的数据包:

     那么当 tcpdump 抓取到 icmp 数据包后, 输出格式如下:

    时间戳协议源地址.源端口 > 目的地址.目的端口网络包详细信息

    从 tcpdump 抓取的 icmp 数据包,我们很清楚的看到 icmp echo 的交互过程了,首先发送方发起了ICMP echo request 请求报文,接收方收到后回了一个 ICMP echo reply 响应报文,之后 seq 是递增的。

    Wireshark 工具如何分析数据包?

    接着把 ping.pcap 文件拖到电脑,再用 Wireshark 打开它。打开后,你就可以看到下面这个界面:

    在 Wireshark 的页面里,可以更加直观的分析数据包,不仅展示各个网络包的头部信息,还会用
    不同的颜色来区分不同的协议,由于这次抓包只有 ICMP 协议,所以只有紫色的条目。接着,在网络包列表中选择某一个网络包后,在其下面的网络包详情中,可以更清楚的看到,这个网络包在协议栈各层的详细信息。

    从 ping 的例子中,我们可以看到网络分层就像有序的分工,每一层都有自己的责任范围和信息,上层协议完成工作后就交给下一层,最终形成一个完整的网络包。

    TCP三次握手抓包

    本次例子,我们将要访问的 http://192.168.3.200 服务端。在终端一用 tcpdump 命令抓取数据包:

     使用 Wireshark 打开 http.pcap 后,你就可以在 Wireshark 中,看到如下的界面:

    Wireshark 可以用时序图的方式显示数据包交互的过程,从菜单栏中,点击 统计 (Statistics) -> 流量图(Flow Graph),然后,在弹出的界面中的「流量类型」选择 「TCP Flows」,你可以更清晰的看到,整个过程中 TCP 流的执行过程:

    你可能会好奇,为什么三次握手连接过程的 Seq 是 0 ?

    实际上是因为 Wireshark 工具帮我们做了优化,它默认显示的是序列号 seq 是相对值,而不是真实值。如果你想看到实际的序列号的值,可以右键菜单, 然后找到「协议首选项」,接着找到「RelativeSeq」后,把它给取消,操作如下:

    TCP四次挥手抓包

    为什么抓到的 TCP 挥手是三次,而不是书上说的四次?

    因为服务器端收到客户端的 FIN 后,服务器端同时也要关闭连接,这样就可以把 ACK 和 FIN 合
    并到一起发送,节省了一个包,变成了“三次挥手”。而通常情况下,服务器端收到客户端的 FIN 后,很可能还没发送完数据,所以就会先回复客户端一个ACK 包,稍等一会儿,完成所有数据包的发送后,才会发送 FIN 包,这也就是四次挥手了。

    如下图,就是四次挥手的过程:

    TCP 三次握手异常情况实战分析

    本次实验用了两台虚拟机,一台作为服务端,一台作为客户端,它们的关系如下:

    实验一:TCP 第一次握手 SYN 丢包

    为了模拟 TCP 第一次握手 SYN 丢包的情况,我是在拔掉服务器的网线后,立刻在客户端执行 curl 命令:

    其间 tcpdump 抓包的命令如下:

     过了一会, curl 返回了超时连接的错误:

     从 date 返回的时间,可以发现在超时接近 1 分钟的时间后,curl 返回了错误。接着,把 tcp_sys_timeout.pcap 文件用 Wireshark 打开分析,显示如下图:

    从上图可以发现, 客户端发起了 SYN 包后,一直没有收到服务端的 ACK ,所以一直超时重传了
    次,并且每次 RTO 超时时间是不同的:

    • 第一次是在 1 秒超时重传
    • 第二次是在 3 秒超时重传
    • 第三次是在 7 秒超时重传
    • 第四次是在 15 秒超时重传
    • 第五次是在 31 秒超时重传

    可以发现,每次超时时间 RTO 是指数(翻倍)上涨的,当超过最大重传次数后,客户端不再发送 SYN包。

    在 Linux 中,第一次握手的 SYN 超时重传次数,是如下内核参数指定的:

    $ cat /proc/sys/net/ipv4/tcp_syn_retries
    5
    
    tcp_syn_retries 默认值为 5,也就是 SYN 最大重传次数是 5 次。

    接下来,我们继续做实验,把 tcp_syn_retries 设置为 2 次:

    $ echo 2 > /proc/sys/net/ipv4/tcp_syn_retries

    重传抓包后,用 Wireshark 打开分析,显示如下图:

    实验一总结

    通过实验一的实验结果,我们可以得知,当客户端发起的 TCP 第一次握手 SYN 包,在超时时间内没收到服务端的 ACK,就会在超时重传 SYN 数据包,每次超时重传的 RTO 是翻倍上涨的,直到 SYN 包的重传次数到达 tcp_syn_retries 值后,客户端不再发送 SYN 包。

    实验二:TCP 第二次握手 SYN、ACK 丢包

    为了模拟客户端收不到服务端第二次握手 SYN、ACK 包,我的做法是在客户端加上防火墙限制,直接粗暴的把来自服务端的数据都丢弃,防火墙的配置如下:

     接着,在客户端执行 curl 命令:

     从 date 返回的时间前后,可以算出大概 1 分钟后,curl 报错退出了。客户端在这其间抓取的数据包,用 Wireshark 打开分析,显示的时序图如下:

    从图中可以发现:

    • 客户端发起 SYN 后,由于防火墙屏蔽了服务端的所有数据包,所以 curl 是无法收到服务端的SYN、ACK 包,当发生超时后,就会重传 SYN 包。
    • 服务端收到客户的 SYN 包后,就会回 SYN、ACK 包,但是客户端一直没有回 ACK,服务端在超时后,重传了 SYN、ACK 包,接着一会,客户端超时重传的 SYN 包又抵达了服务端,服务端收到后,超时定时器就重新计时,然后回了 SYN、ACK 包,所以相当于服务端的超时定时器只触发了一次,又被重置了。
    • 最后,客户端 SYN 超时重传次数达到了 5 次(tcp_syn_retries 默认值 5 次),就不再继续发送SYN 包了。

    所以,我们可以发现,当第二次握手的 SYN、ACK 丢包时,客户端会超时重发 SYN 包,服务端也会超时重传 SYN、ACK 包。

    客户端设置了防火墙,屏蔽了服务端的网络包,为什么 tcpdump 还能抓到服务端的网络包?

    添加 iptables 限制后, tcpdump 是否能抓到包 ,这要看添加的 iptables 限制条件:

    • 如果添加的是 INPUT 规则,则可以抓得到包
    • 如果添加的是 OUTPUT 规则,则抓不到包

    网络包进入主机后的顺序如下:

    • 进来的顺序 Wire -> NIC -> tcpdump -> netfilter/iptables
    • 出去的顺序 iptables -> tcpdump -> NIC -> Wire

    tcp_syn_retries 是限制 SYN 重传次数,那第二次握手 SYN、ACK 限制最大重传次数是多少?

    TCP 第二次握手 SYN、ACK 包的最大重传次数是通过 tcp_synack_retries 内核参数限制的,其默认值如下:

    $ cat /proc/sys/net/ipv4/tcp_synack_retries
    5
    
    是的,TCP 第二次握手 SYN、ACK 包的最大重传次数默认值是 5 次。
    为了验证 SYN、ACK 包最大重传次数是 5 次,我们继续做下实验,我们先把客户端的 tcp_syn_retries
    设置为 1,表示客户端 SYN 最大超时次数是 1 次,目的是为了防止多次重传 SYN,把服务端 SYN、
    ACK 超时定时器重置。

    接着,还是如上面的步骤:

    • 1. 客户端配置防火墙屏蔽服务端的数据包
    • 2. 客户端 tcpdump 抓取 curl 执行时的数据包

    把抓取的数据包,用 Wireshark 打开分析,显示的时序图如下:

    从上图,我们可以分析出:

    • 客户端的 SYN 只超时重传了 1 次,因为 tcp_syn_retries 值为 1
    • 服务端应答了客户端超时重传的 SYN 包后,由于一直收不到客户端的 ACK 包,所以服务端一直在超时重传 SYN、ACK 包,每次的 RTO 也是指数上涨的,一共超时重传了 5 次,因为tcp_synack_retries 值为 5

    接着,我把 tcp_synack_retries 设置为 2, tcp_syn_retries 依然设置为 1:

    $ echo 2 > /proc/sys/net/ipv4/tcp_synack_retries
    $ echo 1 > /proc/sys/net/ipv4/tcp_syn_retries

    依然保持一样的实验步骤进行操作,接着把抓取的数据包,用 Wireshark 打开分析,显示的时序图如下:

    由上图可见:

    • 客户端的 SYN 包只超时重传了 1 次,符合 tcp_syn_retries 设置的值;
    • 服务端的 SYN、ACK 超时重传了 2 次,符合 tcp_synack_retries 设置的值

    实验二总结

    通过实验二的实验结果,我们可以得知,当 TCP 第二次握手 SYN、ACK 包丢了后,客户端 SYN 包会发生超时重传,服务端 SYN、ACK 也会发生超时重传。客户端 SYN 包超时重传的最大次数,是由 tcp_syn_retries 决定的,默认值是 5 次;服务端 SYN、ACK 包时重传的最大次数,是由 tcp_synack_retries 决定的,默认值是 5 次。

    实验三:TCP 第三次握手 ACK 丢包

    为了模拟 TCP 第三次握手 ACK 包丢,我的实验方法是在服务端配置防火墙,屏蔽客户端 TCP 报文中标志位是 ACK 的包,也就是当服务端收到客户端的 TCP ACK 的报文时就会丢弃,iptables 配置命令如下:

     接着,在客户端执行如下 tcpdump 命令:

     然后,客户端向服务端发起 telnet,因为 telnet 命令是会发起 TCP 连接,所以用此命令做测试:

    此时,由于服务端收不到第三次握手的 ACK 包,所以一直处于 SYN_RECV 状态:

    而客户端是已完成 TCP 连接建立,处于 ESTABLISHED 状态:

    过了 1 分钟后,观察发现服务端的 TCP 连接不见了:

     过了 30 分别,客户端依然还是处于 ESTABLISHED 状态:

    接着,在刚才客户端建立的 telnet 会话,输入 123456 字符,进行发送:

     持续「好长」一段时间,客户端的 telnet 才断开连接:

    以上就是本次的实现三的现象,这里存在两个疑点:

    • 为什么服务端原本处于 SYN_RECV 状态的连接,过 1 分钟后就消失了?

    原因:服务端在重传 SYN、ACK 包时,超过了最大重传次数 tcp_synack_retries ,于是服务端的 TCP
    连接主动断开了。

    • 为什么客户端 telnet 输入 123456 字符后,过了好长一段时间,telnet 才断开连接?

    原因:客户端向服务端发送数据包时,由于服务端的 TCP 连接已经退出了,所以数据包一直在超时重传,共重传了 15 次, telnet 就断开了连接。

    上图的流程:

    • 客户端发送 SYN 包给服务端,服务端收到后,回了个 SYN、ACK 包给客户端,此时服务端的TCP 连接处于 SYN_RECV 状态;
    • 客户端收到服务端的 SYN、ACK 包后,给服务端回了个 ACK 包,此时客户端的 TCP 连接处于ESTABLISHED 状态;
    • 由于服务端配置了防火墙,屏蔽了客户端的 ACK 包,所以服务端一直处于 SYN_RECV 状态,没有进入 ESTABLISHED 状态,tcpdump 之所以能抓到客户端的 ACK 包,是因为数据包进入系统的顺序是先进入 tcpudmp,后经过 iptables;
    • 接着,服务端超时重传了 SYN、ACK 包,重传了 5 次后,也就是超过 tcp_synack_retries 的值(默认值是 5),然后就没有继续重传了,此时服务端的 TCP 连接主动中止了,所以刚才处于SYN_RECV 状态的 TCP 连接断开了,而客户端依然处于ESTABLISHED 状态;
    • 虽然服务端 TCP 断开了,但过了一段时间,发现客户端依然处于ESTABLISHED 状态,于是就在客户端的 telnet 会话输入了 123456 字符;
    • 此时由于服务端已经断开连接,客户端发送的数据报文,一直在超时重传,每一次重传,RTO 的值是指数增长的,所以持续了好长一段时间,客户端的 telnet 才报错退出了,此时共重传了 15次。

    TCP快速建立连接

    客户端在向服务端发起 HTTP GET 请求时,一个完整的交互过程,需要 2.5 个 RTT 的时延。由于第三次握手是可以携带数据的,这时如果在第三次握手发起 HTTP GET 请求,需要2个RTT的时延。但是在下一次(不是同个 TCP 连接的下一次)发起 HTTP GET 请求时,经历的 RTT 也是一样,如下图:

    在 Linux 3.7 内核版本中,提供了 TCP Fast Open 功能,这个功能可以减少 TCP 连接建立的时延。

    • 在第一次建立连接的时候,服务端在第二次握手产生一个 Cookie (已加密)并通过 SYN、ACK包一起发给客户端,于是客户端就会缓存这个 Cookie ,所以第一次发起 HTTP Get 请求的时候,还是需要 2 个 RTT 的时延;
    • 在下次请求的时候,客户端在 SYN 包带上 Cookie 发给服务端,就提前可以跳过三次握手的过程,因为 Cookie 中维护了一些信息,服务端可以从 Cookie 获取 TCP 相关的信息,这时发起的 HTTP GET 请求就只需要 1 个 RTT 的时延; 

    注:客户端在请求并存储了Fast Open Cookie 之后,可以不断重复 TCP Fast Open 直至服务器认为Cookie 无效(通常为过期)。

    在 Linux 上如何打开 Fast Open 功能?

    可以通过设置 net.ipv4.tcp_fastopn 内核参数,来打开 Fast Open 功能。net.ipv4.tcp_fastopn 各个值的意义:

    • 0 关闭
    • 1 作为客户端使用 Fast Open 功能
    • 2 作为服务端使用 Fast Open 功能
    • 3 无论作为客户端还是服务器,都可以使用 Fast Open 功能

    TCP Fast Open 抓包分析

    在下图,数据包 7 号,客户端发起了第二次 TCP 连接时,SYN 包会携带 Cooike,并且长度为 5 的数据。服务端收到后,校验 Cooike 合法,于是就回了 SYN、ACK 包,并且确认应答收到了客户端的数据包,ACK = 5 + 1 = 6。

    TCP 重复确认和快速重传

    当接收方收到乱序数据包时,会发送重复的 ACK,以便告知发送方要重发该数据包,当发送方收到 3个重复 ACK 时,就会触发快速重传,立刻重发丢失数据包。

    TCP 重复确认和快速重传的一个案例,用 Wireshark 分析,显示如下:

    • 数据包 1 期望的下一个数据包 Seq 是 1,但是数据包 2 发送的 Seq 却是 10945,说明收到的是乱序数据包,于是回了数据包 3 ,还是同样的 Seq = 1,Ack = 1,这表明是重复的 ACK;
    • 数据包 4 和 6 依然是乱序的数据包,于是依然回了重复的 ACK;
    • 当对方收到三次重复的 ACK 后,于是就快速重传了 Seq = 1 、Len = 1368 的数据包 8;
    • 当收到重传的数据包后,发现 Seq = 1 是期望的数据包,于是就发送了个确认收到快速重传的ACK。

    注意:快速重传和重复 ACK 标记信息是 Wireshark 的功能,非数据包本身的信息。

    以上案例在 TCP 三次握手时协商开启了选择性确认 SACK,因此一旦数据包丢失并收到重复 ACK ,即使在丢失数据包之后还成功接收了其他数据包,也只需要重传丢失的数据包。如果不启用 SACK,就必须重传丢失包之后的每个数据包。如果要支持 SACK ,必须双方都要支持。在 Linux 下,可以通过 net.ipv4.tcp_sack 参数打开这个功能(Linux 2.4 后默认打开)。

    TCP 流量控制

    TCP 为了防止发送方无脑的发送数据,导致接收方缓冲区被填满,所以就有了滑动窗口的机制,它可利用接收方的接收窗口来控制发送方要发送的数据量,也就是流量控制。

    接收窗口是由接收方指定的值,存储在 TCP 头部中,它可以告诉发送方自己的 TCP 缓冲空间区大小,这个缓冲区是给应用程序读取数据的空间:

    • 如果应用程序读取了缓冲区的数据,那么缓冲空间区就会把被读取的数据移除
    • 如果应用程序没有读取数据,则数据会一直滞留在缓冲区。

    接收窗口的大小,是在 TCP 三次握手中协商好的,后续数据传输时,接收方发送确认应答 ACK 报文时,会携带当前的接收窗口的大小,以此来告知发送方。

    假设接收方接收到数据后,应用层能很快的从缓冲区里读取数据,那么窗口大小会一直保持不变,过程如下:

    但是现实中服务器会出现繁忙的情况,当应用程序读取速度慢,那么缓存空间会慢慢被占满,于是为了保证发送方发送的数据不会超过缓冲区大小,服务器则会调整窗口大小的值,接着通过 ACK 报文通知给对方,告知现在的接收窗口大小,从而控制发送方发送的数据大小。

    零窗口通知与窗口探测

    假设接收方处理数据的速度跟不上接收数据的速度,缓存就会被占满,从而导致接收窗口为 0,当发送方接收到零窗口通知时,就会停止发送数据。如下图,可以看到接收方的窗口大小在不断的收缩至 0:接着,发送方会定时发送窗口大小探测报文,以便及时知道接收方窗口大小的变化。

    以下图 Wireshark 分析图作为例子说明:

    • 发送方发送了数据包 1 给接收方,接收方收到后,由于缓冲区被占满,回了个零窗口通知;
    • 发送方收到零窗口通知后,就不再发送数据了,直到过了 3.4 秒后,发送了一个 TCP Keep-Alive 报文,也就是窗口大小探测报文;
    • 当接收方收到窗口探测报文后,就立马回一个窗口通知,但是窗口大小还是 0;
    • 发送方发现窗口还是 0,于是继续等待了 6.8 (翻倍) 秒后,又发送了窗口探测报文,接收方依然还是回了窗口为 0 的通知;
    • 发送方发现窗口还是 0,于是继续等待了 13.5 (翻倍) 秒后,又发送了窗口探测报文,接收方依然还是回了窗口为 0 的通知; 

    可以发现,这些窗口探测报文以 3.4s、6.5s、13.5s 的间隔出现,说明超时时间会翻倍递增。

    TCP 延迟确认与 Nagle 算法

    当我们 TCP 报文的承载的数据非常小的时候,例如几个字节,那么整个网络的效率是很低的,因为每个 TCP 报文中都会有 20 个字节的 TCP 头部,也会有 20 个字节的 IP 头部,而数据只有几个字节,所以在整个报文中有效数据占有的比重就会非常低。

    这就好像快递员开着大货车送一个小包裹一样浪费。那么就出现了常见的两种策略,来减少小报文的传输,分别是:

    • Nagle 算法
    • 延迟确认

    Nagle 算法是如何避免大量 TCP 小数据报文的传输?

    Nagle 算法做了一些策略来避免过多的小数据报文发送,这可提高传输效率。Nagle 算法的策略:

    • 没有已发送未确认报文时,立刻发送数据。
    • 存在未确认报文时,直到「没有已发送未确认报文」或「数据长度达到 MSS 大小」时,再发送数据。

    只要没满足上面条件中的一条,发送方一直在囤积数据,直到满足上面的发送条件。

    • 一开始由于没有已发送未确认的报文,所以就立刻发了 H 字符;
    • 接着,在还没收到对 H 字符的确认报文时,发送方就一直在囤积数据,直到收到了确认报文后,
    • 此时没有已发送未确认的报文,于是就把囤积后的 ELL 字符一起发给了接收方;
    • 待收到对 ELL 字符的确认报文后,于是把最后一个 O 字符发送了出去

    可以看出,Nagle 算法一定会有一个小报文,也就是在最开始的时候。另外,Nagle 算法默认是打开的,如果对于一些需要小数据包交互的场景的程序,比如,telnet 或 ssh这样的交互性比较强的程序,则需要关闭 Nagle 算法。可以在 Socket 设置 TCP_NODELAY 选项来关闭这个算法(关闭 Nagle 算法没有全局参数,需要根据每个应用自己的特点来关闭)。

    那延迟确认又是什么?

    事实上当没有携带数据的 ACK,它的网络效率也是很低的,因为它也有 40 个字节的 IP 头 和 TCP
    头,但却没有携带数据报文。为了解决 ACK 传输效率低问题,所以就衍生出了 TCP 延迟确认。

    TCP 延迟确认的策略:

    • 当有响应数据要发送时,ACK 会随着响应数据一起立刻发送给对方
    • 当没有响应数据要发送时,ACK 将会延迟一段时间,以等待是否有响应数据可以一起发送
    • 如果在延迟等待发送 ACK 期间,对方的第二个数据报文又到达了,这时就会立刻发送 ACK

    延迟等待的时间是在 Linux 内核中定义:关键就需要 HZ 这个数值大小,HZ 是跟系统的时钟频率有关,每个操作系统都不一样。

    延迟确认 和 Nagle 算法混合使用时,会产生新的问题?

    当 TCP 延迟确认 和 Nagle 算法混合使用时,会导致时耗增长,如下图:

    发送方使用了 Nagle 算法,接收方使用了 TCP 延迟确认会发生如下的过程:

    • 发送方先发出一个小报文,接收方收到后,由于延迟确认机制,自己又没有要发送的数据,只能干等着发送方的下一个报文到达;
    • 而发送方由于 Nagle 算法机制,在未收到第一个报文的确认前,是不会发送后续的数据;
    • 所以接收方只能等待最大时间 200 ms 后,才回 ACK 报文,发送方收到第一个报文的确认报文后,也才可以发送后续的数据。

    很明显,这两个同时使用会造成额外的时延,这就会使得网络"很慢"的感觉。要解决这个问题,只有两个办法:

    • 要不发送方关闭 Nagle 算法
    • 要不接收方关闭 TCP 延迟确认

    博文参考

    展开全文
  • matlab仿真丢率代码该存储库包含论文“Xu, L., Y. Mo, and L. Xie, Remote State Estimation with Stochastic Event-triggered Sensor Schedule in the Presence of Packet Drops. 已提交,2019 年”的仿真代码。 ...
  • 网络模型已经成为抽象复杂系统并深入了解许多科学领域中观测变量之间的关系模式的流行方法。这些应用程序大多数集中于分析网络的结构。但是,如果不是直接观察到网络(爱丽丝和鲍勃是朋友),而是根据数据进行估算...

    原文链接:http://tecdat.cn/?p=18279

    网络模型已经成为抽象复杂系统,是深入了解许多科学领域中观测变量之间的关系模式的流行方法。这些应用程序大多数集中于分析网络的结构。但是,如果不是直接观察网络,而是根据数据进行估算(如:吸烟与癌症之间存在关联),则除了网络结构外,我们还可以分析网络中节点的可预测性。也就是说:网络中的所有其余节点如何预测网络中的给定节点?

    可预测性有趣,有几个原因:

    1. 它给我们提供了一个关于边的实用性的想法:如果节点A连接到许多其他节点,但是这些仅说明(假设)其方差的1%,那么边的连接会是怎样的?
    2. 它告诉我们网络的不同部分在多大程度上是网络中的其他因素决定的

    在此博文中,我们使用R-估计网络模型并计算地震灾民数据集上的创伤后应激障碍(PTSD)症状。我们对网络模型和可预测性进行可视化,并讨论如何将网络模型和节点的可预测性相结合来设计症状网络的有效干预措施。

    载入资料

    我们加载提供的数据:

    
    data <- as.matrix(data)
    p <- ncol(data)
    dim(data)
    ## [1] 312  17

    数据集包含对344人的17种PTSD症状的完整反应。症状强度的答案类别范围从1“没有”到5“非常强”。 

    估计网络模型

    我们估计了混合图形模型,其中我们将所有变量都视为连续高斯变量。因此,我们将所有变量的类型设置为,type = 'g'并将每个变量的类别数设置为1:

    
    fit_obj <- (data = data, 
                   type = rep('g', p),
                   level = rep(1, p),
                   lambdaSel = 'CV',
                   ruleReg = 'OR', 
                   pbar = FALSE)
    
    

    计算节点的可预测性

    估计网络模型后,我们准备计算每个节点的可预测性。由于可以通过依次获取每个节点并对其上的所有其他节点进行回归来估计该图,因此可以轻松地计算节点的可预测性)。作为可预测性的度量,我们选择解释的方差的比例:0表示当前节点根本没有被节点中的其他节点解释,1表示完美的预测。我们在估算之前将所有变量中心化,以消除截距的影响。

    有关如何计算预测和选择可预测性度量的详细说明,请查看本文。如果网络中还有其他变量类型(例如分类),我们可以为这些变量选择适当的度量。

    pred_obj <- predict(object = fit_obj, 
                        data = data
    
    pred_obj$error
    ##     Variable    R2
    ## 1  intrusion 0.639
    ## 2     dreams 0.661
    ## 3      flash 0.601
    ## 4      upset 0.636
    ## 5    physior 0.627
    ## 6    avoidth 0.686
    ## 7   avoidact 0.681
    ## 8    amnesia 0.410
    ## 9    lossint 0.520
    ## 10   distant 0.498
    ## 11      numb 0.451
    ## 12    future 0.540
    ## 13     sleep 0.565
    ## 14     anger 0.562
    ## 15    concen 0.638
    ## 16     hyper 0.676
    ## 17   startle 0.626

    我们计算了网络中每个节点的解释方差(R2)的百分比。接下来,我们将估计的网络可视化,并讨论与解释方差有关的结构。

    可视化网络和可预测性

    我们根据估计的加权邻接矩阵和节点的可预测性度量作为参数,进行网络可视化:

    
    graph(fit_obj$pairwise$wadj, # 加权邻接矩阵作为输入
           layout = 'spring', 
           pie = pred_obj$error[,2], # 误差作为饼图的输入
      

     

     

    有关早期研究不同心理障碍症状可预测性的文章,请参见本文

    展开全文
  • 实验结果表明,本网络模型在PASCAL VOC 2007和 PASCAL VOC 2012数据集上进行训练后,在PASCAL VOC 2007测试集上的平均精度均值可达81.0%,检测速度可达85 frame/s,本网络在精度和效率上都达到了很好的效果。
  • 用神经网络确定权重的matlab代码ART-2神经网络和机器监控混合系统 用于在线群集的Matlab工具 这个贡献是实现了ART-2神经网络和监测混合系统的Matlab库,该系统是一个复杂的人工智能系统(ART-2,EMMoG,VBMoG),...
  • 聚结理论下从局部基因谱系推断种群混合网络 GTmix 是一个计算机程序,用于从推断的本地基因谱系推断种群混合网络。 如果您使用 GTmix,请引用: 从本地基因谱系推断种群混合网络:基于聚结的最大似然法,吴宇峰,...
  • 由于实际应用环境中有大量混合流量及产品的处理性能受到...为了评价网络节点的实际处理能力,建立了性能指标测试模型,并给出了网络节点主要参数(吞吐量、混合包的转发能力、新建连接速率等)的测试评估分析及验证实验。
  • 1.混合云环境下的网络安全变化传统IDC环境下,企业业务可能会面临外部互联网的DDOS攻击以及网络层的漏洞扫描和恶意流量攻击等,因此一般会在机房出口处...

    1. 混合云环境下的网络安全变化

    传统IDC环境下,企业业务可能会面临外部互联网的DDOS攻击以及网络层的漏洞扫描和恶意流量攻击等,因此一般会在机房出口处部署抗DDOS流量清洗设备、网络层防火墙设备、网络入侵检测或入侵防御设备、防病毒网关或者统一威胁管理平台等。

    企业使用混合云后,网络层的安全风险和安全控制需求仍然存在,但和传统IDC环境相比,混合云业务部署可能涉及多家IDC、公有云厂商或者自建私有云等情况,导致信息安全需要在多个边界进行安全防护,同时VPC网段和IDC/私有云网段,不同VPC网段之间的通信访问需求,也需要在混合云网络内部不同网段间进行访问控制和流量检测,从而给混合云环境下的网络安全带来更多挑战。

    另外混合云环境下和边界相关的安全问题也包括运维通道相关的VPN和跳板机软硬件产品,可通过SDP产品和多云管理平台如TiOPS产品进行替换,在此不做过多解释。

    2.  混合云环境下的网络安全技术

    根据对传统网络安全的理解,混合云环境安全特性,以及对多家公有云厂商的安全产品调研,我们发现混合云环境下的网络安全技术主要包括包括DDOS流量清洗、高防IP、云防火墙、网络入侵检测系统或网络入侵防御系统、虚拟交换机ACL规则、云主机安全组等。

    DDOS流量清洗,主要用于防御互联网上的DDOS攻击行为,部署在企业云业务和互联网边界处。

    高防IP,用户在业务在遭受大流量DDoS攻击时,可通过配置高防IP,将攻击流量引流到云厂商提供的高防IP地址,对攻击流量进行清洗过滤后再将正常流量转发到源站IP,从而确保源站IP稳定访问。

    云防火墙,主要用于实现互联网和VPC、VPC和VPC之间的网络访问控制和网络安全。一些公有云厂商也会在云防火墙上集成NIPS、防病毒、用户身份认证管理等功能。

    网络入侵检测/入侵防御系统,主要用于对网络流量进行检查并基于规则进行告警或阻断。

    虚拟交换机ACL规则,主要用于VPC内子网间的访问控制。

    安全组,一种虚拟防火墙,具备状态检测和数据包过滤能力,用于实现云主机间网络层的访问控制。

     

    3.  公有云厂商网络安全技术比较

    不同公有云厂商在网络安全方面一般都会提供包括安全组、虚拟交换机ACL访问控制、DDOS流量清洗或高防IP等基础的网络安全服务。部分成熟的公有云厂商,也会提供云防火墙、网络入侵检测/入侵防御系统或防病毒等网络安全服务。

    云厂商名称

    网络层安全技术/服务

    简要说明

     

    阿里云

    DDOS高防IP

    国内清洗中心超过8个,单中心带宽大于1T,10T+总防御带宽。电信、联通、移动、教育等20线独家防御

    云防火墙

    南北4-7层流量和东西4层流量的控制检测

    实现IPS,实时流量监控,虚拟补丁功能

    集成安全组功能进行统一管理

    腾讯云

    DDOS防护

    免费基础防护,高防IP等

    云防火墙

    提供互联网边界、VPC 边界的网络访问控制

    网络入侵防护系统

    通过旁路部署方式,无变更无侵入地对网络4层会话进行实时阻断

    样本智能分析平台

    恶意样本智能分析鉴定平台,支持常见可执行文件(包括32位和64位)、脚本、文档、压缩包、ELF 文件、APK 文件等多种,帮助检测恶意文件、后门、APT攻击等

    高级威胁检测系统

    采用镜像流量旁路进行检测

    天翼云

    Anti-DDoS流量清洗

    Anti-DDoS服务作为安全服务的基础服务,目前属于免费服务。

    DDoS高防IP

    付费增值服务

    云下一代防火墙

    通过虚拟机方式部署,可串联或单臂连接到虚拟网络中(如:虚拟应用服务器前端的网关,或者是VPC网络的边界网关)。集成用户认证、访问控制、入侵防御、病毒过滤、授权管理等多种功能

    华为云

    Anti-DDoS流量清洗

    免费提供基础DDoS 防护,防护能力最高可达5Gbps。本服务默认开启

    DDoS高防AAD

    10+清洗节点,8T+ DDoS高防总体防御能力,单用户T级防御能力,抵御各类网络层、应用层DDoS/CC攻击

    百度智能云

    流量审计分析IDS

    云上旁路入侵检测

    DDOS防护服务

    DDoS防护服务为百度智能云上客户提供5Gb的免费DDoS防护能力。当业务遭受超过5Gb的DDoS攻击时,可以将攻击流量引向高防中心

    浪潮云

    DDOS高防

    适用区域:华北一、华北二

    Ucloud

    DDOS攻击防护

    针对IP进行海量DDoS清洗能力

    金山云

    高防IP

    防护能力按次购买,100G包年仅需28000

     

    4.  混合云环境下的网络分层防护方案

     

    混合云环境下,企业可以使用综合考虑各个云厂商自身提供的网络层安全服务以及云安全市场中其他安全厂商提供的网络产品或服务,从边界DDOS防护、边界云防火墙、VPC间防火墙、虚拟子网间访问控制及云主机间的访问控制等多个层次,构建企业混合云业务的网络层纵深防御体系。

     

     

    l互联网边界处,使用DDOS清洗服务或高防IP,过滤DDOS攻击;

    l互联网边界处,使用云防火墙和IPS技术,实现网络层访问控制、流量监控告警和入侵防护功能,包括不公有同云厂商集成提供的暴力破解、虚拟补丁、信息窃取、防病毒等功能;

    lVPC和VPC边界处,部署VPC边界防火墙,对VPC之间的访问和流量进行管理;

    lVPC内不同网段间,可使用虚拟交换机策略,管理同一VPC内不同子网间的访问;

    l云主机之间,使用安全组策略,管理同一VPC内不同云主机之间的访问;

     

     

     

    5.  混合云环境下的网络安全挑战和应对

    混合云环境下,因为应用系统部署、应用架构调用、业务数据流转及使用人员的复杂性,导致安全人员难以追溯并理清楚各类访问需求和访问路径,无法在用户和应用访问路径的关键节点采取合适的安全防护措施。不过安全仍然可以从以下两方面积极应对:

    1)梳理访问关系

    l梳理IDC、公有云、私有云中各类应用和应用分配的网段;

    l梳理应用、VPC间访问和调用关系并进行分类、分级汇总;

    l梳理使用人员,包括外部业务用户,内部运维、开发、测试,内部业务用户,第三方人员等;

    l梳理使用人员访问各应用的访问路径,并进行分类、分级汇总;

    l明确关键资产的访问对象和访问路径;
     

    2)访问路径的纵深安全控制

    l结合资产价值进行访问路径风险评估,包括现有主要控制措施,补偿性控制措施等;

    l基于纵深安全防御理念,在各个访问通道的关键边界处,进行访问控制、流量检测、攻击流量阻断、虚拟补丁等,同时在访问资产前,加强对用户和访问设备的身份鉴别、权限管理等安全措施。

    l明确混合云环境下的网络安全目标:基于业务/应用/VPC/人员访问需求,在网络层面实现基本的网络隔离和访问控制功能,对访问流量进行检测告警,对异常访问流量进行阻断等。

    l对于一些场景如企业内部员工访问云上SaaS应用,可选择和使用CASB产品对访问资产和路径进行安全控制;

    l考虑使用SDP/ZTNA产品,减少可见攻击面,加强用户身份、设备认证和权限管理,替代VPN访问通道;

     

    展开全文
  • NIHBA(带有混合Benders算法的网络拦截)是一个软件平台,用于识别代谢工程中尽可能多的遗传修饰策略。 它基于基因组规模的代谢模型(GSMM),并将宿主细胞和代谢工程师视为玩游戏的两个不同年龄网络:代谢工程师...
  • 定义多层感知器(MLP)和卷积神经网络(CNN) 使用Keras的多个输入 多输入和混合数据结果 总结 翻译自:Keras: Multiple Inputs and Mixed Data, by Adrian Rosebrock. 摘要 点击此处下载源代码:...

    目录

     

    摘要

    正文

    什么是混合数据?

    Keras如何接受多个输入?

    房价数据集

    获取房价数据集

    项目结构

    加载数值和分类数据

    加载图像数据集

    定义多层感知器(MLP)和卷积神经网络(CNN)

    使用Keras的多个输入

    多输入和混合数据结果

    总结

    翻译自:Keras: Multiple Inputs and Mixed Data, by Adrian Rosebrock.


    摘要

    点击此处下载源代码:https://jbox.sjtu.edu.cn/l/NHfFZu

    以回归预测房价作为背景。房价数据集不仅包括数值类别数据,同样也包括图像数据,称之为多种类型的混合数据。模型需要能够接受多种类型的混合数据输入,并且计算得出回归问题的输出值。

    在本教程的其余部分,您将学习如何:

    1. 定义一个Keras模型,该模型能够同时接受多个类型的输入数据,包括数值、类别和图像等类型的数据。
    2. 在混合数据输入上训练端到端的Keras模型。
    3. 使用多个输入来评估我们的模型。

    正文

    在本教程的第一部分中,我们将简要回顾混合数据的概念以及Keras如何接受多个类型输入数据

    什么是混合数据?

    在这里插入图片描述

    图1:使用灵活的Keras深度学习框架,可以定义一个多输入模型,其分别包括CNN和MLP分支来分别处理混合数据。

    混合数据指的是同时使用不同数据类型的输入数据。
    例如,假设我们是在一家医院工作的机器学习工程师,要开发一个能够对病人的健康状况进行分类的系统。
    我们拥有一个病人的多种类型的输入数据,包括:

    1. 数值/连续值,如年龄、心率、血压
    2. 类别值,包括性别和种族
    3. 图像数据,如MRI、x片等。

    我们的机器学习模型必须能够将这些**“混合数据”**,并对病人的健康状况做出(准确的)预测。

    开发能够处理混合数据的机器学习系统非常具有挑战性,因为每种数据类型可能需要单独的预处理步骤,包括缩放、标准化和特征工程(feature engineering)。

    处理混合数据仍然是一个非常开放的研究领域,并且常常严重依赖于特定的任务/目标。

    Keras如何接受多个输入?

    Keras能够通过它的函数API处理多个输入(甚至多个输出)。

    您以前肯定通过Sequential 类使用过顺序式API,函数式API与之相反相反,可用于定义非顺序的复杂得多的模型,包括:

    • 多输入模型
    • 多输出模型
    • 模型包括多个输入和多个输出
    • 有向无环图
    • 具有共享层的模型

    例如,我们可以将一个简单的序列神经网络定义为:

    model = Sequential()
    model.add(Dense(8, input_shape=(10,), activation="relu"))
    model.add(Dense(4, activation="relu"))
    model.add(Dense(1, activation="linear"))

    该网络是一个简单的前馈神经网络,有10个输入,第一个隐层有8个节点,第二个隐层有4个节点,最后一个输出层用于回归。

    我们可以使用functional API定义样本神经网络:

    inputs = Input(shape=(10,))
    x = Dense(8, activation="relu")(inputs)
    x = Dense(4, activation="relu")(x)
    x = Dense(1, activation="linear")(x)
    model = Model(inputs, x)
    
    # define two sets of inputs
    inputA = Input(shape=(32,))
    inputB = Input(shape=(128,))
     
    # the first branch operates on the first input
    x = Dense(8, activation="relu")(inputA)
    x = Dense(4, activation="relu")(x)
    x = Model(inputs=inputA, outputs=x)
     
    # the second branch opreates on the second input
    y = Dense(64, activation="relu")(inputB)
    y = Dense(32, activation="relu")(y)
    y = Dense(4, activation="relu")(y)
    y = Model(inputs=inputB, outputs=y)
     
    # combine the output of the two branches
    combined = concatenate([x.output, y.output])
     
    # apply a FC layer and then a regression prediction on the
    # combined outputs
    z = Dense(2, activation="relu")(combined)
    z = Dense(1, activation="linear")(z)
     
    # our model will accept the inputs of the two branches and
    # then output a single value
    model = Model(inputs=[x.input, y.input], outputs=z)

    可以看到我们定义了Keras神经网络的两个输入:

    • inputA: 32维
    • inputB: 128维

    可视化模型架构为:

    在这里插入图片描述

    图2:这个模型有两个输入分支,它们最终合并并产生一个输出。Keras函数API允许这种类型的体系结构,你也可以构建任何其他您可以想象的架构。

    注意我们的模型有两个不同的分支。

    第一个分支接受128维输入,而第二个分支接受32维输入。这些分支在连接之前彼此独立运行,连接之后输出一个值。
    在本教程的其余部分中,您将学习如何使用Keras创建多输入的网络。

    房价数据集

    在这里插入图片描述

    图4:房价数据集包括数值数据,类别数据和图像数据。使用Keras,我们将构建一个支持多种输入和混合数据类型的模型,并且通过这个回归模型预测房屋的价值。

    在这一系列文章中,我们使用了Ahmed和Mustafa在2016年发表的论文《从视觉和文本特征估计房价》(House price estimate from visual and text features)中的房价数据集。

    这个数据集包括535个示例房屋的数值数据,类别数据以及图像数据。

    数值属性和分类属性包括:

    1. 数量的卧室
    2. 数量的浴室
    3. 区域(面积)
    4. 邮政编码

    每栋房子一共提供了四幅图片:

    1. 卧室
    2. 浴室
    3. 厨房
    4. 房子的正面

    在本系列的第一篇文章中,您学习了如何根据数值和分类数据训练Keras回归网络。
    在本系列的第二篇文章中,您学习了如何使用Keras CNN进行回归。
    今天我们将使用Keras处理多个输入和混合数据。

    我们将接受数值数据,类别数据和图像数据,通过定义网络的两个分支来处理每种类型的数据,最后将这些分支合并起来,得到我们最终的房价预测。通过这种方式,我们将能够利用Keras处理多个输入和混合数据。

    获取房价数据集

    点击此处下载源代码:https://jbox.sjtu.edu.cn/l/NHfFZu

    房价数据集应该在keras-multi-input目录中,这是我们在这个项目中使用的目录。

    项目结构

    $ tree --dirsfirst --filelimit 10
    .
    ├── Houses-dataset
    │   ├── Houses\ Dataset [2141 entries]
    │   └── README.md
    ├── pyimagesearch
    │   ├── __init__.py
    │   ├── datasets.py
    │   └── models.py
    └── mixed_training.py
     
    3 directories, 5 files

    Houses-dataset文件夹包含我们在本系列中使用的房价数据集。当我们准备好运行mixed_training.py脚本时,您只需要提供一个路径作为数据集的命令行参数(我将在结果部分向您详细说明这是如何完成的)。

    今天我们将回顾三个Python脚本:

    • pyimagesearch/datasets.py: 加载和预处理我们的数字数据,类别数据以及图像数据。

    • pyimagesearch/models.py: 包含多层感知器(MLP)和卷积神经网络(CNN)。这些组件是我们的多输入混合数据模型的输入分支。

    • mixed_training.py: 首先我们的训练脚本将使用pyimagesearch模块来加载和分割训练数据集,添加数据头,并将两个分支连接到我们的网络。然后对模型进行培训和评估。

    加载数值和分类数据

    # import the necessary packages
    from sklearn.preprocessing import LabelBinarizer
    from sklearn.preprocessing import MinMaxScaler
    import pandas as pd
    import numpy as np
    import glob
    import cv2
    import os
     
    def load_house_attributes(inputPath):
    	# initialize the list of column names in the CSV file and then
    	# load it using Pandas
    	cols = ["bedrooms", "bathrooms", "area", "zipcode", "price"]
    	df = pd.read_csv(inputPath, sep=" ", header=None, names=cols)
     
    	# determine (1) the unique zip codes and (2) the number of data
    	# points with each zip code
    	zipcodes = df["zipcode"].value_counts().keys().tolist()
    	counts = df["zipcode"].value_counts().tolist()
     
    	# loop over each of the unique zip codes and their corresponding
    	# count
    	for (zipcode, count) in zip(zipcodes, counts):
    		# the zip code counts for our housing dataset is *extremely*
    		# unbalanced (some only having 1 or 2 houses per zip code)
    		# so let's sanitize our data by removing any houses with less
    		# than 25 houses per zip code
    		if count < 25:
    			idxs = df[df["zipcode"] == zipcode].index
    			df.drop(idxs, inplace=True)
     
    	# return the data frame
    	return df

    load_house_attributes函数。该函数通过pandapd以CSV文件的形式从房价数据集中读取数值和类别数据。

    原始数据需要经过过滤以适应样本分布的不均匀性。如有些邮编仅由1或2所房子表示,因此我们要删除(第23-30行)来自邮编少于25所房子的任何记录。这样邮编样本数量分布不均匀的问题可以得到缓解,这样做的结果是得到一个更精确的模型。

    定义process_house_attributes函数:

    def process_house_attributes(df, train, test):
    	# initialize the column names of the continuous data
    	continuous = ["bedrooms", "bathrooms", "area"]
     
    	# performin min-max scaling each continuous feature column to
    	# the range [0, 1]
    	cs = MinMaxScaler()
    	trainContinuous = cs.fit_transform(train[continuous])
    	testContinuous = cs.transform(test[continuous])
     
    	# one-hot encode the zip code categorical data (by definition of
    	# one-hot encoding, all output features are now in the range [0, 1])
    	zipBinarizer = LabelBinarizer().fit(df["zipcode"])
    	trainCategorical = zipBinarizer.transform(train["zipcode"])
    	testCategorical = zipBinarizer.transform(test["zipcode"])
     
    	# construct our training and testing data points by concatenating
    	# the categorical features with the continuous features
    	trainX = np.hstack([trainCategorical, trainContinuous])
    	testX = np.hstack([testCategorical, testContinuous])
     
    	# return the concatenated training and testing data
    	return (trainX, testX)

    这个函数通过scikit-learnMinMaxScaler(第41-43行)对连续特性应用最小-最大缩放。
    然后,通过scikit-learnLabelBinarizer(第47-49行)计算分类特征的one-hot编码。
    然后将连续的和分类的特性连接起来并返回

    加载图像数据集

    在这里插入图片描述

    图6:我们模型的一个分支接受一个图像——来自房屋的四个图像的拼合图像。利用拼合图像结合数字,类别数据,输入到另一个分支,然后我们的模型使用Keras框架回归与预测住宅的价值。

    下一步是定义一个helper函数来加载输入图像。同样,打开data .py文件并插入以下代码:

    def load_house_images(df, inputPath):
    	# initialize our images array (i.e., the house images themselves)
    	images = []
     
    	# loop over the indexes of the houses
    	for i in df.index.values:
    		# find the four images for the house and sort the file paths,
    		# ensuring the four are always in the *same order*
    		basePath = os.path.sep.join([inputPath, "{}_*".format(i + 1)])
    		housePaths = sorted(list(glob.glob(basePath)))

    load_house_images函数有三个功能:

    1. 从房价数据集中加载所有照片。回想一下,我们每个房子有四张照片(图6)。
    2. 从四张照片生成一个单一的拼合图像。拼合图像总是按照你在图中看到的那样顺序排列。
    3. 将所有这些主蒙版添加到列表/数组中并返回到调用函数。

    继续:

    • 初始化图像列表(第61行)并将用我们创建的所有拼合图像填充这个列表。
    • 循环遍历数据帧中的房屋(第64行)以获取当前住宅的四张照片的路径

    循环内部:

    	# initialize our list of input images along with the output image
    		# after *combining* the four input images
    		inputImages = []
    		outputImage = np.zeros((64, 64, 3), dtype="uint8")
     
    		# loop over the input house paths
    		for housePath in housePaths:
    			# load the input image, resize it to be 32 32, and then
    			# update the list of input images
    			image = cv2.imread(housePath)
    			image = cv2.resize(image, (32, 32))
    			inputImages.append(image)
     
    		# tile the four input images in the output image such the first
    		# image goes in the top-right corner, the second image in the
    		# top-left corner, the third image in the bottom-right corner,
    		# and the final image in the bottom-left corner
    		outputImage[0:32, 0:32] = inputImages[0]
    		outputImage[0:32, 32:64] = inputImages[1]
    		outputImage[32:64, 32:64] = inputImages[2]
    		outputImage[32:64, 0:32] = inputImages[3]
     
    		# add the tiled image to our set of images the network will be
    		# trained on
    		images.append(outputImage)
     
    	# return our set of images
    	return np.array(images)

    到目前为止,代码已经完成了上面讨论的第一个目标(每个房子抓取四个图像)。

    • 在循环中,我们:

      • 执行初始化(第72行和第73行)。我们的inputImages将以列表的形式包含每条记录的四张照片。我们的inputImages将是照片的拼接图像(如图6所示)。

      • 循环4张照片(第76行):

        • 加载、调整大小并将每张照片附加到 inputImages中(第79-81行)。
      • 为四个房子的图片(第87-90行)创建平铺(拼接图像):

        • 左上方的浴室图片。
        • 右上角的卧室图片。
        • 右下角的正面视图。
        • 厨房在左下角。
      • 添加拼接outputImageimages(第94行)。

    • 跳出循环,我们以NumPy数组的形式返回所有图像(第97行)。

    定义多层感知器(MLP)和卷积神经网络(CNN)

    在这里插入图片描述

    图7:Keras多输入(混合数据)模型有一个分支接受数字/类别数据(左),另一个分支接受4张照片拼接形式的图像数据(右)。

    到目前为止,我们已经使用了多个库对数据进行了仔细的处理:panda、scikit-learn、OpenCV和NumPy
    我们已经通过datasets.py对数据集的两种模式进行了组织和预处理。

    • 数字和分类数据
    • 图像数据

    为了实现这一点,我们所使用的技能是通过经验和实践一点点调试开发出来的。请不要忽视我们到目前为止所讨论和使用的数据处理技巧,因为它是我们项目成功的关键。

    让我们换个话题,讨论一下我们将如何使用Keras的函数API构建的多输入和混合数据网络。

    为了建立我们的多输入网络,我们需要两个分支:

    • 第一个分支是一个简单的多层感知器(MLP),用于处理数值输入。
    • 第二个分支是卷积神经网络,用于对图像数据进行操作。
    • 然后将这些分支连接在一起,形成最终的多输入Keras模型。

    我们将在下一节中处理构建最终的连接多输入模型,我们当前的任务是定义这两个分支。

    打开models.py文件,插入如下代码:

    # import the necessary packages
    from keras.models import Sequential
    from keras.layers.normalization import BatchNormalization
    from keras.layers.convolutional import Conv2D
    from keras.layers.convolutional import MaxPooling2D
    from keras.layers.core import Activation
    from keras.layers.core import Dropout
    from keras.layers.core import Dense
    from keras.layers import Flatten
    from keras.layers import Input
    from keras.models import Model
     
    def create_mlp(dim, regress=False):
    	# define our MLP network
    	model = Sequential()
    	model.add(Dense(8, input_dim=dim, activation="relu"))
    	model.add(Dense(4, activation="relu"))
     
    	# check to see if the regression node should be added
    	if regress:
    		model.add(Dense(1, activation="linear"))
     
    	# return our model
    	return model

    我们的类别/数值数据将由一个简单的多层感知器(MLP)处理。
    MLP由create_mlp定义。
    我们的MLP很简单:

    • 具有ReLU激活的完全连接(密集)输入层
    • 一个完全连接的隐藏层,也带有ReLU激活
    • 最后,一个线性激活的可选的回归输出

    虽然我们在第一篇文章中使用了MLP的回归输出,但是在这个多输入混合数据网络中不会使用它。您很快就会看到,我们将显式地设置regress=False,即使它也是默认值。稍后将在整个多输入混合数据网络的头部执行回归

    根据图7,我们现在已经构建了网络的左上分支。

    现在让我们来定义我们网络的右上角分支,CNN:

    def create_cnn(width, height, depth, filters=(16, 32, 64), regress=False):
    	# initialize the input shape and channel dimension, assuming
    	# TensorFlow/channels-last ordering
    	inputShape = (height, width, depth)
    	chanDim = -1
    	
    	# define the model input
    	inputs = Input(shape=inputShape)
     
    	# loop over the number of filters
    	for (i, f) in enumerate(filters):
    		# if this is the first CONV layer then set the input
    		# appropriately
    		if i == 0:
    			x = inputs
     
    		# CONV => RELU => BN => POOL
    		x = Conv2D(f, (3, 3), padding="same")(x)
    		x = Activation("relu")(x)
    		x = BatchNormalization(axis=chanDim)(x)
    		x = MaxPooling2D(pool_size=(2, 2))(x)

    create_cnn函数处理图像数据并接受五个参数:

    • 宽度:输入图像的宽度,单位为像素。
    • 高度:输入图像的高度,单位为像素。
    • 深度:输入图像中的通道数。对于RGB彩色图像,它是3。
    • 过滤器:一组逐渐变大的过滤器,使我们的网络可以学习更多的区分功能。
    • 回归:一个布尔值,指示是否将一个完全连接的线性激活层添加到CNN以进行回归。

    从这里开始,我们开始遍历过滤器并创建一组CONV => RELU > BN =>POOL 层。循环的每次迭代都会累加这些层。

    让我们完成CNN网络分支的建设:

    # flatten the volume, then FC => RELU => BN => DROPOUT
    	x = Flatten()(x)
    	x = Dense(16)(x)
    	x = Activation("relu")(x)
    	x = BatchNormalization(axis=chanDim)(x)
    	x = Dropout(0.5)(x)
     
    	# apply another FC layer, this one to match the number of nodes
    	# coming out of the MLP
    	x = Dense(4)(x)
    	x = Activation("relu")(x)
     
    	# check to see if the regression node should be added
    	if regress:
    		x = Dense(1, activation="linear")(x)
     
    	# construct the CNN
    	model = Model(inputs, x)
     
    	# return the CNN
    	return model

    我们将下一层压平,意味着我们将所有提取到的特征组成一维特征向量,然后添加一个带有BatchNormalization和Dropout的全连接层。

    另一个全连接层用于匹配来自多层感知器的四个节点。匹配节点的数量不是必需的,但它确实有助于平衡分支。

    检查是否添加回归节点,如果需要就相应地将其添加进来。实际上,我们不会在这个分支的末尾进行回归。回归将在多输入混合数据网络的头部执行(图7的最底部)。

    最后,模型由我们的输入和组装在一起的所有层组成。我们可以将CNN分支返回到调用函数(第68行)。

    现在我们已经定义了多输入Keras模型的两个分支,让我们学习如何组合它们!

    使用Keras的多个输入

    现在,我们准备构建最终的Keras模型,该模型能够处理多个输入和混合数据。这是分支聚集的地方——“魔法”发生的地方。
    训练也将在这个脚本中进行。

    创建一个名为mixed_training.py的新文件,打开它,并插入以下代码:

    # import the necessary packages
    from pyimagesearch import datasets
    from pyimagesearch import models
    from sklearn.model_selection import train_test_split
    from keras.layers.core import Dense
    from keras.models import Model
    from keras.optimizers import Adam
    from keras.layers import concatenate
    import numpy as np
    import argparse
    import locale
    import os
     
    # construct the argument parser and parse the arguments
    ap = argparse.ArgumentParser()
    ap.add_argument("-d", "--dataset", type=str, required=True,
    	help="path to input dataset of house images")
    args = vars(ap.parse_args())

    首先,让我们导入必要的模块并且解析命令行参数。

    • datasets: 我们的三个方便的功能,从房屋数据集加载/处理CSV数据和加载/预处理房屋照片。
    • models: 我们的MLP和CNN输入分支,它们将作为我们的多输入混合数据服务。
    • train_test_split: 一个scikit-learn函数,用于构造我们的训练/测试数据分割。
    • concatenate: 一个特殊的Keras函数,它将接受多个输入。
    • argparse: 处理解析命令行参数。

    在第15-18行中,我们有一个命令行参数需要解析,即dataset,它是您下载房价数据集的路径。

    接下来,让我们加载我们的数值/分类数据和图像数据:

    # construct the path to the input .txt file that contains information
    # on each house in the dataset and then load the dataset
    print("[INFO] loading house attributes...")
    inputPath = os.path.sep.join([args["dataset"], "HousesInfo.txt"])
    df = datasets.load_house_attributes(inputPath)
     
    # load the house images and then scale the pixel intensities to the
    # range [0, 1]
    print("[INFO] loading house images...")
    images = datasets.load_house_images(df, args["dataset"])
    images = images / 255.0

    在这里,我们将房价数据集加载为panda dataframe(第23行和第24行)。然后我们加载图像并将其缩放到 [0,1] (第29-30行)。
    如果需要提醒您这些函数的底层功能,请务必查看上面的load_house_attributesload_house_images函数。
    现在我们的数据已经加载完毕,我们将构建我们的培训/测试分割,调整价格,并处理房屋属性:

    # partition the data into training and testing splits using 75% of
    # the data for training and the remaining 25% for testing
    print("[INFO] processing data...")
    split = train_test_split(df, images, test_size=0.25, random_state=42)
    (trainAttrX, testAttrX, trainImagesX, testImagesX) = split
     
    # find the largest house price in the training set and use it to
    # scale our house prices to the range [0, 1] (will lead to better
    # training and convergence)
    maxPrice = trainAttrX["price"].max()
    trainY = trainAttrX["price"] / maxPrice
    testY = testAttrX["price"] / maxPrice
     
    # process the house attributes data by performing min-max scaling
    # on continuous features, one-hot encoding on categorical features,
    # and then finally concatenating them together
    (trainAttrX, testAttrX) = datasets.process_house_attributes(df,
    	trainAttrX, testAttrX)

    我们的训练和测试是在第35行和第36行进行的。我们分配了75%的数据用于培训,25%的数据用于测试。

    在此基础上,我们从培训集(第41行)中找到maxPrice,并相应地调整培训和测试数据(第42行和第43行)。将价值数据调整到[0,1]范围内,可以更好地训练和收敛。

    最后,我们通过对连续特征执行最小-最大缩放和对分类特征执行一次热编码继续处理我们的房子属性。

    process_house_attributes函数处理这些操作,并将连续的和分类的特性连接在一起,返回结果(第48行和第49行)。

    准备好施魔法了吗?
    好吧,我说谎了。在下一个代码块中实际上没有任何“魔力”!但我们将连接我们的网络分支,完成我们的多输入Keras网络:

    # create the MLP and CNN models
    mlp = models.create_mlp(trainAttrX.shape[1], regress=False)
    cnn = models.create_cnn(64, 64, 3, regress=False)
     
    # create the input to our final set of layers as the *output* of both
    # the MLP and CNN
    combinedInput = concatenate([mlp.output, cnn.output])
     
    # our final FC layer head will have two dense layers, the final one
    # being our regression head
    x = Dense(4, activation="relu")(combinedInput)
    x = Dense(1, activation="linear")(x)
     
    # our final model will accept categorical/numerical data on the MLP
    # input and images on the CNN input, outputting a single value (the
    # predicted price of the house)
    model = Model(inputs=[mlp.input, cnn.input], outputs=x)

    当您组织好代码和模型后,使用Keras处理多个输入是非常容易的。

    在第52行和第53行,我们创建mlp和cnn模型。注意regress=False——我们的回归头出现在第62行后面。

    然后我们将连接mlp输出和cnn输出如第57行所示。我将其称为我们的combinedInput,因为它是网络其余部分的输入(从图3中可以看到,这是concatenate_1,两个分支在一起)。

    网络中最后一层的组合输入是基于MLP和CNN分支的 8-4-1 FC层的输出(因为这两个分支都输出4维 FC层,然后我们将它们连接起来创建一个8维向量)。

    我们将一个由四个神经元组成的完全连接的层固定在combinedInput上(第61行)。然后我们添加“lineractivation回归头(第62行),其输出为预测价格。

    让我们继续编译、培训和评估我们新形成的模型:

    # compile the model using mean absolute percentage error as our loss,
    # implying that we seek to minimize the absolute percentage difference
    # between our price *predictions* and the *actual prices*
    opt = Adam(lr=1e-3, decay=1e-3 / 200)
    model.compile(loss="mean_absolute_percentage_error", optimizer=opt)
     
    # train the model
    print("[INFO] training model...")
    model.fit(
    	[trainAttrX, trainImagesX], trainY,
    	validation_data=([testAttrX, testImagesX], testY),
    	epochs=200, batch_size=8)
     
    # make predictions on the testing data
    print("[INFO] predicting house prices...")
    preds = model.predict([testAttrX, testImagesX])

    我们的模型是用“mean_absolute_percentage_error”损失和一个Adam优化器编译的,该优化器具有学习率衰减(第72行和第73行)。

    训练在第77-80行开始。这就是所谓的模型拟合(也就是所有权重都由称为反向传播的过程进行调优的地方)。

    通过对测试数据集调用model.predict(第84行)可以获取模型预测的房屋价值来评估我们的模型。

    现在让我们进行评估:

    # compute the difference between the *predicted* house prices and the
    # *actual* house prices, then compute the percentage difference and
    # the absolute percentage difference
    diff = preds.flatten() - testY
    percentDiff = (diff / testY) * 100
    absPercentDiff = np.abs(percentDiff)
     
    # compute the mean and standard deviation of the absolute percentage
    # difference
    mean = np.mean(absPercentDiff)
    std = np.std(absPercentDiff)
     
    # finally, show some statistics on our model
    locale.setlocale(locale.LC_ALL, "en_US.UTF-8")
    print("[INFO] avg. house price: {}, std house price: {}".format(
    	locale.currency(df["price"].mean(), grouping=True),
    	locale.currency(df["price"].std(), grouping=True)))
    print("[INFO] mean: {:.2f}%, std: {:.2f}%".format(mean, std))

    为了评估我们的模型,我们计算了绝对百分比(第89-91行),并使用它得出了最终的度量标准(第95和96行)。
    这些度量(价格平均值、价格标准差和绝对百分比的平均值以及标准差)将以合适的格式(第100-103行)打印到终端。

    多输入和混合数据结果

    在这里插入图片描述

    图8:房地产价格预测是一项困难的任务,但是我们的Keras多输入和混合输入回归模型在我们有限的房价数据集上产生了比较好的结果。

    最后,我们在混合数据上训练我们的多输入网络!

    确保你准备好了:

    1. 根据本系列的第一个教程配置开发环境。
    2. 使用本教程的源代码。
    3. 使用上面“获取房价数据集”一节中的说明下载房价数据集。

    在此基础上,打开终端,执行以下命令,开始网络训练:

    $ python mixed_training.py --dataset Houses-dataset/Houses\ Dataset/

    我们的平均绝对百分比误差开始非常高,但在整个培训过程中不断下降。
    在训练结束时,我们得到了22.41%的测试集绝对误差,这意味着我们的网络对房价的预测平均会下降22%左右。

    我们将这个结果与本系列之前的两篇文章进行比较:

    1. 仅对数值/分类数据使用MLP: 26.01%
    2. 仅用CNN对图像数据:56.91%
    3. 使用混合数据:22.41%

    如你所见,处理混合数据的方法如下:

    1. 结合我们的数字/l类别数据和图像数据
    2. 对混合数据进行多输入模型的训练。
    3. 带来了一个性能更好的模型!

    总结

    在本教程中,您学习了如何定义能够接受多个输入的Keras网络。

    您还学习了如何使用Keras处理混合数据。

    为了实现这些目标,我们定义了一个能够接受的多输入神经网络:

    • 数值数据
    • 分类数据
    • 图像数据

    在训练前,将数值数据的min-max缩放到[0,1]范围。我们的类别数据是one-hot编码的(确保得到的整数向量在[0,1]范围内)。

    然后将数值和类别数据连接成一个特征向量,形成Keras网络的第一个输入。

    我们的图像数据也被缩放到范围[0,1]——这些数据作为Keras网络的第二个输入。

    模型的一个分支包含严格的全连通层(对于连接的数值和类别数据),而多输入模型的第二个分支本质上是一个小的卷积神经网络。

    将两个分支的输出组合起来,定义一个输出(回归预测)。

    通过这种方式,我们能够训练我们的多个输入网络端到端,从而获得比仅使用其中一个输入更好的准确性。

    翻译自:Keras: Multiple Inputs and Mixed Data, by Adrian Rosebrock.

    展开全文
  • “黑客”必用兵器之“网络工具”

    千次阅读 多人点赞 2018-11-30 16:02:55
    “黑客”必用兵器之“网络工具” 在之前的文章里讲到过网络通信原理、网络协议端口、漏洞扫描等网络相关知识,很多网友看到这些文章以后都说写的不错,但是阅读后感觉还是做不到深刻理解,今天我就教大家一个...
  • 欢迎使用Markdown编辑器 在本教程中,您将学习如何将Keras用于多输入和混合数据...然后,我们将在此混合数据上训练单个端到端网络。 今天是我们三部分系列文章的最后一篇Keras和回归: 基本回归Keras训练Keras CNN...
  • 对抗网络之目标检测应用:A-Fast-RCNN

    千次阅读 2017-08-05 00:21:16
    对抗网络之目标检测应用:A-Fast-RCNN 论文:A-Fast-RCNN: Hard Positive Generation via Adversary for Object Detection 【点击下载】 Caffe代码:【Github】一. 深度学习正确的打开方式 深度学习的根基在于...
  • 用iperf测试网络和延迟

    万次阅读 2015-07-20 18:03:00
    【安装】 yum install iperf 或 apt...【TCP测试】 server端示例: iperf -s -i 1 client端示例: iperf -c $SERVIP -M $MSS -t $TIMELEN -i 1 TCP测试在一段时间内的传输量。得到传输带宽。需要模拟实际应
  • 上表报告了在不同实验设置下对测试集的混合注意力和不混合注意力的原型网络的准确性。我们将原始的原型网络命名为“Proto”。“Proto- IATT”、“Proto- FATT”和“Proto- HATT”分别是实例级、特征级和混合注意的...
  • 1.1 进入聊天室1.2 发送信息测试是否连接1.3 分析聊天信息发送出的ip地址1.4 启动wireshark选择对应的网络进行抓2. 测试分析2.1 西文字符测试2.2 中文字符测试2.3 混合字符测试二、总结三、参考 一、抓分析...
  • PyTorch-混合精度训练

    千次阅读 2021-01-17 16:13:05
    介绍如何使用PyTorch自带的amp模块进行混合精度训练。
  • How To Set Up a Capture 1. 确保你做的事是被允许的!  (1)意思是在不违反法律的情况下抓取可以被允许抓取的。... (1)权限的设置,你是否有权限去获取... (3)你系统的时间时区应该设置正确,抓的时间
  • 今天flutter build apk打包了一个release.apk,在真机上安装后网络数据都不显示,但是在模拟器上没问题,然后又连接真机开debug各种测试,一切都正常!那这会是什么问题呢? 查找搜了一些资料,发现问题所在,...
  • 来源:新智元本文约5000字,建议阅读10+分钟本文提出的混合时空图卷积网络,利用导航数据大大提升了时空预测的效果。[ 导读]时空预测在天气预报、运输规划等领域有着重要的应用价值。交通...
  • 混合模型针对其他传统预测财务模型进行了测试,例如完整历史模型、恒定相关模型、单指数模型和多组模型。 在我们的实证研究中,ARIMA-LSTM 模型的预测能力明显优于所有其他金融模型。 我们的工作意味着值得考虑使用 ...
  • 测试了一种以异步动态系统为模型的具有网络引起的延迟和丢网络控制系统,并基于鲁棒性故障,使用混合系统技术分析了具有传感器故障和执行器故障的网络控制系统的完整性设计。容忍控制理论。 基于线性矩阵不等式...
  • 原型混合模型 该代码用于欧洲计算机视觉会议(ECCV 2020)上的论文“”。 PMM架构: RPMMS体系结构: 概述 该代码包含两种称为PMM和RPMM的方法。您可以在Pascal voc或COCO数据集上对它们进行训练或测试。 将实验...
  • 第4章 Faster R-CNN网络模型设计 4.1 Faster RCN文件结构介绍 本文在介绍具体的训练模型之前,先介绍Faster RCNN的文件结构。如图4.1所示,主要包括了7个文件夹和4个文件。主要的文件夹模块为:caffe-fast-rcnn,...
  • 这篇文章提出了一种基于时间卷积神经网络的时间序列异常检测方法,也是首篇将TCN应用于时间序列异常检测的文章。实验验证了提出的方法的有效性。原论文在文末进行获取。 1 摘要 卷积网络已被证明在提取结构化数据中...
  • 用卷积滤波器matlab代码通过混合网络实现低视力的ECCV学习递归滤波器 2016年10月10日发行。 这些代码基于。 描述 这是ECCV16论文的演示实现:通过混合网络学习用于低级视觉的递归滤波器。 我们提供训练和测试演示,...
  • 极市导读: 本文聚焦于归纳和总结数字图像篡改被动检测方法,对基于特征提取和基于卷积神经网络的两类篡改检测方法进行全面论述,分析其中不足与问题,并讨论了数字图像篡改被动检测技术未来的发展趋势。 目录 0 ...
  • ​ 图神经网络(GNN)如今在社会科学,知识图,化学,物理学,神经科学等的各种应用中得到广泛使用,因此,文献中的论文数量激增。 ​ 但是,在缺乏标准和被广泛采用的基准的情况下,衡量新模型的有效性和
  • 思科 计算机网络 所有测试答案

    万次阅读 多人点赞 2020-06-11 13:38:49
    第一章测试答案 1.在以下哪个场景中推荐使用 WISP? 选择一项: A.城市里的网吧 B.没有有线宽带接入的农村地区的农场 C.任何有多个无线设备的家庭 D.通过有线连接访问 Internet 的大厦公寓 2.一位员工希望以尽可能最...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 98,244
精华内容 39,297
关键字:

网络混合包测试