放牧代码和思想
专注自然语言处理、机器学习算法
    愛しさ 優しさ すべて投げ出してもいい

CS224n Assignment 3

目录

hankcs.com 2017-07-02 下午7.41.06.pngq3-0-dynamics.pngq3-clip-gru.png命名实体识别任务,先实现基于窗口的基线模型,然后进阶到RNN和GRU。中间利用对自动机的模拟和推导展示RNN的缺点,演示梯度剪裁的作用。这是Latex解答,代码已提交,最后还有一个彩蛋。

命名实体识别初步

定位命名实体并将其分类到:

  • 人名PER

  • 组织名ORG

  • 地名LOC

  • 其他MISC

加上非命名实体O一共5类。连续的标注视为同一个实体。比如样本$x^{(t)}$与标注$y^{(t)}$以及预测结果$\hat{y}^{(t)}$:

hankcs.com 2017-07-02 上午11.07.41.png

系统一共识别出3个命名实体,在token级别和entity级别各有评测方法。

token级别

  • P值为预测出的正确非O标签比上预测出的全部非O标签,于是$p=\frac{3}{4}$

  • R值为预测出的正确非O标签比上正确答案的全部非O标签,于是$r=\frac{3}{6}$

  • $F_1$值是两者的调和平均:$F_1=\frac{2pr}{p+r}=\frac{6}{10}$

entity级别

  • P值为完美(不残缺不多余)识别的实体数量比上预测出的所有实体数量,于是$p=\frac{1}{3}$

  • R值为完美识别的实体数量比上正确答案中的实体数量,于是$r=\frac{1}{3}$

  • $F_1$值是两者的调和平均:$F_1=\frac{2pr}{p+r}=\frac{1}{3}$

1 A window into NER

基线模型使用半径$w$窗口中的特征$\boldsymbol{\tilde{x}}^{(t)}$预测$\boldsymbol{y}^{(t)}$ :

hankcs.com 2017-07-02 上午11.20.37.png

模型为一个以ReLU为激活函数的隐藏层的神经网络,输出层为softmax,损失函数为交叉熵:

$$\begin{align}
   %
   \boldsymbol{e}^{(t)} &= [ \boldsymbol{x}^{(t-w)}L, \dots, \boldsymbol{x}^{(t)}L, \dots, \boldsymbol{x}^{(t+w)}L ] \nonumber \\
   %
   \boldsymbol{h}^{(t)} &= \text{ReLU}(\boldsymbol{e}^{(t)}W + \boldsymbol{b}_{1}) \nonumber \\
   %
   \hat{\boldsymbol{y}}^{(t)} &= \text{softmax}(\boldsymbol{h}^{(t)}U + \boldsymbol{b}_{2}) \nonumber \\
   %
   J &= \text{CE}(\boldsymbol{y}^{(t)}, \hat{\boldsymbol{y}}^{(t)}) \nonumber \\
   %
   \text{CE}(\boldsymbol{y}^{(t)}, \hat{\boldsymbol{y}}^{(t)}) &= -\sum_{i} y_{i}^{(t)} \log(\hat{y}_{i}^{(t)})\text{ , } \nonumber
\end{align}$$

其中$L \in \mathbb{R}^{V \times D}$是词嵌入,$\boldsymbol{h}^{(t)}$ 维度为 $H$,$\hat{\boldsymbol{y}}^{(t)}$ 维度 $C$, $V$是词表大小,$D$ 是词嵌入维度,$H$是隐藏层维度,$C$是分类数目(此处为5)。

a 概念

请列举有歧义的命名实体?

太多了:

方地/nr, 的/ude1, 茶/n, 喝/vg, 个/q, 一罐/mq

baoji.png

一个亿.jpg

通常命名实体中含有低频词,为了泛化必须引入除了字符之外的特征,比如词性。这次作业为了简单,只使用字符特征。

b 维度和复杂度

如果窗口大小为$w$,则窗口特征$\boldsymbol{e}^{(t)}$的维度是$(2w + 1) \times D$的行向量。$W$是$((2w + 1) \times D)\times H$的矩阵。$U$是$H \times C$的矩阵。

对长$T$的句子来讲,计算复杂度是$O((2w+1)DHT)$,这是因为从输入到隐藏层是计算瓶颈。

c 实现基线模型

就贴个最重要的predict方法吧:

