python - 如何构建具有多个输入的 Tensorflow 模型?

标签 python tensorflow keras deep-learning

我想使用 Functional API 创建一个 Tensorflow 神经网络模型,但我不确定如何将输入分成两个。我想做这样的事情:给定一个输入,它的前半部分进入神经网络的第一部分,它的后半部分进入第二部分,每个输入通过层,直到它们连接起来,通过另一层,然后最终到达输出。我想到了类似下面的代码片段,以及一个快速草图。

from tensorflow.keras.layers import Dense

def define_model(self):
    input1 = tf.keras.Input(shape=(4,)) #input is a 1D vector containing 7 elements, split as 4 and 3
    input2 = tf.keras.Input(shape=(3,))

    layer1_1 = Dense(4, activation=tf.nn.leaky_relu)(input1)
    layer2_1 = Dense(4, activation=tf.nn.leaky_relu)(layer1_1)

    layer1_2 = Dense(4, activation=tf.nn.leaky_relu)(input2)
    layer2_2 = Dense(3, activation=tf.nn.leaky_relu)(layer1_2)

    concat_layer = tf.keras.concatenate([layer2_1,layer2_2], axis = 0)
    layer3 = Dense(6, activation=tf.nn.leaky_relu)(concat_layer)

    output = Dense(4)(layer3) #no activation

    self.model = tf.keras.Model(inputs = [input1,input2],outputs = output)
    self.model.compile(loss = 'mean_squared_error', optimizer = 'rmsprop')
    return self.model
enter image description here
首先,我应该在这个模型中添加任何 Dropout 或 BatchNormalization 层吗?
此外,输入数组的前 4 个元素是二进制的(如 [1,0,0,1] 或 [0,1,1,1]),而其他 3 个元素可以是任何实数。考虑到第一个使用 0听起来不错,但我无法真正测试它是否应该工作,因为我必须重新编写大量代码以生成足够的数据来训练它。我是朝着正确的方向前进还是应该做一些不同的事情?这段代码会起作用吗?
编辑:我在训练期间遇到问题。假设我想像这样训练模型(值并不重要,重要的是数据类型):
#this snippet generates training data - nothing real, just test examples. Also, I changed the output layer from 4 elements to just 1 to test it.
A1=[np.array([[1.,0,0,1]]),np.array([[0,1.,0]])]
B1=np.array([7])

c=np.array([[5,-4,1,-1],[2,3,-1]], dtype = object)
A2 = [[np.random.randint(2, size= [1,4]),np.random.randint(2, size= [1,3])] for i in range(1000)]
B2 = np.array([np.sum(A[i][0]*c[0])+np.sum(A[i][1]*c[1]) for i in range(1000)]) 

model.fit(A1,B1, epochs = 50, verbose=False) #this works!
model.fit(A2,B2, epochs = 50, verbose=False) #but this doesn't.


最终编辑:这里是 predict() 和 predict_on_batch() 函数。
def predict(a,b):
    pred = m.predict([a,b])
    return pred

def predict_b(c,d):
    preds = m.predict_on_batch([c,d])
    return preds

#a, b, c and d must look like this:
a = [np.array([0,1,0,1])]
b = [np.array([0,0,1])]

c =        [np.array([1, 0, 0, 1]), 
            np.array([0, 1, 1, 1]), 
            np.array([0, 1, 0, 0]), 
            np.array([1, 0, 0, 0]), 
            np.array([0, 0, 1, 0])] 

d =        [np.array([1, 0, 1]),
            np.array([0, 0, 1]),
            np.array([0, 1, 1]),
            np.array([1, 1, 1]),
            np.array([0, 0, 0])]
#notice that all of those should follow the same pattern, which is a list of arrays.
其余代码在 M. Innat 的回答下。

最佳答案

您的代码存在一些问题。我将尝试回答这里的主要问题,并丢弃一些附带问题,例如您是否应该使用 DropoutBatchNormalization是否在您的模型中添加图层,因为这完全超出了您的主要问题的范围,而且也不相关。

如果您尝试构建模型,请使用 m = define_model() ,我很确定你会遇到以下错误:

layer2_1 = Dense(4, activation=tf.nn.leaky_relu)(layer1_1)
layer2_2 = Dense(3, activation=tf.nn.leaky_relu)(layer1_2)
concat_layer = tf.keras.layers.concatenate([layer2_1, layer2_2], axis = 0)

