tensorFlow使用心得(使用中的一些坑)
作为tensorFlow平台使用的新手,笔者在调试过程中遇到了很多坑,这里把一些作为教训贡献出来供大家参考。 1. tensorFlow数组的维度问题
由于tensorFlow的计算图是静态的,所以需要一开始进行计算题的定义,由于在定义神经网路的前向传播过程中,涉及到数组之间的运算,所以很容易出现一些隐性的错误(语法没错,但是结果不对),特别是涉及到一维数组的运算。
在神经网路的教材中,一般对某个层的权重定义的形式是????,?? 其中j是输出层的个数,k是输入层的格式,这样在前向传播模型中,输出层的激活值表示为
Wxplusb=????,?????+??
这里的x是表示输入的激活值,shape=(k,1),b是输出神经元的阈值向量,shape=(j,1)。但是在很多tensorFlow的代码中,都习惯写成
Wxplusb=????,?????+??
这样在定义x和b的时候维度就会发生改变,如果此时不注意的话就会发生以下错误。
在tensorFlow里很多人在初始化权重和阈值的时候是按照如下方式写的
Weights = get_weights_variable([in_size, out_size],regularizer) biases = tf.Variable(tf.random_normal([out_size], stddev=1))
Wx_plus_b=tf.matmul(input_tensor,Weights)+biases
在这里biases是一个一维向量,其形状是shape=(out_size, ),由于input_tensor是一个shape=(1,in_size)的二维数组,所以Wx的结果 tf.matmul(input_tensor,Weights)的shape=(1,out_size)。有一biase是一维数组,而tf.matmul(input_tensor,Weights)的shape=(1,out_size),则最终的Wx_plus_b的shape=(1,out_size)。如果你还是习惯用神经网络基础理论里提到的模式进行编程
Weights = get_weights_variable([out_size, in_size],regularizer) biases = tf.Variable(tf.random_normal([out_size,1], stddev=1))
Wx_plus_b=tf.matmul(input_tensor,Weights)+biases
注意,这里的biases是一个二维数组,其形状为shape=(out_size,1),此时input_tensor的shape=(in_size,1),最终得到的Wx_plus_b的shape=(out_size,1)。如果一切按照这个形式来没问题,但是如果在第二种情形下,对biases初始化时,还是沿用第一种编程方式里提到的手段
biases = tf.Variable(tf.random_normal([out_size], stddev=1)) 这时,由于python的broadencast原则,因为
tf.matmul(input_tensor,Weights)是一个形状为shape=(out_size,1)的二维数组,而biases是shape=(out_size, )的一维数组,最后相加的结果是一个shape=(out_size,out_size)的二维数组,这样传到下一
层网络的时候就会出错。这样因为维度造成错误的例子很多,特别是涉及到一些规约运算例如tf.reduce_mean()等等,还有一些规约求和tf.reduce_sum()
在tensorFlow里有一个函数在分类任务中使用的特别多 tf.nn.sparse_softmax_cross_entropy_with_logits(logits,la
bes)
注意这个函数的logits和labels的格式是[batch_size, class_num]即,对于这个二维数组来说,行数是实例个数,列数表示类别数,labels 是一个[batch_size, ]的一维数组
还有,对于tensorFlow程序,千万别忘了,还有feed_dict={X:x,Y:Y}需要给出,要不然根本没法执行。