pointnet學習(六)train函數第七第八句


 

 第七句

tf.summary.scalar('bn_decay', bn_decay)

查看pointnet學習(二)tf.summary.scalar含義

 第八句

pred, end_points = MODEL.get_model(pointclouds_pl, is_training_pl, bn_decay=bn_decay)

字面意思是獲取模型。調用的是配置模型的get_model,這裏解讀配置的是pointnet_cls.py文件裏的model,主要神經網絡的搭建,初始化。具體實現爲

def get_model(point_cloud, is_training, bn_decay=None):
    """ Classification PointNet, input is BxNx3, output Bx40 """
    batch_size = point_cloud.get_shape()[0].value
    num_point = point_cloud.get_shape()[1].value
    end_points = {}

    with tf.variable_scope('transform_net1') as sc:
        transform = input_transform_net(point_cloud, is_training, bn_decay, K=3)
    point_cloud_transformed = tf.matmul(point_cloud, transform)
    input_image = tf.expand_dims(point_cloud_transformed, -1)

    net = tf_util.conv2d(input_image, 64, [1,3],
                         padding='VALID', stride=[1,1],
                         bn=True, is_training=is_training,
                         scope='conv1', bn_decay=bn_decay)
    net = tf_util.conv2d(net, 64, [1,1],
                         padding='VALID', stride=[1,1],
                         bn=True, is_training=is_training,
                         scope='conv2', bn_decay=bn_decay)

    with tf.variable_scope('transform_net2') as sc:
        transform = feature_transform_net(net, is_training, bn_decay, K=64)
    end_points['transform'] = transform
    net_transformed = tf.matmul(tf.squeeze(net, axis=[2]), transform)
    net_transformed = tf.expand_dims(net_transformed, [2])

    net = tf_util.conv2d(net_transformed, 64, [1,1],
                         padding='VALID', stride=[1,1],
                         bn=True, is_training=is_training,
                         scope='conv3', bn_decay=bn_decay)
    net = tf_util.conv2d(net, 128, [1,1],
                         padding='VALID', stride=[1,1],
                         bn=True, is_training=is_training,
                         scope='conv4', bn_decay=bn_decay)
    net = tf_util.conv2d(net, 1024, [1,1],
                         padding='VALID', stride=[1,1],
                         bn=True, is_training=is_training,
                         scope='conv5', bn_decay=bn_decay)

    # Symmetric function: max pooling
    net = tf_util.max_pool2d(net, [num_point,1],
                             padding='VALID', scope='maxpool')

    net = tf.reshape(net, [batch_size, -1])
    net = tf_util.fully_connected(net, 512, bn=True, is_training=is_training,
                                  scope='fc1', bn_decay=bn_decay)
    net = tf_util.dropout(net, keep_prob=0.7, is_training=is_training,
                          scope='dp1')
    net = tf_util.fully_connected(net, 256, bn=True, is_training=is_training,
                                  scope='fc2', bn_decay=bn_decay)
    net = tf_util.dropout(net, keep_prob=0.7, is_training=is_training,
                          scope='dp2')
    net = tf_util.fully_connected(net, 40, activation_fn=None, scope='fc3')

    return net, end_points

從返回值來看,model就是net以及end_points 

 然後看看輸入參數,第一個是pointcloud=pointclouds_pl,第二個是istrainning=is_training_pl,第三個是bn_decay=bn_decay。回想學習,pointnet學習(五)train函數,第五、六句

則可知,pointcloud是一個shape(32x1024x3)的三維的tensor,裏面存放點雲數據,istrainning是一個bool類型的tensor,shape沒有指定,

現在看getmodel函數體內code:

第一句,獲取bitchsize即爲32,第二句爲獲取點數量1024,第三句爲聲明一個endpoint爲dict字典

