【问题标题】:Invalid argument: Input to reshape is a tensor with x values, but requested shape requires a multiple of y. {node Reshape_13}无效参数:reshape 的输入是具有 x 值的张量,但请求的形状需要 y 的倍数。 {节点重塑_13}
【发布时间】:2019-09-16 23:32:57
【问题描述】:

我正在使用 tensorflow 的 object detection api 和 faster_rcnn_resnet101 并在尝试训练时收到以下错误:

tensorflow.python.framework.errors_impl.InvalidArgumentError:发现 2 个根错误。 (0) 无效参数:reshape 的输入是一个 36 个值的张量,但请求的形状需要 16 的倍数

[[{{node Reshape_13}}]]

[[IteratorGetNext]]

[[IteratorGetNext/_7243]]

(1) 无效参数:reshape 的输入是一个有 36 个值的张量,但请求的形状需要 16 的倍数

[[{{node Reshape_13}}]]

[[IteratorGetNext]]

0 次成功操作。 0 个衍生错误被忽略。

我正在使用 pets-train.sh 文件的略微修改版本来运行训练(仅更改了路径)。我正在尝试对包含大小为 (1280、720) 的 jpg 图像的 tf.record 文件进行训练,并且没有对网络架构进行任何更改(我已经确认记录中的所有图像都是这种大小)。

奇怪的是,当我执行与教程文件 detect_pets.py 中的内容相同的操作时,我可以成功地对这些图像进行推理。这让我觉得我创建 tf.record 文件(下面的代码)的方式有问题,而不是与图像的形状有关,尽管错误与重塑有关。但是,我已经成功地训练了以前以相同方式创建的 tf.records(来自大小为 (600, 600)、(1024, 1024) 和 (720, 480) 的图像,都使用相同的网络)。此外,我之前在大小为 (600, 600) 的不同图像数据集上遇到了类似的错误(只是数字不同,但错误仍然是节点 Reshape_13)。

我正在使用 python 3.7,tf 版本 1.14.0,cuda 10.2,Ubuntu 18.04

我广泛查看了其他各种帖子(hereherehereherehere),但没有取得任何进展。

我尝试调整 keep_aspect_ratio_resizer 参数(最初 min_dimension=600, max_dimension=1024 但我也尝试过 min, max = (720, 1280) 并尝试过 pad_to_max_dimension: true 与这两个最小/最大选择好)。

这是我用来创建 tf.record 文件的代码(这里没有道歉或缩进):

def make_example(imfile, boxes):
with tf.gfile.GFile(imfile, "rb") as fid:
    encoded_jpg = fid.read()

encoded_jpg_io = io.BytesIO(encoded_jpg)
image = PIL.Image.open(encoded_jpg_io)
if image.format != "JPEG":
    raise Exception("Images need to be in JPG format")

height = image.height
width = image.width

xmins = []
xmaxs = []
ymins = []
ymaxs = []
for box in boxes:
    xc, yc, w, h = box
    xmin = xc - w / 2
    xmax = xc + w / 2
    ymin = yc - h / 2
    ymax = yc + h / 2

    new_xmin = np.clip(xmin, 0, width - 1)
    new_xmax = np.clip(xmax, 0, width - 1)
    new_ymin = np.clip(ymin, 0, height - 1)
    new_ymax = np.clip(ymax, 0, height - 1)

    area = (ymax - ymin) * (xmax - xmin)
    new_area = (new_ymax - new_ymin) * (new_xmax - new_xmin)
    if new_area > 0.3 * area:
        xmins.append(new_xmin / width)
        xmaxs.append(new_xmax / width)
        ymins.append(new_ymin / height)
        ymaxs.append(new_ymax / height)

classes_text = ["vehicle".encode("utf8")] * len(boxes)
classes = [1] * len(boxes)
abs_imfile = os.path.abspath(imfile)
difficult = [0] * len(boxes)

example = tf.train.Example(
    features=tf.train.Features(
        feature={
            "image/height": int64_feature(height),
            "image/width": int64_feature(width),
            "image/filename": bytes_feature(imfile.encode("utf8")),
            "image/source_id": bytes_feature(abs_imfile.encode("utf8")),
            "image/encoded": bytes_feature(encoded_jpg),
            "image/format": bytes_feature("jpeg".encode("utf8")),
            "image/object/bbox/xmin": float_list_feature(xmins),
            "image/object/bbox/xmax": float_list_feature(xmaxs),
            "image/object/bbox/ymin": float_list_feature(ymins),
            "image/object/bbox/ymax": float_list_feature(ymaxs),
            "image/object/class/text": bytes_list_feature(classes_text),
            "image/object/class/label": int64_list_feature(classes),
            "image/object/difficult": int64_list_feature(difficult),
        }
    )
)
return example


