最近一直在做Tensorflow复现Faster rcnn的工作,其中的一些细节在复现过程中遇到问题时才会发现。
首先是在Faster rcnn论文中,其核心思想是引入anchor的概念。在搭建网络时,需要人为的构造的一些anchors。这需要使用numpy库的一些操作,但操作的输入是一系列的tensor,不能使用numpy库的操作。并且输入的tensor值一开始是未知的(sess.run之前),所以无法对tensor进行判断操作(例如某个tensor的值是大于零还是小于零),这给Faster rcnn中tensors的筛选也带来的很大的麻烦。为了解决这个问题,使用了Tensorflow的一个库函数tf.py_func()。
首先看这个库函数的接口:
函数的功能是,将用户定义的函数func,func的输入为numpy数组,输出也是numpy数组。而tf.py_func能够将func函数输入转换成tensor形式,输出也是tensor形式。
函数的参数:
inp是输入的tensor list,也就是func函数接受的输入tensor,而tf.py_func函数将这些tensor转换成numpy数组的形式,输入的tensors和func函数的输入numpy数组一一对应
Tout是返回tensor的数据type,shape是list或者tuple的形式,shape的大小要与func函数的输出数量一样。
最终的输出是一系列的tensors。
下面看一个实际的例子:
def my_func(x):
# x will be a numpy array with the contents of the placeholder below
return np.sinh(x)
input = tf.placeholder(tf.float32)
y = tf.py_func(my_func, [input], tf.float32)
第二个细节就是Faster rcnn中的学习率动态改变在tensorflow中的实习。tensorflow有现成的库函数实现学习率的动态改变,但都是相隔固定步数下降固定的decay值,如何实现在训练过程中在任意步数将学习率修改成任意值,是在Faster rcnn复现过程需要考虑的。
首先将学习率设置成tf.varibale变量的形式,并且不可训练,传入的初始化参数也就是最开始的学习率:
lr = tf.Variable(cfg.TRAIN.LEARNING_RATE, trainable=False)
之后可以在任意步数通过tf.assign()操作修改学习率的值,实现学习率的动态改变。
rate *= cfg.TRAIN.GAMMA
sess.run(tf.assign(lr, rate)) #订步骤改变learning rate