Tensorflow的记忆

一般,我们在参加某个比赛或者实现某种算法的时候,需要经历以下几个过程:

  1. 数据集收集、清洗
  2. 特征构建
  3. 模型实现
  4. 得到结果,再根据反馈在2-4进行多次想法的迭代

其中,在模型实现上,比如我主要方向是NLP,而NLP如今基本是深度学习时代(特别是预训练模型BERT出来后),因此多需要对深度学习框架有比较深的了解和使用经验。而Tensorflow和Pytorch两家经常被用来做对比。Tensorflow其实更适合用在工业界(静态图,TensorFlow的运行机制属于”定义”与”运行“相分离。),而Pytorch由于其方便性(动态图)而广泛流行于学术界。所以往往,实际操作时,我们通常会使用Pytorch快速实现模型,在对结果进行多次尝试找到最优参数后,再将使用Tensorflow进行复现。也就是说,Tensorflow很重要!!

Tensorflow的概念:

  1. 张量(tensor):TensorFlow程序使用tensor数据结构来代表所有的数据,计算图中,操作间传递的数据都是tensor,你可以把TensorFlow tensor看做一个n维的数组或者列表。
  2. 变量(variable):常用于定义模型中的参数,是通过不断训练得到的值。比如权重和偏置。
  3. 占位符(placeholder):输入变量的载体。也可以理解成定义函数时的参数。
  4. 图中的节点操作(op):一个op获得0个或者多个Tensor,执行计算,产生0个或者多个Tensor。op是描述张量中的运算关系,是网络中真正结构。

一个TensorFlow图描述了计算的过程,为了进行计算,图必须在会话里启动,会话将图的op分发到诸如CPU或者GPU的设备上,同时提供执行op的方法,这些方法执行后,将产生的tensor返回,在python语言中,返回的tensor是numpy array对象,在C或者C++语言中,返回的tensor是tensorflow:Tensor实例。

session与图的交互过程中定义了以下两种数据的流向机制:

  • 注入机制(feed):通过占位符向模式中传入数据
  • 取回机制(fetch):从模式中取得结果

所以,这里就是记录一些,Tensorflow常用的函数之类的,也当做我的小小笔记本好了。

1
2
3
# NLP类Tensorflow常用导入包
import tensorflow as tf
import tensorflow.contrib.seq2seq as seq2seq

关于tensowflow中的会话相关操作,参考博客:https://www.cnblogs.com/zyly/p/8869763.html

1
2
# set GPU fraction
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=args.gpu_fraction)
1
2
3
4
5
6
7
8
9
10
11
with tf.Session(config=tf.ConfigProto(gpu_options=gpu_options)) as sess:
# build model or load model, 以我参加的一个比赛为例
model = Seq2SeqModel(args, word2id, embeddings)

# 如果有训练好的模型,则导入
# load checkpoint if exists
ckpt = tf.train.get_checkpoint_state(args.model_dir)
if ckpt and tf.train.checkpoint_exists(ckpt.model_checkpoint_path):
model.saver.restore(sess, ckpt.model_checkpoint_path)
else: # 如果没有模型,则初始化参数,进行训练
sess.run(tf.global_variables_initializer())

Tensorflow的summary用法参考博客:https://www.cnblogs.com/lyc-seu/p/8647792.html

1
2
3
4
5
6
7
# 指定一个文件用来保存图,之后可以使用tensorboard查看训练过程
summary_writer = tf.summary.FileWriter(args.model_dir, sess=sess.graph)

# 训练过程中
for batch in tqdm(batches, desc='Training'):
# 如果我们需要记录某个step的图,则调用summary_writer
summary_writer.add_summary(summary, cur_step)

构建多层RNN

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def _create_rnn_cell(self, hidden_size, rnn_type='lstm'):
"""
Create multi-layer rnn with dropout layer, called by decoder
"""
def a_cell(hidden_size, rnn_type):
if rnn_type == 'lstm':
single_cell = tf.contrib.rnn.LSTMCell(hidden_size)
else:
single_cell = tf.contrib.rnn.GRUCell(hidden_size)
cell = tf.contrib.rnn.DropoutWrapper(single_cell, output_keep_prob=self.keep_prob)
return cell

rnn_cell = tf.contrib.rnn.MultiRNNCell([a_cell(hidden_size, rnn_type) for _ in range(self.num_layers)])
return rnn_cell

创建模型:

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
class Seq2SeqModel(object):
def __init__(self, args):
self.num_layers = args.num_layers
# 初始化参数...
def build_model(self, embedding):
## 设置占位符(
self.keep_prob = tf.placeholder(tf.float32, [], name='keep_prob')
self.src_enc_input = tf.placeholder(tf.int32, [None, None], name='src_enc_input')
if self.train_wordvec:
self.word_embed = tf.get_variable('embedding', [self.vocab_size, self.emb_size], dtype=tf.float32)
self.word_embed.assign(embedding)
else:
self.word_embed = tf.get_variable('embedding', [self.vocab_size, self.emb_size], trainable=False, dtype=tf.float32)
self.word_embed.assign(embedding)

## embedding_lookup
self.src_enc_emb = tf.nn.embedding_lookup(self.word_embed, self.src_enc_input)
# ...

##### encoder
src_enc_output, src_enc_state = self.cudnn_rnn(self.num_dirs, self.src_input_emb, self.src_enc_length, self.hidden_size, 'src_enc', self.rnn_type)
# ...
self.tgt_dec_input = tf.placeholder(tf.int32, [None, None], name='tgt_dec_input')
self.tgt_dec_length = tf.placeholder(tf.int32, [None], name='tgt_dec_length')
self.max_target_length = tf.reduce_max(self.tgt_dec_length, name='max_target_length')
# 序列掩码,用于decoder部分
self.mask = tf.sequence_mask(self.tgt_dec_length, self.max_target_length, dtype=tf.float32, name='mask')

##### decoder
1
2
3
4
5
6
# 优化器
optimizer = tf.train.AdamOptimizer(self.learning_rate)
trainable_params = tf.trainable_variables()
gradients = tf.gradients(self.loss, trainable_params)
clip_gradients, _ = tf.clip_by_global_norm(gradients, self.max_grad_norm)
self.train_op = optimizer.apply_gradients(zip(clip_gradients, trainable_params))