我目前正在研究一个用例,我想使用TripletSemiHardLoss来获得相似度的排名。基本上,我有一个训练文件,其中有分类变量,每组变量都有一个对应的类别(标签),它应该与之相关联。为了实现这一点,我实现了以下代码:
导入数据,进行one-hot编码,在锚、正、负集合中分离,建立模型并训练:
def learn_ranking_loss(settings):
training_data, label_columns, label_dict, features_dict, losses, loss_weights = data_handling.training_data_labeling(
['Diagnosis'], settings["CONFIGURATION_FILE_PATH"], binary_features=settings["BINARY_FEATURES"],
ignore=['Runtime', 'Consistency check'])
train_x, test_x, train_labels, test_labels, input_neuron_list, output_neuron_list = data_preprocessing.data_preprocessing_learning(
training_data, label_columns)
training_data = tf.data.Dataset.zip(
(tf.data.Dataset.from_tensor_slices(train_x[:(round(len(train_x) / 3))]),
tf.data.Dataset.from_tensor_slices(
train_x[(round(len(train_x) / 3)):(round(len(train_x) / 3) * 2)]),
tf.data.Dataset.from_tensor_slices(
train_x[(round(len(train_x) / 3) * 2):])))
train_labels = tf.data.Dataset.zip(
(tf.data.Dataset.from_tensor_slices(train_labels[0][:(round(len(train_labels[0]) / 3))]),
tf.data.Dataset.from_tensor_slices(
train_labels[0][(round(len(train_labels[0]) / 3)):(round(len(train_labels[0]) / 3) * 2)]),
tf.data.Dataset.from_tensor_slices(
train_labels[0][(round(len(train_labels[0]) / 3) * 2):])))
dataset = tf.data.Dataset.zip((training_data, train_labels)).batch(32)
emb_mod, model = get_siamese_model([287, ])
# Compile the model
model.compile(
optimizer=tf.keras.optimizers.Adam(0.001),
loss=tfa.losses.TripletSemiHardLoss())
# Train the network
history = model.fit(
dataset,
epochs=1)
return
基于输入的独热编码创建的Tensor是[287,],标签的形状是[52,]。
模型的创建如下:
def create_model(input_shape):
inp = tf.keras.layers.Input(shape=input_shape)
x = tf.keras.layers.Dense(287, activation='relu')(inp)
x = tf.keras.layers.Dense(287, activation='relu')(x)
x = tf.keras.layers.Dense(52, activation=None)(x)
# x = tf.keras.layers.Lambda(lambda y: tf.math.l2_normalize(x, axis=1))(x)
model = tf.keras.Model(inp, x)
return model
def get_siamese_model(input_shape):
# Define the tensors for the triplet of input images
anchor_input = tf.keras.layers.Input(input_shape, name="anchor_input")
positive_input = tf.keras.layers.Input(input_shape, name="positive_input")
negative_input = tf.keras.layers.Input(input_shape, name="negative_input")
# Convolutional Neural Network (same from earlier)
embedding_model = create_model(input_shape)
# Generate the embedding outputs
encoded_anchor = embedding_model(anchor_input)
encoded_positive = embedding_model(positive_input)
encoded_negative = embedding_model(negative_input)
inputs = [anchor_input, positive_input, negative_input]
outputs = [encoded_anchor, encoded_positive, encoded_negative]
# x = tf.keras.layers.Lambda(lambda x: tf.math.l2_normalize(outputs, axis=1))(outputs)
# Connect the inputs with the outputs
siamese_triplet = tf.keras.Model(inputs=inputs, outputs=outputs)
# return the model
return embedding_model, siamese_triplet
运行代码时,返回以下错误消息:
Traceback (most recent call last):
File "C:\Users\mathi\Documents\Studium\Promotion\ConLearn\ranking_loss.py", line 94, in <module>
learn_ranking_loss(settings_dict)
File "C:\Users\mathi\Documents\Studium\Promotion\ConLearn\ranking_loss.py", line 74, in learn_ranking_loss
history = model.fit(
File "C:\Users\mathi\Documents\Studium\Promotion\ConLearn\Python interpreter\lib\site-packages\keras\engine\training.py", line 1189, in fit
tmp_logs = self.train_function(iterator)
File "C:\Users\mathi\Documents\Studium\Promotion\ConLearn\Python interpreter\lib\site-packages\tensorflow\python\eager\def_function.py", line 885, in __call__
result = self._call(*args, **kwds)
File "C:\Users\mathi\Documents\Studium\Promotion\ConLearn\Python interpreter\lib\site-packages\tensorflow\python\eager\def_function.py", line 950, in _call
return self._stateless_fn(*args, **kwds)
File "C:\Users\mathi\Documents\Studium\Promotion\ConLearn\Python interpreter\lib\site-packages\tensorflow\python\eager\function.py", line 3039, in __call__
return graph_function._call_flat(
File "C:\Users\mathi\Documents\Studium\Promotion\ConLearn\Python interpreter\lib\site-packages\tensorflow\python\eager\function.py", line 1963, in _call_flat
return self._build_call_outputs(self._inference_function.call(
File "C:\Users\mathi\Documents\Studium\Promotion\ConLearn\Python interpreter\lib\site-packages\tensorflow\python\eager\function.py", line 591, in call
outputs = execute.execute(
File "C:\Users\mathi\Documents\Studium\Promotion\ConLearn\Python interpreter\lib\site-packages\tensorflow\python\eager\execute.py", line 59, in quick_execute
tensors = pywrap_tfe.TFE_Py_Execute(ctx._handle, device_name, op_name,
tensorflow.python.framework.errors_impl.InvalidArgumentError: Input to reshape is a tensor with 1664 values, but the requested shape has 32
[[{{node TripletSemiHardLoss/PartitionedCall/Reshape}}]] [Op:__inference_train_function_1666]
Function call stack:
train_function
Process finished with exit code 1
在做了一些研究后,我确信这个问题是由我的层的形状引起的,但我无法找出需要改变的地方。我还观察到1664除以32正好是52,所以输出形状。此外,如果我改变我的层的形状,无论发生什么同样的问题。
任何帮助都将非常感激。非常感谢!
最好的问候,马蒂亚斯
1条答案
按热度按时间xe55xuns1#
我已经发现并解决了这个问题。
问题是tensorflow TripletSemiHardLoss期望标签作为分类输入(每个训练项的一系列简单的分类值)。错误是对标签进行one-hot编码,就像你通常对交叉熵损失函数所做的那样。
请在下面找到固定的代码。还请注意,我在训练期间从离线选择锚,positive和negative改为在线选择相同的锚点,因为它是由tensorflow实现TripletSemiHardLoss支持的:
希望这对将来遇到同样问题的人有所帮助。
最好的问候,马蒂亚斯