keras 自定义损失纯 python(没有 keras 后端)
keras custom loss pure python (without keras backend)
我目前正在编写一个用于图像压缩的自动编码器。我想使用纯 python 编写的自定义损失函数,即不使用 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()
上面的代码是使用 Keras 后端的自定义损失函数的 MWE。然而,这不是我想要的!我想用这样的东西替换我代码中的 mse_keras 函数:
def my_mse(A,B):
mse = ((A - B) ** 2).mean(axis=None)
return mse
这又只是一个 MWE。它是纯粹的 python 和 scipy。没有 KERAS 后端!
是否可以使用纯 python 函数作为损失函数(我尝试使用 py_func,但它对我不起作用。)
我问的原因是因为最终我想使用一种已经在 python 中实现的更复杂的损失函数。而且,我不知道如何使用 keras 后端重新实现它。 (老实说,我也没有时间这样做)
(对于好奇:我想用作损失函数的函数可以在这里看到:https://github.com/aizvorski/video-quality)
如有任何帮助,我们将不胜感激。后端可以是theano,tensorflow,我不在乎。如果可能,请在 python 3.X.
中向我提供 MWE
非常感谢。非常感谢您的帮助。
您不能使用纯 Python 函数作为 Keras 的损失。由于您可能在 GPU 上训练并且 python 使用 CPU 这会通过将结果 from/to 传输到 GPU 内存来产生开销。
You can either pass the name of an existing loss function, or pass a TensorFlow/Theano symbolic function that returns a scalar for each data-point and takes the following two arguments: y_true, y_pred
你的函数是(和原来的一样)
def my_mse(A,B):
mse = K.mean(K.pow(A - B, 2), axis=None)
return mse
但是,检查 Keras API,它需要每个数据点的标量,所以取平均值可能不会像这样使用 axis=None
。
我快速浏览了您链接的损失函数,在 Keras 中实现它们应该是可能的,而且不太困难。 Keras(或实际上是后端 Tensorflow)具有与 numpy 类似的接口。了解后端的计算图(即 tensorflow)如何实现损失可能会有用。
我目前正在编写一个用于图像压缩的自动编码器。我想使用纯 python 编写的自定义损失函数,即不使用 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()
上面的代码是使用 Keras 后端的自定义损失函数的 MWE。然而,这不是我想要的!我想用这样的东西替换我代码中的 mse_keras 函数:
def my_mse(A,B):
mse = ((A - B) ** 2).mean(axis=None)
return mse
这又只是一个 MWE。它是纯粹的 python 和 scipy。没有 KERAS 后端! 是否可以使用纯 python 函数作为损失函数(我尝试使用 py_func,但它对我不起作用。) 我问的原因是因为最终我想使用一种已经在 python 中实现的更复杂的损失函数。而且,我不知道如何使用 keras 后端重新实现它。 (老实说,我也没有时间这样做)
(对于好奇:我想用作损失函数的函数可以在这里看到:https://github.com/aizvorski/video-quality)
如有任何帮助,我们将不胜感激。后端可以是theano,tensorflow,我不在乎。如果可能,请在 python 3.X.
中向我提供 MWE非常感谢。非常感谢您的帮助。
您不能使用纯 Python 函数作为 Keras 的损失。由于您可能在 GPU 上训练并且 python 使用 CPU 这会通过将结果 from/to 传输到 GPU 内存来产生开销。
You can either pass the name of an existing loss function, or pass a TensorFlow/Theano symbolic function that returns a scalar for each data-point and takes the following two arguments: y_true, y_pred
你的函数是(和原来的一样)
def my_mse(A,B):
mse = K.mean(K.pow(A - B, 2), axis=None)
return mse
但是,检查 Keras API,它需要每个数据点的标量,所以取平均值可能不会像这样使用 axis=None
。
我快速浏览了您链接的损失函数,在 Keras 中实现它们应该是可能的,而且不太困难。 Keras(或实际上是后端 Tensorflow)具有与 numpy 类似的接口。了解后端的计算图(即 tensorflow)如何实现损失可能会有用。