反演 百度DNS解析规则

Overview

域名系统(DNS)是一种用于 TCP/IP应用程序的分布式数据库,它提供主机名字和IP地址之间的转换及有关电子邮件的选路信息。

通常情况下,我们是先设定DNS解析规则,然后ISP(供应商)依据指定的解析规则进行DNS解析。同样,我们通过测试解析结果,也可以反推DNS解析规则。本文以百度首页为例,分析其DNS解析规则。

DNS地址解析器的核心功能能

  • gethostbyname 主机名–>ip
  • gethostbyaddr ip–主机名

分析方式一:
通过抓包,分析DNS查询和响应报文。每个响应报文对应一条DNS解析规则,通过一条或者多条记录才能完成DNS解析。

分析方式二:
一堆命令,见参考博客。

参考 https://aslibra.com/blog/post/use_dig_dns_check.php
通过dig命令理解DNS
dig挖出DNS的秘密

百度DNS解析规则

编号 主机记录 记录类型 解析线路(isp) 记录值 TTL值(不定) 备注
1 www.baidu.com CNAME www.a.shifen.com 268
2 www.a.shifen.com CNAME www.wshifen.com 271
3 www.wshifen.com A 新加坡 百度 45.113.192.101 160 “1-2-[3 4]”
4 www.wshifen.com A 北京电信 220.181.111.188 160
wshifen.com NS ns1.wshifen.com 163 很多name server
baidu.com A 北京移动 111.13.101.208 见解析方式二
baidu.com A 北京联通… 123.125.114.144
baidu.com SOA dns.baidu.com 900 见解析方式四
baidu.com NS ns1.baidu.com
baidu.com NS ns2.baidu.com
dns.baidu.com A 202.108.22.220 67498 这里只有一个A记录吗?为什么TTL这么高?
ns1.baidu.com A 202.108.22.220 27780 为什么和上个记录同IP?
ns2.baidu.com A 61.135.165.235 86400
shifen.com. NS ns1.baidu.com
shifen.com. A 202.108.250.218
shifen.com SOA dns.shifen.com dig shifen.com soa
dns.shifen.com A 202.108.250.228 dig dns.shifen.com
a.shifen.com NS ns1.a.shifen.com 397 见解析方式五
ns1.a.shifen.com A 61.135.165.224 600

注:所有解析路线由ip.cn提供。

www.wshifen.com 没有NS记录,没有SOA记录。
dig www.wshifen.com ns。没有answer,即没有ns记录
dig wshifen.com ns,有answer

解析方式一: 1–>2 (www.baidu.com,查询类型A,即查询IPv4地址)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 一会功夫变成102了
# DNS响应一般为多个ip,后续连接只用一个ip
$ ping www.baidu.com
PING www.wshifen.com (45.113.192.102) 56(84) bytes of data.
64 bytes from 45.113.192.102: icmp_seq=1 ttl=43 time=87.3 ms

$ wget www.baidu.com
--2018-03-08 11:30:32-- http://www.baidu.com/
Resolving www.baidu.com (www.baidu.com)... 45.113.192.102, 45.113.192.101
Connecting to www.baidu.com (www.baidu.com)|45.113.192.102|:80... connected.
HTTP request sent, awaiting response... 200 OK

$ dig www.baidu.com
;; QUESTION SECTION:
;www.baidu.com. IN A

;; ANSWER SECTION:
www.baidu.com. 337 IN CNAME www.a.shifen.com.
www.a.shifen.com. 191 IN CNAME www.wshifen.com.
www.wshifen.com. 110 IN A 45.113.192.102
www.wshifen.com. 110 IN A 45.113.192.101

解析方式二:9 (baidu.com,查询类型A)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 这种域名一般情况下是不能做cname解析的,只能用A记录
$ ping baidu.com
PING baidu.com (111.13.101.208) 56(84) bytes of data.
64 bytes from 111.13.101.208: icmp_seq=1 ttl=45 time=13.8 ms

# DNS中没有对baidu.com做CNAME记录,貌似。
# 为什么浏览器重定向到http://www.baidu.com/? 后面章节会介绍
$ wget baidu.com
--2018-03-08 11:32:10-- http://baidu.com/
Resolving baidu.com (baidu.com)... 111.13.101.208, 220.181.57.216
Connecting to baidu.com (baidu.com)|111.13.101.208|:80... connected.
HTTP request sent, awaiting response... 200 OK

#
$ dig baidu.com
;; QUESTION SECTION:
;baidu.com. IN A

;; ANSWER SECTION:
baidu.com. 345 IN A 111.13.101.208
baidu.com. 345 IN A 220.181.57.216

解析方式三: 1–>5–>8 (www.baidu.com,查询类型AAAA,即查询IPv6地址)

请求路线:

