标准化x_train / = 255.0和x_train = x_train / 255.0之间的差异

时间:2020-08-29 08:49:21

标签: python tensorflow

我有一些简单的代码,可以加载mnist数据并标准化图像。

    mnist = tf.keras.datasets.mnist

    (x_train, y_train),(x_test, y_test) = mnist.load_data()
    x_train = x_train/255.0
    x_test = x_test/255.0

上面的代码有效,但是,如果我尝试使用速记除法,则会出现错误:

    mnist = tf.keras.datasets.mnist

    (x_train, y_train),(x_test, y_test) = mnist.load_data()
    x_train /= 255.0
    x_test /= 255.0

错误如下: TypeError: ufunc 'true_divide' output (typecode 'd') could not be coerced to provided output parameter (typecode 'B') according to the casting rule ''same_kind''

通过玩转,我找到了一个解决方案,将x_train转换为float32可以消除错误,但是我偶然发现了该修复程序。我不明白为什么下面的代码可以解决问题

    mnist = tf.keras.datasets.mnist

    (x_train, y_train),(x_test, y_test) = mnist.load_data(path=path)
    x_train = x_train.astype('float32')
    x_test = x_test.astype('float32')
    x_train /= 255.0
    x_test /= 255.0

有人可以解释一下这里发生了什么吗?为什么两个版本的行为不同?为什么在第二个实例中需要一个显式的案例,而在第一个实例中却不需要?
我发现在任何地方都记录有这种行为并不太幸运。

编辑:我不确定我需要提供什么其他“调试细节”,因为我基本上已经提供了完整的代码,结果以及我不理解的细节。我也没有收到任何评论来解释为什么关闭该问题和/或期望在此处获得其他信息。我希望进行一些建设性的批评,以便至少可以以一种更好的方式提出这个问题,如果目前的形式本身不能令人满意。

2 个答案:

答案 0 :(得分:1)

增强除法(x_train /= 255.)不仅仅是常规除法的简写。它的实现方式不同于常规划分方式,并且具有不同的意图。 Python对象具有实现算术函数的方法。

  • /__truediv__(self, other): ==> object
  • /=__itruediv__(self, other): ==> object

两者都返回结果对象(请参见 Emulating numeric types(在python文档中)。

它们相似,但是在使用可变对象(例如列表或numpy数组)时具有不同的意图。 __truediv__不应修改self,而__itruediv__应该修改。实现可以随意忽略,但是通常c = a / b不应修改a,而a /= b应该修改a。当某个对象未实现__itruediv__时,python会退回到__truediv__ -不可变对象通常无法实现增强版本,因为它们无法修改自身。

对于numpy数组,增强除法(/=)最终会调用numpy.true_divide。由于扩充除法修改了原始数组,因此它使用out参数将结果广播到原始对象中。这就是错误的所在-您不能将不同的数据类型广播到现有数组中。增强分割与

相同
>>> import numpy as np
>>> x_train = np.array([1,2,3], dtype='B')
>>> np.true_divide(x_train, 255., out=x_train)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: ufunc 'true_divide' output (typecode 'd') could not be coerced to provided output parameter (typecode 'B') according to the casting rule ''same_kind''

其中标准划分与

相同
>>> x_train = np.array([1,2,3], dtype='B')
>>> foo = np.true_divide(x_train, 255.)
>>> x_train = foo

在您的情况下,部门上的差异并不是真正的错误。由于您的操作创建了不同的类型,因此numpy需要分配不同大小的内存块来容纳它。您可以坚持使用非增强除法,也可以像对float32一样预先转换数组。它们都是合理的方法。增强运算符的窍门是要注意,它们将结果广播回原始数组,并具有广播的所有限制。

答案 1 :(得分:0)

如果您不想将类型更改为float32,则可以执行以下操作:

mnist = tf.keras.datasets.mnist

(x_train, y_train),(x_test, y_test) = mnist.load_data()
div = x_train / 255.0
x_train = div