我目前正在尝试将自定义卷积从PyTorch转换为Tensorflow(V.2.2.0)。
卷积在PyTorch中定义为:
std::complex<double>
其中 self.quantizer = q = nn.Conv1d(1, 2*nq, kernel_size=1, bias=True)
a = (nq-1) / gap
#1st half = lines passing to (min+x,1) and (min+x+1/a,0) with x = {nq-1..0}*gap/(nq-1)
q.weight.data[:nq] = -a
q.bias.data[:nq] = torch.from_numpy(a*min + np.arange(nq, 0, -1)) # b = 1 + a*(min+x)
#2nd half = lines passing to (min+x,1) and (min+x-1/a,0) with x = {nq-1..0}*gap/(nq-1)
q.weight.data[nq:] = a
q.bias.data[nq:] = torch.from_numpy(np.arange(2-nq, 2, 1) - a*min) # b = 1 - a*(min+x)
# first and last one are special: just horizontal straight line
q.weight.data[0] = q.weight.data[-1] = 0
q.bias.data[0] = q.bias.data[-1] = 1
,nq = 20
和min = 0
。
我的重新实现看起来像这样:
max = 1
这些功能用作权重和偏差初始化:
my_weight = my_init_weight((1,1,nq*2))
q = tf.nn.convolution(input_q, my_weight)
q = tf.nn.bias_add(q, my_init_bias((40,1), tf.float32))
输入是一个矩阵,其形状用于PyTorch(首先使用通道),def my_init_weight(shape, dtype=None):
weights = np.zeros(shape, dtype=np.float32)
weights[:, :, :nq] = -a
weights[:, :, nq:] = a
weights[:, :, 0] = weights[:, :, -1] = 0
return tf.convert_to_tensor(weights, dtype=tf.float32)
def my_init_bias(shape, dtype=None):
weights = np.zeros(shape[0], dtype=np.float32)
weights[:nq] = a*min + np.arange(nq, 0, -1)
weights[nq:] = np.arange(2-nq, 2, 1) - a*min
weights[0] = weights[-1] = 1
return weights
,用于Tensorflow(最后使用通道)的1681, 1, 1600
,输出是1681, 1600, 1
或1681, 40, 1600
。因此应该是正确的,但是两个卷积的输出是不同的。
输入,输出:随机1681, 1600, 40
图像上的Tensorflow:
100, 100
输入,输出:随机my_weight = my_init_weight((1,1,nq*2))
my_weight = tf.nn.bias_add(my_weight, my_init_bias((40,1), tf.float32))
q = tf.nn.convolution(test_conv, my_weight)
q_left, q_right = tf.split(q, 2, axis=2)
q = tf.math.minimum(q_left, q_right)
nbs = tf.reduce_sum(q, axis=0)
图像上的PyTorch:
100, 100
答案 0 :(得分:0)
好的,我找到了解决方法:
我忘记添加.clamp(min=0)
。
将q = tf.clip_by_value(q, 0, tf.keras.backend.max(q))
添加到
my_weight = my_init_weight((1,1,nq*2))
my_weight = tf.nn.bias_add(my_weight, my_init_bias((40,1), tf.float32))
q = tf.nn.convolution(test_conv, my_weight)
q_left, q_right = tf.split(q, 2, axis=2)
q = tf.math.minimum(q_left, q_right)
q = tf.clip_by_value(q, 0, tf.keras.backend.max(q)) <-----------
nbs = tf.reduce_sum(q, axis=0)
解决了这个问题。