Python 为什么TensorFlow深度学习提供的代码结果与书中的快照不同

Python 为什么TensorFlow深度学习提供的代码结果与书中的快照不同,python,tensorflow,keras,tensorflow2.0,mnist,Python,Tensorflow,Keras,Tensorflow2.0,Mnist,在TensorFlow深度学习的第一章中,给出了一个如何建立一个简单的手写数字识别神经网络的例子。根据描述,本书的代码包可以在以下位置找到: 从上下文来看,我认为运行一个简单的TensorFlow 2.0网络并建立一个基线的部分使用了与之相同的代码。当我运行此示例代码时,它给出以下输出: 书中的快照是: 我的屏幕截图中的结果是375/375,而书的快照中的结果是48000/48000。另外,我错过了对48000个样本的培训,对12000个样本的验证。为什么会发生这种情况?如何使用书本中的快照

在TensorFlow深度学习的第一章中,给出了一个如何建立一个简单的手写数字识别神经网络的例子。根据描述,本书的代码包可以在以下位置找到:

从上下文来看,我认为运行一个简单的TensorFlow 2.0网络并建立一个基线的部分使用了与之相同的代码。当我运行此示例代码时,它给出以下输出:

书中的快照是:

我的屏幕截图中的结果是
375/375
,而书的快照中的结果是
48000/48000
。另外,我错过了对48000个样本的
培训,对12000个样本的验证。为什么会发生这种情况?如何使用书本中的快照获得相同的结果

从我的输出来看,我认为我加载的数据集的大小与代码中描述的相同:

#加载MNIST数据集
#核实
#列车和试验的比例分别为60000和10000
#自动应用一个热的
mnist=keras.datasets.mnist
(X_列,Y_列),(X_测试,Y_测试)=列表负载数据()
我的软件包版本:

$python--版本
Python 3.6.8
$python3-c'导入tensorflow作为tf;打印(tf.\uuuuu版本)'
2.3.1
$python3-c'导入tensorflow作为tf;打印(tf.keras.uuuuu版本)
2.4.0

我试图从源代码中找到答案。
fit
方法在中定义。在这个方法中,它实例化一个对象,然后创建一个对象

#training.py类模型方法拟合
#配置和调用`tf.keras.Callback`的容器。
如果不存在(回调、回调\模块回调列表):
callbacks=callbacks\u module.CallbackList(
回调,
添加_history=True,
add_progbar=verbose!=0,
模型=自我,
冗长的,
时代,
步骤=数据\u处理程序。推断的\u步骤)
#callbacks.py类程序记录器
def on_epoch_begin(self、epoch、logs=None):
self.\u reset\u progbar()
如果self.verbose和self.epochs>1:
打印('Epoch%d/%d'(Epoch+1,self.epochs))
列车批次端def(自身、批次、日志=无):
self.\u批处理\u更新\u程序条(批处理,日志)
def\u批处理\u更新\u程序条(自身、批处理、日志=无):
# ...
如果self.verbose==1:
#仅当verbose=1时块异步。
logs=tf_utils.to_numpy_或_python_类型(日志)
self.progbar.update(self.seen,list(logs.items()),finalize=False)
ProgbarLogger
然后调用update方法来更新进度条

#generic_utils.py类程序条方法更新
如果self.verbose==1:
# ...
如果self.target不是None:
numdigits=int(np.log10(self.target))+1
bar=('%'+str(numdigits)+'d/%d[')%(当前,self.target)
375
self.target
的值。然后我找到了
self.target的值。target
是从
CallbackList
对象的
steps
参数传递过来的。在第一个代码段中,您可以看到
steps=data\u handler.推断的\u steps
。属性
推断的\u steps
定义在

@属性
def/U步骤(自):
“”“创建的“数据集”的每个历元的推断步数。”。
在下列情况下,此项为“无”:
(1) 基数未知的“Dataset”已传递给“DataHandler”,并且
(2) 未提供“每个时代的步骤”,以及
(3) 迭代的第一个阶段尚未完成。
返回:
创建的“数据集”的每个历元的推断步数。
"""
返回自我。\u推断\u步骤
我不知道如何计算
self.\u推断出的步骤

我认为脱线与……有关,但我不知道V1是什么意思

def\u print\u train\u info(num\u samples\u或步骤,val\u samples\u或步骤,is\u数据集):
增量='steps'如果是'samples'
msg='Train on{0}{increment}'。格式(
num_采样数_或_步数,增量=增量)
如果val_采样或步骤:
msg+=',在{0}{increment}上验证。格式(
val_采样或步数,增量=增量)
打印(msg)
问得好

让我们把它分成更小的部分

您使用48.000个样本进行训练,并使用12.000进行测试。但是,您的代码显示375而不是48.000

如果查看批次大小,其值为128

快速除法-->
48.000//128=375

您的代码是正确的,这很好

问题来自这样一个事实:在旧版本的Keras和TensorFlow中,无论使用的批次大小,每个步骤的整个样本都会显示(48.000)。在本例中,进度条会更新为:
0、128、256…直到48.000

现在,在较新的版本中,
steps\u per\u epoch
validation\u steps
参数等于样本数(比如
48.000
)除以
批量大小
维度(比如
128
),因此
375

两种显示都是正确的,这只是不同进度条的问题,我个人同意并更喜欢后者,因为如果批量大小为
128
,我更愿意同意查看
1、2、3…375
的逻辑

更新以进一步澄清:

这里有
model.fit()
参数的详细说明

每_历元的步数为整数或无。总步数(批数) 在宣布一个纪元结束并开始下一个纪元之前 时代

验证步骤仅在提供了验证数据且 一个tf.data数据集。要绘制的步骤总数(样本批次) 在每个历元结束时执行验证时停止之前

好问题

让我们休息一下