【问题标题】:Making a Sampling Layer in Keras在 Keras 中制作采样层
【发布时间】:2021-07-11 07:08:27
【问题描述】:

我正在尝试构建一个自定义 Keras 层,该层返回从前一个 softmax 层中选择的类的一个热向量,即,如果 Sofmax 层返回 [0.4 0.1 0.5] 我想要根据这个 softmax 概率随机选择 0 到 2 类。

这是我到目前为止所做的:

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras import utils



def sampling(x):

    # HERE: I need to input 'x' into the 'tf.math.log' function, but after trying it created an error

    samples = tf.random.categorical(tf.math.log([[0.4 0.1 0.5]]), 1) # samples should be like [[z]] with z a number between 0 and 2

    return utils.to_categorical(samples[0][0], num_classes=3)



x = keras.Input(shape=(1,1,))

x, _, _ = layers.LSTM(100, return_sequences=True, return_state=True)(x)

x = layers.Dense(3, activation="softmax")(x)

x = layers.Lambda(sampling)(x)

此代码返回:

/usr/local/lib/python3.7/dist-packages/tensorflow/python/keras/utils/np_utils.py 在 to_categorical(y, num_classes, dtype) 67 68 """ ---> 69 y = np.array(y, dtype='int') 70 input_shape = y.shape 71 如果 input_shape 和 input_shape[-1] == 1 并且 len(input_shape) > 1:

TypeError: array() 接受 1 个位置参数,但给出了 2 个

Here 是 Google Colab 链接

【问题讨论】:

    标签: python tensorflow machine-learning keras deep-learning


    【解决方案1】:

    你可以用tf.one_hot来做。

    如果采样函数的输入是二维的:

    X = np.random.uniform(0,1, (100,1,1))
    y = tf.keras.utils.to_categorical(np.random.randint(0,3, (100,)))
    
    def sampling(x):
        zeros = x*0 ### useless but important to produce gradient
        samples = tf.random.categorical(tf.math.log(x), 1)
        samples = tf.squeeze(tf.one_hot(samples, depth=3), axis=1) 
        return zeros+samples
    
    
    inp = Input(shape=(1,1,))
    x, _, _ = LSTM(100, return_sequences=False, return_state=True)(inp)
    x = Dense(3, activation="softmax")(x)
    out = Lambda(sampling)(x)
    
    model = Model(inp, out)
    model.compile('adam', 'categorical_crossentropy')
    model.fit(X,y, epochs=3)
    

    如果采样函数的输入是3D:

    tf.random.categorical 仅接受 2D logits。您可以使用 tf.map_fn 调整操作以适应 3D logits

    X = np.random.uniform(0,1, (100,1,1))
    y = tf.keras.utils.to_categorical(np.random.randint(0,3, (100,)))
    y = y.reshape(-1,1,3)
    
    def sampling(x):
        zeros = x*0 ### useless but important to produce gradient
        samples = tf.map_fn(lambda t: tf.random.categorical(tf.math.log(t), 1), x, fn_output_signature=tf.int64)
        samples = tf.squeeze(tf.one_hot(samples, depth=3), axis=1) 
        return zeros+samples
    
    
    inp = Input(shape=(1,1,))
    x, _, _ = LSTM(100, return_sequences=True, return_state=True)(inp)
    x = Dense(3, activation="softmax")(x)
    out = Lambda(sampling)(x)
    
    model = Model(inp, out)
    model.compile('adam', 'categorical_crossentropy')
    model.fit(X,y, epochs=3)
    

    here正在运行的笔记本

    【讨论】:

      猜你喜欢
      • 2019-07-29
      • 2015-06-04
      • 1970-01-01
      • 2020-02-10
      • 2019-11-11
      • 2022-09-30
      • 2015-11-21
      • 2018-01-24
      • 2017-10-16
      相关资源
      最近更新 更多