tensorflow,训练后拆分自动编码器

Posted

技术标签:

【中文标题】tensorflow,训练后拆分自动编码器【英文标题】:tensorflow, splitting autoencoder after training 【发布时间】:2019-12-24 21:22:45 【问题描述】:

我在 tensorflow 1x(不是 keras)中有自动编码器模型,我试图在训练后将模型拆分为编码器和解码器。

两个函数在同一范围内 我有 3 个 PlaceHolders

self.X = tf.placeholder(shape=[None, vox_res64, vox_res64, vox_res64, 1], dtype=tf.float32)
self.Z = tf.placeholder(shape=[None,500], dtype=tf.float32)

self.Y = tf.placeholder(shape=[None, vox_rex256, vox_rex256, vox_rex256, 1], dtype=tf.float32)

 with tf.variable_scope('aeu'):
            self.lfc=self.encoder(self.X)

            self.Y_pred, self.Y_pred_modi = self.decoder(self.lfc)

编码器和解码器如下

    def encoder(self,X):
        with tf.device('/gpu:'+GPU0):
            X = tf.reshape(X,[-1, vox_res64,vox_res64,vox_res64,1])
            c_e = [1,64,128,256,512]
            s_e = [0,1 , 1, 1, 1]
            layers_e = []
            layers_e.append(X)
            for i in range(1,5,1):
                layer = tools.Ops.conv3d(layers_e[-1],k=4,out_c=c_e[i],str=s_e[i],name='e'+str(i))
                layer = tools.Ops.maxpool3d(tools.Ops.xxlu(layer, label='lrelu'), k=2,s=2,pad='SAME')
                layers_e.append(layer)

            ### fc
            [_, d1, d2, d3, cc] = layers_e[-1].get_shape()
            d1=int(d1); d2=int(d2); d3=int(d3); cc=int(cc)
            lfc = tf.reshape(layers_e[-1],[-1, int(d1)*int(d2)*int(d3)*int(cc)])
            lfc = tools.Ops.xxlu(tools.Ops.fc(lfc, out_d=500,name='fc1'), label='relu')
            print (d1)
            print(cc)
        return lfc


    def decoder(self,Z):
        with tf.device('/gpu:'+GPU0):


            lfc = tools.Ops.xxlu(tools.Ops.fc(Z, out_d=2*2*2*512, name='fc2'), label='relu')

            lfc = tf.reshape(lfc, [-1,2,2,2,512])

            c_d = [0,256,128,64]
            s_d = [0,2,2,2]
            layers_d = []
            layers_d.append(lfc)
            for j in range(1,4,1):

                layer = tools.Ops.deconv3d(layers_d[-1],k=4,out_c=c_d[j],str=s_d[j],name='d'+str(len(layers_d)))

                layer = tools.Ops.xxlu(layer, label='relu')
                layers_d.append(layer)
            ###
            layer = tools.Ops.deconv3d(layers_d[-1],k=4,out_c=1,str=2,name='dlast')
            print("****************************",layer)
            ###
            Y_sig = tf.nn.sigmoid(layer)
            Y_sig_modi = tf.maximum(Y_sig,0.01)

        return Y_sig, Y_sig_modi

当我在训练后尝试使用模型时


 X = tf.get_default_graph().get_tensor_by_name("Placeholder:0")
 Z = tf.get_default_graph().get_tensor_by_name("Placeholder_1:0")
 Y_pred = tf.get_default_graph().get_tensor_by_name("aeu/Sigmoid:0")
 lfc = tf.get_default_graph().get_tensor_by_name("aeu/Relu:0")


获取潜在代码工作正常

 lc = sess.run(lfc, feed_dict=X: x_sample)

现在我想使用潜在代码作为解码器的输入我得到错误我必须填写 X(PLACEHOLDER)

 y_pred = sess.run(Y_pred, feed_dict=Z: lc)

如何拆分为编码器解码器? 我搜索了只找到了 keras 示例

【问题讨论】:

【参考方案1】:

我注意到的第一件事是你没有将 self.Z 传入解码器的任何地方。因此 tensorflow 不能自动将该占位符与您之前使用的 z 链接起来。

您可以采取一些措施来解决此问题。最简单的方法是尝试重新创建解码器图,但是当您调用变量范围时,请设置重用=True。


    with tf.variable_scope('aeu',reuse=True):
        self.new_Y, self.new_Y_modi = self.decoder(self.Z)

    y_pred = sess.run(self.new_Y, feed_dict=self.Z: lc)

这可能是最容易做到的方法。在这种情况下,您也可能会被要求填写占位符 X,但您可以只用一个空数组填写它。通常 Tensorflow 不会要求它,除非有某种控制依赖将两者联系在一起。

【讨论】:

【参考方案2】:

我找到了如何拆分模型。

如果有人想知道,我会给出答案

我的错误是:

1:我没有将 self.Z 传递给解码器

2:用于以下行

y_pred = sess.run(Y_pred, feed_dict=Z: lc)

在我训练我的模型后,这行在不同的文件中 tensorflow 将不知道 [ z ] 指的是什么,因此您必须使用与您标识张量相同的变量,如下所示

 lfc = tf.get_default_graph().get_tensor_by_name("aeu/Relu:0")

我把它命名为 [lfc] 而不是 [Z]

所以更改代码以解决问题

y_pred = sess.run(Y_pred, feed_dict=lfc: lc)

【讨论】:

以上是关于tensorflow,训练后拆分自动编码器的主要内容,如果未能解决你的问题,请参考以下文章

如何拆分自己的数据集以在 Tensorflow CNN 中进行训练和验证

使用预训练 vgg19 tensorflow,Keras 在 CNN 自动编码器中定义自定义损失(感知损失)

使用 tensorflow 将数据集拆分为训练和测试

[TensorFlow系列-15]:TensorFlow基础 - 张量的操作 - 拆分与分割

如何拆分卷积自动编码器?

无法使用经过训练的 Tensorflow 模型