抓包内容

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
# 目前使用IPv6的还是极少数,所以得不到AAAA记录的。
# DNS响应报文中的资源记录部分:回答字段、授权字段和附加信息字段,均采用一种称为资源记录RR( Resource Record)的相同格式。
#
Domain Name System (response)
Questions: 1
Answer RRs: 2
Authority RRs: 1
Additional RRs: 0
Queries
www.baidu.com: type AAAA, class IN
Answers # 回答字段
www.baidu.com: type CNAME, class IN, cname www.a.shifen.com
Name: www.baidu.com
Type: CNAME (Canonical NAME for an alias) (5)
CNAME: www.a.shifen.com
www.a.shifen.com: type CNAME, class IN, cname www.wshifen.com
Name: www.a.shifen.com
Type: CNAME (Canonical NAME for an alias) (5)
Class: IN (0x0001)
Time to live: 271
Data length: 14
CNAME: www.wshifen.com
Authoritative nameservers # 授权字段
wshifen.com: type SOA, class IN, mname ns1.wshifen.com
Name: wshifen.com
Type: SOA (Start Of a zone of Authority) (6)
Primary name server: ns1.wshifen.com baidu_dns_master.baidu.com

dig 内容

1
2
3
4
5
6
7
8
9
10
$ dig www.baidu.com AAAA
;; QUESTION SECTION:
;www.baidu.com. IN AAAA

;; ANSWER SECTION:
www.baidu.com. 4 IN CNAME www.a.shifen.com.
www.a.shifen.com. 174 IN CNAME www.wshifen.com.

;; AUTHORITY SECTION:
wshifen.com. 250 IN SOA ns1.wshifen.com. baidu_dns_master.baidu.com. 1803080001 60 30 2592000 3600

解析方式四:11 (baidu.com,查询类型AAAA)

1
2
3
4
5
6
7
8
9
10
11
Domain Name System (response)
Questions: 1
Answer RRs: 0
Authority RRs: 1
Queries
baidu.com: type AAAA, class IN
Authoritative nameservers
baidu.com: type SOA, class IN, mname dns.baidu.com
Name: baidu.com
Type: SOA (Start Of a zone of Authority) (6)
Primary name server: dns.baidu.com

1
2
3
4
5
6
$ dig baidu.com AAAA
;; QUESTION SECTION:
;baidu.com. IN AAAA

;; AUTHORITY SECTION:
baidu.com. 4581 IN SOA dns.baidu.com. sa.baidu.com. 2012138564 300 300 2592000 7200

解析方式五: 12 (www.a.shifen.com,查询类型AAAA)

1
2
3
4
5
6
7
8
9
$ dig www.a.shifen.com AAAA
;; QUESTION SECTION:
;www.a.shifen.com. IN AAAA

;; ANSWER SECTION:
www.a.shifen.com. 34 IN CNAME www.wshifen.com.

;; AUTHORITY SECTION:
wshifen.com. 235 IN SOA ns1.wshifen.com. baidu_dns_master.baidu.com. 1803080001 60 30 2592000 3600

疑问 & 剖析

编号1中,别名www.a.shifen.com的作用

觉得没啥用啊。看看网上的说法:

  • 使用CNAME有个好处就是,我IP地址去做改动的时候不需要去DNS运营商上面做改动,只需要自己的服务器做改动就好,方便自己的域名与实际IP地址做对应。 –觉得没什么道理啊
  • 百度弄的一个域名保护壳。?
  • CDN加速节点?

逆向思维吧。如果没什么用,为什么要保留呢?是不是还有点作用?

编号2,3中,多条A记录的作用

  • 可用于多线智能解析,为了每条线路(电信、联通/网通、移动等)上的用户都能最快访问站点
  • 可用于简单的负载均衡(dns轮询)
  • 可HA(高可用)

关于返回主机(IP)的策略

考虑的因素有:

当我一个IP到DNS上面请求DNS域名解析的时候,DNS系统会根据你的IP地址所到达的域名对应的IP地址中路由跳数最小的那个IP地址作为访问的IP地址,具体你可以用LINUX的NSLOOKUP来查看域名所对应的IP地址,然后用PC的TRACERT的功能把所有DNS解析出来的IP地址进行跳数记录,然后在访问该域名,查看具体是哪个地址解析给你的PC。

为什么无法直接访问www.a.shifen.com

流程:

  • [1,2,3,4] - DNS解析
  • [5,6,7] - 三次握手,建立TCP连接
  • [8] - 发送HTTP Get请求
  • [9] - 服务器返回RST复位信号,强制关闭TCP连接

服务器成功收到了HTTP Get请求,后台逻辑认为这个连接不符合规范()。所谓baidu定义的规范那应该就是服务器检查host,非baidu.coms就拒绝访问。

