У меня есть функция предварительной обработки данных, которая выполняет блочный DCT для трехмерных массивов в режиме YCbCr.
def perform_blockwise_dct(img, ratio):
imsize = img.shape
dct_blocks = np.zeros(imsize)
for i in np.r_[:imsize[0]:8]:
for j in np.r_[:imsize[1]:8]:
dct_blocks[i:(i+8),j:(j+8), 0] = dct(dct(img[i:(i+8),j:(j+8), 0].T, norm='ortho').T, norm='ortho')
dct_blocks[i:(i+8),j:(j+8), 1] = dct(dct(img[i:(i+8),j:(j+8), 1].T, norm='ortho').T, norm='ortho')
dct_blocks[i:(i+8),j:(j+8), 2] = dct(dct(img[i:(i+8),j:(j+8), 2].T, norm='ortho').T, norm='ortho')
return dct_blocks
Чтобы иметь возможность реализовать пользовательскую функцию среднеквадратичной ошибки, я бы хотел изменить эту функцию. Проблема в том, что при реализации функции потерь это тензор тензора. Существует обратная функция DCT для использования. Однако я не знаю, как выполнить эквивалентный двойной цикл for, чтобы сделать это по блокам. В настоящее время это делается для всего изображения, например:
def mse_custom_loss(a, b)
y = tf.spectral.idct(a[:,:,0], norm='ortho')
cb = tf.spectral.idct(a[:,:,1], norm='ortho')
cr = tf.spectral.idct(a[:,:,2], norm='ortho')
a = K.stack([y, cb, cr], axis=-1)
y = tf.spectral.idct(b[:,:,0], norm='ortho')
cb = tf.spectral.idct(b[:,:,1], norm='ortho')
cr = tf.spectral.idct(b[:,:,2], norm='ortho')
b = K.stack([y, cb, cr], axis=-1)
return mean_square_error(a, b)
Есть идеи, как это правильно сделать? Я предполагаю, что лямбда-функции могут быть возможны?