forked from neubig/nn4nlp-code
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcnn-class.py
More file actions
76 lines (66 loc) · 2.42 KB
/
cnn-class.py
File metadata and controls
76 lines (66 loc) · 2.42 KB
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
from collections import defaultdict
import time
import random
import dynet as dy
import numpy as np
# Functions to read in the corpus
w2i = defaultdict(lambda: len(w2i))
t2i = defaultdict(lambda: len(t2i))
UNK = w2i["<unk>"]
def read_dataset(filename):
with open(filename, "r") as f:
for line in f:
tag, words = line.lower().strip().split(" ||| ")
yield ([w2i[x] for x in words.split(" ")], t2i[tag])
# Read in the data
train = list(read_dataset("../data/classes/train.txt"))
w2i = defaultdict(lambda: UNK, w2i)
dev = list(read_dataset("../data/classes/test.txt"))
nwords = len(w2i)
ntags = len(t2i)
# Start DyNet and define trainer
model = dy.ParameterCollection()
trainer = dy.AdamTrainer(model)
# Define the model
EMB_SIZE = 64
W_emb = model.add_lookup_parameters((nwords, 1, 1, EMB_SIZE)) # Word embeddings
WIN_SIZE = 3
FILTER_SIZE = 64
W_cnn = model.add_parameters((1, WIN_SIZE, EMB_SIZE, FILTER_SIZE)) # cnn weights
b_cnn = model.add_parameters((FILTER_SIZE)) # cnn bias
W_sm = model.add_parameters((ntags, FILTER_SIZE)) # Softmax weights
b_sm = model.add_parameters((ntags)) # Softmax bias
def calc_scores(words):
dy.renew_cg()
if len(words) < WIN_SIZE:
words += [0] * (WIN_SIZE-len(words))
cnn_in = dy.concatenate([dy.lookup(W_emb, x) for x in words], d=1)
cnn_out = dy.conv2d_bias(cnn_in, W_cnn, b_cnn, stride=(1, 1), is_valid=False)
pool_out = dy.max_dim(cnn_out, d=1)
pool_out = dy.reshape(pool_out, (FILTER_SIZE,))
pool_out = dy.rectify(pool_out)
return W_sm * pool_out + b_sm
for ITER in range(100):
# Perform training
random.shuffle(train)
train_loss = 0.0
train_correct = 0.0
start = time.time()
for words, tag in train:
scores = calc_scores(words)
predict = np.argmax(scores.npvalue())
if predict == tag:
train_correct += 1
my_loss = dy.pickneglogsoftmax(scores, tag)
train_loss += my_loss.value()
my_loss.backward()
trainer.update()
print("iter %r: train loss/sent=%.4f, acc=%.4f, time=%.2fs" % (ITER, train_loss/len(train), train_correct/len(train), time.time()-start))
# Perform testing
test_correct = 0.0
for words, tag in dev:
scores = calc_scores(words).npvalue()
predict = np.argmax(scores)
if predict == tag:
test_correct += 1
print("iter %r: test acc=%.4f" % (ITER, test_correct/len(dev)))