tf.data API 无法打印所有批次
tf.data API cannot print all the batches
我正在自学 tf.data
API。我正在使用 MNIST
数据集进行二元分类。训练 x 和 y 数据以完整 train_dataset 压缩在一起。与此 zip 方法链接在一起的首先是 batch()
数据集方法。数据以 30 的批次大小进行批处理。由于我的训练集大小为 11623,批次大小为 128,因此我将有 91 个批次。最后一批的大小将是 103,这很好,因为这是 LSTM。此外,我正在使用辍学。当我计算批准确度时,我关闭了 drop-out。
完整代码如下:
#Ignore the warnings
import warnings
warnings.filterwarnings("ignore")
import pandas as pd
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (8,7)
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/")
Xtrain = mnist.train.images[mnist.train.labels < 2]
ytrain = mnist.train.labels[mnist.train.labels < 2]
print(Xtrain.shape)
print(ytrain.shape)
#Data parameters
num_inputs = 28
num_classes = 2
num_steps=28
# create the training dataset
Xtrain = tf.data.Dataset.from_tensor_slices(Xtrain).map(lambda x: tf.reshape(x,(num_steps, num_inputs)))
# apply a one-hot transformation to each label for use in the neural network
ytrain = tf.data.Dataset.from_tensor_slices(ytrain).map(lambda z: tf.one_hot(z, num_classes))
# zip the x and y training data together and batch and Prefetch data for faster consumption
train_dataset = tf.data.Dataset.zip((Xtrain, ytrain)).batch(128).prefetch(128)
iterator = tf.data.Iterator.from_structure(train_dataset.output_types,train_dataset.output_shapes)
X, y = iterator.get_next()
training_init_op = iterator.make_initializer(train_dataset)
#### model is here ####
#Network parameters
num_epochs = 2
batch_size = 128
output_keep_var = 0.5
with tf.Session() as sess:
init.run()
print("Initialized")
# Training cycle
for epoch in range(0, num_epochs):
num_batch = 0
print ("Epoch: ", epoch)
avg_cost = 0.
avg_accuracy =0
total_batch = int(11623 / batch_size + 1)
sess.run(training_init_op)
while True:
try:
_, miniBatchCost = sess.run([trainer, loss], feed_dict={output_keep_prob: output_keep_var})
miniBatchAccuracy = sess.run(accuracy, feed_dict={output_keep_prob: 1.0})
print('Batch %d: loss = %.2f, acc = %.2f' % (num_batch, miniBatchCost, miniBatchAccuracy * 100))
num_batch +=1
except tf.errors.OutOfRangeError:
break
当我 运行 这段代码时,它似乎正在工作并正在打印:
Batch 0: loss = 0.67276, acc = 0.94531
Batch 1: loss = 0.65672, acc = 0.92969
Batch 2: loss = 0.65927, acc = 0.89062
Batch 3: loss = 0.63996, acc = 0.99219
Batch 4: loss = 0.63693, acc = 0.99219
Batch 5: loss = 0.62714, acc = 0.9765
......
......
Batch 39: loss = 0.16812, acc = 0.98438
Batch 40: loss = 0.10677, acc = 0.96875
Batch 41: loss = 0.11704, acc = 0.99219
Batch 42: loss = 0.10592, acc = 0.98438
Batch 43: loss = 0.09682, acc = 0.97656
Batch 44: loss = 0.16449, acc = 1.00000
但是,很容易看出,有些地方不对劲。只打印了 45 批次而不是 91 批次,我不知道为什么会这样。我尝试了很多东西,但我想我错过了一些东西。
我可以使用 repeat()
函数,但我不想那样做,因为我对最后一批有多余的观察,我希望 LSTM 来处理它。
在直接基于 tf.data
迭代器的 get_next()
输出定义模型时,这是一个恼人的陷阱。在您的循环中,您有两个 sess.run
调用,其中 both 将使迭代器前进一步。这意味着每个循环迭代实际上消耗了两个批次(而且你的损失和准确度计算是在不同的批次上计算的)。
不完全确定是否有 "canonical" 解决此问题的方法,但您可以
- 在与 cost/training 步骤相同的
run
调用中计算准确度。这意味着精度计算也会受到 dropout mask 的影响,但由于它是仅基于一批的近似值,所以这应该不是一个大问题。
- 改为基于占位符定义您的模型,并在每个循环迭代中
run
get_next
op 本身,然后将生成的 numpy 数组(即批处理)提供给 loss/accuracy 计算。
我正在自学 tf.data
API。我正在使用 MNIST
数据集进行二元分类。训练 x 和 y 数据以完整 train_dataset 压缩在一起。与此 zip 方法链接在一起的首先是 batch()
数据集方法。数据以 30 的批次大小进行批处理。由于我的训练集大小为 11623,批次大小为 128,因此我将有 91 个批次。最后一批的大小将是 103,这很好,因为这是 LSTM。此外,我正在使用辍学。当我计算批准确度时,我关闭了 drop-out。
完整代码如下:
#Ignore the warnings
import warnings
warnings.filterwarnings("ignore")
import pandas as pd
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (8,7)
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/")
Xtrain = mnist.train.images[mnist.train.labels < 2]
ytrain = mnist.train.labels[mnist.train.labels < 2]
print(Xtrain.shape)
print(ytrain.shape)
#Data parameters
num_inputs = 28
num_classes = 2
num_steps=28
# create the training dataset
Xtrain = tf.data.Dataset.from_tensor_slices(Xtrain).map(lambda x: tf.reshape(x,(num_steps, num_inputs)))
# apply a one-hot transformation to each label for use in the neural network
ytrain = tf.data.Dataset.from_tensor_slices(ytrain).map(lambda z: tf.one_hot(z, num_classes))
# zip the x and y training data together and batch and Prefetch data for faster consumption
train_dataset = tf.data.Dataset.zip((Xtrain, ytrain)).batch(128).prefetch(128)
iterator = tf.data.Iterator.from_structure(train_dataset.output_types,train_dataset.output_shapes)
X, y = iterator.get_next()
training_init_op = iterator.make_initializer(train_dataset)
#### model is here ####
#Network parameters
num_epochs = 2
batch_size = 128
output_keep_var = 0.5
with tf.Session() as sess:
init.run()
print("Initialized")
# Training cycle
for epoch in range(0, num_epochs):
num_batch = 0
print ("Epoch: ", epoch)
avg_cost = 0.
avg_accuracy =0
total_batch = int(11623 / batch_size + 1)
sess.run(training_init_op)
while True:
try:
_, miniBatchCost = sess.run([trainer, loss], feed_dict={output_keep_prob: output_keep_var})
miniBatchAccuracy = sess.run(accuracy, feed_dict={output_keep_prob: 1.0})
print('Batch %d: loss = %.2f, acc = %.2f' % (num_batch, miniBatchCost, miniBatchAccuracy * 100))
num_batch +=1
except tf.errors.OutOfRangeError:
break
当我 运行 这段代码时,它似乎正在工作并正在打印:
Batch 0: loss = 0.67276, acc = 0.94531
Batch 1: loss = 0.65672, acc = 0.92969
Batch 2: loss = 0.65927, acc = 0.89062
Batch 3: loss = 0.63996, acc = 0.99219
Batch 4: loss = 0.63693, acc = 0.99219
Batch 5: loss = 0.62714, acc = 0.9765
......
......
Batch 39: loss = 0.16812, acc = 0.98438
Batch 40: loss = 0.10677, acc = 0.96875
Batch 41: loss = 0.11704, acc = 0.99219
Batch 42: loss = 0.10592, acc = 0.98438
Batch 43: loss = 0.09682, acc = 0.97656
Batch 44: loss = 0.16449, acc = 1.00000
但是,很容易看出,有些地方不对劲。只打印了 45 批次而不是 91 批次,我不知道为什么会这样。我尝试了很多东西,但我想我错过了一些东西。
我可以使用 repeat()
函数,但我不想那样做,因为我对最后一批有多余的观察,我希望 LSTM 来处理它。
在直接基于 tf.data
迭代器的 get_next()
输出定义模型时,这是一个恼人的陷阱。在您的循环中,您有两个 sess.run
调用,其中 both 将使迭代器前进一步。这意味着每个循环迭代实际上消耗了两个批次(而且你的损失和准确度计算是在不同的批次上计算的)。
不完全确定是否有 "canonical" 解决此问题的方法,但您可以
- 在与 cost/training 步骤相同的
run
调用中计算准确度。这意味着精度计算也会受到 dropout mask 的影响,但由于它是仅基于一批的近似值,所以这应该不是一个大问题。 - 改为基于占位符定义您的模型,并在每个循环迭代中
run
get_next
op 本身,然后将生成的 numpy 数组(即批处理)提供给 loss/accuracy 计算。