如何使用张量流处理嵌套循环?
How to handle nested loops with tensorflow?
我是张量流的新手。我正在使用 keras,但为了创建自定义损失函数,我或多或少被迫在 tensorflow 中编写一个函数。
我陷入了必须将以下 numpy for 循环转换为 tensorflow 语法的地步。
for j in range(grid):
for k in range(modes):
for l in range(dim):
for m in range(dim):
lorentz[:,j,l,m] += 1J*osc_stre[:,l,m,k]/(energies[j]-e_j[:,k])
if l == m == k:
lorentz[:,j,l,m] += 1
在这里你可以看到数组的初始形状:
e_j = zeros([sample_nr,modes],dtype='complex')
osc_stre = zeros([sample_nr,dim,dim,modes],dtype='complex')
lorentz = zeros([sample_nr,grid,dim,dim],dtype='compex')
能量[j] 的形状为(网格)
tensorflow可以解决这个问题吗?谁能给我提示如何将其转换为 tensorflow 语法?我已经尝试过一些类似 tensorflow while 循环的方法,但其中一个大问题是,tensorflow 对象不支持项目分配。
编辑:
我想我已经为这个问题的简化版本想出了一个解决方案:
for j in range(grid):
for k in range(modes):
lorentz[j] += 1J*osc_stre[k]/(energies[j]-e_j[k])
if k == 0:
lorentz[j] += 1
解决方法:
lorentz_list = []
tf_one = tf.ones([1], complex64)
tf_i = tf.cast(tf.complex(0.,1.), complex64)
energies_float = tf.cast(energies,float32)
energies_complex = tf.complex(energies_float,tf.zeros([energy_grid],float32))
for j in range(energy_grid):
lorentz_list.append(tf.add(tf_one,tf.reduce_sum(tf.multiply(tf_i,tf.divide(osc_stre_tot,tf.subtract(energies_complex[j],e_j))),-1)))
lorentz = tf.stack(lorentz_list)
假设这些:
lorentz.shape == (batch, grid, dim, dim)
并且在循环之前为零。
osc_stre.shape == (batch, dim, dim, modes)
energies.shape == (grid,)
e_j.shape == (batch, modes)
然后:
osc_stre = K.reshape(osc_stre, (-1, 1, dim, dim, modes))
energies = K.reshape(energies, (1, grid, 1, 1, 1))
e_j = K.reshape(e_j, (-1, 1, 1, 1, modes))
lorentz = 1J*osc_stre/(energies-e_j)
identity = np.zeros((1, 1, dim, dim, modes))
for d in range(min(modes,dim)):
identity[0,0,d,d,d] = 1
identity = K.variable(identity, dtype = tf.complex64)
lorentz += identity
lorentz = K.sum(lorentz, axis=-1)
我是张量流的新手。我正在使用 keras,但为了创建自定义损失函数,我或多或少被迫在 tensorflow 中编写一个函数。 我陷入了必须将以下 numpy for 循环转换为 tensorflow 语法的地步。
for j in range(grid):
for k in range(modes):
for l in range(dim):
for m in range(dim):
lorentz[:,j,l,m] += 1J*osc_stre[:,l,m,k]/(energies[j]-e_j[:,k])
if l == m == k:
lorentz[:,j,l,m] += 1
在这里你可以看到数组的初始形状:
e_j = zeros([sample_nr,modes],dtype='complex')
osc_stre = zeros([sample_nr,dim,dim,modes],dtype='complex')
lorentz = zeros([sample_nr,grid,dim,dim],dtype='compex')
能量[j] 的形状为(网格)
tensorflow可以解决这个问题吗?谁能给我提示如何将其转换为 tensorflow 语法?我已经尝试过一些类似 tensorflow while 循环的方法,但其中一个大问题是,tensorflow 对象不支持项目分配。
编辑:
我想我已经为这个问题的简化版本想出了一个解决方案:
for j in range(grid):
for k in range(modes):
lorentz[j] += 1J*osc_stre[k]/(energies[j]-e_j[k])
if k == 0:
lorentz[j] += 1
解决方法:
lorentz_list = []
tf_one = tf.ones([1], complex64)
tf_i = tf.cast(tf.complex(0.,1.), complex64)
energies_float = tf.cast(energies,float32)
energies_complex = tf.complex(energies_float,tf.zeros([energy_grid],float32))
for j in range(energy_grid):
lorentz_list.append(tf.add(tf_one,tf.reduce_sum(tf.multiply(tf_i,tf.divide(osc_stre_tot,tf.subtract(energies_complex[j],e_j))),-1)))
lorentz = tf.stack(lorentz_list)
假设这些:
lorentz.shape == (batch, grid, dim, dim)
并且在循环之前为零。osc_stre.shape == (batch, dim, dim, modes)
energies.shape == (grid,)
e_j.shape == (batch, modes)
然后:
osc_stre = K.reshape(osc_stre, (-1, 1, dim, dim, modes))
energies = K.reshape(energies, (1, grid, 1, 1, 1))
e_j = K.reshape(e_j, (-1, 1, 1, 1, modes))
lorentz = 1J*osc_stre/(energies-e_j)
identity = np.zeros((1, 1, dim, dim, modes))
for d in range(min(modes,dim)):
identity[0,0,d,d,d] = 1
identity = K.variable(identity, dtype = tf.complex64)
lorentz += identity
lorentz = K.sum(lorentz, axis=-1)