抓包貌似看不到整个路由,是吗?如何分析整个路由?

。。

为什么访问 baidu.com 会跳转到 www.baidu.com

baidu.com返回的页面如下:

1
2
3
<html>
<meta http-equiv="refresh" content="0;url=http://www.baidu.com/">
</html>

表示0秒之后跳转到www.baidu.com主页。这种叫做HTML redirections。并非30X 重定向。参考

参考

https://www.zhihu.com/question/36891472/answer/69455356

http://skyrover.me/2017/02/19/BAIDU%E7%9A%84DNS%E8%A7%A3%E6%9E%90/

矢量图的制作

矢量图制作

入门级(并不低级):

  • powerpoint: 首先group元素,然后save as png/emf。如需要svg,可再用Inkscape转化。
  • visio:
  • Inkscape 功能貌似很强大,但我用过它的格式转化功能。实例图片

专业级:

流程图

visio
iGrafx(流程图)

online工具:

ico制作

DL next

DL future

底层 nvidia-cda AMD microsoft

中层

高层

google带记忆的网络 新思路 发现复用的pattern, 第四种分形复用, deep-fusion-network

  • 通用人工智能

超大网络,大部分神经元休眠。!!!!!!!!
未来神经网络是可演化,优胜劣汰,遗传变异。

【神经网络] Going Deeper

residual & highway 发展历程

Highway Networks

既然LSTM gate 也是为了解决 Information flow,有没有其他方式去解决?更直观一点的,不通过 gradient 的?既然 information 像被阻隔了一样,我们就“暴力”让它通过一下,给它们来个特权——在某些 gate 上,你就不用接受“审查”(transform)了,直接通过吧。这像高速公路一样——于是就有了这个名字,Highway Networks(HW-Nets)。 (gate直接等于1吗?)

Deep Residual Learning for Image Recognition

Identity Mappings in Deep Residual Networks

分析了 ResNet 中 Identity mapping 为什么比较好,为何能让梯度在网络中顺畅的传递而不会爆炸或消失

Residual Net 核心思想是,去拟合残差函数 F (F = y - h(x)),选 h(x)=x 时效果最好。

code

待看blog

【深度学习-RNN系列】GRU简介 & 源码实现

简介

LSTM 计算较为复杂,参数也非常多,难以训练。GRU(Gated Recurrent Units)应运而生。

在 GRU 中,大幅简化了 LSTM 结构

背后的逻辑

  1. 新增 reset gate,即图中的 r 开关;
  2. 将输入门和遗忘门合并为“update gate”,即图中的 z 开关;
  3. 将细胞状态 C 和隐藏状态 m 合并为 h;
  4. 省掉了输出门;

应用实例

  • 百度的Deep speech2

GRU的实现源码

GRU-tensorflow

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

def call(self, inputs, state):
"""Gated recurrent unit (GRU) with nunits cells."""

gate_inputs = math_ops.matmul(
array_ops.concat([inputs, state], 1), self._gate_kernel)
gate_inputs = nn_ops.bias_add(gate_inputs, self._gate_bias)

value = math_ops.sigmoid(gate_inputs)
r, u = array_ops.split(value=value, num_or_size_splits=2, axis=1)

r_state = r * state

candidate = math_ops.matmul(
array_ops.concat([inputs, r_state], 1), self._candidate_kernel)
candidate = nn_ops.bias_add(candidate, self._candidate_bias)

c = self._activation(candidate)
new_h = u * state + (1 - u) * c
return new_h, new_h

pytorch

缺陷

参考

【深度学习-RNN系列】递归神经网络 RNN (从HMM到RNN)

简介

递归神经网络(RNN)是两种人工神经网络的总称。一种是时间递归神经网络(recurrent neural network),另一种是结构递归神经网络(recursive neural network)。
时间递归神经网络的神经元间连接构成矩阵,而结构递归神经网络利用相似的神经网络结构递归构造更为复杂的深度网络。RNN一般指代时间递归神经网络。单纯递归神经网络因为无法处理随着递归,权重指数级爆炸或消失的问题(Vanishing gradient problem),难以捕捉长期时间关联;而结合不同的LSTM可以很好解决这个问题。
—— 维基百科

其他翻译

  • recurrent:“循环神经网络”
  • recursive 递归神经网络
  • feedforward

总结

  • RNN解决了HMM的
  • 双向RNN解决了上下文依赖问题
  • LSTM解决了RNN训练中梯度消失和梯度爆炸的问题
  • GRU取消了LSTM中的cell,结构上更加简单,在性能上,训练时间更短,epoch更小的情况下可以收敛。

