Tensorflow:批处理整个数据集(MNIST教程)

时间:2018-03-09 03:46:15

标签: python tensorflow dataset mnist tensorflow-datasets

遵循本教程:https://www.tensorflow.org/versions/r1.3/get_started/mnist/pros

我想自己用标记图像解决分类问题。由于我没有使用MNIST数据库,我花了几天时间在tensorflow中创建自己的数据集。它看起来像这样:

#variables
batch_size = 50
dimension = 784
stages = 10

#step 1 read Dataset
filenames = tf.constant(filenamesList)
labels = tf.constant(labelsList)

#step 2 create Dataset
dataset = tf.data.Dataset.from_tensor_slices((filenames, labels))

#step 3: parse every image in the dataset using `map`
def _parse_function(filename, label):
    #convert label to one-hot encoding
    one_hot = tf.one_hot(label, stages)

    #read image file
    image_string = tf.read_file(filename)
    image_decoded = tf.image.decode_image(image_string, channels=3)
    image = tf.cast(image_decoded, tf.float32)

    return image, one_hot

#step 4 final input tensor
dataset = dataset.map(_parse_function)
dataset = dataset.batch(batch_size) #batch_size = 100

iterator = dataset.make_one_shot_iterator()
images, labels = iterator.get_next()

images = tf.reshape(images, [batch_size,dimension]).eval()
labels = tf.reshape(labels, [batch_size,stages]).eval()

for _ in range(10):
    dataset = dataset.shuffle(buffer_size = 100)
    dataset = dataset.batch(batch_size)
    iterator = dataset.make_one_shot_iterator()
    images, labels = iterator.get_next()

    images = tf.reshape(images, [batch_size,dimension]).eval()
    labels = tf.reshape(labels, [batch_size,stages]).eval()

    train_step.run(feed_dict={x: images, y_:labels})

以某种方式使用更高的batch_sizes将破坏python 。我想要做的是在每次迭代时用新批次训练我的神经网络。这就是我也使用dataset.shuffle(...)的原因。使用dataset.shuffle也会破坏我的Python。

我想做的事情(因为随机休息)是批处理整个数据集。通过评估(' .eval()')我会得到一个numpy数组。然后我将使用numpy.random.shuffle(images)对数组进行洗牌,然后选择一些第一个元素来训练它。

e.g。

for _ in range(1000):
    images = tf.reshape(images, [batch_size,dimension]).eval()
    labels = tf.reshape(labels, [batch_size,stages]).eval()

    #shuffle
    np.random.shuffle(images)
    np.random.shuffle(labels)

    train_step.run(feed_dict={x: images[0:train_size], y_:labels[0:train_size]})

但接下来是我无法批量处理整个数据集的问题。看起来数据太大,python无法使用。 我该如何解决这个问题?

由于我没有使用MNIST数据库,因此没有类似 mnist.train.next_batch(100)的功能,这对我来说非常方便。

2 个答案:

答案 0 :(得分:3)

请注意您如何在for循环中调用shuffle ?这是错的。 TF中的batch以函数式编程的方式工作,因此您实际上正在定义一个管道,用于预处理数据以提供给您的模型。在某种程度上,你给出一个回答问题的食谱"给定这些原始数据,我应该做哪些操作(地图等)来获得我可以提供给神经网络的批次?"

现在您要为每个批次修改该管道!会发生的是第一次迭代,批量大小是Dataset。在下一次迭代中,此形状的元素将再次批次,再分配到[32 3600],依此类推。

有一个很棒的tutorial on the TF website,您可以在其中了解[32 32 3600]的工作原理,但以下是一些如何解决问题的建议。

  • 在"步骤2"之后将洗牌移至右侧。在你的代码中。然后你正在改组整个数据集,这样你的批次就会有很好的例子。同时增加Dataset参数,这适用于different way than you probably assume。尽可能早地进行随机播放通常是一个好主意,因为如果你有一个大型数据集,这可能是一个缓慢的操作 - 数据集的混洗部分必须被读入内存。在这里,您是否随机播放文件名和标签,或者读取的图像和标签并不重要 - 但后者将有更多的工作要做,因为到那时数据集更大。

  • 在开始训练循环之前,将批处理和迭代器生成器移动到最后一步。

  • 不要将buffer_sizefeed_dict迭代器一起使用,以将数据输入到模型中。相反,根据Dataset的输出定义模型并省略iterator.get_next()参数。请参阅此问答的详细信息:Tensorflow: create minibatch from numpy array > 2 GB

答案 1 :(得分:0)

我在创建张量流数据集方面遇到了很多问题。所以我决定使用OpenCV导入图像。

import opencv as cv
imgDataset = []
for i in range(len(files)):
    imgDataset.append(cv2.imread(files[i]))
imgDataset = np.asarray(imgDataset)

imgDataset的形状是(num_img,height,width,col_channels)。获得第i个图像应该是imgDataset [i]。

对数据集进行混洗,只获得批量数据集可以这样做:

from sklearn.utils import shuffle
X,y = shuffle(X, y)
X_feed = X[batch_size]
y_feed = y[batch_size]

然后将X_feed和y_feed输入模型