このページは Cloud Translation API によって翻訳されました。
Switch to English

おおよその最近傍とテキスト埋め込みを使用したセマンティック検索

TensorFlow.orgで表示 GoogleColabで実行 GitHubで表示ノートブックをダウンロードTFハブモデルを参照してください

このチュートリアルでは、入力データを指定してTensorFlowハブ(TF-Hub)モジュールから埋め込みを生成し、抽出された埋め込みを使用して近似最近傍(ANN)インデックスを構築する方法を示します。インデックスは、リアルタイムの類似性のマッチングと検索に使用できます。

大量のデータを処理する場合、リポジトリ全体をスキャンして特定のクエリに最も類似したアイテムをリアルタイムで見つけることにより、正確なマッチングを実行することは効率的ではありません。したがって、近似類似性マッチングアルゴリズムを使用します。これにより、正確な最近傍一致を見つける際の精度を少しトレードオフして、速度を大幅に向上させることができます。

このチュートリアルでは、ニュースのヘッドラインのコーパスをリアルタイムでテキスト検索して、クエリに最も類似したヘッドラインを見つける例を示します。キーワード検索とは異なり、これはテキスト埋め込みにエンコードされた意味的類似性をキャプチャします。

このチュートリアルの手順は次のとおりです。

  1. サンプルデータをダウンロードします。
  2. TF-Hubモジュールを使用してデータの埋め込みを生成します
  3. 埋め込み用のANNインデックスを作成します
  4. 類似性マッチングにインデックスを使用する

Apache Beamを使用して、TF-Hubモジュールから埋め込みを生成します。また、SpotifyのANNOYライブラリを使用して、おおよその最近傍インデックスを作成します。

その他のモデル

同じアーキテクチャであるが異なる言語でトレーニングされたモデルについては、このコレクションを参照しください。ここでは、現在tfhub.devでホストされているすべてのテキスト埋め込みを見つけることができます。

セットアップ

必要なライブラリをインストールします。

pip install -q apache_beam
pip install -q sklearn
pip install -q annoy

必要なライブラリをインポートします

import os
import sys
import pickle
from collections import namedtuple
from datetime import datetime
import numpy as np
import apache_beam as beam
from apache_beam.transforms import util
import tensorflow as tf
import tensorflow_hub as hub
import annoy
from sklearn.random_projection import gaussian_random_matrix
print('TF version: {}'.format(tf.__version__))
print('TF-Hub version: {}'.format(hub.__version__))
print('Apache Beam version: {}'.format(beam.__version__))
TF version: 2.3.1
TF-Hub version: 0.9.0
Apache Beam version: 2.24.0

1.サンプルデータをダウンロードする

Million News Headlinesデータセットには、評判の良いAustralian Broadcasting Corp.(ABC)から提供された15年間に発行されたニュースヘッドラインが含まれています。このニュースデータセットには、オーストラリアに焦点を当てた、2003年初頭から2017年末までの世界中の注目すべきイベントの要約された履歴レコードがあります。

形式:タブで区切られた2列のデータ:1)発行日と2)見出しテキスト。見出しのテキストにのみ関心があります。

wget 'https://dataverse.harvard.edu/api/access/datafile/3450625?format=tab&gbrecs=true' -O raw.tsv
wc -l raw.tsv
head raw.tsv
--2020-10-02 12:26:52--  https://dataverse.harvard.edu/api/access/datafile/3450625?format=tab&gbrecs=true
Resolving dataverse.harvard.edu (dataverse.harvard.edu)... 206.191.184.198
Connecting to dataverse.harvard.edu (dataverse.harvard.edu)|206.191.184.198|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 57600231 (55M) [text/tab-separated-values]
Saving to: ‘raw.tsv’

raw.tsv             100%[===================>]  54.93M  27.0MB/s    in 2.0s    

2020-10-02 12:26:55 (27.0 MB/s) - ‘raw.tsv’ saved [57600231/57600231]

