Как кластеризовать и классифицировать слова-векторы - PullRequest
0 голосов
/ 09 июля 2019

В настоящее время я тренирую модель скип-граммы, чтобы изучать различные объекты по их описанию. После того, как я получил вложения слова из этой модели, я хочу сгруппировать их в похожие группы и пометить их.

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

это мой текущий результат:

https://imgur.com/6xBQ6ng

Проблема в том, что новые категории обозначены как 60, 61 и 62. Модель интерпретирует их как сходные и помещает их в одно и то же пространство.

Эти категории не должны быть одинаковыми, и они не находятся рядом с векторами, которыми они должны быть. Я делаю это неправильно? Как я могу повторно использовать мою модель для кластеризации и классификации этих объектов?

pretrained_vectors_cat =
array([[-0.00703605, -0.00456019, -0.07583138, ..., -0.00803135,
        -0.03794867, -0.03410311],
       [-0.06226502, -0.03059928, -0.07528683, ...,  0.11714505,
         0.01752528, -0.00584977],
       [-0.07654897, -0.04235281, -0.02850686, ...,  0.06900358,
         0.00327334, -0.10425693],
       ...,
       [-0.50258852, -0.57102433, -0.28687169, ..., -0.26322143,
        -0.0910767 ,  0.13004072],
       [-0.53029969,  0.71982554, -0.80099767, ...,  0.75670917,
        -0.61081131,  0.59293241],
       [ 0.22630654, -0.69713363, -0.1661163 , ..., -0.23165715,
         0.18017072, -0.90354915]])

with graph_pretrained.as_default():

    with tf.name_scope('inputs'):
        train_inputs = tf.placeholder(tf.int32, shape=[batch_size], name="train_inputs")
        train_labels = tf.placeholder(tf.int32, shape=[batch_size, 1], name="train_labels")

    with tf.device(device_name):
        with tf.name_scope('embeddings_pretrained'):
            embeddings = tf.get_variable("embeddings", initializer=pretrained_vectors_cat)
            embed = tf.nn.embedding_lookup(embeddings, train_inputs)

            embeddings = tf.cast(embeddings, tf.float32)
            embed = tf.cast(embed, tf.float32)

        with tf.name_scope('weights'):
            nce_weights = tf.Variable(tf.truncated_normal(shape=[vocabulary_size_cat, embedding_size],
                                                          stddev=1.0 / math.sqrt(embedding_size)), 
                                      name="weight_matrix")

        with tf.name_scope('biases'):
            nce_biases = tf.Variable(tf.zeros([vocabulary_size_cat]), name="bias_matrix")

    with tf.name_scope('loss'): 
        loss = tf.reduce_mean(tf.nn.nce_loss(
                weights=nce_weights,
                biases=nce_biases,
                inputs=embed,
                labels=train_labels,
                num_sampled=num_sampled,
                num_classes=vocabulary_size_cat))

    loss_summary = tf.summary.scalar('loss', loss)

    with tf.name_scope('optimizer'):
        optimizer = tf.train.GradientDescentOptimizer(learningrate).minimize(loss)

    norm = tf.sqrt(tf.reduce_sum(tf.square(embeddings), 1, keepdims=True))
    normalized_embeddings = embeddings / norm

    merged = tf.summary.merge_all()

    init = tf.global_variables_initializer()

    saver = tf.train.Saver()

with tf.Session(graph=graph_pretrained, config=session_config) as session:
    # Open a writer to write summaries.
    writer = tf.summary.FileWriter(log_dir + "/", session.graph)
    writer_loss = tf.summary.FileWriter(log_dir + "/loss {}".format(model_name))
    init.run()
    average_loss = 0

    for step in xrange(num_steps):      
        progbar.update(step)

        batch_inputs, batch_labels = generateCenterContextBatch(batch_size, window_size, new_project_mark)

        feed_dict = {train_inputs: batch_inputs, train_labels: batch_labels}#, embedding_placeholder: pretrained_vectors}

        run_metadata = tf.RunMetadata()
        _, summary, loss_val = session.run([optimizer, merged, loss],
                                            feed_dict=feed_dict,
                                            run_metadata=run_metadata)

        average_loss += loss_val

        # Add returned summaries to writer in each step.
        writer_loss.add_summary(summary, step)

        # Add metadata to visualize the graph for the last run.
        if step == (num_steps - 1):
            writer_loss.add_run_metadata(run_metadata, 'step%d' % step)

    final_embeddings_category = normalized_embeddings.eval()

    # Save the model for checkpoints.
    saver.save(session, os.path.join(logdir_model", 'model.ckpt'))

writer_loss.close()

1 Ответ

1 голос
/ 15 июля 2019

Проблема решена.

TensorBoard Projector неправильно вычисляет косинусные расстояния. Получение расстояний с помощью sklearn дает правильные кластеры.

TensorBoard может уменьшить исходную размерность с 300 до 200 и вычислить расстояния от уменьшенных размеров. Поэтому ярлык «ближайшие точки в исходном пространстве» вводит в заблуждение.

--- проверка: установленные_пакеты
ИНФОРМАЦИЯ: установлено: тензорная доска == 1.13.1
ИНФОРМАЦИЯ: установлено: tenorflow-gpu == 1.13.1
ИНФОРМАЦИЯ: установлено: tenorflow == 1.14.0

...