В продолжение [этого вопроса] несколько замечаний о том, чего мы хотим достичь:
- У нас есть два входа
X
и Y
с различными размерами выборки n
и m
и логический вектор z
размера nm
. Каждый элемент z
обозначает, являются ли два элемента в X
и Y
каким-либо совпадением
- Мы хотим использовать слои встраивания (возможно, одинаковые, возможно, разные) в
X
и Y
, прежде чем попарно объединить выходные данные этих слоев встраивания для получения ввода в выходной слой.
Вот один пример того, как может выглядеть простая сеть:
Связанный ответ и несколько других ресурсов помогли добраться до этого примера, который строит модель, но выдает эту ошибку во время подбора: ValueError: All input arrays (x) should have the same number of samples. Got array shapes: [(10, 2), (12, 2)]
.
Последние версии Keras позволяют пропускать проверку размеров , эту проверку можно пропустить в Tensorflow? Я также был бы рад использовать Keras, но я не уверен, как выполнить изменение формы и сцепление в Keras в середине модели.
Или это просто невозможно? Является ли единственный вариант расширения и попарной конкатенации перед для ввода?
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np
k = 2
N = 10
M = 12
x = np.random.randint(2, size = 2 * N).reshape((-1,2))
y = np.random.randint(2, size = 2 * M).reshape((-1,2))
x_rep = np.tile(x, (1, M)).reshape((-1,2))
y_rep = np.tile(y, (N, 1))
xy = np.concatenate((x_rep, y_rep), axis=1)
xy = xy.astype(bool)
z = (xy[:,0] == xy[:,2]) * (xy[:,1] ^ xy[:,3])
print(z[:20])
xy = xy.astype(int)
z = z.astype(int)
first = keras.Input(shape=(k,))
second = keras.Input(shape=(k,))
shared_dense = layers.Dense(k)
first_dense = shared_dense(first)
second_dense = shared_dense(second)
first_tiled = layers.Lambda(tf.tile, arguments={'multiples':[1, M]}, name='first_expanded' )(first_dense) #keras.backend.tile(first_dense, [1, M])
second_tiled = layers.Lambda(tf.tile, arguments={'multiples':[N,1]}, name='second_expanded')(second_dense) #keras.backend.tile(first_dense, [1, M])
first_reshaped = layers.Reshape((k,))(first_tiled)
concatenated = layers.Concatenate()([first_reshaped, second_tiled])
out = layers.Dense(1)(concatenated)
model = keras.Model([first, second], out)
keras.utils.plot_model(model, 'tf_nw.png', show_shapes=True)
model.compile('Adam', loss='binary_crossentropy', metrics=['accuracy'])
model.fit([x, y], z)