请参见以下代码示例:
import tensorflow as tf
import numpy as np
images = np.random.rand(5, 108, 56, 3)
y_pred = np.random.rand(5, 4)
y_true = np.array(['aa', 'bb', 'cc', 'dd', 'ee'])
dataset = tf.data.Dataset.from_tensor_slices((images, y_true))
dataset = dataset.batch(5)
dataset = dataset.repeat()
model = tf.keras.Sequential([
tf.keras.layers.Conv2D(16, [3,3], activation='relu'),
tf.keras.layers.GlobalAveragePooling2D(),
tf.keras.layers.Dense(4)
])
def triplet_loss(y_true, y_pred):
all_diffs = tf.expand_dims(y_pred, axis=1) - tf.expand_dims(y_pred, axis=0)
distances = tf.sqrt(tf.reduce_sum(tf.square(all_diffs), axis=-1) + 1e-12)
furthest_positive = tf.reduce_max(distances, axis=1)
closest_negative = tf.map_fn(lambda x: tf.reduce_min(x),
distances)
diff = furthest_positive - closest_negative
diff = tf.nn.softplus(diff)
return diff
optimizer = tf.optimizers.Adam(learning_rate=0.001)
model.compile(loss=triplet_loss,
optimizer=optimizer)
model.fit(dataset, steps_per_epoch=5, epochs=10, verbose=1)
此处y_true包含可以比较的字符串(假设一些度量学习实验)。网络为每个输入输出一个特征向量。具有相同标签的输入在特征空间中应该相似。
但是此代码给出错误:
tensorflow.python.framework.errors_impl.UnimplementedError:强制转换 不支持浮点字符串[Op:Cast]名称:Cast /
似乎无法将字符串作为标签处理,并试图将它们转换为某个位置的浮点数。
但是当我使用gradientTape而不是model.fit时就没有问题
for images, labels in dataset:
with tf.GradientTape() as tape:
y_pred = model(images, training=True)
loss_value = triplet_loss(labels, y_pred)
grads = tape.gradient(loss_value, model.trainable_variables)
optimizer.apply_gradients(zip(grads, model.trainable_variables))
print('iteration done')
这很好。这是model.fit()中的错误吗?是否有一些解决方法仍然可以使用model.fit()?
答案 0 :(得分:0)
转换所需的小代码(建议@danzfang)
import numpy as np
raw_y_true = ['a', 'b', 'c', 'd', 'b', 'c']
mapping_to_numbers = {}
y_true = np.zeros((len(raw_y_true)))
for i, raw_label in enumerate(raw_y_true):
if raw_label not in mapping_to_numbers:
mapping_to_numbers[raw_label] = len(mapping_to_numbers)
y_true[i] = mapping_to_numbers[raw_label]
print(y_true)
# [0. 1. 2. 3. 1. 2.]
print(mapping_to_numbers)
# {'d': 3, 'a': 0, 'c': 2, 'b': 1}
如您所见,您不需要知道标签的数量。