keras preprocess_input就地更改数组,但不更改Tensor

yrdbyhpb  于 2022-11-24  发布在  其他
关注(0)|答案(1)|浏览(108)

我注意到preprocess_input中的一些奇怪行为,这个函数用于对图像进行预处理,以正确地对您正在使用的特定预训练网络的值进行归一化。经过几个小时的调试,似乎当将Tensor用作输入时,输入Tensor未被修改,并且它将处理后的输入作为新Tensor返回:

tensor = tf.ones(3)*100
print(tensor)
tensor2 = tf.keras.applications.mobilenet_v2.preprocess_input (tensor)
print(tensor)
print(tensor2)

返回

tf.Tensor([100. 100. 100.], shape=(3,), dtype=float32)
tf.Tensor([100. 100. 100.], shape=(3,), dtype=float32)
tf.Tensor([-0.21568626 -0.21568626 -0.21568626], shape=(3,), dtype=float32)

然而,当执行完全相同的操作,但使用numpy数组作为输入时,除了将处理后的版本作为新数组返回之外,* 原始数组将被更改为与新数组相同 *:

array = np.ones(3)*100
print(array)
array2 = tf.keras.applications.mobilenet_v2.preprocess_input (array)
print(array)
print(array2)
array+=1
print(array)
print(array2)

返回

[100. 100. 100.]
[-0.21568627 -0.21568627 -0.21568627]       # <== input has changed!!!
[-0.21568627 -0.21568627 -0.21568627]
[0.78431373 0.78431373 0.78431373]
[0.78431373 0.78431373 0.78431373]          # <== further changes to input change output

三个问题:
1.为什么行为不一致?
1.为什么认为改变原有的阵列是有益的?
1.为什么preprocess_input既返回新值,又就地修改-通常不是两者之一吗?两者都做会让人困惑......

yftpprvb

yftpprvb1#

公平地说,docs确实提到了这种行为:
如果数据类型是兼容的,预处理数据将覆盖输入数据。为了避免这种行为,可以使用numpy.copy(x)。
所以这种Q1 -Tensor的答案是不可变的,所以不能被覆盖,而np个数组是可变的,所以可以在原地改变。
注意:这不是一个很好的答案--如果这个函数在Tensor上被大量使用,那么它的行为肯定应该是固定的,这样即使在数组上它也会表现得一样。也就是说,它 * 永远 * 不应该改变输入,所以它表现得一致,人们会知道会发生什么。

相关问题