首页 > 解决方案 > 在 Keras (2.4.3) 和 Tensorflow (2.4.1) 中使用 NumPy 数组

问题描述

我想在 Keras 中实现一个 lambda 层或自定义层,它将输入张量的值传递给一个接受并返回 Numpy 数组的外部库。该库执行物理模拟,我无法使用 tensorflow.experimental.numpy 或 keras.backend 模块合理地重现该模拟。

我看到这是 StackOverflow 和 GitHub 上许多问题和答案的常见问题。但是,我无法找到适用于我已安装的 Keras 和 Tensorflow 版本(目前是 PyPI 上的最新版本)的解决方案。

到目前为止,我已确保启用了 Eager Execution,尝试使用 Keras 自定义层而不是 lambda 层,并尝试了执行转换的不同方法(例如 tf.make_ndarray 和 tf.convert_to_tensor)。在每种情况下,我都会触发一个错误,表明该函数没有被急切地执行,例如:

AttributeError:“张量”对象没有属性“张量形状”

我观察到tf.executing_eagerly()从 lambda 层中使用的函数中调用时返回 false。我知道这个问题源于 Keras 层的父类没有包含在急切的执行中 - 但我不确定从那里去哪里。

下面是一个最小的可重现示例。如果删除第 31 行,则执行代码。

import numpy as np
import tensorflow as tf

tf.config.run_functions_eagerly(True)
print(tf.executing_eagerly())

def function(input_tensor):
    print(tf.executing_eagerly())
    array = tf.keras.backend.eval(input_tensor)
    array = array + 0.2
    out = np.empty([1,sample_dim])
    out[0,:] = array[:]
    return tf.keras.backend.variable(out)

samples = 20
sample_dim = 10

x = np.empty([20,10], dtype = np.float32)
y = np.empty([20,10], dtype = np.float32)

for i in range(samples):
    x[i,:] = np.array([j + i for j in range(10)], dtype = np.float32)/10
    y[i,:] = x[i,:] + 0.1

model = tf.keras.Sequential()

model.add(tf.keras.Input(shape=(sample_dim)))
model.add(tf.keras.layers.Dense(sample_dim, activation = "relu"))
model.add(tf.keras.layers.Lambda(function, output_shape = (sample_dim)))
model.add(tf.keras.layers.Dense(sample_dim, activation = "relu"))
model.build()
model.compile(optimizer='sgd',loss="mse", run_eagerly=True)
model.fit(x, y, batch_size=10, epochs=10)

标签: pythonnumpytensorflowkeras

解决方案


推荐阅读