【问题标题】:One-hot encoding Tensorflow StringsOne-hot 编码 TensorFlow 字符串
【发布时间】:2017-09-25 21:09:04
【问题描述】:

我有一个字符串列表作为训练神经网络的标签。现在我想通过 one_hot 编码转换它们,以便我可以将它们用于我的 tensorflow 网络。 我的输入列表如下所示:

 labels = ['"car"', '"pedestrian"', '"car"', '"truck"', '"car"']

请求的结果应该类似于

 one_hot [0,1,0,2,0]

最简单的方法是什么?任何帮助将不胜感激。

干杯, 安迪

【问题讨论】:

  • 您的输出不是 one hot 编码。这是一个简单的索引字符串。看看sklearn.preprocessing.LabelEncoder()大概吧。
  • 这不是一种热编码。你有错误的概念

标签: tensorflow one-hot-encoding


【解决方案1】:

期望的结果看起来像 sklearn 中的 LabelEncoder,而不像 OneHotEncoder - 在 tf 中你需要 CategoryEncoder - 但它是 一个对整数特征进行编码的预处理层。:

inp = layers.Input(shape=[X.shape[0]])
x0 = layers.CategoryEncoding(
          num_tokens=3, output_mode="multi_hot")(inp)

model = keras.Model(inputs=[inp], outputs=[x0])
model.compile(optimizer= 'adam',
    loss='categorical_crossentropy',
    metrics=[tf.keras.metrics.CategoricalCrossentropy()])
print(model.summary())
  • 这部分获取唯一值的编码...并且您可以在此模型中创建另一个分支来输入您的初始向量并根据此参考分支中的标签对其进行拟合(就像将参考表与事实表连接在任何数据库)——这里将是引用数据和您需要的数据和输出的集合......

注意 -- num_tokens=3, output_mode="multi_hot" -- 被明确给出...并且来自 class_names 的数字优先于模型使用,特征工程也是如此 - 像这样(在 pd.DataFrame 中)

import numpy as np
import pandas as pd

d = {'transport_col':['"car"', '"pedestrian"', '"car"', '"truck"', '"car"']}
dataset_df =  pd.DataFrame(data=d)

classes = dataset_df['transport_col'].unique().tolist()
print(f"Label classes: {classes}")

df= dataset_df['transport_col'].map(classes.index).copy()
print(df)

来自manual example REF: 将分类标签编码为整数。 详细信息:如果您的分类标签表示为字符串,则此阶段是必要的。注意:Keras 期望分类标签是整数。

【讨论】:

    【解决方案2】:

    在另一个架构中,也许你可以使用StringLookup

    vocab= np.array(np.unique(labels))
    inp = tf.keras.Input(shape= labels.shape[0], dtype=tf.string)
    x = tf.keras.layers.StringLookup(vocabulary=vocab)(inp)
    

    但标签通常是依赖变量,而不是特征,不应在输入中使用

    Everything in keras.docs

    可能的完整代码:

    import numpy as np
    import pandas as pd
    import keras
    
    X = np.array([['"car"', '"pedestrian"', '"car"', '"truck"', '"car"']])
    vocab= np.unique(X)
    print(vocab)
    
    y=  np.array([[0,1,0,2,0]])
    
    inp = layers.Input(shape=[X.shape[0]], dtype='string')
    x0= tf.keras.layers.StringLookup(vocabulary=vocab, name='finish')(inp)    
    
    model = keras.Model(inputs=[inp], outputs=[x0])
    model.compile(optimizer= 'adam',
        loss='categorical_crossentropy',
        metrics=[tf.keras.metrics.categorical_crossentropy])
    print(model.summary())
    
    from tensorflow.keras import backend as K
    for layerIndex, layer in enumerate(model.layers):
        print(layerIndex)
        func = K.function([model.get_layer(index=0).input], layer.output)
        layerOutput = func([X])  # input_data is a numpy array
        print(layerOutput)
        if layerIndex==1:   # the last layer here
          scale = lambda x: x - 1 
          print(scale(layerOutput))
    

    回复:

    [[0 1 0 2 0]]

    【讨论】:

      【解决方案3】:

      您的情况的另一种可能的解决方案 - layers.TextVectorization

      import numpy as np
      import keras
      
      input_array = np.atleast_2d(np.array(['"car"', '"pedestrian"', '"car"', '"truck"', '"car"']))
      vocab= np.unique(input_array)
      
      input_data = keras.Input(shape=(None,), dtype='string') 
      layer = layers.TextVectorization( max_tokens=None, standardize=None, split=None, output_mode="int",  vocabulary=vocab) 
      
      int_data = layer(input_data) 
      model = keras.Model(inputs=input_data, outputs=int_data)
      
      output_dataset = model.predict(input_array)
      print(output_dataset) # starts from 2 ... probably [0, 1] somehow concerns binarization ?
      
      scale = lambda x: x - 2 
      print(scale(output_dataset))
      

      结果:

      数组([[0, 1, 0, 2, 0]])

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-07
        • 2016-12-11
        • 2021-07-20
        • 2018-05-09
        • 1970-01-01
        • 2017-06-21
        相关资源
        最近更新 更多