序列建模的发展史

  • Memoryless models for sequences
  • Markov: bi-gram, tri-gram, n-gram
    • 严格的独立性假设条件,无法建模任意长度的上下文信息
    • n-gram矩阵太大,太稀疏,(2-gram也很大很稀疏)。怎样解决?词典大小$V$,
    • 详见HMM博客
  • HMM
  • RNN
    • HMM转移概率矩阵太大,这里可以认为是对其降维。
  • LSTM

RNN与HMM

基本结构上是挺像的,都是通过hidden state 的演化来刻画 序列间的依赖关系

RNN与HMM的本质区别是RNN没有马尔科夫假设,可以考虑很长的历史信息。

  1. 隐状态的表示: hmm是onehot, RNN是分布表示,RNN的表示能力强很多,或者说在面对高维度时,表示效率更高。类似nlp里,对单个token的表示,一种是onehot, 一种是word vector 。
  2. 隐状态的演化方式: hmm是线性的,RNN是高度非线性。
  3. 在垂直方向上,实际中的lstm还会增加depth, 来增加不同层面的抽象表示,也会使得表示能力指数增加,随着depth 增加。

RNN也是基于马尔可夫假设的,当前的隐状态仅依赖前一个时刻的隐状态。在有马尔可夫假设的模型中,不代表距离超过1的两个状态是无依赖的。

印象中有paper证明, 在HMM中两个状态的依赖关系随距离指数衰减,而在RNN中是power law decay. 也就是大家通常说的 rnn可以略好的刻画 long term dependency.

另,SLAM中还有种算法跟hmm类似,kalman filter.

https://www.zhihu.com/question/57396443/answer/263019702

RNN Overview

  • 狭义上的RNN,指vanilla RNN。
  • 广义上的RNN,lstm gru等都属于RNN框架。

该文章针对广义上的RNN。

RNN的核心思想就是利用当前时刻的输入$X_t$和上一时刻的隐状态$h_{t-1}$来计算$h_t$:

1
out, hidden = lstm(input, hidden)  # 来自pytorch的抽象

$$ h_t = f(x_t, h_{t-1}) $$

针对不同的任务又有不同的RNN形式

大部分应用都可归入该框架。具体的应用可参考karpathy

名词解释:

  • hidden 也叫cell, hidden_state, cell_state。它是forget的关键
  • out 也叫 output,
  • hidden
  • cell
  • output在stack RNN中也叫hidden

output = new_state =

Most basic RNN:

1
output = new_state = act(W * input + U * state + B)

https://www.quora.com/How-is-the-hidden-state-h-different-from-the-memory-c-in-an-LSTM-cell

vanilla RNN中没有cell,所以hidden=cell=out
LSTM中

RNN的高层抽象

抽象不是实现,是API。由整体到局部,可把RNN当做一个黑盒子,有需求的情况下再细看其具体实现。

keras的RNN抽象

1
2
3
keras.layers.RNN(cell, return_sequences=False, return_state=False, go_backwards=False, stateful=False, unroll=False)
# return_sequences: 是否返回整个序列out
# return_state: 是否返回整个序列的hidden

应用示例–lstm用于二分类

1
2
3
4
model = Sequential()
model.add(Embedding(num_words, 128)) # 输入整个sequence
model.add(LSTM(128, dropout=0.2, recurrent_dropout=0.2)) # 输出最后一个cell的output
model.add(Dense(1, activation='sigmoid')) # 二分类

这是上图中的many to one模式。

  • 关于
  • 关于静态图:sequence的数目固定为80

应用示例–基于lstm的seq2seq

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Define an input sequence and process it.
encoder_inputs = Input(shape=(None, num_encoder_tokens))
encoder = LSTM(latent_dim, return_state=True)
encoder_outputs, state_h, state_c = encoder(encoder_inputs)
# We discard `encoder_outputs` and only keep the states.
encoder_states = [state_h, state_c]

# Set up the decoder, using `encoder_states` as initial state.
decoder_inputs = Input(shape=(None, num_decoder_tokens))
# We set up our decoder to return full output sequences,
# and to return internal states as well. We don't use the
# return states in the training model, but we will use them in inference.
decoder_lstm = LSTM(latent_dim, return_sequences=True, return_state=True)
decoder_outputs, _, _ = decoder_lstm(decoder_inputs,
initial_state=encoder_states)
decoder_dense = Dense(num_decoder_tokens, activation='softmax')
decoder_outputs = decoder_dense(decoder_outputs)




应用示例–基于lstm的attention-seq2seq



keras是对整个sequence做的抽象。因为keras是面向tensorflow和theano的静态图做的封装。

pytorch的RNN抽象

应用示例–基于lstm的

1
2
3
4
# for a sequence inputs
for input in inputs:
# Step through the sequence one element at a time
out, hidden = lstm(input, hidden)

1
output, (h_n, c_n) = lstm(input, (h_0, c_0))

