【问题标题】:Tensorflow Error when indexing a 4D array: ValueError: Shapes must be equal rank, but are 1 and 0索引 4D 数组时出现 Tensorflow 错误:ValueError: Shapes must be equal rank, but are 1 and 0
【发布时间】:2017-05-25 07:18:39
【问题描述】:

我在 Tensorflow 中修改一个简单的 CNN,当我索引一个 4d 数组时,我得到了这个错误。 我的可重现示例是:

from __future__ import print_function
import pdb
import numpy as np
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

def weight_variable(shape):
    initial = tf.truncated_normal(shape, stddev=0.1)
    return tf.Variable(initial)

def bias_variable(shape):
    initial = tf.constant(0.1, shape=shape)
    return tf.Variable(initial)

def conv2d(x, W, stride=1):
    return tf.nn.conv2d(x, W, strides=[1, stride, stride, 1], padding='SAME')

def max_pool_2d(x, k=10):
    return tf.nn.max_pool(x, ksize=[1, k, k, 1],
                                                strides=[1, k, k, 1], padding='SAME')


indices = np.array([[0, 1], [5, 2],[300, 400]]).astype(np.int32)

input_updatable = weight_variable(shape=[1, 1200, 600, 100])

# Convolutional layer 1
W_conv1 = weight_variable([5, 5, 100, 100])
b_conv1 = bias_variable([100])

h_conv1 = tf.nn.relu(conv2d(input_updatable, W_conv1) + b_conv1)
h_pool1 = max_pool_2d(h_conv1)

# Convolutional layer 2
W_conv2 = weight_variable([5, 5, 100, 100])
b_conv2 = bias_variable([100])

h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
h_pool2 = max_pool_2d(h_conv2)

#extract vectoris based on input
l1_vecs = input_updatable[0, indices[:, 0], indices[:, 1], :]



# Training steps
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())

    max_steps = 1000
    for step in range(max_steps):
        l1 = sess.run(l1_vecs)
        pdb.set_trace()

此代码引发以下错误:

   l1_vecs = input_updatable[0, indices[:, 0], indices[:, 1], :]
  File "/home/arahimi/anaconda2/lib/python2.7/site-packages/tensorflow/python/ops/array_ops.py", line 722, in _SliceHelperVar
    return _SliceHelper(var._AsTensor(), slice_spec, var)
  File "/home/arahimi/anaconda2/lib/python2.7/site-packages/tensorflow/python/ops/array_ops.py", line 480, in _SliceHelper
    stack(begin), stack(end), stack(strides))
  File "/home/arahimi/anaconda2/lib/python2.7/site-packages/tensorflow/python/ops/array_ops.py", line 824, in stack
    return gen_array_ops._pack(values, axis=axis, name=name)
  File "/home/arahimi/anaconda2/lib/python2.7/site-packages/tensorflow/python/ops/gen_array_ops.py", line 2041, in _pack
    result = _op_def_lib.apply_op("Pack", values=values, axis=axis, name=name)
  File "/home/arahimi/anaconda2/lib/python2.7/site-packages/tensorflow/python/framework/op_def_library.py", line 763, in apply_op
    op_def=op_def)
  File "/home/arahimi/anaconda2/lib/python2.7/site-packages/tensorflow/python/framework/ops.py", line 2329, in create_op
    set_shapes_for_outputs(ret)
  File "/home/arahimi/anaconda2/lib/python2.7/site-packages/tensorflow/python/framework/ops.py", line 1717, in set_shapes_for_outputs
    shapes = shape_func(op)
  File "/home/arahimi/anaconda2/lib/python2.7/site-packages/tensorflow/python/framework/ops.py", line 1667, in call_with_requiring
    return call_cpp_shape_fn(op, require_shape_fn=True)
  File "/home/arahimi/anaconda2/lib/python2.7/site-packages/tensorflow/python/framework/common_shapes.py", line 610, in call_cpp_shape_fn
    debug_python_shape_fn, require_shape_fn)
  File "/home/arahimi/anaconda2/lib/python2.7/site-packages/tensorflow/python/framework/common_shapes.py", line 676, in _call_cpp_shape_fn_impl
    raise ValueError(err.message)
ValueError: Shapes must be equal rank, but are 1 and 0
        From merging shape 2 with other shapes. for 'strided_slice/stack_1' (op: 'Pack') with input shapes: [], [3], [3], [].

请注意,当我提取 input_updatable 的值时:

ip = sess.run(input_updatable)

然后我可以使用索引:

l1_vecs = input_updatable[0, indices[:, 0], indices[:, 1], :]

我不确定是什么原因。

【问题讨论】:

  • 你尝试过使用 tf.gather_nd() 吗? tensorflow.org/api_docs/python/tf/gather_nd
  • @hars 提到 tf.gather_nd() 有效。 TF 不支持 numpy 的高级索引,所以我不得不将索引更改为 3D 矩阵来索引 input_updatable。

标签: tensorflow matrix-indexing numpy-indexed


【解决方案1】:

如果你在 Tensorflow 中有如下变量:

input_updatable = weight_variable(shape=[1, 1200, 600, 100])

你有索引,一个大小为 Nx2 的二维数组,将 input_updatable 索引到输出中,一个 Nx100 数组在 numpy 中,你可以这样做:

input_updatable[0, Indices[:, 0], Indices[:, 1], :]

我认为您也可以在 Theano 中执行此操作。但是 Tensorflow 不支持高级索引,因此您需要使用 tf.gather_nd()

您需要首先通过以下方式将 0 列添加到所有行,将 2d 索引转换为 3d:

# create a zero column to index into the first dimension of input_updatable
zz = np.zeros(shape=(Indices.shape[0], 1), dtype=np.int32)
#then attach this vector to 2d matrix Indices (Nx2) to create a 3d (Nx3) matrix where the first column is zero.
Indices = np.hstack((zz, Indices))
#then use gather_nd
output = tf.gather_nd(input_updatable, Indices)

其中输出是一个 Nx100 矩阵。

【讨论】:

  • 很高兴知道它有效。我希望您已经验证了输出的值。
猜你喜欢
  • 1970-01-01
  • 2019-07-15
  • 1970-01-01
  • 2020-12-04
  • 2017-12-03
  • 2021-12-29
  • 2022-07-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多