我正在尝试使用numpy操作来实现tensorflow的conv1d,暂时忽略跨度和填充。我以为在我的previous question之后我就理解了它,但今天意识到当我处理比1更宽的内核时,我仍然没有得到正确的答案。
所以现在我尝试使用tflearn作为模板,因为它会为我计算内核形状。现在我知道卷积可以作为矩阵乘法计算,我尝试相应地使用内核矩阵,但我得到的答案与tflearn不同。检查源代码是相当不透明的,因为它只是调用tensorflow的专用编译实现。
这是我到目前为止所得到的:
inp = np.arange(10).reshape(1,10,1).astype(np.float32)
filters = 2
width = 3
z = tflearn.conv_1d(inp, filters, width, strides=1, padding='same', bias=False)
s = tf.Session()
s.run(tf.global_variables_initializer())
z1, w = s.run([z, z.W])
print('tflearn output shape', z1.shape)
print('tflearn kernel shape', w.shape)
print('numpy matmul shape', (inp @ w).shape)这表明tflearn内核将宽度作为在开头插入的额外维度:
tflearn output shape (1, 10, 2)
tflearn kernel shape (3, 1, 1, 2)
numpy matmul shape (3, 1, 10, 2)因此,我得到的结果具有额外的3维度。好吧,那么我如何正确地减少它,以获得与tensorflow相同的答案?我试着对这个维度求和,但它不正确:
print('tflearn output:')
print(z1)
print('numpy output:')
print(np.sum(inp @ w, axis=0))给予,
tflearn output:
[[[-0.02252221 0.24712706]
[ 0.49539018 1.0828717 ]
[ 0.0315876 2.0945265 ]
[-0.43221498 3.1061814 ]
[-0.89601755 4.117836 ]
[-1.3598201 5.129491 ]
[-1.823623 6.141146 ]
[-2.2874253 7.152801 ]
[-2.7512276 8.164455 ]
[-2.989808 6.7048397 ]]]
numpy output:
[[[ 0. 0. ]
[-0.46380258 1.0116549 ]
[-0.92760515 2.0233097 ]
[-1.3914077 3.0349646 ]
[-1.8552103 4.0466194 ]
[-2.319013 5.0582743 ]
[-2.7828155 6.069929 ]
[-3.2466178 7.0815845 ]
[-3.7104206 8.093239 ]
[-4.174223 9.104893 ]]]它们显然是不同的。z.W当然已经被初始化为随机值,所以这些数字也是随机的,但我正在寻找使它们等于z1的numpy计算,因为它们执行的是相同的内核。显然,它不像inp @ w那么简单。
谢谢。
发布于 2020-01-01 23:52:56
好的,对不起,我已经回答了我自己的问题……这就是我在上一个问题中尝试介绍的滑动窗口操作的用武之地:
y = (inp @ w)
y[0,:,:-2,:] + y[1,:,1:-1,:] + y[2,:,2:,:]给予,
array([[[ 0.49539018, 1.0828717 ],
[ 0.0315876 , 2.0945265 ],
[-0.43221498, 3.1061814 ],
[-0.89601755, 4.117836 ],
[-1.3598201 , 5.129491 ],
[-1.823623 , 6.141146 ],
[-2.2874253 , 7.152801 ],
[-2.7512276 , 8.164455 ]]], dtype=float32)这等同于z1忽略了第一行和最后一行,这正是我对3点卷积的期望。
编辑:但如果有人能提出一种更简洁/更有效的方式来表达滑动窗口,我将不胜感激。我从前面的问题中想到,即使是滑动窗口也可以在矩阵乘法中考虑在内,所以很不幸需要显式地编写索引逻辑。
https://stackoverflow.com/questions/59553815
复制相似问题