1103664 raw.tsv
publish_date    headline_text
20030219    "aba decides against community broadcasting licence"
20030219    "act fire witnesses must be aware of defamation"
20030219    "a g calls for infrastructure protection summit"
20030219    "air nz staff in aust strike for pay rise"
20030219    "air nz strike to affect australian travellers"
20030219    "ambitious olsson wins triple jump"
20030219    "antic delighted with record breaking barca"
20030219    "aussie qualifier stosur wastes four memphis match"
20030219    "aust addresses un security council over iraq"

簡単にするために、見出しのテキストのみを保持し、発行日を削除します

!rm -r corpus
!mkdir corpus

with open('corpus/text.txt', 'w') as out_file:
  with open('raw.tsv', 'r') as in_file:
    for line in in_file:
      headline = line.split('\t')[1].strip().strip('"')
      out_file.write(headline+"\n")
rm: cannot remove 'corpus': No such file or directory

tail corpus/text.txt
severe storms forecast for nye in south east queensland
snake catcher pleads for people not to kill reptiles
south australia prepares for party to welcome new year
strikers cool off the heat with big win in adelaide
stunning images from the sydney to hobart yacht
the ashes smiths warners near miss liven up boxing day test
timelapse: brisbanes new year fireworks
what 2017 meant to the kids of australia
what the papodopoulos meeting may mean for ausus
who is george papadopoulos the former trump campaign aide

2.データの埋め込みを生成します。

このチュートリアルでは、ニューラルネットワーク言語モデル(NNLM)を使用して、ヘッドラインデータの埋め込みを生成します。文の埋め込みは、類似性を意味する文レベルを計算するために簡単に使用できます。 ApacheBeamを使用して埋め込み生成プロセスを実行します。

埋め込み抽出方法

embed_fn = None

def generate_embeddings(text, module_url, random_projection_matrix=None):
  # Beam will run this function in different processes that need to
  # import hub and load embed_fn (if not previously loaded)
  global embed_fn
  if embed_fn is None:
    embed_fn = hub.load(module_url)
  embedding = embed_fn(text).numpy()
  if random_projection_matrix is not None:
    embedding = embedding.dot(random_projection_matrix)
  return text, embedding

tfに変換します。メソッドの例

def to_tf_example(entries):
  examples = []

  text_list, embedding_list = entries
  for i in range(len(text_list)):
    text = text_list[i]
    embedding = embedding_list[i]

    features = {
        'text': tf.train.Feature(
            bytes_list=tf.train.BytesList(value=[text.encode('utf-8')])),
        'embedding': tf.train.Feature(
            float_list=tf.train.FloatList(value=embedding.tolist()))
    }
  
    example = tf.train.Example(
        features=tf.train.Features(
            feature=features)).SerializeToString(deterministic=True)
  
    examples.append(example)
  
  return examples

ビームパイプライン

def run_hub2emb(args):
  '''Runs the embedding generation pipeline'''

  options = beam.options.pipeline_options.PipelineOptions(**args)
  args = namedtuple("options", args.keys())(*args.values())

  with beam.Pipeline(args.runner, options=options) as pipeline:
    (
        pipeline
        | 'Read sentences from files' >> beam.io.ReadFromText(
            file_pattern=args.data_dir)
        | 'Batch elements' >> util.BatchElements(
            min_batch_size=args.batch_size, max_batch_size=args.batch_size)
        | 'Generate embeddings' >> beam.Map(
            generate_embeddings, args.module_url, args.random_projection_matrix)
        | 'Encode to tf example' >> beam.FlatMap(to_tf_example)
        | 'Write to TFRecords files' >> beam.io.WriteToTFRecord(
            file_path_prefix='{}/emb'.format(args.output_dir),
            file_name_suffix='.tfrecords')
    )

ランダムプロジェクションウェイトマトリックスの生成

ランダム投影は、ユークリッド空間にある一連の点の次元を減らすために使用される、シンプルでありながら強力な手法です。理論的背景については、ジョンソン-リンデンシュトラウスの補題を参照してください。