pytorch是动态图,会随着inputsequence

源码实现

tensorflow的抽象

示例–基于lstm的语言模型

1
2
lstm = tf.contrib.rnn.BasicLSTMCell(lstm_size)
output, state = lstm(words, state) # 这里的输入和输出都是符号,类型是tf.placeholder,lstm参数是tf.variable

BasicLSTMCell源码

基于RNN的变形(mainstream variation)

cell

cascade rnn

char-rnn + word rnn (Finding Function in Form: Compositional Character Models for Open Vocabulary Word Representation)
char-cnn + word rnn (Exploring the Limits of Language Modeling)

sequence labeling

Part-of-speech Tagging

attention

未分类

recurrent highway network

框架 总结

Sequence Modeling按照架构一般分为:

  1. Encoder 架构
    • Sequence Classification
    • Sequence Labeling/Prediction
  2. Deep Encoder 架构
  3. Encoder – Decoder 架构

    其中input和output都是sequence的架构,又叫seq2seq
    • encoder:
      • CNN:图片一般采用CNN,文本也可以采用CNN
      • RNN:
    • decoder:
      • simple decoder: 通常是LSTM作为解码器[^seq2seq-NN][^seq2seq-MT][^seq2seq-Conversation]. encodes the “meaning” of the input sequence into a single vector of a fixed dimensionality. Then another deep LSTM to decode the target sequence from the vector. (only last output of the encoder. This last output is sometimes called the context vector as it encodes context from the entire sequence.
        map the input sequence)

        缺陷:只用了一个vector(context vector)表征输入序列压力太大(it carries the burden of encoding the entire sentence).

        解决: 整个序列都用

        1. 一个简单的方式是对序列vector取均值,高大上点叫mean pooling

        2. 对序列vector线性加权。难点:加权系数怎么来?因为这是不定长序列,不能像DNN那样放一个全连接参数W让模型去学。于是就出现了attention,以及self-attention。
      • attention decoder: LSTM+attention

        The decoder decides parts of the source sentence to pay attention to.

        It relieves the encoder from the burden of having to encode all information in the source sentence into a fixedlength vector.


        Attention allows the decoder network to “focus” on a different part of the encoder’s outputs for every step of the decoder’s own outputs. First we calculate a set of attention weights.

列个表,input和output

参考

[^RNN]: The Unreasonable Effectiveness of Recurrent Neural Networks
[^seq2seq-NN]: Sequence to Sequence Learning with Neural Networks | nips 2014
[^seq2seq-MT]: Learning Phrase Representations using RNN Encoder-Decoder for Statistical Machine Translation | EMNLP 2014
[^seq2seq-Conversation]: A Neural Conversational Model
[]: 吴恩达《序列模型》精炼笔记 – 循环神经网络(RNN)

【深度学习-RNN系列】长短期记忆 LSTM (从RNN到LSTM)

传统方法 History

error signals “flowing backwards in time” tend to either blow up or vanish

bp算法中为什么会产生梯度消失? | 知乎

LSTM

LSTM网络是RNN的一种,专门设计用于解决long-term dependency/memory问题,1997年由 Hochreiter & Schmidhuber提出。
由于独特的设计结构,LSTM适合于处理和预测时间序列中间隔和延迟非常长的重要事件。

名字:long short-term memory
意思是vanilla RNN是short-term memory,sequence太长,

  • LSTM只能避免RNN的梯度消失gradient vanishing);
  • 梯度膨胀(gradient explosion)不是个严重的问题,一般靠裁剪后的优化算法即可解决,比如gradient clipping(如果梯度的范数大于某个给定值,将梯度同比收缩)。下面简单说说LSTM如何避免梯度消失.
  • 梯度弥散是什么鬼?

cell: memory_cell

关于梯度消失问题

梯度消失问题–直观解释

传统RNN中存在的梯度消失。

梯度消失 – 产生的原因

本质原因就是因为矩阵高次幂导致的

在多层网络中,影响梯度大小的因素主要有两个:权重和激活函数的偏导。

深层的梯度是多个激活函数偏导乘积的形式来计算,如果这些激活函数的偏导比较小(小于1)或者为0,那么梯度随时间很容易vanishing;相反,如果这些激活函数的偏导比较大(大于1),那么梯度很有可能就会exploding。因而,梯度的计算和更新非常困难。

https://www.zhihu.com/question/34878706

参考:

梯度消失问题 – 解决方案

见后续的gate

梯度消失问题 – LSTM是如何避免的

1、当gate是关闭的,那么就会阻止对当前信息的改变,这样以前的依赖信息就会被学到。2、当gate是打开的时候,并不是完全替换之前的信息,而是在之前信息和现在信息之间做加权平均。所以,无论网络的深度有多深,输入序列有多长,只要gate是打开的,网络都会记住这些信息。


