У меня проблемы с измерениями при попытке создать сиамскую сеть
. Этот код я использовал в качестве своей пользовательской функции потерь и для своей модели
input_shape = (1, 18)
embedding_size = 25
class CosineLossLayer(Layer):
def __init__(self, **kwargs):
super(CosineLossLayer, self).__init__(**kwargs)
def cosine_loss(self, inputs):
x, y = inputs
x = K.l2_normalize(x, axis=-1)
y = K.l2_normalize(y, axis=-1)
return -K.mean(x * y, axis=-1, keepdims=True)
def call(self, inputs):
loss = self.cosine_loss(inputs)
self.add_loss(loss)
return loss
def build_network(input_shape, embeddingsize):
model = models.Sequential()
print(input_shape)
model.add(Dense(64, activation="relu", input_shape=input_shape))
model.add(Dense(64, activation="relu"))
model.add(Flatten())
model.add(Dense(embeddingsize, activation=None))
return model
def build_model(input_shape, network):
'''
Define the Keras Model for training
Input :
input_shape : shape of input images
network : Neural network to train outputing embeddings
'''
print(input_shape)
# Define the tensors for the three input images
train_input = Input(input_shape, name="train_input")
anchor_input = Input(input_shape, name="anchor_input")
# Generate the encodings (feature vectors) for the three images
encoded_t = network(train_input)
encoded_a = network(anchor_input)
# cosine distance
loss_layer = CosineLossLayer(name='Cosine_loss_layer')([encoded_a,encoded_t])
# Connect the inputs with the outputs
network_train = models.Model(inputs=[anchor_input,train_input],outputs=loss_layer)
# return the model
return network_train
Когда я компилирую и суммирую это так:
network = build_network(input_shape,embeddingsize=25)
network_train = build_model(input_shape,network)
optimizer = Adam(lr = 0.00006)
network_train.compile(loss=None,optimizer=optimizer)
network_train.summary()
Я получаю
(18, 1)
(18, 1)
WARNING:tensorflow:Output Cosine_loss_layer missing from loss dictionary. We assume this was done on purpose. The fit and evaluate APIs will not be expecting any data to be passed to Cosine_loss_layer.
Model: "model_4"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
anchor_input (InputLayer) [(None, 18, 1)] 0
__________________________________________________________________________________________________
train_input (InputLayer) [(None, 18, 1)] 0
__________________________________________________________________________________________________
sequential_4 (Sequential) (None, 25) 33113 train_input[0][0]
anchor_input[0][0]
__________________________________________________________________________________________________
Cosine_loss_layer (CosineLossLa (None, 1) 0 sequential_4[2][0]
sequential_4[1][0]
==================================================================================================
Total params: 33,113
Trainable params: 33,113
Non-trainable params: 0
__________________________________________________________________________________________________
Это именно то, что я хочу.
Но потом, когда я пытаюсь подогнать свою модель, используя мои данные, я не может из-за ошибок измерения:
network_train.fit(x =[train_1, train_2], y=[X_tr1, X_tr2], epochs = 50, batch_size = 1)
.
.
.
opt/conda/lib/python3.6/site-packages/tensorflow_core/python/keras/engine/training_utils.py in standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix)
571 ': expected ' + names[i] + ' to have ' +
572 str(len(shape)) + ' dimensions, but got array '
--> 573 'with shape ' + str(data_shape))
574 if not check_batch_axis:
575 data_shape = data_shape[1:]
ValueError: Error when checking input: expected anchor_input to have 3 dimensions, but got array with shape (91965, 18)
При поиске в Интернете я не понимаю, что здесь происходит и почему моя сеть ожидает 3 измерения, может кто-нибудь объяснить это, пожалуйста?