我注意到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既返回新值,又就地修改-通常不是两者之一吗?两者都做会让人困惑......
1条答案
按热度按时间yftpprvb1#
公平地说,docs确实提到了这种行为:
如果数据类型是兼容的,预处理数据将覆盖输入数据。为了避免这种行为,可以使用numpy.copy(x)。
所以这种Q1 -Tensor的答案是不可变的,所以不能被覆盖,而np个数组是可变的,所以可以在原地改变。
注意:这不是一个很好的答案--如果这个函数在Tensor上被大量使用,那么它的行为肯定应该是固定的,这样即使在数组上它也会表现得一样。也就是说,它 * 永远 * 不应该改变输入,所以它表现得一致,人们会知道会发生什么。