上面这个例子中,数据从实心1向后传递。通过gate的配合,成功在节点4和6输出该数据。数据流(梯度)不会因long-term传输而消失,有效解决RNN的梯度消失问题。即梯度保持

用数学来表达,就是f=1,i=0,那么就状态保持(完整)。f=0,i=1就状态遗忘(后面也LSTM的变种,采用i=1-f)。

  • 当gate是关闭的,那么就会阻止对当前信息的改变,这样以前的依赖信息就会被学到。
  • 当gate是打开的时候,并不是完全替换之前的信息,而是在之前信息和现在信息之间做加权平均。所以,无论网络的深度有多深,输入序列有多长,只要gate是打开的,网络都会记住这些信息。

参考

LSTM的设计思想

LSTM的核心:cell + gate。
用于解决传统RNN中的梯度消失问题 (Gradient Vanish)

关于gate

gate,即阀门、开关。取值范围[0,1],0表示关闭,1表示通行

使用一个合适激活函数,它的梯度在一个合理的范围。LSTM使用gate function,有选择的让一部分信息通过。gate是由一个sigmoid单元和一个逐点乘积操作组成,sigmoid单元输出1或0,用来判断通过还是阻止,然后训练这些gate的组合。所以,当gate是打开的(梯度接近于1),梯度就不会vanish。并且sigmoid不超过1,那么梯度也不会explode

LSTM信息流

包括:input gate, output gate, forget gate

Gates are a way to optionally let information through.

待看

  • An Empirical Exploration of Recurrent Network Architectures.
  • Empirical Evaluation of Gated Recurrent Neural Networks on Sequence Modeling.

关于cell的设计

$h_t$在RNN中承担两个角色:

  • 作为当前时刻的output,用于prediction
  • 作为当前时刻的hidden state,用于时序信息的传递

LSTM将这两个角色拆分为 $h_t$和$C$,这样LSTM中的隐状态实际上就是$C$了,$h_t$作为output。通过这样的设计,输出层只利用$h_t$的信息,而不直接利用内部cell的值 $C$。

x和h_t-1做一个拼接,过sigmoide得到forget-gate。
forget-gate作用在c_t-1上。

为什么要设计cell?这样抽象的意义?

LSTM中c和h的区别: 仅仅是一个输出门的区别(c没过输出门,h_t-1作为上一时刻的输出,要过输出门)。

  • c与x拼接送入forget gate呢?
  • forget作用在h上呢?

https://zhuanlan.zhihu.com/p/28919765

GRU中合并了cell state和和hidden state

关于激活函数

sigmoid

sigmoid之类的大量用在rnn的门也并非是概率解释的问题。而是理想门函数是阶跃函数,但其本身不可导,所以soft成sigmoid是一种折中。而且rnn中sigmoid陷入饱和区本身也是一件无所谓的事儿,因为门的作用本身就是通过与不通过,他希望的就是激活值大量集中在0/1附近而不是其他的连续值。

为什么rnn中sigmoid陷入饱和区本身也是一件无所谓的事儿?不影响梯度消失?

tanh

为什么用tanh不用ReLU?

在CNN等结构中将原先的sigmoid、tanh换成ReLU可以取得比较好的效果。
为什么在RNN中,将tanh换成ReLU不能取得类似的效果?

从信号处理的方式说,要保证系统稳定。类似线性系统极点要在单位圆里,非线性直接加个激活卡住。所以简而言之:Relu不行,越界了;sigmoid差一半平面;只有tanh刚好。tanh还有个好处是零点梯度为1,这个性质比sigmoid好,relu在右半平面也是1,但越界不稳定,然并卵了。

参考:https://www.zhihu.com/question/61265076/answer/239987704

接口设计

1
2
output, (h_n, c_n) = lstm(input, (h_0, c_0))  # pytorch的接口
new_h, (new_c, new_h) = lstm(inputs, (c, h)) # tensorflow的接口,其中state=(c, h)

LSTM可以看做有两个隐状态h和c,对应的隐层就是一个Tuple。
这里可以对比RNN的接口。

在RNN中 $output = c_t = h_t$,即$h$既是hidden state又是output

为什么lstm代码里和有些图里,习惯吧output称作h(hidden)? 前面已经解释了

这里为什么要用 tuple 呢?直接把它们拼成一个 Tensor 不行吗,tuple 还得一个一个遍历,这多麻烦?

不行。因为多层 RNN 并不需要每一层都一样大,例如有可能最底层维度比较高,隐层单元数较大,越往上则隐层维度越小。这样一来,每一层的状态维度都不一样,没法 concat 成一个 Tensor 啊!);而这个大的 RNN 单元的输出则只有原先的最上层 RNN 的输出,即整体的

