python - 如何在 TensorFlow 中高效地实现这个简单的结构
问题描述
小问题。您将如何使用密集层显式实现以下函数 f(x),以便在 Python3 中的 TensorFlow 中快速构建和评估?
我首先尝试使用列表然后连接来执行此操作,但是该函数的构建时间f_TF
很糟糕,请参阅下面的最小示例代码的输出(在我的笔记本电脑上为 128 个函数构建几乎 2 秒,评估时间很好,最后检查numpy 最后,提取权重 W 和变量符号中的偏差 b vs
)。我确信有一些明显的方法可以有效地构建它,但我现在看不到它。
import numpy as np
import tensorflow as tf
import datetime
#%% Parameters
# Dimension of input x number n_p of data points
n = 4
n_p = 10
# Number of functions
m = 128
#%% Generate data
# Input data x
D = np.random.rand(n_p,n)
#%% TF
# Placeholder for input x
x_p = tf.placeholder(dtype=tf.float64,shape=[None,n])
# Build f(x)
t1 = datetime.datetime.now()
fs = []
for _ in range(m):
floc = tf.layers.dense(x_p,n,tf.square,bias_initializer=tf.glorot_normal_initializer())
floc = tf.sin(tf.reduce_sum(floc,axis=1,keepdims=True))
fs.append(floc)
f_TF = tf.concat(fs,axis=1)
t2 = datetime.datetime.now()
print('Time to build f(x): \n\t%s' % (t2-t1))
# Session and evaluate
sess = tf.Session()
sess.run(tf.global_variables_initializer())
t1 = datetime.datetime.now()
f_TF_values = sess.run(f_TF,{x_p:D})
t2 = datetime.datetime.now()
print('Time for TF evaluation: \n\t%s' % (t2-t1))
# Extract weights and biases
t1 = datetime.datetime.now()
vs = tf.global_variables()
vs = [sess.run(v) for v in vs]
t2 = datetime.datetime.now()
print('Time for extraction of variables: \n\t%s' % (t2-t1))
sess.close()
tf.reset_default_graph()
#%% NP
# Check single evaluation
i = np.random.randint(0,n_p)
x0 = D[i]
f0 = np.array([np.sin(np.linalg.norm(np.matmul(x0,vs[2*i])+vs[2*i+1])**2) for i in range(len(vs)//2)])
print('Deviation from single evaluation: \n\t%.2e' % np.linalg.norm(f0-f_TF_values[i]))
# Check all
t1 = datetime.datetime.now()
f_NP_values = np.hstack([
np.sin(np.linalg.norm(np.matmul(D,vs[2*i])+vs[2*i+1],axis=1,keepdims=True)**2)
for i in range(len(vs)//2)])
t2 = datetime.datetime.now()
print('Time for NP evaluation: \n\t%s' % (t2-t1))
print('Deviation between TF and NP computations: \n\t%.2e' % np.linalg.norm(f_TF_values - f_NP_values))
解决方案
您可以创建一个形状的权重矩阵,(N, N, M)
然后用于tf.tensordot()
一起计算tf.matmul()
所有这些W
矩阵:
import tensorflow as tf
import numpy as np
N = 4
M = 3
n_samples = 5
def sin_layer(x, units):
N = x.get_shape().as_list()[-1]
w = tf.Variable(tf.random.normal((N, N, units)), tf.float32)
b = tf.Variable(tf.zeros((N, units)))
tensor = tf.tensordot(x, w, axes=[[1], [0]]) + b # <-- matmul all `W`s at once
tensor = tf.reduce_sum(tf.square(tensor), axis=1) # <-- reduce `N` dimension
tensor = tf.math.sin(tensor)
return tensor
x = tf.placeholder(tf.float32, shape=(None, N))
tensor = sin_layer(x, units=M)
x_data = np.random.normal(size=(n_samples, N)) # <-- 5 samples of size `N==4`
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
res = sess.run(tensor, feed_dict={x:x_data})
print(res.shape) # <-- `(5, 3)==(n_samples, M)`
print(res)
# [[ 0.24542944 -0.25523183 0.9970544 ]
# [ 0.992266 -0.98576933 -0.65339005]
# [ 0.95481074 0.8390483 0.41041443]
# [-0.6582102 -0.98120177 -0.00824349]
# [ 0.61224973 0.7946086 0.6564668 ]]
推荐阅读
- python - 基于关键比较两个数据帧
- c# - Winform 应用程序为名称为“程序”的数据库表引发错误
- google-drive-api - googleapi:错误 403:超出速率限制,rateLimitExceeded
- python - 使用python求和并追加2个文件的输入
- python - 如何在匹配列值上垂直合并数据框
- reactjs - 有人可以解释为什么我不应该直接更新 React `context` 中的值吗?
- sql-server - 如何返回一个依赖于另一个值的值?
- xml - 无法插入以下 XML 节点 VB.net
- linux - 从很长的行中提取多个子字符串
- ruby - Authenticate_with_http_basic 块未执行