В настоящее время я программирую автоэнкодер для сжатия изображений. Я хотел бы использовать настраиваемую функцию потерь, написанную на чистом питоне, то есть без использования бэкэнд-функций keras. Возможно ли это вообще, и если да, то как? Если можно, был бы очень признателен за минимально рабочий пример (MWE). Пожалуйста, посмотрите на этот MWE, в частности на функцию mse_keras:
# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
import numpy as np
import keras.backend as K
from keras.datasets import mnist
from keras.models import Model, Sequential
from keras.layers import Input, Dense
def mse_keras(A,B):
mse = K.mean(K.square(A - B), axis=-1)
return mse
# Loads the training and test data sets (ignoring class labels)
(x_train, _), (x_test, _) = mnist.load_data()
# Scales the training and test data to range between 0 and 1.
max_value = float(x_train.max())
x_train = x_train.astype('float32') / max_value
x_test = x_test.astype('float32') / max_value
x_train.shape, x_test.shape
# ((60000, 28, 28), (10000, 28, 28))
x_train = x_train.reshape((len(x_train), np.prod(x_train.shape[1:])))
x_test = x_test.reshape((len(x_test), np.prod(x_test.shape[1:])))
(x_train.shape, x_test.shape)
# ((60000, 784), (10000, 784))
# input dimension = 784
input_dim = x_train.shape[1]
encoding_dim = 32
compression_factor = float(input_dim) / encoding_dim
print("Compression factor: %s" % compression_factor)
autoencoder = Sequential()
autoencoder.add(Dense(encoding_dim, input_shape=(input_dim,), activation='relu'))
autoencoder.add(Dense(input_dim, activation='sigmoid'))
autoencoder.summary()
input_img = Input(shape=(input_dim,))
encoder_layer = autoencoder.layers[0]
encoder = Model(input_img, encoder_layer(input_img))
encoder.summary()
autoencoder.compile(optimizer='adam', loss=mse_keras, metrics=['mse'])
history=autoencoder.fit(x_train, x_train,
epochs=3,
batch_size=256,
shuffle=True,
validation_data=(x_test, x_test))
num_images = 10
np.random.seed(42)
random_test_images = np.random.randint(x_test.shape[0], size=num_images)
decoded_imgs = autoencoder.predict(x_test)
#print(history.history.keys())
plt.figure()
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test', 'mse1', 'val_mse1'], loc='upper left')
plt.show()
plt.figure(figsize=(18, 4))
for i, image_idx in enumerate(random_test_images):
# plot original image
ax = plt.subplot(3, num_images, i + 1)
plt.imshow(x_test[image_idx].reshape(28, 28))
plt.gray()
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
# plot reconstructed image
ax = plt.subplot(3, num_images, 2*num_images + i + 1)
plt.imshow(decoded_imgs[image_idx].reshape(28, 28))
plt.gray()
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
plt.show()
Приведенный выше код представляет собой MWE для настраиваемой функции потерь с использованием бэкэнда Keras. Однако я хочу не этого! Я хотел бы заменить в своем коде функцию mse_keras примерно так:
def my_mse(A,B):
mse = ((A - B) ** 2).mean(axis=None)
return mse
Это опять же просто MWE. Это чистый питон и scipy. НЕТ КЕРАС НАЗАД! Можно ли использовать чистые функции python в качестве функций потерь (я пробовал использовать py_func, но у меня это не сработало). Я спрашиваю, потому что в конечном итоге я хотел бы использовать более сложную функцию потерь, которая является уже реализован на Python. И я не понимаю, как я мог бы повторно реализовать его, используя бэкэнд keras. (У меня тоже нет на это времени, если честно)
(Для любопытных: функции, которые я хотел бы использовать в качестве функции потерь, можно увидеть здесь: https://github.com/aizvorski/video-quality)
Любая помощь будет принята с благодарностью. Backend может быть theano, tensorflow, мне все равно. Если возможно, предоставьте мне MWE на python 3.X.
Спасибо заранее. Ваша помощь очень ценится.