接口(对LSTM的封装)要具有良好的扩展性(水平扩展-sequence,垂直扩展-stack)。
在stack lstm中,下一层的out对接上一层的input,在深度模型的概念里这就是隐含层hidden的作用,所以命名为hidden。

但是呢,作为一个cell,我还是觉得叫output比较好。追根溯源,谁第一个采用hidden命名的?

为什么lstm代码里要把(c, h)封装成一个tuple?

  1. 为什么不拼成一个tensor?
  2. 为什么不用2个独立元素?

这样设计的目的是为了兼容RNN的接口(毕竟LSTM属于RNN的一种)。另外

example 应用示例

应用示例–基于lstm的语言模型

1
2
3
4
5
lstm = tf.contrib.rnn.BasicLSTMCell(lstm_size)
# current_batch_of_words不是sequence,只是
for current_batch_of_words in words:
# 这里的输入和输出都是符号,类型是tf.placeholder,lstm参数是tf.variable
output, state = lstm(current_batch_of_words, state)

LSTM: 实现

In order to make the learning process tractable, it is common practice to create an “unrolled” version of the network, which contains a fixed number (num_steps) of LSTM inputs and outputs. The model is then trained on this finite approximation of the RNN. This can be implemented by feeding inputs of length num_steps at a time and performing a backward pass after each such input block.

为什么要限定长度?
对于任意长度的序列,BP算法计算复杂,因此采用固定长度的序列。

LSTM: tensorflow实现

tensorflow源码 - BasicLSTMCell

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
# 源码精简版
def call(self, inputs, state):
"""Run one step of LSTM.
Args:
inputs: `2-D` tensor with shape `[batch_size, input_size]`. 是单个时间节点的batch样本
state:
Returns:
hidden state, new state ().
"""
c, h = state
gate_inputs = math_ops.matmul(
array_ops.concat([inputs, h], 1), self._kernel)
gate_inputs = nn_ops.bias_add(gate_inputs, self._bias)
# i = input_gate, j = new_input, f = forget_gate, o = output_gate
i, j, f, o = array_ops.split(
value=gate_inputs, num_or_size_splits=4, axis=one)

forget_bias_tensor = constant_op.constant(self._forget_bias, dtype=f.dtype)

# update
new_c = add(multiply(c, sigmoid(add(f, forget_bias_tensor))),
multiply(sigmoid(i), self._activation(j)))
new_h = multiply(self._activation(new_c), sigmoid(o))
new_state = LSTMStateTuple(new_c, new_h)
return new_h, new_state

pytorch

包装的好复杂,参考 https://blog.ddlee.cn/2017/05/29/LSTM-Pytorch%E5%AE%9E%E7%8E%B0/

缺陷

  • 难并行
  • 计算量大
    • low rank approximation之类的参数控制,运算量会是对应RNN的四倍以上。所以Gating其实是一种代价很高的方法。

FAQ 汇总

关于静态图和动态图?

  • LSTM为什么要设置cell? cell state 和 hidden state的关系、区别?为什么lstm代码里和有些图里,习惯吧output称作h(hidden)?
  • 为什么要引入gate?
  • gate是点,还是向量?
    • 向量, decides what parts of the cell state we’re going to output
  • LSTM为什么不用ReLU?

其他参考

其他

黄畅:我补充一点。关于 LSTM,不管你是单向的、双向的、摞一起的、不摞一起的,其实都有一个问题:信息传导的约束很强。换句话说,不管是做前向预测还是后向 BP(反向传播),一个信息从左边到右边,或者从开始到结束,都要经过很长的路径。而且在整个过程中,会有很多非线性的变化,尤其是 LSTM 这种典型的、很容易进入自我限制状态的模型。经过很多次这样的事情,就导致整个优化变得异常困难。这个结构天生就使得优化变得非常困难。

这是 LSTM 的弊病,它的结构设计有很大限制性。你可以类比一些其他结构,比如 ResNet,它通过建立 free-way 的方式,人为地架了很多 short-pass(短路径),使得本来在网络上距离很远的两个单元之间建立一些高速的快速通道。直观的理解就是可以让它们之间的信息沟通更加顺畅,减轻我前面说的那个问题。

更进一步,你会发现在语音识别中有人用完整的 CNN 替代 LSTM,包括讯飞、微软、百度。刚开始的时候 CNN 用得很浅,只是作为基本的局部表达,后来发现可以用 CNN 不断堆积,而且堆的很有技巧。在计算量不显著增加的情况下,这样就可以用 CNN 覆盖很大的语境

就是说优化算法本身也许没有很好的进步,但是通过网络结构的设计可以规避目前主要基于 SGD 的优化算法难以解决的 LSTM 问题,直接构造一个更适合目前优化算法去优化的网络结构。所以本质上很难说哪个结构更好,你只能说这个结构更适合现在主流的这种优化方法。

