You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Keras生成器模型中对输出序列执行独热编码?

问题描述

我正在为特定GAN模型构建噪声生成器:

  • 输入:100个浮点数组成的随机序列
  • 输出要求:先得到809个取值范围为1至21的整数,最终独热编码为形状(None, 809, 22)的张量

当前模型执行到tf$squeeze(axis=-1L)时运行正常,此时输出形状为(None, 809)。尝试用layer_integer_lookup实现独热编码:

one_int<- layer_integer_lookup(vocabulary=dicint,
                                 oov_token = 0,
                                 num_oov_indices = 1L,
                                 output_mode = "one_hot")

添加到模型末尾后触发报错:

RuntimeError: Evaluation error: ValueError: Exception encountered when calling layer "integer_lookup_4" (type IntegerLookup).

When output_mode is not `'int'`, maximum supported output rank is 2. Received output_mode one_hot and input shape (None, 809), which would result in output rank 3.
Call arguments received:
• inputs=tf.Tensor(shape=(None, 809), dtype=float32)

附完整模型代码:

######################### Constants #########################
depth=809
kwidth=22
rnd_seq=100
bsize=8L
noise=function(bsize,rnd_seq){tf$random$normal(c(bsize,rnd_seq))}
flt=8
kernels=12

######################### Model ##########################
model_GAN = function(batch_size,flt,kernels,depth,rnd_seq) {
 prot_input2 = layer_input(shape = c(rnd_seq))
 GAN= prot_input2 %>% 
    layer_dense(depth) %>%
    layer_reshape(target_shape = c(depth,1)) %>%
    layer_conv_1d_transpose(filters=flt,kernel_size = c(kernels),strides = kernels/2 )%>% 
    layer_activation_leaky_relu(alpha=0.2) %>%
    layer_flatten() %>%
    #layer_conv_1d(filters = flt, kernel_size = c(kernels), strides = (kernel_size/2), activation = 'sigmoid') %>%
    layer_dense(depth,activation="sigmoid") %>%
    layer_reshape(target_shape = c(depth,1)) %>%
     recode_aa() %>%
    tf$squeeze(axis=-1L) %>%
  ?????????  my_conv()   ###### here I need help!!!
   
model=keras_model(inputs=prot_input2,outputs = GAN)  
    summary(model)
    return(model)
  }
#################### Build the model ####################

modelGAN=model_GAN(batch_size,flt,kernels,depth,rnd_seq)

模型执行至tf$squeeze(axis=-1L)时的结构摘要:

Model: "model_1"
___________________________________________________________________________________________________________________________
 Layer (type)                                          Output Shape                                     Param #            
===========================================================================================================================
 input_12 (InputLayer)                                 [(None, 100)]                                    0                   
                                                                                                                           
 dense_19 (Dense)                                      (None, 809)                                      81709               
                                                                                                                           
 reshape_19 (Reshape)                                  (None, 809, 1)                                   0                   
                                                                                                                           
 conv1d_transpose_9 (Conv1DTranspose)                  (None, 4860, 8)                                  104                 
                                                                                                                           
 leaky_re_lu_9 (LeakyReLU)                             (None, 4860, 8)                                  0                   
                                                                                                                           
 flatten_9 (Flatten)                                   (None, 38880)                                    0                   
                                                                                                                           
 dense_18 (Dense)                                      (None, 809)                                      31454729            
                                                                                                                           
 reshape_18 (Reshape)                                  (None, 809, 1)                                   0                   
                                                                                                                           
 tf.math.add_9 (TFOpLambda)                            (None, 809, 1)                                   0                   
                                                                                                                           
 tf.math.truediv_9 (TFOpLambda)                        (None, 809, 1)                                   0                   
                                                                                                                           
 tf.math.round_9 (TFOpLambda)                          (None, 809, 1)                                   0                   
                                                                                                                           
 tf.compat.v1.squeeze_9 (TFOpLambda)                   (None, 809)                                      0                   
                                                                                                                           
===========================================================================================================================
Total params: 31,536,542
Trainable params: 31,536,542
Non-trainable params: 0
___________________________________________________________________________________________________________________________
解决方案

方法1:用Lambda层包装tf.one_hot

layer_integer_lookup在output_mode="one_hot"时仅支持输入rank≤1(输出rank≤2),而你的输入是rank2的(None,809),会导致输出rank3超出限制。直接用tf.one_hot更适配序列型独热编码需求:

# 定义独热编码Lambda层
one_hot_layer <- layer_lambda(function(x) {
  # 强制转换为整数类型(tf.one_hot要求输入为整数)
  x <- tf$cast(x, tf$int32)
  # depth=22对应0-21共22个类别(包含oov的0和1-21的有效值)
  tf$one_hot(x, depth = 22, axis = -1L)
})

替换模型中需要修改的部分:

GAN= prot_input2 %>% 
    # ... 保留前面所有层 ...
    tf$squeeze(axis=-1L) %>%
    one_hot_layer()

这样输出形状会直接变为(None,809,22),完全符合需求。

方法2:调整IntegerLookup的使用流程

如果一定要用layer_integer_lookup,可以先展平输入,处理后再重塑回目标形状:

one_int <- layer_integer_lookup(
  vocabulary = dicint,
  oov_token = 0,
  num_oov_indices = 1L,
  output_mode = "one_hot"
)

# 修改模型流程
GAN= prot_input2 %>% 
    # ... 保留前面所有层 ...
    tf$squeeze(axis=-1L) %>%
    layer_flatten() %>%
    one_int() %>%
    layer_reshape(target_shape = c(depth, 22))  # 重塑为(None,809,22)

注意要确保dicint包含1-21的所有值,oov_token=0会被映射到第一个独热位,最终输出的类别数为22。

额外注意事项

  • 确认recode_aa()层输出的整数确实在1-21范围内,避免过多OOV(未登录词)影响模型效果;
  • 若后续需要计算损失,独热编码后的输出可直接与目标张量计算交叉熵损失。

内容的提问来源于stack exchange,提问作者Davide

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 02:02:12