def add_prediction_op(self):
    """Adds the 1-hidden-layer NN:
        h = Relu(xW + b1)
        h_drop = Dropout(h, dropout_rate)
        pred = h_dropU + b2
    Recall that we are not applying a softmax to pred. The softmax will instead be done in
    the add_loss_op function, which improves efficiency because we can use
    tf.nn.softmax_cross_entropy_with_logits
    When creating a new variable, use the tf.get_variable function
    because it lets us specify an initializer.
    Use tf.contrib.layers.xavier_initializer to initialize matrices.
    This is TensorFlow's implementation of the Xavier initialization
    trick we used in last assignment.
    Note: tf.nn.dropout takes the keep probability (1 - p_drop) as an argument.
        The keep probability should be set to the value of dropout_rate.
    Returns:
        pred: tf.Tensor of shape (batch_size, n_classes)
    """
    x = self.add_embedding()
    dropout_rate = self.dropout_placeholder
    ### YOUR CODE HERE (~10-20 lines)
    b1 = tf.get_variable(name='b1', shape = [self.config.hidden_size,], \
                         initializer=tf.contrib.layers.xavier_initializer(seed=1))
    b2 = tf.get_variable(name='b2', shape = [self.config.n_classes], \
                         initializer=tf.contrib.layers.xavier_initializer(seed=2))
    W = tf.get_variable(name='W', shape = [self.config.n_window_features * self.config.embed_size, self.config.hidden_size], \
                        initializer=tf.contrib.layers.xavier_initializer(seed=3))
    U = tf.get_variable(name='U', shape = [self.config.hidden_size, self.config.n_classes], \
                        initializer=tf.contrib.layers.xavier_initializer(seed=4))
    z1 = tf.matmul(x,W) + b1
    h = tf.nn.relu(z1)
    h_drop = tf.nn.dropout(h, dropout_rate)
    pred = tf.matmul(h_drop,U) + b2
    ### END YOUR CODE
    return pred

d 分析结果

DEBUG:Token-level confusion matrix:
go\gu   PER     ORG     LOC     MISC    O    
PER     2968    26      84      16      55   
ORG     147     1621    131     65      128  
LOC     48      88      1896    26      36   
MISC    37      40      54      1030    107  
O       42      46      18      39      42614
DEBUG:Token-level scores:
label   acc     prec    rec     f1   
PER     0.99    0.92    0.94    0.93 
ORG     0.99    0.89    0.77    0.83 
LOC     0.99    0.87    0.91    0.89 
MISC    0.99    0.88    0.81    0.84 
O       0.99    0.99    1.00    0.99 
micro   0.99    0.98    0.98    0.98 
macro   0.99    0.91    0.89    0.90 
not-O   0.99    0.89    0.87    0.88 
INFO:Entity level P/R/F1: 0.82/0.85/0.84

最拖后腿的是机构名识别,经常误识别为人名或非NER。

由于窗口的限制,模型不擅长做完整连续的识别,如果增大窗口则会有所进步。

窗口=2

DEBUG:Token-level confusion matrix:
go\gu   PER     ORG     LOC     MISC    O    
PER     2995    23      50      10      71   
ORG     148     1679    96      52      117  
LOC     54      65      1910    24      41   
MISC    40      51      48      1029    100  
O       34      42      25      29      42629
DEBUG:Token-level scores:
label   acc     prec    rec     f1   
PER     0.99    0.92    0.95    0.93 
ORG     0.99    0.90    0.80    0.85 
LOC     0.99    0.90    0.91    0.90 
MISC    0.99    0.90    0.81    0.85 
O       0.99    0.99    1.00    0.99 
micro   0.99    0.98    0.98    0.98 
macro   0.99    0.92    0.89    0.91 
not-O   0.99    0.91    0.88    0.90 
INFO:Entity level P/R/F1: 0.85/0.87/0.86

知识共享许可协议 知识共享署名-非商业性使用-相同方式共享码农场 » CS224n Assignment 3

评论 5

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  1. #4

    q3_gru.py add_prediction_op() 中dynamic_rnn应该取output而不是state吧?
    outputs, state = tf.nn.dynamic_rnn(cell, x, dtype=tf.float32)
    output = outputs[:, -1]
    preds = tf.sigmoid(output)

    thinkdoom6年前 (2018-05-29)回复
    • 代码提示里有写“returns the final state as a prediction”

      wswsdcc5年前 (2018-12-24)回复
  2. #3

    3 GRU–a latch–ii这道题目的最后一种情况,即h(t−1)=1, x(t)=1,为何h~(t)必须为0?是否可以是这种情况:h~(t)=1, 而z(t)=0,仍然可以使h(t)=1。
    博主请抽空指点一下,谢谢

    人墙6年前 (2017-11-28)回复
  3. #2

    3 GRU a latch ii这个题的最后一种情况,当x_t=h_t=1时,h~t为什么只能为0?h~t和z_t同为1,h_t也能为1,对不对?楼主能抽空答疑一下吗,谢谢。

    人墙6年前 (2017-11-28)回复
  4. #1

    谢谢博主= =!
    因为用的win10,作业要求用python2.7,但没有对应的tensorFlow版本….(也是醉了)
    全靠您的代码,我才可以校对
    很谢谢

    zy7年前 (2017-08-17)回复

我的作品

HanLP自然语言处理包《自然语言处理入门》