def make_tfrecord(outfile, imfiles, truthfiles):
writer = tf.python_io.TFRecordWriter(outfile)

for imfile, truthfile in zip(imfiles, truthfiles):
    print(imfile)
    boxes = pd.read_csv(truthfile)
    if boxes.empty:
        boxes = []
    else:
        boxes = [
            (box.Xc, box.Yc, box.Width, box.Height) for box in boxes.itertuples()
        ]

    example = make_example(imfile, boxes)
    writer.write(example.SerializeToString())
writer.close()

def make_combined_train_dset(names):
imfiles = []
truthfiles = []
traindir = os.path.join(tf_datadir, "train")
valdir = os.path.join(tf_datadir, "val")

for name in names:
    imdir = os.path.join(processed_datadir, name, "images")
    truthdir = os.path.join(processed_datadir, name, "truth")

    imfiles.extend(sorted(glob.glob(os.path.join(imdir, "*.jpg"))))
    truthfiles.extend(sorted(glob.glob(os.path.join(truthdir, "*.csv"))))

inds = list(range(len(imfiles)))
np.random.shuffle(inds)
imfiles = [imfiles[i] for i in inds]
truthfiles = [truthfiles[i] for i in inds]

ntrain = round(0.9 * len(imfiles))
train_imfiles = imfiles[:ntrain]
train_truthfiles = truthfiles[:ntrain]
val_imfiles = imfiles[ntrain:]
val_truthfiles = truthfiles[ntrain:]

chunksize = 1500

for d in [traindir, valdir]:
    if not os.path.exists(d):
        os.mkdir(d)

for i in range(0, len(train_imfiles), chunksize):
    print(f"{i} / {len(train_imfiles)}", end="\r")
    cur_imfiles = train_imfiles[i : i + chunksize]
    cur_truthfiles = train_truthfiles[i : i + chunksize]
    testfile = os.path.join(traindir, f"{i}.tfrecord")
    make_tfrecord(testfile, cur_imfiles, cur_truthfiles)

for i in range(0, len(val_imfiles), chunksize):
    print(f"{i} / {len(val_imfiles)}", end="\r")
    cur_imfiles = val_imfiles[i : i + chunksize]
    cur_truthfiles = val_truthfiles[i : i + chunksize]
    testfile = os.path.join(valdir, f"{i}.tfrecord")
    make_tfrecord(testfile, cur_imfiles, cur_truthfiles)

def make_train_dset(name, train_inc=1, val_inc=1, test_inc=1):
trainfile = os.path.join(tf_datadir, name + "-train.tfrecord")
valfile = os.path.join(tf_datadir, name + "-val.tfrecord")

imdir = os.path.join(processed_datadir, name, "images")
truthdir = os.path.join(processed_datadir, name, "truth")

imfiles = sorted(glob.glob(os.path.join(imdir, "*.jpg")))
truthfiles = sorted(glob.glob(os.path.join(truthdir, "*.csv")))

n = len(imfiles)
ntrain = round(0.9 * n)

print(trainfile)
make_tfrecord(trainfile, imfiles[:ntrain:train_inc], truthfiles[:ntrain:train_inc])
print(valfile)
make_tfrecord(valfile, imfiles[ntrain::val_inc], truthfiles[ntrain::val_inc])

对于其他数据集,我已经能够使用上面定义的函数 make_combined_train_dset(或 make_train_dset)创建一个 tf.record,然后在 faster_rcnn_resnet101.config 文件中提供这些数据集的路径,然后训练正常进行(只是如教程示例中所示)。使用这个新数据集(以及至少一个其他数据集),我得到了上述重塑错误。尽管如此,我仍然可以对这个数据集中的图像进行推断,所以这让我认为问题在于 tf 记录或它们的读取方式,而不是图像或其大小的内在问题。

任何人都可以提供任何帮助将不胜感激,因为我已经为此苦苦挣扎了好几天了。

【问题讨论】:

    标签: python tensorflow object-detection-api


    【解决方案1】:

    我是个白痴:确认。

    问题在于 classes_text、classes 和 hard 的长度不正确。

    替换

    classes_text = ["vehicle".encode("utf8")] * len(boxes)
    classes = [1] * len(boxes)
    difficult = [0] * len(boxes)
    

    classes_text = ["vehicle".encode("utf8")] * len(xmins)
    classes = [1] * len(xmins
    difficult = [0] * len(xmins)
    

    它运行良好。发布此内容以防其他人遇到类似问题。

    感谢任何为我的问题投入时间或思考的人。希望这可以帮助别人不要浪费时间。

    【讨论】:

    • 非常感谢您发布此信息!我能够以不同的difficult 长度捕获我的错误,导致相同的错误!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-30
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多