Event-Extraction/models/Extracting Entities and Events as a Single Task Using a Transition-Based Neural Model/ops.py
2020-10-04 21:33:42 +08:00

136 lines
4.2 KiB
Python

import numpy as np
import dynet as dy
import nn
def cat(xs, dim=-1):
head_shape, batch_size = xs[0].dim()
if dim > len(head_shape):
raise RuntimeError('Bad dim %d for shape %s, you can '
'use -1 to indicate last dim '
% (dim, str(head_shape)))
if dim == -1:
dim = len(head_shape)
return dy.concatenate(xs, d=dim)
def expand_dims(x, dim=-1):
head_shape, batch_size = x.dim()
if dim > len(head_shape):
raise RuntimeError('Bad dim %d for shape %s, you can '
'use -1 to indicate last dim '
%(dim, str(head_shape)))
if dim == -1:
dim = len(head_shape)
ex_shape = list(head_shape)
ex_shape.insert(dim, 1)
return dy.reshape(x, tuple(ex_shape))
def layer_norm(xs):
head_shape, batch_size = xs[0].dim()
g = dy.ones(head_shape)
b = dy.zeros(head_shape)
return [dy.layer_norm(x, g, b) for x in xs]
def squeeze(x, dim=None):
head_shape, batch_size = x.dim()
if dim is None:
sq_shape = [d for d in head_shape if d != 1]
else:
if dim > len(head_shape):
raise RuntimeError('Bad dim %d for shape %s, you can '
'use -1 to indicate last dim. Hint: '
'you can not squeeze batch dim due to dynet mechanism'
% (dim, str(head_shape)))
if head_shape[dim] != 1:
raise RuntimeError('You can not squeeze dim %d for shape %s' % (dim, str(head_shape)))
sq_shape = list(head_shape)
sq_shape.pop(dim)
return dy.reshape(x , tuple(sq_shape))
def sum(x, dim=None, include_batch_dim=False):
if isinstance(x, list):
return dy.esum(x)
head_shape, batch_size = x.dim()
if dim is None:
x = dy.sum_elems(x)
if include_batch_dim and batch_size > 1:
return dy.sum_batches(x)
else:
return x
else:
if dim == -1:
dim = len(head_shape) - 1
return dy.sum_dim(x, d=[dim], b=include_batch_dim)
def mean(x, dim=None, include_batch_dim=False):
if isinstance(x, list):
return dy.average(x)
head_shape, batch_size = x.dim()
if dim is None:
# warning: dynet only implement 2 or lower dims for mean_elems
x = dy.mean_elems(x)
if include_batch_dim and batch_size > 1:
return dy.mean_batches(x)
else:
return x
else:
if dim == -1:
dim = len(head_shape) - 1
return dy.mean_dim(x, d=[dim], b=include_batch_dim)
def split(x, dim=1):
head_shape, batch_size = x.dim()
res = []
if dim == 0:
for i in range(head_shape[0]):
res.append(dy.select_rows(x, [i]))
elif dim == 1:
for i in range(head_shape[1]):
res.append(dy.select_cols(x, [i]))
return res
def pick_mat(x, row_idx, col_idx):
return x[row_idx][col_idx]
def logsumexp_dim(x, dim=0):
return dy.logsumexp_dim(x, d=dim)
# def logsumexp(x):
# return dy.logsumexp(x)
def log_sum_exp(scores, n_tags):
npval = scores.npvalue()
argmax_score = np.argmax(npval)
max_score_expr = dy.pick(scores, argmax_score)
max_score_expr_broadcast = dy.concatenate([max_score_expr] * n_tags)
return max_score_expr + dy.log(dy.sum_cols(dy.transpose(dy.exp(scores - max_score_expr_broadcast))))
def dropout_list(rep_list, dp_rate):
return [dy.dropout(rep, dp_rate) for rep in rep_list]
def dropout_dim_list(rep_list, dp_rate, dim=0):
return [dy.dropout_dim(rep, dim, dp_rate) for rep in rep_list]
def cat_list(rep_list_a, rep_list_b, dim=0):
return [dy.concatenate([rep_a, rep_b], d=dim) for rep_a, rep_b in zip(rep_list_a, rep_list_b)]
def add_list(rep_list_a, rep_list_b):
return [rep_a + rep_b for rep_a, rep_b in zip(rep_list_a, rep_list_b)]
def sum_list(rep_list_a, rep_list_b):
return [rep_a+rep_b for rep_a, rep_b in zip(rep_list_a, rep_list_b)]
def binary_cross_entropy(x, y):
max_val = nn.relu(-x)
loss = x - dy.cmult(x, y) + max_val + dy.log(dy.exp(-max_val) + dy.exp(-x - max_val))
return nn.mean(loss)
def max_np(np_vec):
np_vec = np_vec.flatten()
return np.max(np_vec), np.argmax(np_vec)