第四第五句,爲加載transformnet,因爲pointnet網絡在進行分類之前先進入transformnet將點雲旋轉爲正向方位,雖然有後續文章之處此net對後續分類並沒有什麼影響,但是還是照舊加上了。

tf.variable_scope('transform_net1') as sc

設置transformnet名字爲transform_net1。

transform = input_transform_net(point_cloud, is_training, bn_decay, K=3)

下面來看transform_net的構建,也是包括了跟model一樣的三個參數,除此之外添加了一個K參數。

定義另一維的kernel的值,此工程返回的transform_net的shape爲[32,3,3]輸出對應bitchsize個3x3旋轉矩陣,根據卷積,池化得到的大量特徵點的旋轉矩陣,有點類似圖像處理中提取特徵點,然後對比源和目標特徵點計算的旋轉矩陣的原理,參考pointnet學習(七)input_transform_net

得到transformnet的輸出之後,與inputcloud進行叉乘,得到

第六句

point_cloud_transformed = tf.matmul(point_cloud, transform)

旋轉矩陣求得之後,那麼就應該讓我們的input的point_cloud經過相乘得到正向的點雲模型了,後面

第七句

input_image = tf.expand_dims(point_cloud_transformed, -1)

爲了卷積,繼續對旋轉後的32個batch的點雲模型進行卷積

第八、九句,

net = tf_util.conv2d(input_image, 64, [1,3],
                         padding='VALID', stride=[1,1],
                         bn=True, is_training=is_training,
                         scope='conv1', bn_decay=bn_decay)
    net = tf_util.conv2d(net, 64, [1,1],
                         padding='VALID', stride=[1,1],
                         bn=True, is_training=is_training,
                         scope='conv2', bn_decay=bn_decay)

這兩句就很熟悉了,參考pointnet學習(八)tf_util.conv2d,也是對我旋轉後的點雲模型,xyz進行卷積,因爲輸出爲64,所以有64個1x3的核驗numpoint方向以及xyz方向,1,1步幅進行卷積,得到了32,1024,1,64的tensor,因爲沒有maxpolling所以依然是1024個點的每個點的xyz卷積和分爲64個channel存儲因爲同一個點讓64個1,3卷積kernel進行了卷積。

第九句,繼續進行卷積,依然出來32,1024,1,64的tensor這裏相當於對於這卷積後的xyz繼續乘以一個w+b的到的值

第十,十一句

    with tf.variable_scope('transform_net2') as sc:
        transform = feature_transform_net(net, is_training, bn_decay, K=64)

第二個transform的網絡層。是對特徵值進行旋轉偏移,參考pointnet input_transform_net

第十二句

 net_transformed = tf.matmul(tf.squeeze(net, axis=[2]), transform)
先看tf.squeeze(net, axis=[2]),功能是,移除tensor中所有維度爲1的數據或者指定某一維的數據移除,這句是指移除32,1024,1,64中第三維數據,變爲32,1024,64的tensor。跟feature transform64*64進行矩陣相乘,旋轉,偏移。得到新的卷積得到特徵值之後的input、

第十三句

net_transformed = tf.expand_dims(net_transformed, [2])

重新將之前刪除的第三維拓展方便後續的卷積運算

十四~十八句。對32,1024,1,64的tensor進行卷積,分別輸出[32,1024,1,64]tensor,[32,1024,1,126]tensor,[32,1024,1,1024]tensor,最後maxpolling輸出得到[32,1,1,1024]tensor,重新reshape爲[32,1024]tensor.

十九句,初始化一個1024,512的weighttensor以及512,512的biastensor進行運算得到32,512的tensor

第二十句

net = tf_util.dropout(net, keep_prob=0.7, is_training=is_training,
                          scope='dp1')

參考pintnet tf_util.dropout

第二十一二十二句與第十九二十句一樣,轉換爲32,256tensor,

第二十三句,最後一層fullyconnect,乘以weight+你、bias,最後得到32,40tensor,

至此,net與transformnet搭建完成

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章