【问题标题】:NumPy - creating 1-hot tensor from a 2D numpy arrayNumPy - 从 2D numpy 数组创建 1-hot 张量
【发布时间】:2018-01-15 08:13:36
【问题描述】:

我有一个数值范围从 0 到 59 的 numpy 二维数组。

对于那些熟悉 DL 尤其是图像分割的人 - 我从 .png 图像创建数组(称为 L),每个像素的值 L[x,y] 表示该像素所属的类( 60 个班级)。

我想创建一个 1-hot 张量 - Lhot,其中 (Lhot[x,y,z] == 1) 仅当 (L[x,y] == z) 时,否则为 0。

我想用某种广播/索引(1,2 行)创建它 - 没有循环。

它应该在功能上等同于这段代码(Dtype对应L):

Lhot = np.zeros((L.shape[0], L.shape[1], 60), dtype=Dtype)
for i in range(L.shape[0]):
    for j in range(L.shape[1]):
        Lhot[i,j,L[i,j]] = 1

有人有想法吗? 谢谢!

【问题讨论】:

    标签: python numpy deep-learning image-segmentation


    【解决方案1】:

    由于为一维向量定义了典型的 one-hot 编码,您所要做的就是展平矩阵,使用 scikit-learn(或任何其他具有 one-hot 编码的库)中的一个热编码器并重新整形。

    from sklearn.preprocessing import OneHotEncoder
    n, m = L.shape
    k = 60
    Lhot = np.array(OneHotEncoder(n_values=k).fit_transform(L.reshape(-1,1)).todense()).reshape(n, m, k)
    

    当然你也可以手工做

    n, m = L.shape
    k = 60
    Lhot = np.zeros((n*m, k)) # empty, flat array
    Lhot[np.arange(n*m), L.flatten()] = 1 # one-hot encoding for 1D
    Lhot = Lhot.reshape(n, m, k) # reshaping back to 3D tensor
    

    【讨论】:

    • 谢谢,我现在正在运行它,但需要很长时间,因为我有很多图像(标签)需要运行它
    • 问题是你真的需要它吗?您也可以让系统的其余部分(我想是神经网络)接受 id 而不是 one-hot 数据。将实时处理表示为网络的一部分也将为您节省大量 RAM/时间。
    • 你是对的,但我在 caffe 上使用预定义的网络运行它,似乎那里的 3d softmax 期望标签是 1-hot 表示,以符合分数 blob尺寸
    【解决方案2】:

    使用纯numpy 的方式更快更清洁

    Lhot = np.transpose(np.eye(60)[L], (1,2,0))
    

    使用多维 one-hots 时会遇到的问题是它们变得真的大而真的稀疏,并且没有好的方法来处理超过 2D 的稀疏数组numpy/scipy(或 sklearn 或我认为的许多其他 ML 包)。你真的需要一个 nd one-hot 吗?

    【讨论】:

    • 我正在为 FCN-8s 网络中的标签创建一个 LMDB 文件以进行图像分割(使用 PASCAL-VOC 2012 数据集进行训练)。最后的 softmax 层需要 2 个参数 - 网络分数和这些标签,我看到分数维度是 {width,height,numClasses} ,这让我认为它必须是 1-hot 表示并且我必须以相同的方式构建标签
    猜你喜欢
    • 1970-01-01
    • 2022-09-23
    • 2017-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多