首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在R中使用Keras编写自定义层(3D RoI池)

在R中使用Keras编写自定义层(3D RoI池)
EN

Stack Overflow用户
提问于 2020-06-17 02:44:12
回答 1查看 307关注 0票数 0

使用R,我想要生成一个Keras自定义层来执行3D感兴趣区域(RoI)池。我的3D RoI池函数在R6Class KerasLayer之外正常工作,但是我很难将它集成到自定义层中。我不确定在下面的例子中我是否正确地使用了签名。对于我来说,在定制层的“调用”部分使用R函数(即循环)时,我需要在签名中包装函数。

下面的定制层用于为Keras的R用户应用3D RoI池(没有训练权重)吗?

3d_RoI_Pool层的输入包括:

(i) VNet模型的输出层,

  • shape=(无,16,16,40,1)

(ii)定义输入层在每个RoI范围内的“指数”的张量,

代码语言:javascript
复制
  - tf.Variable 'Variable:0' shape=(1, 1, 6) dtype=float64, numpy=array([[[ 5.,  5.,  4.,  5., 10., 20.]]])

(3)集合3D RoIs的输出维数。

  • 在本例中c(1,1,5,5,5,1)表示c(Batch_Size,RoI_Size,X,Y,Z,通道)

以下是一些我不清楚的问题:

  • 我最初使用layer_cropping_3d来裁剪每个RoI,但不确定是否允许自定义层使用可用的layers层?由于这个原因,我在代码中执行了自己的裁剪。
  • 是在自定义的
  • 中正确使用签名的方法吗?我使用layer_lambda()作为这样一个函数(即将任意表达式包装为一个层),因为在3D_RoI_Pooling层中没有可训练的权重?

下面是从V获取输出层并为自定义层准备输入的代码:

代码语言:javascript
复制
  # FINAL LAYERS OF V_Net
  Output_shortcut = up1_DeConv
  Final_Conv <- up1_Concat %>%
    # 1st
    layer_conv_3d(filters = Filter_Start, kernel_size = Kernel_Conv_Size, padding = "same", name = "Final_Conv") %>%
    layer_batch_normalization() %>%
    layer_activation("relu")

  Final_Conv <- layer_add(c(Final_Conv, Output_shortcut), name = "Final_Conv_ResNet")

  # PREPARE INPUT FOR CUSTOM LAYER
  n_RoI <- 1 
  Batch_Size <- 1 

  Table_RoI <- list(list(c(5, 5), c(4, 5), c(10, 20)))
  Table_RoI <- array_reshape(unlist(Table_RoI), c(Batch_Size,n_RoI,6), order="F")
  Table_RoI <- tf$Variable(Table_RoI, tf$int16)

  output_dim <- c(Batch_Size, n_RoI, 5,5,5, as.numeric(dim(Final_Conv)[5]))

  # FEED CUSTOM LAYER TO CNN
  Final_Conv2 <- Final_Conv %>% layer_3D_ROI_pooled(Table_RoI=Table_RoI, output_dim= output_dim)

下面是生成错误的实际3D RoI池自定义层:

代码语言:javascript
复制
# 3D ROIpooled_Layer (R KERAS )
ROIpooled_Layer <- R6::R6Class("KerasLayer",
                                inherit = KerasLayer,
                                public = list(
                                  Table_RoI = NULL,
                                  output_dim = NULL, 

                                  ###############
                                  # INITIALISE
                                  ###############

                                  initialize = function(Table_RoI, output_dim) {
                                    self$Table_RoI = Table_RoI
                                    self$output_dim = output_dim
                                    },

                                  ###############
                                  # CALL FUNCTION   ROIpooled_Function <-
                                  ###############
                                  call = autograph(function(x, mask = NULL,
                                                            Table_RoI,
                                                            output_dim) {

                                    ## Input_L ROI_Table 
                                    n_Batch <- output_dim[1]
                                    n_RoI <- output_dim[2]
                                    Channels <- output_dim[6]

                                    for(r in 1:n_RoI){


                                        # layer_cropping_3d(Input_L, cropping = list(list(as.numeric(Table_RoI[,r,1]), as.numeric(Table_RoI[,r,2])), 
                                        #                                                               list(as.numeric(Table_RoI[,r,3]), as.numeric(Table_RoI[,r,4])), 
                                        #                                                               list(as.numeric(Table_RoI[,r,5]), as.numeric(Table_RoI[,r,6]))))

                                      RoI_Cropped <-x[,(as.numeric(Table_RoI[,r,1])+1):(dim(feature_map_T)[2]-as.numeric(Table_RoI[,r,2])),
                                                                  (as.numeric(Table_RoI[,r,3])+1):(dim(feature_map_T)[3]-as.numeric(Table_RoI[,r,4])),
                                                                  (as.numeric(Table_RoI[,r,5])+1):(dim(feature_map_T)[4]-as.numeric(Table_RoI[,r,6])),]

                                      RoI_X_Res <- as.array(k_shape(RoI_Cropped)[2])
                                      RoI_Y_Res <- as.array(k_shape(RoI_Cropped)[3])
                                      RoI_Z_Res <- as.array(k_shape(RoI_Cropped)[4])

                                      New_X_Res <- as.array(output_dim[3])
                                      New_Y_Res <- as.array(output_dim[4])
                                      New_Z_Res <- as.array(output_dim[5])

                                      X_step = RoI_X_Res / New_X_Res    
                                      Y_step = RoI_Y_Res  / New_Y_Res  
                                      Z_step = RoI_Z_Res  / New_Z_Res  

                                      for(ch in 1:Channels) { 
                                        print(paste("ch", ch))
                                        for (k in 1:New_Z_Res) { 
                                          print(paste("k", k))
                                          for (j in 1:New_Y_Res) { 
                                            print(paste("j", j, "k", k))
                                            for (i in 1:New_X_Res) { 
                                              # INDEX X
                                              Index_Xstart <- floor((i-1)*X_step+1)
                                              if(i+1 <= RoI_X_Res){
                                                Index_Xend <- floor((i)*X_step)
                                              }else{
                                                Index_Xend <- RoI_X_Res
                                              }
                                              # INDEX Y
                                              Index_Ystart <-  floor((j-1)*Y_step+1) 
                                              if(j+1 <= RoI_Y_Res){
                                                Index_Yend <- floor((j)*Y_step)
                                              }else{
                                                Index_Yend <-RoI_Y_Res
                                              }
                                              # INDEX Z        
                                              Index_Zstart <-  floor((k-1)*Z_step+1) 
                                              if(k+1 <= RoI_Z_Res){
                                                Index_Zend <- floor((k)*Z_step)
                                              }else{
                                                Index_Zend <-RoI_Z_Res
                                              }
                                              Max_Pool_X_Value <- as.array(k_max(RoI_Cropped[n_Batch,Index_Xstart:Index_Xend, Index_Ystart:Index_Yend, Index_Zstart:Index_Zend,ch])) # ADD BATCH AND CHANNEL LAYERS
                                              RoI_Pooled_Array[,r,i,j,k,ch] <- Max_Pool_X_Value
                                            }# i LOOP
                                          } # j LOOP 
                                        } # k Loop
                                      } #Ch LOOP 
                                    } # r LOOP (ROI)
                                    feature_map_ROIpooled <- tf$Variable(RoI_Pooled_Array, tf$int16) # ??? NOT SURE IF RETURN NEEDS TO BE A VARIABLE

                                    return (feature_map_ROIpooled)

                                  }), # END OF AUTO, # END OF CALL ... AUTOGRAPH FUNCTION

                                  ##############
                                  # OUTPUT SHAPE
                                  ##############

                                  compute_output_shape = function(input_shape) { 
                                    list(self$output_dim) 
                                    }
                                )
                              )
# 
###############################
# Create layer wrapper function
###############################

layer_3D_ROI_pooled <- function(object, Table_RoI, output_dim, name = NULL, trainable = TRUE) {
  create_layer(ROIpooled_Layer, object, list(Table_RoI = Table_RoI, 
                                              output_dim = as.integer(output_dim), 
                                              name = name,
                                              trainable = FALSE
                                            ))
}

错误:

代码语言:javascript
复制
Error in value[[3L]](cond) : 
   The R function's signature must not contains esoteric Python-incompatible constructs. Detailed traceback: SyntaxError: non-default argument follows default argument (<string>, line 3)

如有任何帮助/洞察力/清晰度,将不胜感激。

你好,多姆

EN

回答 1

Stack Overflow用户

发布于 2020-06-19 04:23:10

我不确定这是否是正确的协议来回答自己的问题,但我认为我有一个工作的3D RoI池自定义层共享。上面的错误很多,但最明显的变化是在for循环中.我认为我需要首先生成一个表示每个池RoI的张量列表,然后将其重新格式化为所需的输出形状。

