【实验踩坑小结】如何在keras构建model中取出tensor中的某一维数据

问题描述:

上一层得到的tensor是一个二维的【Tensor(“dense_3/BiasAdd:0”, shape=(?, 2), dtype=float32)】,我想对tensor中的不同列做不同的激活函数操作,所以需要单独的把我需要的那部分取出来。


错误做法:
inputs = Input((128, 128,1))
fc = Dense(2)(inputs)
a = fc[:,0]
s = fc[:,1]
a = Activation('relu')(a)
s = Activation('sigmoid')(s)

a = UpSampling2D((128,128))(Reshape([1,1,1])(a))
s = UpSampling2D((128,128))(Reshape([1,1,1])(s))
outputs = Lambda(lambda x: tf.where(tf.less_equal(x[0], x[1]), x[0]*x[2], x[0]))([inputs, s, a])

model = Model(inputs = inputs, outputs = outputs)

在运行过程中是不存在语法问题的,且把a和s打印出来也可以看到的确是正确的tensor维度,但是到了构建model的时候,会报出以下错误:

AttributeError: ‘NoneType’ object has no attribute ‘_inbound_nodes’

非常眼熟的问题,之前写的那篇keras.layer中反复提到的报错问题——构建model的过程中出现了不属于keras.layer的函数。一步步往前排查,发现就是直接对fc取值时出了错,不能直接取。


解决方法:

用Lambda封装为layer。我最开始还用了tf.slice,其实可以直接把取值操作进行封装。

\\直接封装取值操作【类似list的做法】
a = Lambda(lambda x: x[:,0])(fc)
s = Lambda(lambda x: x[:,1])(fc)

\\用tf.slice,也需要封装
a = Lambda(lambda x: tf.slice(x,[0,0],[128,1]))(fc) 
s = Lambda(lambda x: tf.slice(x,[0,1],[128,1]))(fc) 

ps:需要特别注意的是,list做法会导致降维,所以后续可能需要reshape操作等。而tf.slice的输出形状是和输入形状一致,shape不发生变化。

附录:

(1)tf.slice:把tensor切片

def slice(input_, begin, size, name=None):

input_:需要切片的tensor
begin:每一个维度的起始位置
size:每个维度拿几个元素出来

例子:

t = tf.constant([[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]], [[5, 5, 5], [6, 6, 6]]])
a = tf.slice(t, [1, 0, 0], [1, 1, 3])

//a = [[[3, 3, 3]]]
  • t的shape为[3,2,3],第一个维度是t = [A, B, C]。A = [[1, 1, 1], [2, 2, 2]],B = [[3, 3, 3], [4, 4, 4]], C = [[5, 5, 5], [6, 6, 6]]。第二个维度是 A,B,C=[i, j],以A为例,i = [1, 1, 1],j = [2, 2, 2]。第三个维度就是i,j中对应得元素个数。
  • begin参数对应[1,0,0]。意思是在第一个维度从index为1开始算,由于起始index为0,所以此处指的是B。以此类推,第二个维度从i开始算,第三个维度从内框中的第一个元素开始算。
  • size参数对应[1,1,3]。意思是每个维度取几个元素。和begin综合来看就是,第一个维度,从B开始取,取一个,就是只取B;第二个维度从i开始算,也是只取一个,就是取i;第三个维度从起始开始算,取三个,就是把i中的元素取三个。

(2)tf.where

tf.where(condition, A, B)

  • condition:一个Tensor,数据类型为tf.bool类型

  • 如果A、B均为空,那么返回condition中值为True的位置的Tensor

  • 如果A、B不为空的话(形状必相同),返回值和A、B有相同的形状,如果condition对应位置值为True那么返回Tensor对应位置为A的值,否则为B的值

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值