ランダム投影を使用して埋め込みの次元を減らすことは、ANNインデックスの構築とクエリに必要な時間が短縮されることを意味します。

このチュートリアルでは、 Scikit-learnライブラリのGaussian RandomProjectionを使用します。

def generate_random_projection_weights(original_dim, projected_dim):
  random_projection_matrix = None
  random_projection_matrix = gaussian_random_matrix(
      n_components=projected_dim, n_features=original_dim).T
  print("A Gaussian random weight matrix was creates with shape of {}".format(random_projection_matrix.shape))
  print('Storing random projection matrix to disk...')
  with open('random_projection_matrix', 'wb') as handle:
    pickle.dump(random_projection_matrix, 
                handle, protocol=pickle.HIGHEST_PROTOCOL)
        
  return random_projection_matrix

パラメータを設定する

ランダム投影なしで元の埋め込みスペースを使用してインデックスを作成する場合は、 projected_dimパラメーターをNone設定します。これにより、高次元の埋め込みのインデックス作成手順が遅くなることに注意してください。

module_url = 'https://tfhub.dev/google/tf2-preview/nnlm-en-dim128/1' 
projected_dim = 64  

パイプラインを実行する

import tempfile

output_dir = tempfile.mkdtemp()
original_dim = hub.load(module_url)(['']).shape[1]
random_projection_matrix = None

if projected_dim:
  random_projection_matrix = generate_random_projection_weights(
      original_dim, projected_dim)

args = {
    'job_name': 'hub2emb-{}'.format(datetime.utcnow().strftime('%y%m%d-%H%M%S')),
    'runner': 'DirectRunner',
    'batch_size': 1024,
    'data_dir': 'corpus/*.txt',
    'output_dir': output_dir,
    'module_url': module_url,
    'random_projection_matrix': random_projection_matrix,
}

print("Pipeline args are set.")
args
A Gaussian random weight matrix was creates with shape of (128, 64)
Storing random projection matrix to disk...
Pipeline args are set.

/home/kbuilder/.local/lib/python3.6/site-packages/sklearn/utils/deprecation.py:86: FutureWarning: Function gaussian_random_matrix is deprecated; gaussian_random_matrix is deprecated in 0.22 and will be removed in version 0.24.
  warnings.warn(msg, category=FutureWarning)

{'job_name': 'hub2emb-201002-122712',
 'runner': 'DirectRunner',
 'batch_size': 1024,
 'data_dir': 'corpus/*.txt',
 'output_dir': '/tmp/tmp5jrvr165',
 'module_url': 'https://tfhub.dev/google/tf2-preview/nnlm-en-dim128/1',
 'random_projection_matrix': array([[-0.23496406, -0.05090818, -0.0451953 , ...,  0.12301853,
         -0.17872473,  0.16310186],
        [ 0.06431372,  0.18794477,  0.06454892, ...,  0.03056835,
          0.04524009,  0.01850725],
        [-0.12029645,  0.22026643,  0.0286414 , ...,  0.09062128,
         -0.12451738, -0.08198714],
        ...,
        [-0.07137172, -0.0165681 , -0.09059493, ...,  0.08598557,
         -0.2998788 , -0.07498167],
        [-0.08950686,  0.03670846,  0.03048793, ..., -0.1782675 ,
          0.11021995, -0.19888922],
        [-0.01926155, -0.00277134,  0.0535409 , ..., -0.00921094,
          0.23301195,  0.04889218]])}
print("Running pipeline...")
%time run_hub2emb(args)
print("Pipeline is done.")
WARNING:apache_beam.runners.interactive.interactive_environment:Dependencies required for Interactive Beam PCollection visualization are not available, please use: `pip install apache-beam[interactive]` to install necessary dependencies to enable all data visualization features.

Running pipeline...

