Tensorflow model.fit () не работает со строками в качестве меток - PullRequest
0 голосов
/ 03 мая 2019

См. Этот пример кода:

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 содержит строки, которые можно сравнивать (предположим, некоторый эксперимент по обучению метрике).Сеть выводит вектор признаков для каждого входа.Входные данные с одинаковыми метками должны быть одинаковыми в пространстве признаков.

Однако этот код выдает ошибку:

tenorflow.python.framework.errors_impl.UnimplementedError: Преобразование строки в число с плавающей точкой неподдерживается [Op: Cast] имя: Cast /

Кажется, что он не может обрабатывать строки как метки и пытается привести их к чему-то в плавающее число.

Но когда яиспользуйте вместо градиента Лента градиента. Нет проблем

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 ()?

1 Ответ

0 голосов
/ 03 мая 2019

Небольшой код, необходимый для преобразования (предлагается @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}

Как видите, вам не нужно знать количество меток.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...