keras自定义丢失纯python(无keras后端)

时间:2018-06-24 14:43:31

标签: python tensorflow keras loss-function

我目前正在为图像压缩编写自动编码器。我想使用以纯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。

非常感谢。非常感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

不能将纯Python函数用作Keras的损失。当您可能在GPU上训练并且python使用CPU时,这会通过从GPU内存传输结果到GPU内存而产生开销。

来自https://keras.io/losses/

  

您可以传递现有损失函数的名称,也可以传递TensorFlow / Theano 符号函数,该函数为每个数据点返回标量,并采用以下两个参数:y_true,y_pred < / p>

您的功能将是(与原始功能相同)

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类似的接口。了解后端的计算图(即张量流)如何实现损失可能很有用。