在线时间 1630 小时 最后登录 2024-1-29 注册时间 2017-5-16 听众数 82 收听数 1 能力 120 分 体力 563361 点 威望 12 点 阅读权限 255 积分 174231 相册 1 日志 0 记录 0 帖子 5313 主题 5273 精华 3 分享 0 好友 163
TA的每日心情 开心 2021-8-11 17:59
签到天数: 17 天
[LV.4]偶尔看看III
网络挑战赛参赛者
网络挑战赛参赛者
自我介绍 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
群组 : 2018美赛大象算法课程
群组 : 2018美赛护航培训课程
群组 : 2019年 数学中国站长建
群组 : 2019年数据分析师课程
群组 : 2018年大象老师国赛优
【文本匹配】交互型模型 8 [- c5 @$ A! K
3 M4 j$ c0 k3 z 表示型的文本匹配模型存在两大问题:(1)对各文本抽取的仅仅是最后的语义向量,其中的信息损失难以衡量;(2)缺乏对文本pair间词法、句法信息的比较
1 ~5 @: G( t1 ]% H8 x $ J i% B T; a' S) y4 X( \
而交互型的文本匹配模型通过尽早在文本pair间进行信息交互,能够改善上述问题。! m3 o8 A0 ~; ]3 R6 a$ a
9 k) I" ?4 l( S# c; ]/ s% n: D 基于交互的匹配模型的基本结构包括:
8 S1 _$ |5 Y4 v9 R7 l7 N
7 Z6 q$ P. y! Z1 k9 B* \ (1)嵌入层,即文本细粒度的嵌入表示;
- ?5 ?, P' K* S" V& t7 Y$ N
* M1 r7 o m; o5 G" C3 u4 Y. W (2)编码层,在嵌入表示的基础上进一步编码;
; q) w: a( k& a/ P+ r1 @, s
, p" q/ z5 i3 R. j (3)匹配层:将文本对的编码层输出进行交互、对比,得到各文本强化后的向量表征,或者直接得到统一的向量表征;6 F5 i5 e6 Z; H6 I! f8 O- W
2 d; d% q1 `2 j; A6 M
(4)融合层:对匹配层输出向量进一步压缩、融合;6 }/ m9 o1 R7 m2 d$ d) F5 l
) v( o- I2 x4 o. P1 e2 W# [
(5)预测层:基于文本对融合后的向量进行文本关系的预测。- u7 R3 S( D. G) _2 w
" ^, ~- o: E1 h L- E
8 ~1 `1 L0 a& E! `( _7 z" z3 B
, l, n- }! g$ N4 ?, t" Y 1. ARC-II6 @/ t. m/ J& Z! t/ g
ARC-II模型是和表示型模型ARC-I模型在同一篇论文中提出的姊妹模型,采用pair-wise ranking loss的目标函数。3 w; e9 V$ O) Z) E$ s
; q" o( P+ u& S8 @
其核心结构为匹配层的设计:, p7 r1 a: [3 u1 e
7 e. r i8 [/ z; {3 z
(1)对文本pair的n-gram Embedding结果进行拼接,然后利用1-D CNN得到文本S_X中任一token i和文本S_Y中任一token j的交互张量元素M_{ij}。该操作既然考虑了n-gram滑动窗口对于local信息的捕捉,也通过拼接实现了文本pair间低层级的交互。
$ C5 c k% {, v8 y# {2 r0 l# A
; c& _. g9 L& b (2)对交互张量进行堆叠的global max-pooling和2D-CNN操作,从而扩大感受野。 N, M8 V$ x3 f
) \! u. M# X3 ]. B' E
2. PairCNN* P. X6 d" E/ o7 z$ P
PairCNN并没有选择在Embedding后直接进行query-doc间的交互,而是首先通过TextCNN的方式分别得到query和doc的向量表征,然后通过一个中间Matrix对query和doc向量进行交互得到pair的相似度向量,然后将query的向量表征、doc的向量表征、相似度向量以及其它的特征向量进行拼接,最后经过两层的MPL得到最后的二分类向量。. Z- J! o' p9 c! U( O j
! W& C" u9 b% R% B4 M( i$ C) |
PairCNN的模型架构中的亮点在于各View向量的拼接,既能利用原始的语义向量,还能够很便捷的融入外部特征。. p! B1 V7 u6 A% }
% E0 \4 B8 S p- C 3. MatchPyramid ?8 A g/ B! C
无论是ARC-II中的n-gram拼接+1D conv还是Pair-CNN中的中间Matrix虽然均通过运算最终达到了信息交互的作用,但其定义还不够显式和明确,MatchPyramid借鉴图像卷积网络的思想,更加显式的定义了细粒度交互的过程。
' ^ L$ X6 `: K% z$ D M' n3 n MatchPyramid通过两文本各token embedding间的直接交互构造出匹配矩阵,然后将其视为图片进行2D卷积和2D池化,最后Flatten接MLP计算得匹配分数。本文共提出了三种匹配矩阵的构造方式:
2 l& r+ L$ i$ {/ C% X 3 u S% i2 }. F* h$ z" K
(1)Indicator:0-1型,即一样的token取1,否则取0;这种做法无法涵盖同义多词的情况;
- X+ C0 D! D F9 p9 R( X- r, l' } * l& x2 s* l* ?# y6 K7 _: J8 R' i
(2)Cosine:即词向量的夹角余弦;
+ N$ M/ K5 D" C4 U# b- T3 v2 Z* K ; s2 o; v& p! ?+ l# t
(3)Dot Product:即词向量的内积6 E' f! {' M6 J% n! `( y) A
1 B3 a) G7 X4 @* [
此外值得注意的是因为各个文本pair中句子长度的不一致,本文并没有采用padding到max-lenght的惯用做法,而是采用了更灵活的动态池化层,以保证MPL层参数个数的固定。4 ~: n* a6 @- Q* p4 x
B9 G1 @# Q/ j8 a& a 4. DecAtt; A/ Z* _4 b7 e7 g' t
DecAtt将注意力机制引入到交互型文本匹配模型中,从而得到各token信息交互后增强后的向量表征。
! s+ a1 ^* Q2 `$ r0 a# j* W
8 m# T; r3 C$ E* {0 v6 G8 u- f5 l 模型被概括为如下层级模块:
7 c3 B# ~" R4 c' o) q2 j 2 B* E" P8 v" n& `
(1)Attend层:文章提供了两种注意力方案,分别为文本间的cross-attention,以及各文本内的intra-attention。具体而言,分别采用前向网络F和F_{intra}对文本token embedding进行编码,然后通过F(x)F(y)计算cross-attention的score,以及F_{intra}(x)F_{intra}(y)计算self-attention的score。然后利用softmax将attention score进行归一化,再对各token embedding进行加权平均,得到当前query token处的增强表征,最后与原始token embedding进行拼接计为attend后的最终embedding。) z @. s% j5 G7 k; `' u- a& l
: M* M( Y; _' U2 x6 P
(2)Compare层:将前序Attend层计算得到的最终embedding,喂入一个全连接层进行向量维度的压缩。) |7 t9 F/ H* w$ [9 b! o) Z
6 p" y1 {8 a6 m/ _: o (3)Aggregate层:将每个文本各token处压缩后的向量进行简单的求和,再拼接起来通过MPL得到最后的匹配得分。
: `+ @& \7 ]4 m& I; d) F& B + y5 S. n( M; U5 Y# V
5. CompAgg0 v" L/ k4 i+ o7 Z x5 r8 S
CompAgg详细对比了在文本间cross-attention得到的各token向量表征与原始token向量进行compare的各种方案。
% [4 @; z, T; G1 O( k" K* ~
- B' [: y- t& w. C+ G* I 该模型的主要结构包括:$ j: X1 ]3 S1 t/ ?% j; g) F
" |) v( ~( o, h' K% F
(1)reprocessing层:采用类似于LSTM/GRU的神经网络得到token的深层表示(图中的\bar a_i);
' o/ V: v. Y; D: u0 n , t4 \/ h" S2 `9 _ P* [) p* L& h
(2)Attention层:利用软注意力机制计算文本间的cross-attention(与DecAtt相同),从而得到各token处交互后的向量表示(图中的h_i);8 ~0 A6 c1 f0 ^+ M5 p4 A; E
+ ?5 m5 E' r( D0 p" w# _, t9 G" y (3)Comparison层:通过各种网络结构或计算将\bar a_i和h_i计算求得各token的最终表征。/ @, s* T4 V9 x: _. X/ v
+ D; P; w( r* u1 o1 K
(4)Aggregation层:利用CNN网络对Comparison层的输出进行计算,得到最后的匹配得分。1 ?2 n3 o+ Z5 ~( L3 ^0 s
s* b* K' z# M4 `: p; {2 ~
其中Comparison层的构造方式包括:4 b* { Q% u; _/ y2 b6 ~
0 L0 [ y' V' w) R3 I
(1)矩阵乘法,类似于Pair-CNN中的中间Matrix
" X+ i+ c6 \3 Q: x + I& F6 ?: Y' u( y( I
(2)前向神经网络,即将\bar a_i和h_i进行拼接,然后利用输入FFN;8 a. s+ @! p0 x, n( C
K+ `0 z7 X+ f" j (3)分别计算cosine和欧式距离,然后拼接;
' K! |/ ~. C: D; y2 v
; M, I& Y! p- m$ c$ Q+ t8 N (4)各维度进行减法;
1 P8 p* q! Y; v: c 2 b) b# D! L1 N' t. V
(5)各维度进行乘法;
5 u5 S4 ^ Q4 J+ I
# a5 n9 @5 H5 |7 |' l+ q7 N1 ` ? (6)各维度进行减法和乘法,然后再接一个前向网络。
k* H# L7 U ?' m
5 D% ]5 b! N* a% C- }& Y% Q1 E 6. ABCNN3 t- q5 G2 f# @* \3 s* G4 T- h& B
ABCNN是将Attention机制作用于BCNN架构的文本匹配模型。: F, r7 W8 v7 N& ]" l' ^
1 k0 ?3 C* W/ h5 h
6.1 BCNN
5 w( N, Y- W; |4 i# i' f9 G5 y, v 首先简单介绍下BCNN架构:$ g1 @" L1 Y, F+ }. H0 U1 W# p
7 V1 }+ M7 l# j9 C; d, y
BCNN的整体结构比较简单:(1)输入层;(2)卷积层,因为采用了反卷积的形式,所以在size上会增加;
# f* w! e1 \9 |* ?5 M6 U4 v : _1 [: ^! p) R2 U7 E& g
(3)池化层,采用了两种池化模式,在模型开始阶段采用的是local平均池化,在最后句子向量的抽取时采用了global平均池化;(4)预测层,句子向量拼接后采用LR得到最后的匹配得分。8 F8 P8 C0 j( Q7 \( p( _
; Y4 W& C" X& w' [6 I
ABCNN共包括三种变形,下面依次介绍。
5 V- h ~6 x |% N l0 O, d. v. h& l, k. I
6.2 ABCNN
7 |% `9 N" U7 W1 J $ y, m6 q/ E5 ?7 M0 O
ABCNN-1直接将Attention机制作用于word embedding层,得到phrase 级的词向量表示。区别于CompAgg中的软注意力机制,ABCNN-1直接基于下式得到注意力矩阵: A i j = 1 1 + ∣ x i − y j ∣ A_{ij}=\frac{1}{1+|x_i-y_j|} A , w9 Y1 `+ p% \4 S% A, v
ij P9 n7 M D! y1 ]7 @8 t# ~& K |
7 j& ?6 U9 ]: E: }; w8 Z
=
* o" O! }! M4 I/ u* z3 N 1+∣x
8 E \ u$ ]& L. N. G1 k i8 P4 F) a- Y. y3 N4 i2 ]
7 U6 j% T7 K3 m7 P# G
−y ' K+ N! B4 U' H& c8 z+ j, G s1 v2 }
j4 W6 b8 C" K! [# ~
8 R! A* `/ R' }+ z
∣+ l0 Z/ r. Y- E+ [, x) N5 C
1
0 B- I8 p) g" _: F$ b; T. X ) J6 }0 ^- v1 E
,然后分别乘以可学习的权重矩阵 W 0 W_0 W
& R0 s) [8 `7 P! r 0- K5 a, |- C; a0 H$ V2 {
% W4 \4 S! Y7 g, W( J7 P( I3 T
和 W 1 W_1 W
2 H7 S$ ?& I+ ?1 P1 q 1" }! y) L( n/ [* R" S5 c
# a8 X6 w0 O5 r$ }$ y% k* s 得到attetion feature map。
& D) D( a* _7 H, H
' Y1 l) I6 x0 J% ?; I- Z- T 6.3 ABCNN-2) h2 x: m' V7 `3 _& c/ b! d, {
2 d/ w7 y3 r; G ABCNN-2将Attention机制作用于word embedding层后的反卷积层的输出结果,其中注意力矩阵的计算原理与ABCNN-1一致。然后将注意力矩阵沿着row和col的方向分别求和,分别代表着各文本token的attention socre;接着将反卷积层的输出结果与attention socre进行加权平均池化,得到与输入层相同shape的特征图。
1 u- {. T- E& W b
/ ~2 `; f2 q# N' h5 n4 f0 A; F7 u 6.4 ABCNN-3
3 @$ w) }% S% V( B1 Q: z ; n7 h, C, H" j* R" z5 T# X
ABCNN-3的基本模块可视为ABCNN-1和ABCNN-2的堆叠,即在嵌入层和卷积层上面都引入了attention的机制用来增强对token向量的表示。, ?5 F# L% ^& R2 s: ^! `0 x% s
5 \. S2 j: ~" ]4 ]: o 7. ESIM; H) I+ i' z2 M3 a
ESIM模型基于NLI任务给出了一种强有力的交互型匹配方法。其采用了BiLSTM和Tree-LSTM分别对文本序列和文本解析树进行编码,其亮点在于:
: L7 f6 B' p0 l2 j- T
# O, {8 z4 u8 i0 K& C9 \ (1)匹配层定义了cross-attention得到各token的向量表示与原token向量间的详细交互关系,即采用 [ a ˉ , a ^ , a ˉ − a ^ , a ˉ ∗ a ^ ] [\bar a, \hat a,\bar a-\hat a,\bar a* \hat a] [ & N* `- l; H% J/ U) Y9 ?0 E2 b
a
6 E! q& T R6 N k- ~2 e ˉ
3 ^. t. J" _5 S; ?4 H0 u$ c8 y/ ^4 D ,
3 t* }. z: P6 d5 b0 c# ^ a
g2 } O E* o4 u) Q ^
2 P0 Y. F2 \: q( p) B , 8 h3 R/ w/ S4 A3 p9 W# t- c
a
, I3 N; N* n% \$ J/ Q: Q. y0 J ˉ4 l7 u; t; L+ j5 B" ?. @9 k
− ' R( G6 t. q/ b
a
4 Y/ Z( V6 D6 r5 o0 m ^8 n" ^8 t x! C8 _; |
,
0 n- W w; ?/ G* R# Z6 U( q& p* x a
# p( y C6 P- g* ? Y$ f ˉ% H, u* m, T# c4 U$ P) {. q
∗
& G/ q' }- X8 f L# |/ r1 J a
& b2 J! m y6 J+ ~5 R ^" g7 C0 n' m1 B5 _' L' Y7 h; P! ~
]作为最终文本token的向量表示,这也成为后续文本匹配模型的惯用做法。
/ k, L, r2 i: h' y3 @. [1 l$ X5 Q
( O9 a6 C; a$ L: _1 L (2)聚合层通过BiLSTM得到各文本token的编码,从而进一步增强了文本序列的信息传递;
+ N* o0 G! G: g/ m0 W$ C1 M
$ m% w3 `1 @& e; a0 c; c/ l (3)预测层通过拼接各文本token编码的max-pooling和mean-pooling结果,再经过MPL进行匹配预测。% U: W* c9 W- x. g5 l, x0 _3 Q
; \* E; _3 b/ c8 Q E- c! m
% R2 r+ l( d" Z# b
! q* s2 Z3 O3 c& H: M 8. Bimpm
3 G0 p* d( O) D' C Bimpm可视为对之前各类交互型文本匹配模型的一次总结。" j3 G4 w) E$ d# [/ j- ]
; ~2 y1 U* j- ?$ a
该模型在各层的具体做法总结如下:
u* s! \6 Q% w8 h U
1 U' a9 d) b- |/ i1 Y (1)编码层采用BiLSTM得到每个token隐层的向量表示;" ^' t* R6 r$ N' \* b
0 `' o$ d8 I, q+ O1 b
(2)匹配层遵循 m k = c o s i n e ( W k ∗ v 1 , W k ∗ v 2 ) m_k=cosine(W_k*v_1,W_k*v_2) m
: n! h' e1 U" S( K k
7 r5 j6 ^5 `# y3 f* }% T 9 y% F5 T; e) _2 |& u6 u
=cosine(W
/ T, O# [5 p& g; A1 u: E k) y9 p: g0 q+ H5 ]6 T/ |& M
P7 e6 c2 O/ K8 a/ N1 j; s ∗v
3 }9 \4 R( { ~) `! q 1
# g1 ^4 k- ~' {: ?+ f6 u
( W" T: M2 x5 S1 Y5 g; M3 }* O ,W 2 F1 X/ K" c) K' R, _
k8 ~- `1 x$ i" d( q5 h' h
& ~1 I8 V7 k5 a% u- l6 i x8 n: ^9 H ∗v
! Y1 E3 O, R$ f5 o' u0 } 2, \1 o/ ?: l" r+ G8 w
5 b( D z5 }# f- ]/ ^8 u s
)的方式可以得到两个文本的任意token pair之间在第k个view下的匹配关系,至于 v 1 v_1 v , P7 y' G) ?" [) ~; i8 K0 D2 z0 e" F0 J, U
1
+ h) K" U, Y) z8 X0 ~( J! k8 I 7 j3 c) Q2 N) p9 i4 ?5 n4 B4 M
和 v 2 v_2 v
9 I" W1 p" [/ ~4 ~% c6 t3 J: o, M 2
" s4 y; X1 O" w/ T % X! ~8 o( U. z9 L) I
如何取,文章提供了4种策略:
$ q) T' g! w& F; X$ A 4 I/ O7 _: M8 o2 T
策略一:其中一个句子取各token隐层的向量表示,另一个句子采用隐层最后时间步处的输出;
- b" g3 z. ^3 |# b! I 策略二:其中一个句子取各token隐层的向量表示,另一个句子采用隐层各时间步输出与之匹配后取再取Max-Pooling值;: E& E+ ~: z) i
策略三:其中一个句子取各token隐层的向量表示,另一个句子采用cross-attentive后得到的加权句子向量;
: ]* ]: b+ N' v% g' N$ W 策略四:其中一个句子取各token隐层的向量表示,另一个句子采用cross-attentive后attention score最高处token的向量作为句子向量。
7 V9 f2 v* j* I 这四种策略的区别在于对句子向量的计算不同。; s6 o) G+ _/ p1 `- D9 _( H4 Y& Z
4 P' d( F! [5 T* c U( V+ ]
' j9 P7 U8 D0 V6 ]( m
(3)聚合层,首先对上面各种策略得到的输出层再通过一层BiLSTM层,然后将各策略下最后时间步的输出进行拼接,得到最后的聚合向量;
8 t5 c" I' a2 O; O6 l' H 0 G6 `- p% C1 c
(4)预测层:两层MPL+softmax6 c4 K+ X$ q- e( _$ E
( [! ?9 i6 d/ F8 s. d' w; @0 S9 A
9. HCAN
T% m. I. q M2 }8 R0 A HCAN是除Bert类模型外在文本匹配领域表现最为优异的深度模型之一,其采用了较为复杂的模型结构。6 O% u/ Q3 H% Y* a; @0 m2 i2 o5 x
4 P: l! d5 C3 Z3 n* ^% i+ d 针对于信息抽取问题,文章首先分析了相关性匹配和语义匹配的差异:
, z X( K& y! P% _, d1 {( d ) q7 k0 w' u$ O: L
(1)相关性匹配主要关注于关键词的对比,因此更关注低层级词法、语法结构层面的匹配性;
; o6 O k% g6 V0 o; t6 y& [8 ]7 U7 B 0 R% p+ t& C: y' _ H9 S ?
(2)语义匹配代表着文本的平均意义,因此其关注更高、更丑想的语义层面的匹配性。
/ A0 E, W. _ h0 Z: K7 ?
$ I6 o6 z& w! G: T 该模型首先采用三类混合的编码器对query和context进行编码:
! M5 |! J+ q- W 5 l* L8 A+ ]/ G. L' {7 s
(1)深层相同卷积核大小的CNN编码器;) ~, b% B' M, L+ m, S: h
6 {+ l& u5 V, _0 s& r (2)不同卷积核大小的CNN编码器的并行编码;$ S M8 S( a) X- l0 s9 d
' E1 N7 e: u6 G- j5 a
(3)沿着时序方向的stacked BiLSTM编码;
9 {4 G) ^9 B8 d/ L , b0 g7 L% B( P0 i+ o; A1 o: j
对于前两者,通过控制卷积核的大小可以更好的捕捉词法和句法特征,即符合相关性匹配的目的;而对于后者,其能表征更长距离的文本意义,满足语义匹配的目的。: @# E- p! B5 b5 p! H8 \4 u
A( J0 f4 w, u" _% S 在这三类编码器的编码结果基础上,模型分别进行了相关性匹配和语义匹配操作。其中相关性匹配主要采用各phrase间内积+max pooling/mean pooling的方式获取相关性特征,并通过IDF指进行各phrase的权重调整。而在语义匹配中,模型采用了精心设计的co-attention机制,并最终通过BiLSTM层输出结果。
6 ~4 v) o3 \' j% ?+ N( s0 z
: O% O- l% i0 n0 z% h1 i# R1 R5 M 最后的预测层仍采用MPL+softmax进行预测。9 l1 T. r E# b& f7 }
. m& b2 S# h6 e 10. 小结
7 f5 [# P' U. K/ m( D8 j- W( s 交互型语言匹配模型由于引入各种花式attention,其模型的精细度和复杂度普遍强于表示型语言模型。交互型语言匹配模型通过尽早让文本进行交互(可以发生在Embedding和/或Encoding之后)实现了词法、句法层面信息的匹配,因此其效果也普遍较表示型语言模型更好。
0 R0 A g6 ~, O0 Z3 Y6 {; f6 p, \
; X8 r0 r$ {8 c4 ^. P' `. S 【Reference】5 m1 B4 C) G, I: u7 w
7 |8 O' v( I; {( J/ Y8 C
ARC-II: Convolutional Neural Network Architectures for Matching Natural Language Sentences' X8 ?( e( M8 B* o% t; y1 H
Q- {, `0 D1 i0 e5 L. s& g0 l PairCNN: Learning to Rank Short Text Pairs with Convolutional Deep Neural Networks' M6 ]4 Q: x7 ^8 q( j
* B) D! l% ]5 C; w0 Y
MatchPyramid: Text Matching as Image Recognition
. [, v! q. y/ t) o 8 k. I6 N7 d5 y1 Y1 ]$ e
DecAtt: A Decomposable Attention Model for Natural Language Inference3 f4 T4 u& C. ~, X; p/ T) a
6 r* [) W* }. `& @4 m1 V CompAgg: A Compare-Aggregate Model for Matching Text Sequences
3 R' Y7 O9 J% D. i4 e6 T * N7 l+ Z3 g+ u4 I
ABCNN: ABCNN: Attention-Based Convolutional Neural Network
+ O, }* c: C8 m( T for Modeling Sentence Pairs
3 h! o' S! H6 g, \' E
$ i; z& t" ?) Q, c ESIM: Enhanced LSTM for Natural Language Inference
+ N" I/ u$ q4 O6 g . m+ _( v3 ?: r
Bimpm: Bilateral Multi-Perspective Matching for Natural Language Sentences8 J, r& k( e( m2 W+ n) }+ R0 U
8 p' k) `0 E% L0 E
HCAN: Bridging the Gap Between Relevance Matching and Semantic Matching
z- \! B5 a. o+ V8 A' Y+ E for Short Text Similarity Modeling9 N" U9 e6 B3 x1 W9 J- Y
: i$ y$ u4 z/ O- X 文本匹配相关方向打卡点总结(数据,场景,论文,开源工具)& o7 T0 I9 U% Y9 w: L
% @0 M& t, b& _( w j 谈谈文本匹配和多轮检索
1 x7 n# t" F$ x. |# b( g( i 1 S* P% f) Y" b: E
贝壳找房【深度语义匹配模型 】原理篇一:表示型* T( o$ k( x( X: p* @2 p
————————————————* o/ k1 X$ ^ F
版权声明:本文为CSDN博主「guofei_fly」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。1 ~) {6 d q+ s. `
原文链接:https://blog.csdn.net/guofei_fly/article/details/107501276
+ c9 v, q& X" |4 G+ ` : W2 ]6 P/ s% j8 G
; ~) m" u b, z
zan