1. 程式人生 > >CNN卷積層到全連線層的輸入格式變換錯誤 tf.reshape()和slim.flatten()

CNN卷積層到全連線層的輸入格式變換錯誤 tf.reshape()和slim.flatten()

TypeError: Failed to convert object of type < type ‘list’>to Tensor. Contents: [None, 9216]. Consider casting elements to a supported type.


在CNN卷積神經網路中,卷積層和全連線層進行連線時有個輸入格式轉換過程,即卷積層的輸出是一個x*y*z的矩陣,而全連線層的輸入是一個向量,需要把矩陣拉直成向量。我的程式中使用瞭如下程式碼:

# 卷積層9
weights9 = tf.get_variable('weights9', shape=[3
, 3, 256, 256], dtype=tf.float32, initializer=tf.contrib.layers.xavier_initializer(False)) conv9 = tf.nn.conv2d(actived_conv8, weights9, strides=[1, 1, 1, 1], padding='SAME') conv9 = tf.contrib.layers.batch_norm(conv9, is_training=is_train) actived_conv9 = tf.nn.relu(conv9) # 全連線層,將矩陣拉直成一個向量
conv_shape = actived_conv9.get_shape().as_list() nodes = conv_shape[1]*conv_shape[2]*conv_shape[3] # 向量的長度為矩陣的長寬及深度的乘積 reshaped = tf.reshape(actived_conv9,[conv_shape[0],nodes]) # conv_shape[0]為一個batch中資料的個數 # 全連線層1 fc1_weights = tf.get_variable('fc_weights', shape=[nodes, 512],dtype = tf.float32, initializer=tf.contrib.layers.xavier_initializer(False
)) if regularizer != None: # 正則化,只在全連線層的權重使用 tf.add_to_collection('losses',regularizer(fc1_weights)) fc1_biases = tf.get_variable('fc1_biases',[512],initializer=tf.constant_initializer(0.1)) fc1 = tf.nn.relu(tf.matmul(reshaped,fc1_weights) + fc1_biases)

然而程式執行中報出瞭如下的錯誤:TypeError: Failed to convert object of type < type ‘list’> to Tensor. Contents: [None, 9216]. Consider casting elements to a supported type.

在檢查程式後發現問題出在conv_shape[0]上面,在卷積輸入佔位符裡使用的是如下程式碼:

x_Label = tf.placeholder(tf.float32,[None,patch_size,patch_size,band])

注意shape第一維使用的是None,這是便於輸入的batch大小的調整,然而在conv_shape= actived_conv9.get_shape().as_list()中shape讀取時conv_shape[0]讀取到的是None, tf.reshape(actived_conv9,[conv_shape[0],nodes]) 函式無法將卷積層輸出的矩陣轉換為向量。

最開始我的解決辦法是將conv_shape[0] 直接換成batch的大小,這樣解決了此問題,但在後面的除錯過程中又出現另外的bug,所以不是好的方案。

最後採用的是使用slim.flatten()函式,直接進行轉換,不需要讀取shape的大小,程式碼如下:

conv9 = tf.contrib.layers.batch_norm(conv9, is_training=is_train)
actived_conv9 = tf.nn.relu(conv9)

#全連線層,將矩陣拉直成一個向量
reshaped = slim.flatten(actived_conv9)      
conv_shape = actived_conv9.get_shape().as_list()
nodes = conv_shape[1]*conv_shape[2]*conv_shape[3]   # 向量的長度為矩陣的長寬及深度的乘積

#全連線層1
fc1_weights = tf.get_variable('fc_weights', shape=[nodes, 512],dtype = tf.float32,
                              initializer=tf.contrib.layers.xavier_initializer(False))
if regularizer != None:     # 正則化,只在全連線層的權重使用
   tf.add_to_collection('losses',regularizer(fc1_weights))
fc1_biases = tf.get_variable('fc1_biases',[512],initializer=tf.constant_initializer(0.1))
fc1 = tf.nn.relu(tf.matmul(reshaped,fc1_weights) + fc1_biases)