Это происходит из-за того, что вызывается Numpy широковещательной рассылкой, которая описывает, как Numpy обрабатывает массивы с разными формами.
Давайте сначала определим два тензора A и B тензоры со следующими формами,
dim(A) = (32, 60, 1)
dim(B) = (32,)
Например, если вы попытаетесь выполнить некоторые операции, такие как вычитание , сложение или любая поэлементная операция между A и B , в этом случае так, как Tensorflow представляет B
dim(B) = (do_not_care, do_not_care, 32)
Таким образом, при итерации скалярное значение x вычитается из массива из 32 элементов (значений), поэтому на выходе получается матрица столбцов содержит 32 различных значения.
dim(output) = (32, 60, 32)
, что допустимо, но неожиданное поведение.
Такая операция может быть реализована рекурсивно , мы выполняем итерацию по тензору с более высоким размером, начиная с 1-го копейки nsion ( axis ) к известной размерности второго тензора, то мы можем применить требуемую операцию к результирующему тензору chunked , если их формы совпадают, другими словами, широковещательный успешно .
Реализация широковещательной передачи для вычитания может быть выполнена следующим образом.
def supstract(a, b): # a and b are numpy.array()
# check if shape valid
if a.squeeze().ndim == b.squeeze().ndim:
if b.squeeze().shape[-1] == b.squeeze().shape[-1]:
print(a - b, '\n')
return
else:
raise ValueError(f'could not Broadcasting, {a.shape} != {b.shape}')
elif a.ndim > b.ndim:
for sub_a in a:
supstract(sub_a, b) # recursive call
else:
for sub_b in b:
supstract(a, sub_b) # recursive call
Я использовал следующий пример для проверки реализации, поэтому Возможно, я пропустил некоторые условия (обработка разных случаев).
a = np.random.randint(1, 4, (2, 2, 6, 1))
b = np.random.randint(1, 4, (4, ))
В вашем случае Tensorflow требуется Y для вычисления функции потерь, вы используете MSE , которое является просто скалярным значением, вычисленным с использованием Keras бэкэнда следующим образом.
from tensorflow.keras import backend as K
def mean_squared_error(y_true, y_pred):
return K.mean((y_pred - y_true) ** 2) # broadcasting (y_pred - y_true)
Обновление
|1 2 3| + |7 8 9|
|4 5 6|
|1 2 3| + 7 = |8 9 10|
|4 5 6| |11 12 13|
На основе Tensorflow документация для описания трансляции . Numpy (широковещательная передача) обрабатывает любую из вышеперечисленных операций, но математически вы не можете применить ни одну из них. Если вы хотите получать предупреждения для любой операции вещания, вы можете ожидать получения тонн предупреждений.