代码之家  ›  专栏  ›  技术社区  ›  Mehran

如何在Python中使用TensorBoard和Keras来可视化嵌入

  •  14
  • Mehran  · 技术社区  · 7 年前

    我正在读这本书 深入学习Python 它使用Keras。在第7章中,通过一个例子展示了如何使用TensorBoard来监控训练阶段的进度:

    import keras
    from keras import layers
    from keras.datasets import imdb
    from keras.preprocessing import sequence
    
    max_features = 2000
    max_len = 500
    (x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_features)
    x_train = sequence.pad_sequences(x_train, maxlen=max_len)
    x_test = sequence.pad_sequences(x_test, maxlen=max_len)
    
    model = keras.models.Sequential()
    model.add(layers.Embedding(max_features, 128, input_length=max_len, name='embed'))
    model.add(layers.Conv1D(32, 7, activation='relu'))
    model.add(layers.MaxPooling1D(5))
    model.add(layers.Conv1D(32, 7, activation='relu'))
    model.add(layers.GlobalMaxPooling1D())
    model.add(layers.Dense(1))
    model.summary()
    
    model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['acc'])
    
    callbacks = [
        keras.callbacks.TensorBoard(
            log_dir='my_log_dir',
            histogram_freq=1,
            embeddings_freq=1,
        )
    ]
    history = model.fit(x_train, y_train, epochs=20, batch_size=128, validation_split=0.2, callbacks=callbacks)
    

    显然,Keras库已经经历了一些变化,因为这段代码引发了一些异常:

    ValueError: To visualize embeddings, embeddings_data must be provided.
    

    这是在完成第一个历元和第一次运行回调(第一次运行TensorBoard)之后。我知道缺少的是张力板的参数 embeddings_data .但我不知道该给它分配什么。

    有人有这样的例子吗?

    以下是我正在使用的版本:

    Python: 3.6.5
    Keras: 2.2.0
    Tensorflow: 1.9.0
    

    [更新]

    为了测试任何可能的解决方案,我测试了以下内容:

    import numpy as np
    
    callbacks = [
        keras.callbacks.TensorBoard(
            log_dir='my_log_dir',
            histogram_freq = 1,
            embeddings_freq = 1,
            embeddings_data = np.arange(0, max_len).reshape((1, max_len)),
        )
    ]
    history = model.fit(x_train, y_train, epochs=20, batch_size=128, validation_split=0.2, callbacks=callbacks)
    

    这是我唯一能填充的方法 嵌入数据 这不会导致错误。但即便如此,这也无济于事。仍然是 PROJECTOR 张力板的选项卡为空:

    enter image description here

    感谢您的帮助。

    3 回复  |  直到 7 年前
        1
  •  6
  •   ttigong    6 年前

    我还在读《Python深度学习》一书,书中使用了Keras。这是我对这个问题的解答。首先,我尝试以下代码:

    callbacks = [keras.callbacks.TensorBoard(
        log_dir = 'my_log_dir',
        histogram_freq = 1,
        embeddings_freq = 1,
        embeddings_data = x_train,
    )]
    history = model.fit(x_train, y_train, epochs=2, batch_size=128, validation_split=0.2, callbacks=callbacks)
    

    但有一个错误: ResourceExhaustedError .

    因为“x_train”中有25000个样本,所以很难将它们全部嵌入我的旧笔记本中。接下来我尝试嵌入“x_train”的前100个样本,这是有意义的。

    代码和结果显示在这里。

    callbacks = [keras.callbacks.TensorBoard(
        log_dir = 'my_log_dir',
        histogram_freq = 1,
        embeddings_freq = 1,
        embeddings_data = x_train[:100],
    )]
    history = model.fit(x_train, y_train, epochs=2, batch_size=128, validation_split=0.2, callbacks=callbacks)
    

    Projector of 100 samples

    请注意,在投影仪中,“Points:100”表示有100个样本,“Dimension:64000”表示每个样本的嵌入向量长度 样本是64000。一个样本中有500个单词,如“max_len=500”,每个单词有一个128_dim向量,因此500*128=64000。

        2
  •  1
  •   nuric    7 年前

    是的,这是正确的,你需要提供 什么 使用 embeddings_data 论点:

    callbacks = [
        keras.callbacks.TensorBoard(
            log_dir='my_log_dir',
            histogram_freq=1,
            embeddings_freq=1,
            embeddings_data=np.array([3,4,2,5,2,...]),
        )
    ]
    

    嵌入数据 :在嵌入层名称中指定的层中嵌入的数据。Numpy数组(如果模型有一个输入)或Numpy数组列表(如果模型有多个输入)。

    看一看 documentation 获取关于这些论点的最新信息。

        3
  •  1
  •   Philipp Schäfer    7 年前

    我只是问自己同样的问题。从文档来看,不太清楚“嵌入数据”应该是什么。但它是一个要嵌入的单词列表,或者更确切地说是它们的索引,这是有道理的。

    但我对格式有点困惑。通过使用keras标记器进行标记,我有一个“单词索引”,其中包含我词汇表中所有单词的一个数字,其中最常见的是 maxwords 使用条目。标记器为我提供从0到0的整数列表 maxwords 或者是一袋热编码的单词。然后我将这些序列填充到 麦克斯伦 .

    max_words = 1000
    
    tokenizer = Tokenizer(num_words=max_words)
    tokenizer.fit_on_texts(X_train)
    
    X_train_sequences = tokenizer.texts_to_sequences(X_train)
    X_train_one_hot_results = tokenizer.texts_to_matrix(X_train, mode='binary')
    
    X_test_sequences = tokenizer.texts_to_sequences(X_test)
    X_test_one_hot_results = tokenizer.texts_to_matrix(X_test, mode='binary')
    
    #####
    
    maxlen = 100
    X_train_pad = pad_sequences(X_train_sequences, maxlen=maxlen)
    X_test_pad = pad_sequences(X_test_sequences, maxlen=maxlen)
    

    然后,我创建了一个从嵌入层开始的模型:

    embedding_dim = 300
    
    model = Sequential()
    model.add(Embedding(max_words,embedding_dim,input_length=maxlen, name='embed'))
    model.add(Flatten())
    ...
    

    所以 max_words 是我的词汇量,一个热编码单词/文本的大小, 嵌入_dim 是图层输出的大小,并且 麦克斯伦 是序列的长度,即句子中的字数,通过填充保持不变。 单词索引中的数字是“嵌入数据”应该得到的吗?

    当我输入“仅”一个numpy数组时,它列出了任意数量的单词索引

    ...
    tensorboard = TensorBoard(log_dir='log_dir', histogram_freq=1, embeddings_freq=1, embeddings_data=np.array([1,2,3]))
    ...
    

    我得到了这个错误:

    ValueError:无法为张量'embed_input_2:0'提供形状(3,1)的值,该张量具有形状'(?,100)'

    在我的例子中,100是序列的长度。这令人困惑。因为我想想象单个单词,而不是句子或文本,不是吗?显然,回调函数想要向层提供一个或多个序列。

    那么,我应该如何对我的“皇后”、“国王”、“女人”、“男人”标记进行编码,以便我能看到语义关系(希望如此)? 或者更一般地说:如何对所有词汇元素进行概述,以发现单独培训的嵌入的总体趋势?

        4
  •  0
  •   zahbaz    6 年前

    这里有一个 example 对基本MNIST卷积神经网络分类器使用嵌入。这个 embedding_data 恰好是这个场景中的输入数据,我相信它通常是通过网络转发的任何数据。

    以下是带有评论的链接脚本。首先,他们从基本的MNIST设置开始。

    '''Trains a simple convnet on the MNIST dataset and embeds test data.
    The test data is embedded using the weights of the final dense layer, just
    before the classification head. This embedding can then be visualized using
    TensorBoard's Embedding Projector.
    '''
    
    from __future__ import print_function
    
    from os import makedirs
    from os.path import exists, join
    
    import keras
    from keras.callbacks import TensorBoard
    from keras.datasets import mnist
    from keras.models import Sequential
    from keras.layers import Dense, Dropout, Flatten
    from keras.layers import Conv2D, MaxPooling2D
    from keras import backend as K
    
    import numpy as np
    
    batch_size = 128
    num_classes = 10
    epochs = 12
    log_dir = './logs'
    
    if not exists(log_dir):
        makedirs(log_dir)
    
    # input image dimensions
    img_rows, img_cols = 28, 28
    
    # the data, split between train and test sets
    (x_train, y_train), (x_test, y_test) = mnist.load_data()
    
    if K.image_data_format() == 'channels_first':
        x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
        x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
        input_shape = (1, img_rows, img_cols)
    else:
        x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
        x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
        input_shape = (img_rows, img_cols, 1)
    
    x_train = x_train.astype('float32')
    x_test = x_test.astype('float32')
    x_train /= 255
    x_test /= 255
    print('x_train shape:', x_train.shape)
    print(x_train.shape[0], 'train samples')
    print(x_test.shape[0], 'test samples')
    

    现在为tensorboard创建了元数据。对于此分类任务 嵌入数据 这是测试集。然后元数据必须包含相应的数字标签。

    # save class labels to disk to color data points in TensorBoard accordingly
    with open(join(log_dir, 'metadata.tsv'), 'w') as f:
        np.savetxt(f, y_test)
    
    # convert class vectors to binary class matrices
    y_train = keras.utils.to_categorical(y_train, num_classes)
    y_test = keras.utils.to_categorical(y_test, num_classes)
    

    现在定义tensorboard回调。请注意,“特征”指的是感兴趣的嵌入层,在模型构建期间命名。这个 嵌入数据 这里只是测试集。

    tensorboard = TensorBoard(batch_size=batch_size,
                              embeddings_freq=1,
                              embeddings_layer_names=['features'],
                              embeddings_metadata='metadata.tsv',
                              embeddings_data=x_test)
    
    model = Sequential()
    model.add(Conv2D(32, kernel_size=(3, 3),
                     activation='relu',
                     input_shape=input_shape))
    model.add(Conv2D(64, (3, 3), activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.25))
    model.add(Flatten())
    

    下一层名为“features”。

    model.add(Dense(128, activation='relu', name='features'))
    model.add(Dropout(0.5))
    model.add(Dense(num_classes, activation='softmax'))
    
    model.compile(loss=keras.losses.categorical_crossentropy,
                  optimizer=keras.optimizers.Adadelta(),
                  metrics=['accuracy'])
    
    model.fit(x_train, y_train,
              batch_size=batch_size,
              callbacks=[tensorboard],
              epochs=epochs,
              verbose=1,
              validation_data=(x_test, y_test))
    score = model.evaluate(x_test, y_test, verbose=0)
    print('Test loss:', score[0])
    print('Test accuracy:', score[1])
    
    # You can now launch tensorboard with `tensorboard --logdir=./logs` on your
    # command line and then go to http://localhost:6006/#projector to view the
    # embeddings