首页 > 解决方案 > 如何在 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))

在此处输入图像描述

标签: pythontensorflow

解决方案


您可以创建一个形状的权重矩阵,(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 ]]

推荐阅读