Tensorflow中的reshape、set_shape的区别!!!
讨论reshape与set_shape的区别之前,我们首先需要知道dynamic shape和static shape的区别:
Tensorflow在构建图的时候,tensor的shape被称为static(inferred);而在实际运行中,常常出现图中tensor的具体维数不确定而用placeholder代替的情况,因此static shape未必是已知的。tensor在训练过程中的实际维数被称为dynamic shape,而dynamic shape是一定的。
import tensorflow as tf
x1 = tf.placeholder(tf.int32)
print(x1.get_shape())
sess = tf.Session()
print(sess.run(tf.shape(x1), feed_dict={x1:[0,1,2,3]}))
print(sess.run(tf.shape(x1), feed_dict={x1:[[0,1],[2,3]]}))
结果为:
unknown
[4]
[2,2]
第一个结果代表构建图时x1的shape,此时它是未知的,尽管在Session中运行了以后给出了[0,1,2,3]的传入值,但无法改变图中的x1的static shape。而后面的print也可以看到,随着传入值的不同,x1的dynamic shape是会变化的。
get_shape()方法和tf.shape()的区别,get_shape()是tensor的方法,返回一个tuple,而tf.shape()则返回一个tensor。第三行的unknown直接代表了x1的shape数组,假如我们这里用:
print(tf.shape(x1))
shape返回值是一个tensor,而get_shape返回的是一个tuple.因此,我们在获取x1的shape的时候,要用tf.shape方法,让指针指向一个tensor,不然使用get_shape()指针就会指向一个tuple从而报错。
下面说下set_shape()和reshape()的区别。其实从官方说明中可以看出,这两个主要是适用场合的区别,前者用于更新图中某个tensor的shape,而后者则往往用于动态地创建一个新的tensor。
一个set_shape的典型用法如下:
import tensorflow as tf
x1 = tf.placeholder(tf.int32)
x1.set_shape([2,2])
print(x1.get_shape())
sess = tf.Session()
#print(sess.run(tf.shape(x1), feed_dict={x1:[0,1,2,3]}))
print(sess.run(tf.shape(x1), feed_dict={x1:[[0,1],[2,3]]}))
(2,2)
[2,2]
这代表了图中最开始没有shape的x1在使用了set_shape后,它的图中的信息已经改变了,如果取消掉注释就会报错,因为我们传入了和图不符合的参数。
reshape的典型用法则是这样:
import tensorflow as tf
x1 = tf.placeholder(tf.int32)
x2 = tf.reshape(x1, [2,2])
print(x1.get_shape())
sess = tf.Session()
print(sess.run(tf.shape(x2), feed_dict={x1:[0,1,2,3]}))
print(sess.run(tf.shape(x2), feed_dict={x1:[[0,1],[2,3]]}))
(2,2)
[2,2]
[2,2]
即它并不是想改变图,而只是想创造一个新的tensor以供我们使用。
但是reshape能否和set_shape有着相同的用法,即用来改变图?我们试着修改上面的代码:
import tensorflow as tf
x1 = tf.placeholder(tf.int32)
x1 = tf.reshape(x1, [2,2]) # use tf.reshape()
print(tf.shape(x1))
sess = tf.Session()
#print(sess.run(tf.shape(x1), feed_dict={x1:[0,1,2,3]}))
print(sess.run(tf.shape(x1), feed_dict={x1:[[0,1],[2,3]]}))
经测试,reshape后x1的shape也发生了变化,注释不取消仍然会有报错现象。
那么set_shape和reshape的用法是否完全一样呢?还是有一定差别的。
reshape可以改变原有tensor的shape,而set_shape只能更新信息没办法直接改变值,可以参考下面的程序:
import tensorflow as tf
x1 = tf.Variable([[0, 1], [2, 3]])
print(x1.get_shape())
x1 = tf.reshape(x1, [4, 1]) # if we use x1.set_shape([4, 1]),the program cannot run
print(x1.get_shape())
最后总结一下,reshape应用场合比较广泛,当我们需要创建新的tensor或者动态地改变原有tensor的shape的时候可以使用;而当我们只是想更新图中某个tensor的shape或者补充某个tensor的shape信息可以使用set_shape来进行更新。
本文深入探讨了TensorFlow中reshape与set_shape的区别,解释了它们在更新tensor形状和创建新tensor上的不同用途。同时,文章还解析了staticshape与dynamicshape的概念,以及get_shape()与tf.shape()的使用场景。
2791

被折叠的 条评论
为什么被折叠?



