SQLNet学习

WikiSQL数据集

WikiSQL的优点

  • 数据量多,可有效训练神经网络。
  • 大量的人为创造的自然语言问句,问题范围广,有助于克服训练中的过拟合问题。
  • 由自然语言问句和表结构来生成SQL,不依赖表格内容。
  • 训练集、验证集、测试集是分开的,有助于更好的评估

WikiSQL的任务

  • 输入:1.自然语言问题 2. 表列名
  • 输出:SQL语句
  • 注意:WikiSQL中一张表对应一个SQL语句
    666

SQLNet

SQLNet的基本解决思想

  • 采用插槽填充的思想,通过对自然语言问句的刨析来向SQL结构中的插槽填充各种值。这样有效地避免了seq2seq中where语句的顺序问题。
    在这里插入图片描述
    其中AGG为聚合函数,COLUMN是列名,OP有{>,=,<}等,VALUE是自然语言问题中的子字符串。
  • 引入了两种方法
    • Sequence-to-set(序列到集合)
    • Column attention(列注意力)

SQLNet的两种方法

  • Sequence-to-set

    • Where子句中的列名是表格所有列名的一个子集。因此预测表格中的列名是否是Where感兴趣的列名,而不是直接去预测where子句需要的列名的集合。这种思想就称为Sequence-to-set。
    • 计算条件概率:在某Question的条件下,表格中一列名是where子句需要列名的概率为: P w h e r e c o l ( c o l Q ) = s i g m o i d ( u c T E c o l + u q T E Q ) 1 P_{wherecol}(col|Q)=sigmoid(u_c^TE_{col}+u_q^TE_Q) (1)
      其中,Ecol和EQ是Embedding,分别为列名序列和问题序列通过两个Bi-LSTM后得到的隐层状态向量。这两个Bi-LSTM不共享权重。
  • Column attention

    • 如上的EQ仅能代表自然语言问题的一些信息,对于针对特定列时,EQ的表现不足以足够的信息,因此引入了Column attention机制,用EQ|col来代替EQ
    • 假设HQ是一个d×L的矩阵,其中L是自然语言的长度,d是embedding的大小,HQi表示问题的第i个token对应的Bi-LSTM的隐状态输出。相当于分别把问题的每个token embedding都与表中列名的embedding挂钩,然后所有的Vi做softmax得到一个概率分布w,此时这个w就包含了自然语言问句中每个词与当前表格列名的某种关系,之后在与HQ相乘,将维度变换好。 v i = ( E c o l ) T W H Q i v_i=(E_{col})^TWH_Q^i w = s o f t m a x ( v ) w=softmax(v) E Q c o l = H Q w E_{Q|col}=H_Qw 替换EQ: P w h e r e c o l ( c o l Q ) = s i g m o i d ( u c T E c o l + u q T E Q c o l ) 2 P_{wherecol}(col|Q)=sigmoid(u_c^TE_{col}+u_q^TE_{Q|col}) (2) 经过测试,加入tanh可以提高预测性能: P w h e r e c o l ( c o l Q ) = s i g m o i d ( ( u a c o l ) T t a n h ( u c c o l E c o l + u q c o l E Q c o l ) ) 3 P_{wherecol}(col|Q)=sigmoid((u_a^{col})^Ttanh(u_c^{col}E_{col}+u_q^{col}E_{Q|col})) (3)

SQLNet的具体方法

  • 预测WHERE子句
    Where 子句是 WikiSQL 任务中要预测的最复杂的结构,根据SQLNet 模型首先预测 WHERE 子句中出现的列集,然后对于每个列,它通过预测 OP 和VALUE 槽来生成约束。

    • Column slots
      在根据(3)计算后,要选择Where中包含哪些列。

      • 一种方法是设置阈值,当阈值大于设定时,选择该列。
      • 另一种方法:由于where中列名不止一个,所以可以先预测where中包含列名的个数(0-N),即为N+1类的分类问题: P # c o l ( K Q ) = s o f t m a x ( U 1 # c o l t a n h ( U 2 # c o l E Q Q ) ) i P_{\#col}(K|Q)=softmax(U_1^{\#col}tanh(U_2^{\#col}E_{Q|Q}))_i
    • OP slots
      预测的槽值是一个三分类问题:{=,>,<} P o p ( i Q , c o l ) = s i g m o i d ( U 1 o p t a n h ( u c o p E c o l + u q o p E Q c o l ) ) P_{op}(i|Q,col)=sigmoid(U_1^{op}tanh(u_c^{op}E_{col}+u_q^{op}E_{Q|col}))

    • VALUE slot
      我们需要从自然语言问句中预测子字符串。SQLNet 使用seq2seq来生成子字符串。
      P v a l ( i Q , c o l , h ) = s o f t m a x ( a ( h ) ) P_{val}(i|Q,col,h)=softmax(a(h)) a ( h ) i = ( u v a l ) T t a n h ( U 1 v a l H Q i + U 2 v a l E c o l + U 3 v a l h ) a(h)_i=(u^{val})^Ttanh(U_1^{val}H_Q^i+U_2^{val}E_{col}+U_3^{val}h)

  • 预测SELECT子句
    Select 子句有聚合函数和列名。

    • Select 子句中列名的预测与 WHERE 子句非常相似。主要的区别在于,对于 SELECT 子句只需要在所有列中选择一列。因此计算: P s e l c o l ( i Q ) = s o f t m a x ( s e l ) i P_{selcol}(i|Q)=softmax(sel)_i s e l i = ( u a s e l ) T t a n h ( U c s e l E c o l i + U q s e l E Q c o l i ) sel_i=(u_a^{sel})^Ttanh(U_c^{sel}E_{col_i}+U_q^{sel}E_{Q|col_i})

    • 对于聚合函数,假设 SELECT 子句的预测列名为 col,我们可以简单地计算 P a g g ( i Q , c o l ) = s o f t m a x ( U a g g t a n h ( U a E Q c o l ) ) i P_{agg}(i|Q,col)=softmax(U^{agg}tanh(U_aE_{Q|col}))_i

训练细节

  • 不同slots间不共享权重,但是共享embedding
  • 允许embedding更新,实验证明效果更好
  • 上述各个子模块都采用的标准的交叉熵loss
发布了45 篇原创文章 · 获赞 6 · 访问量 6923

猜你喜欢

转载自blog.csdn.net/Smile_mingm/article/details/105146517