python - 如何在Keras模型末尾添加 tensorflow 数学函数?

标签 python tensorflow keras deep-learning

我正在尝试将简单的 tensorflow 数学函数添加到 Keras 模型的末尾,但它不起作用。这是我使用 native Keras Add() 函数的荒谬但最小的工作代码:

import numpy as np
import matplotlib.pyplot as plt
import scipy.signal as ss

from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Conv1D, Add
import tensorflow as tf

kernel_size = 64
epochs = 1000

## Data generation for training

x_train = np.random.randn(1024, 512)

t = np.linspace(0, x_train.shape[1], x_train.shape[1], endpoint=False)
sine = np.sin(2*np.pi*t/32)
cosine = np.cos(2*np.pi*t/32)

x_I = np.multiply(x_train, cosine)
x_Q = np.multiply(x_train, sine)

b_I = ss.tukey(kernel_size)
b_Q = ss.tukey(kernel_size)

x_I_filt = np.array([np.convolve(b_I, x_I_i, mode='valid') for x_I_i in x_I])
x_Q_filt = np.array([np.convolve(b_Q, x_Q_i, mode='valid') for x_Q_i in x_Q])

y_train = x_Q_filt + x_I_filt

x_I = np.expand_dims(x_I, axis=2)
x_Q = np.expand_dims(x_Q, axis=2)
y_train = np.expand_dims(y_train, axis=2)

## Keras model

input_I = Input(shape=(x_I.shape[1], 1))
input_Q = Input(shape=(x_Q.shape[1], 1))

conv_I_1D = Conv1D(filters=1, kernel_size=kernel_size, activation=None, padding='valid', use_bias=False)(input_I)
conv_Q_1D = Conv1D(filters=1, kernel_size=kernel_size, activation=None, padding='valid', use_bias=False)(input_Q)

out_I_Q = Add()([conv_I_1D, conv_Q_1D]) 
# out_I_Q = tf.math.add(conv_I_1D, conv_I_1D)

model_1D = Model([input_I, input_Q], out_I_Q)

model_1D.compile(optimizer='sgd', loss='mean_squared_error') 
history_1D = model_1D.fit([x_I, x_Q], y_train, epochs=epochs, verbose=0)

40 个 epoch 后,我得到了几乎完美的初始过滤器内核:

plt.semilogy(history_1D.history['loss'])
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.show()

enter image description here

但是如果我用 tensorflow 等效添加函数替换 Keras Add() 函数: out_I_Q = tf.math.add(conv_I_1D, conv_I_1D) 我会得到这个悲伤的损失图形: enter image description here 我认为 tensorflow 数学函数不是此配置中 Keras 模型的一部分。更改优化器类型根本没有帮助。我使用的是tensorflow 2.0 和Keras 2.2.5。

最佳答案

您应该使用tf.keras.layers.Lambda layertf.math.add() 结合如下:

def add_func(inputs):
    return tf.math.add(inputs[0], inputs[1])

out_I_Q = Lambda(add_func)([conv_I_1D, conv_Q_1D])

out_I_Q = Lambda(lambda x: tf.math.add(x[0], x[1]))([conv_I_1D, conv_Q_1D])

来自文档:

The Lambda layer exists so that arbitrary TensorFlow functions can be used when constructing Sequential and Functional API models.

完整示例:

import numpy as np
import matplotlib.pyplot as plt
import scipy.signal as ss

from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Conv1D, Add, Lambda
import tensorflow as tf

kernel_size = 64
epochs = 100

## Data generation for training

x_train = np.random.randn(1024, 512)

t = np.linspace(0, x_train.shape[1], x_train.shape[1], endpoint=False)
sine = np.sin(2*np.pi*t/32)
cosine = np.cos(2*np.pi*t/32)

x_I = np.multiply(x_train, cosine)
x_Q = np.multiply(x_train, sine)

b_I = ss.tukey(kernel_size)
b_Q = ss.tukey(kernel_size)

x_I_filt = np.array([np.convolve(b_I, x_I_i, mode='valid') for x_I_i in x_I])
x_Q_filt = np.array([np.convolve(b_Q, x_Q_i, mode='valid') for x_Q_i in x_Q])

y_train = x_Q_filt + x_I_filt

x_I = np.expand_dims(x_I, axis=2)
x_Q = np.expand_dims(x_Q, axis=2)
y_train = np.expand_dims(y_train, axis=2)

## Keras model

input_I = Input(shape=(x_I.shape[1], 1))
input_Q = Input(shape=(x_Q.shape[1], 1))

conv_I_1D = Conv1D(filters=1, kernel_size=kernel_size, activation=None, padding='valid', use_bias=False)(input_I)
conv_Q_1D = Conv1D(filters=1, kernel_size=kernel_size, activation=None, padding='valid', use_bias=False)(input_Q)

out_I_Q = Lambda(lambda x: tf.math.add(x[0], x[1]))([conv_I_1D, conv_Q_1D])

model_1D = Model([input_I, input_Q], out_I_Q)

model_1D.compile(optimizer='sgd', loss='mean_squared_error') 
history_1D = model_1D.fit([x_I, x_Q], y_train, epochs=epochs, verbose=0)

plt.semilogy(history_1D.history['loss'])
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.show()

输出:

enter image description here

关于python - 如何在Keras模型末尾添加 tensorflow 数学函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59469404/

相关文章:

python - 减去两个不同大小的数据帧,但至少保持第一个数据帧的大小

python - 如何为 Google Cloud Endpoints 方法生成 pydoc 文档?

python-2.7 - Tensorflow(python):train_step.run(…)中的“ValueError:设置具有序列的数组元素”

python - Python : Is there a way to use pool. imap 中的多处理不积累内存?

merge - 凯拉斯 : How to merge a dense layer and an embedding layer

Python从html表单中获取图像的问题

python - AWS Lambda 函数中的音频文件到文本转换

tensorflow - 使用 Google 的 DEEPLAB V3+ 获取图像分割中每个语义类别的类别概率分数

python - 为经过训练的 tensorflow 网络中的所有输入获取相同的预测值

machine-learning - 在训练 Keras 模型时,当 valid_split 为 0 时,训练会发生什么情况?