Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 张量流中的张量展开_Python_Tensorflow - Fatal编程技术网

Python 张量流中的张量展开

Python 张量流中的张量展开,python,tensorflow,Python,Tensorflow,在TensorFlow中,我打算用带有某些近似项的sin(x)泰勒级数来处理张量。为此,我尝试用sin(x)的泰勒级数处理灰度图像(32,32)),效果很好。现在,我很难将用于(32,32)形状的灰度图像处理为(32,32,3)形状的RGB图像,并且它没有给我正确的数组。直观地说,我试图用泰勒展开的sin(x)来操纵张量。有人能告诉我在tensorflow中做这件事的可能方法吗?有什么想法吗 我的尝试: 这是在x=0:1-x+x**2/2-x**3/6处的sin(x)的泰勒展开式,有三个展开项

在TensorFlow中,我打算用带有某些近似项的sin(x)泰勒级数来处理张量。为此,我尝试用sin(x)的泰勒级数处理灰度图像(32,32)),效果很好。现在,我很难将用于
(32,32)
形状的灰度图像处理为
(32,32,3)
形状的RGB图像,并且它没有给我正确的数组。直观地说,我试图用泰勒展开的sin(x)来操纵张量。有人能告诉我在tensorflow中做这件事的可能方法吗?有什么想法吗

我的尝试

这是在
x=0:1-x+x**2/2-x**3/6
处的
sin(x)
的泰勒展开式,有三个展开项

from tensorflow.keras.datasets import mnist
(X_train, y_train), (X_test, y_test) = mnist.load_data()

x= X_train[1,:,:,1]
k= 3
func = 'sin(x)'

new_x = np.zeros((x.shape[0], x.shape[1]*k))
new_x = new_x.astype('float32') 
nn = 0
for i in range(x.shape[1]):
    col_d = x[:,i].ravel()
    new_x[:,nn] = col_d
    if n_terms > 0:
        for j in range(1,k):
            if func == 'cos(x)':
                new_x[:,nn+j] = new_x[:,nn+j-1]
我想我可以用TensorFlow更有效地实现这一点,但这对我来说不是很直观。有人能提出一个可行的解决方案来实现这一目标吗?有什么想法吗

更新

在2dim数组中,col_d=x[:,i].ravel()是将二维数组展平的像素向量。类似地,我们可以通过以下方式将3dim数组重塑为2维:
x.transpose(0,1,2)。在for循环中重塑(x.shape[1],-1)
,因此它可以是
x[:,i]。transpose(0,1,2)。重塑(x.shape[1],-1)
,但这仍然不正确。我认为tensorflow可能有更好的方法。如何更有效地利用sin(x)的泰勒级数操纵张量?有什么想法吗

目标


直观地说,在sin(x)的泰勒级数中,
x
是张量,如果我们只需要sin(x)的泰勒级数的2,3个近似项作为每个张量,我想用新的张量将它们连接起来。我们应该如何在TensorFlow中有效地执行它?有什么想法吗?

我想你可以对一维张量这样做:

def expend_func(x):     
    p1 = x
    p2 = x - ((x**2)/2)
    new_x = K.concatenate([p1, p2], axis=1)
    return new_x
请注意,
x
是您的1D张量,新的带有两个项的x。如果需要包含三个术语的新函数,可以使用三个术语修改
expense\u funcs
。对于2D张量,应该使用
tf.stack()
,这不是一种优雅的方式,但可能会有所帮助

new_x=np.zero((x.shape[0],x.shape[1]*n_项))

这行没有意义,为什么要为3个泰勒展开项分配96个元素的空间

(new_x[:, 3:] == 0.0).all() = True # check

具有n项的逐像素泰勒展开




通常避免使用数值近似方法,因为它们计算成本高(阶乘)且不太稳定,因此基于梯度的优化通常是最好的,对于用于近似hessian矩阵(二阶导数)的高阶导数算法,如
BFGS
LBFGS
. 像Adam和SGD这样的优化器就足够了,并且计算量要少得多。使用神经网络,我们也许能够找到更好的展开式


n项展开的张量流解





将三个展开项放入轴=1处的张量中