其实论文出来时我稍微看了一点,它本质上好像和 attention model 很像。attention model 的概念是不管语境是怎么传过来的,总是有选择的看所有东西,做决策(比如生成一个词)的时候有选择的去做。这时候会产生一个 attention mask,这可以理解成一个 gate,封住一些不想看的东西,保留想看的。

这个在图像和 NLP 里面已经得到很好的验证。NLP、语音、图像其实都是相通的,你会发现很多思想、结构、设计理念会越来越相似。这也给了我们信心,让我们可以实现语音图像识别一体化交互,用一套统一的专用架构去做解决各种各样的问题。

FAQ

关于websocket

websocket属于服务器推送技术的一种。
HTML5定义了 WebSocket 协议,以及相关的编程API,能更好的实现双向通信且节省服务器资源和带宽。

WebSocket 实际上指的是一种协议,与我们熟知的 Http 协议是同等的一个网络协议。用网络模型结构来解释的话, WebSocket 和 Http 协议都属于 应用层协议,两者都基于传输层协议 TCP。

http协议 http://
ftp协议 ftp://
websocket协议 ws://

Websocket是基于HTTP协议的,或者说借用了HTTP的协议来完成一部分握手。
在握手阶段是一样的

背景

以前的网站为了实现推送功能,使用的方法都是轮询。所谓的轮询就是在特定的时间间隔(例如1秒),由浏览器向服务器发出一个 Http request,然后服务器返回最新的数据给客户端浏览器,从而给出一种服务端实时推送的假象。由于Http Request的Header(请求头)很长,而传输的数据可能很短就只占一点点,每次请求消耗的带宽大部分都消耗在 Header上。从网上资料得知后来还有改进的轮询方法叫做 Comet,使用 Ajax。但这种技术虽然可达到双向通信,但依然需要发出请求,而且在Comet中,普遍采用了长链接,这也会大量消耗服务器带宽和资源。

流程

  1. 首先WebSocket 服务器启动,并监听端口
  2. 客户端new websocket(dfd),建立连接

客户端的API (js)

不同浏览器有不同的实现,但都提供的javascript API,所以客户端API都类似,或者可以统一API。

服务端的实现

websocket服务器则因语言不同而提供不同的调用方式。

是叫实现,还是应该叫封装?

原理

1
2
3
4
5
6
7
8
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket ## 这个就是Websocket的核心了,告诉Apache、Nginx等服务器:注意啦,窝发起的是Websocket协议,快点帮我找到对应的助理处理~不是那个老土的HTTP。
Connection: Upgrade ##
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

参考

疑问

  • websocket是依赖TCP吗?

如何debug websocket?

方式一:在chrome inspect中查看websocket连接

network下的WS选项可以查看websocket连接。
能看到Request连接:wss://echo.websocket.org/
在frame中能看到明文数据,wss竟然也是明文传输

超详细教程

方式二:通过chrome console中命令查看

1
2
var webSocket = new WebSocket('ws://address:port');
webSocket.onmessage = function(data) { console.log(data); }

方式三:在chrome internal里查看

chrome://net-internals/#sockets

方式四:通过抓包查看

见network/tools/wireshark/抓包

如何查看websocket发送的数据?

浏览器inspect能看到websocket连接,为什么没看到发送的数据包?
那么通过抓包总能够看到吧。

  • websocket的实现原理是什么?在TCP的基础上做了什么?加了header?

online demo

##

##

微信网页版 聊天原理

Overview

微信网页版聊天,未采用websocket,而是基于long polling(长轮询)。

客户端消息发送

客户端消息接收(伪服务端推送)

  1. 客户端间隔性发送http请求sync(每隔)源码; beauty后的源码
  2. 服务端对该请求延时返回,强制建立长连接
  3. 当服务端有需要推送的消息,即时在已建立的长连接中返回http response
  4. 客户端收到response后,立即发送一个新的http request
  5. goto 2

客户端发送http request

客户端间隔性发送ajax请求

1
2
3
4
5
6
7
8
9
10
11
Request URL: https://webpush.wx.qq.com/cgi-bin/mmwebwx-bin/synccheck?
Referrer Policy: no-referrer-when-downgrade

# Query String Parameters
r: 151**
skey: @crypt_d8e**
sid: a5ne**
uin: 1709**
deviceid: e2387***
synckey: 1_677803136|2_677803**
_: 1517**

这是一个服务器端强制保持的长连接。

待看

疑问

为什么不采用websocket?

websocket占用资源多?不安全?socket连接数限制?低端浏览器不支持?手机浏览器不支持?
知乎说,是因为懒