Warning:tensorflow:5 out of the last 5 calls to <function recreate_function.<locals>.restored_function_body at 0x7f70cc0bee18> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has experimental_relax_shapes=True option that relaxes argument shapes that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/tutorials/customization/performance#python_or_tensor_args and https://www.tensorflow.org/api_docs/python/tf/function for  more details.

Warning:tensorflow:5 out of the last 5 calls to <function recreate_function.<locals>.restored_function_body at 0x7f70cc0bee18> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has experimental_relax_shapes=True option that relaxes argument shapes that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/tutorials/customization/performance#python_or_tensor_args and https://www.tensorflow.org/api_docs/python/tf/function for  more details.

Warning:tensorflow:6 out of the last 6 calls to <function recreate_function.<locals>.restored_function_body at 0x7f70cc0be488> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has experimental_relax_shapes=True option that relaxes argument shapes that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/tutorials/customization/performance#python_or_tensor_args and https://www.tensorflow.org/api_docs/python/tf/function for  more details.

Warning:tensorflow:6 out of the last 6 calls to <function recreate_function.<locals>.restored_function_body at 0x7f70cc0be488> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has experimental_relax_shapes=True option that relaxes argument shapes that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/tutorials/customization/performance#python_or_tensor_args and https://www.tensorflow.org/api_docs/python/tf/function for  more details.

Warning:tensorflow:7 out of the last 7 calls to <function recreate_function.<locals>.restored_function_body at 0x7f70cc1099d8> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has experimental_relax_shapes=True option that relaxes argument shapes that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/tutorials/customization/performance#python_or_tensor_args and https://www.tensorflow.org/api_docs/python/tf/function for  more details.

Warning:tensorflow:7 out of the last 7 calls to <function recreate_function.<locals>.restored_function_body at 0x7f70cc1099d8> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has experimental_relax_shapes=True option that relaxes argument shapes that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/tutorials/customization/performance#python_or_tensor_args and https://www.tensorflow.org/api_docs/python/tf/function for  more details.
WARNING:apache_beam.io.tfrecordio:Couldn't find python-snappy so the implementation of _TFRecordUtil._masked_crc32c is not as fast as it could be.

CPU times: user 9min 13s, sys: 9min 51s, total: 19min 4s
Wall time: 2min 29s
Pipeline is done.

ls {output_dir}
emb-00000-of-00001.tfrecords

生成された埋め込みのいくつかを読んでください...

embed_file = os.path.join(output_dir, 'emb-00000-of-00001.tfrecords')
sample = 5

# Create a description of the features.
feature_description = {
    'text': tf.io.FixedLenFeature([], tf.string),
    'embedding': tf.io.FixedLenFeature([projected_dim], tf.float32)
}

def _parse_example(example):
  # Parse the input `tf.Example` proto using the dictionary above.
  return tf.io.parse_single_example(example, feature_description)

dataset = tf.data.TFRecordDataset(embed_file)
for record in dataset.take(sample).map(_parse_example):
  print("{}: {}".format(record['text'].numpy().decode('utf-8'), record['embedding'].numpy()[:10]))

headline_text: [ 0.1652589  -0.06406656  0.06406891 -0.14836317 -0.04433651 -0.01402062
 -0.04169092  0.03712815 -0.05279795 -0.06765237]
aba decides against community broadcasting licence: [-0.20160258  0.00256393  0.01182815  0.1255717  -0.08481464  0.13993788
 -0.00667449 -0.14515129  0.26369372 -0.03051737]
act fire witnesses must be aware of defamation: [-0.17959927 -0.20737727  0.15803404  0.250352    0.05415684 -0.0414118
 -0.08157488  0.05439697  0.31761077  0.00750144]
a g calls for infrastructure protection summit: [-0.306443    0.03760489  0.05141833  0.10717567 -0.09257486  0.05315739
  0.08237746  0.04033889  0.04984799 -0.04539666]
air nz staff in aust strike for pay rise: [-0.17491291 -0.04590164  0.04062048  0.1097874   0.06837258  0.23613107
 -0.17138828  0.2218      0.10151701 -0.12856439]