ValueError: A `Concatenate` layer requires inputs with matching shapes 
except for the concat axis. Got inputs shapes: [(None, 4), (None, 3)]
正确 axis默认情况下应该是 -11但不是 0同时连接不相同的形状(例如 Dense(4)Dense(3) )。您可以设置相同的输出形状,即 Dense(3)Dense(4)或设置 axis = 1 .让我们选择一个(根据您的抽奖):
from tensorflow.keras import Input
from tensorflow.keras import layers

def define_model():
    input1 = Input(shape=(4,)) 
    input2 = Input(shape=(3,))

    layer1_1 = layers.Dense(4, activation=tf.nn.leaky_relu)(input1)
    layer2_1 = layers.Dense(4, activation=tf.nn.leaky_relu)(layer1_1)

    layer1_2 = layers.Dense(4, activation=tf.nn.leaky_relu)(input2)
    layer2_2 = layers.Dense(3, activation=tf.nn.leaky_relu)(layer1_2)

    concat_layer = layers.concatenate([layer2_1, layer2_2], axis = 1) 
    layer3 = layers.Dense(6, activation=tf.nn.leaky_relu)(concat_layer)

    output = layers.Dense(4)(layer3) 
    model = tf.keras.Model(inputs = [input1,input2],outputs = output)
    model.compile(loss = 'mean_squared_error', optimizer = 'rmsprop')
    return model

m = define_model()
更多详细信息,请参阅选择 axis 的输出形状参数:
x1 = tf.keras.layers.Dense(8)(np.arange(10).reshape(5, 2))
x2 = tf.keras.layers.Dense(8)(np.arange(10, 20).reshape(5, 2))
print(x1.shape, x2.shape)
# (5, 8) (5, 8)

# using axis = 0
concatted = tf.keras.layers.Concatenate(axis=0)([x1, x2])
concatted.shape
# TensorShape([10, 8])

# using axis = 1
concatted = tf.keras.layers.Concatenate(axis=1)([x1, x2])
concatted.shape
# TensorShape([5, 16])

测试模型
适合您的输入:
A1_i = np.array([[1.,0, 0,1]])
A1_j = np.array([[0, 1., 0]])
B1   = np.array([4])

print(type(A1_i), type(A1_j), type(B1))
print(A1_i.shape, A1_j.shape, B1.shape)
m.fit([A1_i, A1_j], B1, epochs = 2, verbose=2) 
<class 'numpy.ndarray'> <class 'numpy.ndarray'> <class 'numpy.ndarray'>
(1, 4) (1, 3) (1,)
Epoch 1/2
584ms/step - loss: 15.9902
Epoch 2/2
4ms/step - loss: 15.8900
<tensorflow.python.keras.callbacks.History at 0x7fb1b484b890>
其他对您不起作用的部分有几个问题,第一个模型输入应该是 numpy数组,不是 list .第二个问题来自建模部分,它连接起来。但是,正确的方法应该如下:
c = np.array([[5,-4,1,-1],[2,3,-1]], dtype = object)

A2_i = np.random.randint(10, size = [100,4])
A2_j = np.random.randint(10, size = [100,3])
B2   = np.array( [np.sum(A2_i[i][0]*c[0]) + 
                  np.sum(A2_j[i][1]*c[1]) for i in range(100)]) 

print(type(A2_i), type(A2_j), type(B2))
print(A2_i.shape, A2_j.shape, B2.shape)
m.fit([A2_i, A2_j], B2, epochs = 2, verbose=2) 
<class 'numpy.ndarray'> <class 'numpy.ndarray'> <class 'numpy.ndarray'>
(100, 4) (100, 3) (100,)
Epoch 1/2
4ms/step - loss: 683.9537
Epoch 2/2
4ms/step - loss: 681.0673
<tensorflow.python.keras.callbacks.History at 0x7fb1600a8d50>

关于python - 如何构建具有多个输入的 Tensorflow 模型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67171002/

相关文章:

python - tf.dataset.Dataset 上的数据增强

python - 调用 BashOperator 时出错 : Bash command failed

javascript - Bittrex v3 API - 无效签名响应

python - TensorFlow 数据集 API 中的 IDE 断点映射 py_function?

python - 在 Tensorflow-lite 中输入具有动态尺寸的图像

tensorflow - ValueError : Error when checking input: expected dense_1_input to have shape (3, )但得到形状为(2,)的数组

python - 尝试使用 re.sub 和 split 方法拆分字符串

python - python中输入过大如何处理?

python - Tensorflow 的 tf.contrib.training.batch_sequences_with_states API 如何工作?

machine-learning - Keras - 无法获得正确的类别预测