Tensorflow1.14中placeholder.shape和tf.shape(placeholder)的區別
最近在看TensorFlow的程式碼,還是1.14版本的TensorFlow的,程式碼難度確實比pytorch的難上不是多少倍,pytorch的程式碼看一遍基本能看懂個差不多,TensorFlow的程式碼看一遍沒懂,再看一遍還沒懂,再看一遍呢,還沒懂,不過這時候基本也就快崩潰了。
記錄一個剛學到的TensorFlow的知識點,那就是對TensorFlow中的tensor取shape操作時需要注意的事項,也就是說有一個TensorFlow的tensor,它是由placeholder生成的,使用程式碼如下:
import tensorflow as tf import numpy as np num_actions= 5 p=tf.placeholder(shape=(None, 4), dtype=np.int8) batch_size = tf.shape(p)[0] random_actions = tf.random_uniform(tf.stack([batch_size]), minval=0, maxval=num_actions, dtype=tf.int64) with tf.Session() as sess: print( sess.run(random_actions, {p:np.array([[1,1,1,1], [2,2,2,2], [3,3,3,3], [4,4,4,4]])}) )
執行後結果:
import tensorflow as tf import numpy as np num_actions = 5 p=tf.placeholder(shape=(None, 4), dtype=np.int8) # batch_size = tf.shape(p)[0] batch_size = p.shape[0] random_actions = tf.random_uniform(tf.stack([batch_size]), minval=0, maxval=num_actions, dtype=tf.int64) with tf.Session() as sess:print( sess.run(random_actions, {p:np.array([[1,1,1,1], [2,2,2,2], [3,3,3,3], [4,4,4,4]])}) )
執行結果:(報錯)
兩個程式碼的區別就是對於一個placeholder生成的tensor,對它取某個維度,如果它的某個維度在定義時並沒有賦值,也就是使用了None數值來佔位,那麼再構建神經網路時用到了這個維度如果取這個維度是用tensorflow的函式來取和直接呼叫這個tensor的shape來取會有不同的效果的。
如果是使用TensorFlow的函式,tf.shape來取,這個維度及時沒有賦值也是會一個TensorFlow的變數存在的:
可以知道取這個維度的變數本身也就是一個tensor變數,即時這個變數的數值並不清楚(因為它是由None佔位生成的),這個tensor變數也是可以進行下一步操作的。
但是如果使用p.shape[0]的方式,那麼取出的其實是一個python變數而不是tensor變數,而這個python變數內部儲存的數值是None,而這個數值是不能參與TensorFlow中的神經網路構建的:
因此,上面的第二個程式碼執行時會報錯。
==================================================================
修改程式碼:
import tensorflow as tf import numpy as np num_actions = 5 p=tf.placeholder(shape=(None, 4), dtype=np.int8) batch_size = tf.shape(p)[1] random_actions = tf.random_uniform(tf.stack([batch_size]), minval=0, maxval=num_actions, dtype=tf.int64) with tf.Session() as sess: print( sess.run(random_actions, {p:np.array([[1,1,1,1], [2,2,2,2], [3,3,3,3], [4,4,4,4]])}) )
import tensorflow as tf import numpy as np num_actions = 5 p=tf.placeholder(shape=(None, 4), dtype=np.int8) # batch_size = tf.shape(p)[0] # batch_size = p.shape[0] batch_size = p.shape[1] random_actions = tf.random_uniform(tf.stack([batch_size]), minval=0, maxval=num_actions, dtype=tf.int64) with tf.Session() as sess: print( sess.run(random_actions, {p:np.array([[1,1,1,1], [2,2,2,2], [3,3,3,3], [4,4,4,4]])}) )
上面的這兩個程式碼均可以正常執行。
這說明python的數值是可以參與TensorFlow的神經網路構建的,只不過None是不可以參與TensorFlow的網路構建的,如果某個tensor的維度是由placeholder的None生成的,我們只能使用tf.shape的方式來取,這樣取到的則為還沒有賦值的tensor變數而不是None的python變數。
========================================