3.埋め込み用のANNインデックスを作成します

ANNOY (近似最近傍点Oh Yeah)は、特定のクエリポイントに近い空間内のポイントを検索するためのPythonバインディングを備えたC ++ライブラリです。また、メモリにmmapされる大きな読み取り専用のファイルベースのデータ構造を作成します。これは、 Spotifyによって作成され、音楽の推奨のために使用されます。

def build_index(embedding_files_pattern, index_filename, vector_length, 
    metric='angular', num_trees=100):
  '''Builds an ANNOY index'''

  annoy_index = annoy.AnnoyIndex(vector_length, metric=metric)
  # Mapping between the item and its identifier in the index
  mapping = {}

  embed_files = tf.io.gfile.glob(embedding_files_pattern)
  num_files = len(embed_files)
  print('Found {} embedding file(s).'.format(num_files))

  item_counter = 0
  for i, embed_file in enumerate(embed_files):
    print('Loading embeddings in file {} of {}...'.format(i+1, num_files))
    dataset = tf.data.TFRecordDataset(embed_file)
    for record in dataset.map(_parse_example):
      text = record['text'].numpy().decode("utf-8")
      embedding = record['embedding'].numpy()
      mapping[item_counter] = text
      annoy_index.add_item(item_counter, embedding)
      item_counter += 1
      if item_counter % 100000 == 0:
        print('{} items loaded to the index'.format(item_counter))

  print('A total of {} items added to the index'.format(item_counter))

  print('Building the index with {} trees...'.format(num_trees))
  annoy_index.build(n_trees=num_trees)
  print('Index is successfully built.')
  
  print('Saving index to disk...')
  annoy_index.save(index_filename)
  print('Index is saved to disk.')
  print("Index file size: {} GB".format(
    round(os.path.getsize(index_filename) / float(1024 ** 3), 2)))
  annoy_index.unload()

  print('Saving mapping to disk...')
  with open(index_filename + '.mapping', 'wb') as handle:
    pickle.dump(mapping, handle, protocol=pickle.HIGHEST_PROTOCOL)
  print('Mapping is saved to disk.')
  print("Mapping file size: {} MB".format(
    round(os.path.getsize(index_filename + '.mapping') / float(1024 ** 2), 2)))
embedding_files = "{}/emb-*.tfrecords".format(output_dir)
embedding_dimension = projected_dim
index_filename = "index"

!rm {index_filename}
!rm {index_filename}.mapping

%time build_index(embedding_files, index_filename, embedding_dimension)
rm: cannot remove 'index': No such file or directory
rm: cannot remove 'index.mapping': No such file or directory
Found 1 embedding file(s).
Loading embeddings in file 1 of 1...
100000 items loaded to the index
200000 items loaded to the index
300000 items loaded to the index
400000 items loaded to the index
500000 items loaded to the index
600000 items loaded to the index
700000 items loaded to the index
800000 items loaded to the index
900000 items loaded to the index
1000000 items loaded to the index
1100000 items loaded to the index
A total of 1103664 items added to the index
Building the index with 100 trees...
Index is successfully built.
Saving index to disk...
Index is saved to disk.
Index file size: 1.6 GB
Saving mapping to disk...
Mapping is saved to disk.
Mapping file size: 50.61 MB
CPU times: user 9min 58s, sys: 55.4 s, total: 10min 54s
Wall time: 5min 13s

ls
corpus         random_projection_matrix
index          raw.tsv
index.mapping  tf2_semantic_approximate_nearest_neighbors.ipynb

4.類似性マッチングにインデックスを使用する

これで、ANNインデックスを使用して、入力クエリに意味的に近いニュースの見出しを見つけることができます。

インデックスとマッピングファイルをロードします

index = annoy.AnnoyIndex(embedding_dimension)
index.load(index_filename, prefault=True)
print('Annoy index is loaded.')
with open(index_filename + '.mapping', 'rb') as handle:
  mapping = pickle.load(handle)
