-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmodel.py
109 lines (87 loc) · 4.42 KB
/
model.py
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import numpy as np
import tensorflow as tf
class Model():
def __init__(self, learning_rate=0.001, batch_size=16, num_steps=32, num_words=5000, dim_embedding=128, rnn_layers=3):
r"""初始化函数
Parameters
----------
learning_rate : float
学习率.
batch_size : int
batch_size.
num_steps : int
RNN有多少个time step,也就是输入数据的长度是多少.
num_words : int
字典里有多少个字,用作embeding变量的第一个维度的确定和onehot编码.
dim_embedding : int
embding中,编码后的字向量的维度
rnn_layers : int
有多少个RNN层,在这个模型里,一个RNN层就是一个RNN Cell,各个Cell之间通过TensorFlow提供的多层RNNAPI(MultiRNNCell等)组织到一起
"""
self.batch_size = batch_size
self.num_steps = num_steps
self.num_words = num_words
self.dim_embedding = dim_embedding
self.rnn_layers = rnn_layers
self.learning_rate = learning_rate
def make_cell(self):
cell = tf.nn.rnn_cell.BasicLSTMCell(num_units=self.dim_embedding)
if self.is_training == 1 and self.keep_prob < 1:
cell = tf.nn.rnn_cell.DropoutWrapper(cell, output_keep_prob=self.keep_prob)
return cell
def build(self, embedding_file=None):
# global step
self.global_step = tf.Variable(
0, trainable=False, name='self.global_step', dtype=tf.int64)
self.X = tf.placeholder(
tf.int32, shape=[None, self.num_steps], name='input')
self.Y = tf.placeholder(
tf.int32, shape=[None, self.num_steps], name='label')
self.keep_prob = tf.placeholder(tf.float32, name='keep_prob')
self.is_training = tf.placeholder(tf.int32, name='is_training')
with tf.variable_scope('embedding'):
if embedding_file:
# if embedding file provided, use it.
embedding = np.load(embedding_file)
embed = tf.constant(embedding, name='embedding')
else:
# if not, initialize an embedding and train it.
embed = tf.get_variable(
'embedding', [self.num_words, self.dim_embedding])
tf.summary.histogram('embed', embed)
data = tf.nn.embedding_lookup(embed, self.X)
with tf.variable_scope('rnn'):
##################
lstm_cell = tf.nn.rnn_cell.MultiRNNCell([self.make_cell() for i in range(self.rnn_layers)])
self.state_tensor = lstm_cell.zero_state(self.batch_size,dtype=tf.float32)
seq_output,self.outputs_state_tensor = tf.nn.dynamic_rnn(lstm_cell,data,initial_state=self.state_tensor)
##################
# flatten it
seq_output_final = tf.reshape(seq_output, [-1, self.dim_embedding])
with tf.variable_scope('softmax'):
##################
w_o = tf.get_variable('w_o',[self.dim_embedding,self.num_words],initializer=tf.truncated_normal_initializer(stddev=0.001))
b_o = tf.get_variable('b_o',[self.num_words,],initializer=tf.constant_initializer(0.0))
logits = tf.matmul(seq_output_final,w_o)+b_o
##################
tf.summary.histogram('logits', logits)
self.predictions = tf.nn.softmax(logits, name='predictions')
loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=tf.reshape(self.Y, [-1]),logits=logits)
mean, var = tf.nn.moments(logits, -1)
self.loss = tf.reduce_mean(loss)
tf.summary.scalar('logits_loss', self.loss)
var_loss = tf.divide(10.0, 1.0+tf.reduce_mean(var))
tf.summary.scalar('var_loss', var_loss)
# 把标准差作为loss添加到最终的loss里面,避免网络每次输出的语句都是机械的重复
self.loss = self.loss + var_loss
tf.summary.scalar('total_loss', self.loss)
# gradient clip
tvars = tf.trainable_variables()
grads, _ = tf.clip_by_global_norm(tf.gradients(loss, tvars), 5)
train_op = tf.train.AdamOptimizer(self.learning_rate)
self.optimizer = train_op.apply_gradients(
zip(grads, tvars), global_step=self.global_step)
tf.summary.scalar('loss', self.loss)
self.merged_summary_op = tf.summary.merge_all()