Skip to main content
 首页 » 编程设计

python之Tensorflow之keras之'strided_slice' 的形状错误(使用调整大小的 MNIST 数据集)

2024年12月31日24java哥

我打算使用 tf.keras 和 MNIST 手写数字数据集制作一些 GAN 模型测试器。因为我的模型将用于 128x128 图像,所以我将 MNIST 数据集的大小调整为 128x128x1。但是,该程序出现了一些我从未见过的错误。

(x_train, _), (_, _) = mnist.load_data() 
x_train = (x_train.astype(np.float32) - 127.5) / 127.5 
x_train = tf.image.resize_images(x_train, [128, 128]) 
 
idx = np.random.randint(0, x_train.shape[0], batch_size)  # picks some data, count is batch_size=32. 
imgs = x_train[idx]  # This line made errors 

最后一行有两个错误:

tensorflow.python.framework.errors_impl.InvalidArgumentError: Shape must be rank 1 but is rank 2 for 'strided_slice_1' (op: 'StridedSlice') with input shapes: [60000,128,128,1], [1,32], [1,32], [1].

和,

ValueError: Shape must be rank 1 but is rank 2 for 'strided_slice_1' (op: 'StridedSlice') with input shapes: [60000,128,128,1], [1,32], [1,32], [1].

我认为数字“32”意味着 batch_size(=32)。

我试图找到有关此错误的信息,但找不到类似的错误。

我没有任何解决这个问题的想法(因为我一周前开始使用keras,在我使用pytorch之前)。

请您参考如下方法:

你上面的代码有更多问题,但错误的主要原因是tensorflow不支持numpy类型的高级切片。 实际上错误消息是因为tensorflow试图在他的strided-slices中对齐你的输入数组。 :

跨步切片的示例:

foo[5:,:,:3] on a 7x8x9 tensor is equivalent to foo[5:7,0:8,0:3]. foo[::-1] reverses a tensor with shape 8.

遗憾的是,目前 Tensorflow 中仅提供基本类型索引。高级类型索引正在开发中。

次要问题是您调整大小不合适。 Tensorflow 假定 3D 或 4D 输入。您尝试将 2D 图像传递给 `tf.image.resize_images(),它不会返回所需的新图像尺寸。所以我们必须像这样 reshape 原始图像:

x_train = x_train.reshape((-1, x_train.shape[1], x_train.shape[1], 1)) 

只有这样我们才能将它们传递给:

`x_train = tf.image.resize_images(x_train, [128, 128]) 

然后它将返回正确的尺寸:

print(x_train.shape) 

输出:

(60000, 128, 128, 1) 

所以总结一下整个解决方案,目前可以做如下操作:

import numpy as np 
import tensorflow as tf 
 
batch_size = 32 
 
mnist = tf.keras.datasets.mnist 
 
(x_train, _), (_, _) = mnist.load_data() 
 
x_train = x_train.reshape((-1, x_train.shape[1], x_train.shape[1], 1)) 
x_train = (x_train.astype(np.float32) - 127.5) / 127.5 
x_train = tf.image.resize_images(x_train, [128, 128]) 
 
idx = np.random.randint(0, x_train.shape[0], batch_size) 
 
imgs = [x_train[i,:,:,:] for i in idx] 

这是一个相当困惑的“解决方案”。

其他,实际上是一个真正的解决方案,通过重新排列原始代码,我们可以实现我们的目标,作为解决 tensorflow 索引问题的方法:

import numpy as np 
import tensorflow as tf 
 
batch_size = 32 
 
mnist = tf.keras.datasets.mnist 
 
(x_train, _), (_, _) = mnist.load_data() 
 
x_train = (x_train.astype(np.float32) - 127.5) / 127.5 
idx = np.random.randint(0, x_train.shape[0], batch_size) 
x_train = x_train[idx] 
 
x_train = x_train.reshape((-1, x_train.shape[1], x_train.shape[1], 1)) 
x_train = tf.image.resize_images(x_train, [128, 128]) 
 
print(x_train.shape) 

输出:

(32, 128, 128, 1) 

就是这样!

或者,您可以使用其他图像工具代替 tf.image.resize_images(),例如 skimage.transform.resize()来自 scikit-image返回 numpy 数组类型数据。