在Keras中制作采样层 [英] Making a Sampling Layer in Keras

查看:74
本文介绍了在Keras中制作采样层的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试构建一个自定义Keras层,该层返回一个从上一个softmax层中选择的类的一个热矢量,即,如果 Sofmax 层返回[0.4 0.1 0.5],我想根据此 softmax 概率,对0至2类进行随机选择.

I am trying to build a custom Keras Layer that returns a one hot vector of a class chosen from a previous softmax layer, i.e, if Sofmax layer returns [0.4 0.1 0.5] I want to make a ramdom choice on classes 0 to 2 according to this softmax probability.

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

Here is what I have done so far:

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)中6768""--->69 y = np.array(y,dtype ='int')70 input_shape = y.shape如果input_shape和input_shape [-1] == 1并且len(input_shape)> 71,则返回71.1:

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

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

TypeError: array() takes 1 positional argument but 2 were given

此处是Google Colab链接

Here is the Google Colab link

推荐答案

您可以使用 tf.one_hot 来实现.

如果采样功能的输入是2D:

If the input of the sampling function is 2D:

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:

If the input of the sampling function is 3D:

tf.random.categorical 仅接受2D Logit.您可以使用 tf.map_fn

tf.random.categorical accepts only 2D logits. You can adapt the operation for 3D logits using tf.map_fn

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)

此处正在运行的笔记本

这篇关于在Keras中制作采样层的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