print('Mapping file is loaded.')

Annoy index is loaded.

/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/ipykernel_launcher.py:1: FutureWarning: The default argument for metric will be removed in future version of Annoy. Please pass metric='angular' explicitly.
  """Entry point for launching an IPython kernel.

Mapping file is loaded.

類似性マッチング方法

def find_similar_items(embedding, num_matches=5):
  '''Finds similar items to a given embedding in the ANN index'''
  ids = index.get_nns_by_vector(
  embedding, num_matches, search_k=-1, include_distances=False)
  items = [mapping[i] for i in ids]
  return items

特定のクエリから埋め込みを抽出します

# Load the TF-Hub module
print("Loading the TF-Hub module...")
%time embed_fn = hub.load(module_url)
print("TF-Hub module is loaded.")

random_projection_matrix = None
if os.path.exists('random_projection_matrix'):
  print("Loading random projection matrix...")
  with open('random_projection_matrix', 'rb') as handle:
    random_projection_matrix = pickle.load(handle)
  print('random projection matrix is loaded.')

def extract_embeddings(query):
  '''Generates the embedding for the query'''
  query_embedding =  embed_fn([query])[0].numpy()
  if random_projection_matrix is not None:
    query_embedding = query_embedding.dot(random_projection_matrix)
  return query_embedding

Loading the TF-Hub module...
CPU times: user 799 ms, sys: 643 ms, total: 1.44 s
Wall time: 1.43 s
TF-Hub module is loaded.
Loading random projection matrix...
random projection matrix is loaded.

extract_embeddings("Hello Machine Learning!")[:10]
WARNING:tensorflow:5 out of the last 1082 calls to <function recreate_function.<locals>.restored_function_body at 0x7f70cc04f7b8> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has experimental_relax_shapes=True option that relaxes argument shapes that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/tutorials/customization/performance#python_or_tensor_args and https://www.tensorflow.org/api_docs/python/tf/function for  more details.

Warning:tensorflow:5 out of the last 1082 calls to <function recreate_function.<locals>.restored_function_body at 0x7f70cc04f7b8> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has experimental_relax_shapes=True option that relaxes argument shapes that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/tutorials/customization/performance#python_or_tensor_args and https://www.tensorflow.org/api_docs/python/tf/function for  more details.

array([ 0.1089144 ,  0.05490944,  0.05110935, -0.15313255, -0.16363258,
        0.05206677, -0.1233749 , -0.26143147, -0.08646249, -0.22889622])

クエリを入力して、最も類似したアイテムを見つけます


query = "confronting global challenges" 

print("Generating embedding for the query...")
%time query_embedding = extract_embeddings(query)

print("")
print("Finding relevant items in the index...")
%time items = find_similar_items(query_embedding, 10)

print("")
print("Results:")
print("=========")
for item in items:
  print(item)
Generating embedding for the query...
CPU times: user 2.4 ms, sys: 3.15 ms, total: 5.55 ms
Wall time: 3.08 ms

Finding relevant items in the index...
CPU times: user 540 µs, sys: 305 µs, total: 845 µs
Wall time: 571 µs

Results:
=========
confronting global challenges
conference examines challenges facing major cities
beef industry facing challenges
readfearn a two faced approach to cutting global emissions
industry challenges
european organic foods facing credibility crisis
regional tourism faces challenges
climate delegates ponder developing world hurdles
global food crisis sparks us survivalist resurgence
study highlights global food wastage

詳細を知りたいですか?

TensorFlowの詳細については、 tensorflow.orgをご覧ください。また、TF- HubAPIのドキュメントをtensorflow.org/hubご覧ください。で利用可能TensorFlowハブモジュールを探すtfhub.dev複数のテキスト埋め込みモジュールと画像特徴ベクトルのモジュールを含みます。

また、Googleのペースの速い、実用的な機械学習の紹介である機械学習クラッシュコースもご覧ください。