使用tensorflow實現卷積的幾種操作
阿新 • • 發佈:2019-02-02
這裡簡要總結一下tensorflow實現卷積操作的幾種寫法,定義方式有很多。例如使用一個9x9的卷積核將一個三通道影象轉換成64通道的feature,遇到過的有以下一些:
直接定義就寫
這種寫法簡單粗暴,一邊定義卷積核、偏置和卷及操作一邊寫,優點是操作靈活,但是程式碼量太大尤其是重複單元較多的時候,一個例子如下:
weight = tf.get_variable('weight',[9,9,3,64], initializer=tf.truncated_normal_initializer(stddev=0.01))#定義權重
biases = tf.get_variable('bias' ,[64],initializer = tf.constant(0.01))#定義偏置
conv = tf.nn.conv2d(input,weight,stride=[1,1,1,1],padding='SAME')#卷積
bias = tf.nn.bias_add(conv,biases)#加偏置
activate_conv = tf.nn.relu(bias)# 啟用
對卷積中的各部分做封裝再寫
不過上面這樣實現卷積仍然過於複雜,如果每層都這麼弄那麼程式碼量會非常大,因此可以對權重定義等做封裝,如下所示:
def weight_variable(shape,name): #定義權重
initial = tf.truncated_normal(shape,stddev=0.01)
return tf.Variable(initial,name=name)
def bias_variable(shape,name): #定義偏置
initial = tf.constant(0.01,shape=shape)
return tf.Variable(initial,name=name)
def conv2d(x,W): #定義卷積
return tf.nn.conv2d(x,W,strides=[1,1,1,1],padding='SMAE' )
#這樣上述的卷積可以寫成
W1 = weight_varialble([9,9,3,64],name='W1')
b1 = bias_variable([64],name='b1')
out = tf.nn.relu(conv2d(input,W1)+b1)
這樣每層都可以用三行程式碼就搞定了,相比於原來的六層程式碼少寫了很多,當然藉助tensorflow的slim庫,程式碼量還可以減少的更多。
通過slim庫再寫
emsp; slim庫對卷積的封裝程度非常高的,匯入slim庫,一行就能搞定
out = slim.conv2d(input,64,kernel_size=[9,9])
這個操作可以說是很簡潔了,就連偏置和啟用函式都省略了,當然靈活度也降低了很多,slim預設加上bias,啟用函式預設使用relu,具體定義介面如下:
def convolution(inputs,
num_outputs,
kernel_size,
stride=1,
padding='SAME',
data_format=None,
rate=1,
activation_fn=nn.relu,
normalizer_fn=None,
normalizer_params=None,
weights_initializer=initializers.xavier_initializer(),
weights_regularizer=None,
biases_initializer=init_ops.zeros_initializer(),
biases_regularizer=None,
reuse=None,
variables_collections=None,
outputs_collections=None,
trainable=True,
scope=None):
現在使用多了,還是偏向於使用slim,畢竟方便,當然以後還是要慢慢轉pytorch,感覺除錯更友好啊。