x=tf.ones([8,32,32,3],tf.float32)*0.5#示例batchsize=8,imageshape=[32,32,3]
x=tf.stack([x,-(1/6)*tf.math.pow(x,3),(1/120)*tf.math.pow(x,5)],轴=1)#sin(x)的三项展开式,[8,3,32,32,3]
如果您使用tf.keras函数API或顺序API,您可能会创建一个keras自定义层



编辑:在第一个答案中,我推荐了
tf.keras.layers.Lambda
,但它可能不适用于tf.math.pow或tf.stack(我还没有尝试过)。你会同意的。

我认为上述尝试可以在TensorFlow中有效地完成。在扩展原始张量之后,您是否要为您的
新张量使用
Lambda(new_x,…)
函数?我想这就是你们在展开后想要做的,是吗?@kim确切地说,在得到一个新的张量
new\ux
之后,我将使用
Lambda(new\ux,…)
进行实验。我们如何在TensorFlow中做到这一点?有什么想法吗?谢谢你的帮助。我们如何编写一般函数,所以取决于哪个函数(即sin(x)或cos(x))和展开项(2,3,4,等等),我们将得到新的张量x=tf.stack([…])?我尝试了一个自定义函数,它接受函数类型、展开项和输入张量的参数,并期望返回展开的张量。我们怎样才能写出这样的一般函数呢?有什么想法吗?谢谢我认为您可以简单地循环生成一个列表并将其放入tf.stack。
def sin_exp_step(x, i):

  c1 = 2 * i + 1
  c2 = (-1) ** i / np.math.factorial(c1)

  t = c2 * (x ** c1) 
  
  return t
# validate

x = 45.0
x = (np.pi / 180.0) * x 

y = np.sin(x)

approx_y = 0

for i in range(n_terms):

  approx_y += sin_exp_step(x, i)

abs(approx_y - y) < 1e-8
x= X_train[1,:,:,:]
n_terms = 3
func = 'sin(x)'

new_x = np.zeros((*x.shape, n_terms))

for i in range(0, n_terms):

  if func == 'sin(x)': # sin(x)

    new_x[..., i] += sin_exp_step(x, i)
import numpy as np

import tensorflow as tf
from tensorflow.keras.datasets import cifar10
from tensorflow.keras.layers import Input, LocallyConnected2D
from tensorflow.keras.models import Model
from tensorflow.keras import backend as K

(x_train, y_train), (x_test, y_test) = cifar10.load_data()

x_train = tf.constant(x_train, dtype=tf.float32)
x_test = tf.constant(x_test, dtype=tf.float32)
def expansion_approx_of(func):

  def reconstruction_loss(y_true, y_pred):

    loss = (y_pred - func(y_true)) ** 2
    loss = 0.5 * K.mean(loss)

    return loss

  return reconstruction_loss
class Expansion2D(LocallyConnected2D): # n-terms expansion layer

  def __init__(self, i_shape, n_terms, kernel_size=(1, 1), *args, **kwargs):
    
    if len(i_shape) != 3:
      
      raise ValueError('...')

    self.i_shape = i_shape
    self.n_terms = n_terms

    filters = self.n_terms * self.i_shape[-1]
    
    super(Expansion2D, self).__init__(filters=filters, kernel_size=kernel_size,
                                      use_bias=False, *args, **kwargs)
    
  def call(self, inputs):

    shape =  (-1, self.i_shape[0], self.i_shape[1], self.i_shape[-1], self.n_terms)

    out = super().call(inputs)

    expansion = tf.reshape(out, shape)
    
    out = tf.math.reduce_sum(expansion, axis=-1)
    
    return out, expansion
inputs = Input(shape=(32, 32, 3))

# expansion: might be a taylor expansion or something better.
out, expansion = Expansion2D(i_shape=(32, 32, 3), n_terms=3)(inputs)

model = Model(inputs, [out, expansion])

opt = tf.keras.optimizers.Adam(learning_rate=0.0001, beta_1=0.9, beta_2=0.999)
loss = expansion_approx_of(K.sin)

model.compile(optimizer=opt, loss=[loss])

model.summary()
model.fit(x_train, x_train, batch_size=1563, epochs=100)
x_pred, x_exp = model.predict_on_batch(x_test[:32])

print((x_exp[0].sum(axis=-1) == x_pred[0]).all())

err = abs(x_pred - np.sin(x_test[0])).mean()

print(err)