代码语言:javascript
复制
################################################################################################
# ROI_3D_pooled_Layer (Custom layer class)
##########################################
ROI_3D_pooled_Layer <- R6::R6Class("KerasLayer",

                                   inherit = KerasLayer,

                                   public = list(
                                     List_RoI = NULL,
                                     output_dim = NULL, 

                                     initialize = function(List_RoI, output_dim) {
                                       self$List_RoI = List_RoI
                                       self$output_dim = output_dim
                                     },

                                     call = function(x, mask = NULL) {   
                                       List_RoI <- self$List_RoI
                                       output_dim <- self$output_dim

                                       # EXTRACT INFORMATION ON OUTPUT DIMENSION
                                       n_Batch <- as.integer(output_dim[1])
                                       n_RoIs <- as.integer(output_dim[2])
                                       n_Channels <- as.integer(output_dim[6])

                                       New_X_Res <- as.numeric(output_dim[3])
                                       New_Y_Res <- as.numeric(output_dim[4])
                                       New_Z_Res <- as.numeric(output_dim[5])

                                       input_shape <- dim(x)

                                       # EMPTY LIST TO STORE TENSORS
                                       output_list = list()
                                       for(r in 1:n_RoIs){ # LOOP RoIs
                                         # GET one RoI AND CROP INPUT LAYER
                                         if(n_RoIs > 1){
                                           oneList_RoI <- List_RoI[[r]]
                                         }else{
                                           oneList_RoI <- List_RoI
                                         }

                                         RoI_Cropped <-x[,(oneList_RoI[[1]][1]+1):(as.numeric(input_shape[2])-oneList_RoI[[1]][2]),
                                                         (oneList_RoI[[2]][1]+1):(as.numeric(input_shape[3])-oneList_RoI[[2]][2]),
                                                         (oneList_RoI[[3]][1]+1):(as.numeric(input_shape[4])-oneList_RoI[[3]][1]),]

                                         # GET RoI Dimensions for XYZ
                                         RoI_X_Res <- as.numeric(dim(RoI_Cropped)[2])
                                         RoI_Y_Res <- as.numeric(dim(RoI_Cropped)[3])
                                         RoI_Z_Res <- as.numeric(dim(RoI_Cropped)[4])

                                         # CALCULATE STEPS IN ALL DIMENSIONS FOR POOLING
                                         X_step = RoI_X_Res / New_X_Res    
                                         Y_step = RoI_Y_Res  / New_Y_Res  
                                         Z_step = RoI_Z_Res  / New_Z_Res  

                                         for(ch in 1:n_Channels) { # LOOP CHANNEL
                                           for (k in 1:New_Z_Res) { # LOOP Z
                                             for (j in 1:New_Y_Res) { # LOOP Y
                                               for (i in 1:New_X_Res) { # LOOP X
                                                 # INDEX X
                                                 Index_Xstart <- floor((i-1)*X_step+1)
                                                 if(i+1 <= RoI_X_Res){
                                                   Index_Xend <- floor((i)*X_step)
                                                 }else{
                                                   Index_Xend <- RoI_X_Res
                                                 }
                                                 # INDEX Y
                                                 Index_Ystart <-  floor((j-1)*Y_step+1) 
                                                 if(j+1 <= RoI_Y_Res){
                                                   Index_Yend <- floor((j)*Y_step)
                                                 }else{
                                                   Index_Yend <-RoI_Y_Res
                                                 }
                                                 # INDEX Z        
                                                 Index_Zstart <-  floor((k-1)*Z_step+1) 
                                                 if(k+1 <= RoI_Z_Res){
                                                   Index_Zend <- floor((k)*Z_step)
                                                 }else{
                                                   Index_Zend <-RoI_Z_Res
                                                 }

                                                 # MAX POOL VOLUME FOR EACH ELEMENT IN FINAL LAYER AND PUT IN EMPTY ARRAY
                                                 Max_Pool_X_Value <-k_max(RoI_Cropped[,Index_Xstart:Index_Xend, Index_Ystart:Index_Yend, Index_Zstart:Index_Zend,ch])

                                                 # APPEND EACH RoI_Pooled element into a list
                                                 output_list <- list.append(output_list, Max_Pool_X_Value)
                                               }# i LOOP
                                             } # j LOOP 
                                           } # k Loop
                                         } #Ch LOOP 
                                       } # r LOOP (ROI)

                                       # STACK THE OUTPUT LIST AND RESHAPE TO THE DESIRED OUTPUT SIZE 
                                       output_Stack <- k_stack(output_list, axis = 1)
                                       feature_map_ROIpooled <- k_reshape(output_Stack, shape = c(n_Batch, n_RoIs, New_X_Res, New_Y_Res, New_Z_Res, n_Channels))
                                       return (feature_map_ROIpooled)
                                     },
                                     compute_output_shape = function(input_shape) {
                                       return(self$output_dim)
                                     }
                                   )
)

# Create layer wrapper function
layer_3D_ROI_pooled <- function(object, List_RoI, output_dim) {
  create_layer(ROI_3D_pooled_Layer, object, list(List_RoI = List_RoI, 
                                                 output_dim = as.integer(output_dim)
  ))
}

这是我第一次尝试使用Keras自定义层(使用R),因此请提供改进建议。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62420644

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档