Python 如何使用TensorFlow正确实现动态卷积神经网络

Python 如何使用TensorFlow正确实现动态卷积神经网络,python,python-3.x,machine-learning,tensorflow,conv-neural-network,Python,Python 3.x,Machine Learning,Tensorflow,Conv Neural Network,我知道这是一个非常广泛的问题,但我提出了许多其他问题,我仍然无法正确地实现一个简单的dynamic-k max pooling卷积神经网络,如本文所述。目前,我正在尝试修改教程中的代码。我相信我已经成功地实现了dynamic-k部分。然而,我的主要问题是因为每个输入的k值不同,产生的张量是不同的形状。我尝试了无数的方法来修复这个问题(这就是为什么你可能会看到一些有趣的重塑),但我不知道怎么做。我认为你需要填充每个张量,使它们都成为最大张量的大小,但我似乎无法让它起作用。这是我的代码(很抱歉,它一

我知道这是一个非常广泛的问题,但我提出了许多其他问题,我仍然无法正确地实现一个简单的dynamic-k max pooling卷积神经网络,如本文所述。目前,我正在尝试修改教程中的代码。我相信我已经成功地实现了dynamic-k部分。然而,我的主要问题是因为每个输入的k值不同,产生的张量是不同的形状。我尝试了无数的方法来修复这个问题(这就是为什么你可能会看到一些有趣的重塑),但我不知道怎么做。我认为你需要填充每个张量,使它们都成为最大张量的大小,但我似乎无法让它起作用。这是我的代码(很抱歉,它一般都比较草率)

这是实际的DCNN类:

import tensorflow as tf


class TextDCNN(object):
    """
    A CNN for NLP tasks. Architecture is as follows:
    Embedding layer, conv layer, max-pooling and softmax layer
    """

    def __init__(self, sequence_lengths, sequence_length, num_classes, vocab_size, embedding_size, filter_sizes, num_filters):
        """
        Makes a new CNNClassifier
        Args:
            sequence_length: The length of each sentence
            num_classes: Number of classes in the output layer (positive and negative would be 2 classes)
            vocab_size: The size of the vocabulary, needed to define the size of the embedding layer
            embedding_size: Dimensionality of the embeddings
            filter_sizes: Number of words the convolutional filters will cover, there will be num_filters for each size
            specified.
            num_filters: The number of filters per filter size.

        Returns: A new CNNClassifier with the given parameters.

        """
        # Define the inputs and the dropout
        print("SEQL")
        print(sequence_length)
        self.input_x = tf.placeholder(tf.int32, [None, sequence_length], name="input_x")
        self.input_y = tf.placeholder(tf.float32, [None, num_classes], name="input_y")
        self.dropout_keep_prob = tf.placeholder(tf.float32, name="dropout_keep_prob")

        # Runs the operations on the CPU and organizes them into an embedding scope
        with tf.device("/cpu:0"), tf.name_scope("embedding"):
            W = tf.Variable(  # Make a 4D tensor to store batch, width, height, and channel
                tf.random_uniform([vocab_size, embedding_size], -1.0, 1.0),
                name="W"
            )

            self.embedded_chars = tf.nn.embedding_lookup(W, self.input_x)
            self.embedded_chars_expanded = tf.expand_dims(self.embedded_chars, -1)

        pooled_outputs = []
        for i, filter_size in enumerate(filter_sizes):
            with tf.name_scope("conv-maxpool-%s" % filter_size):
                # Conv layer
                filter_shape = [filter_size, embedding_size, 1, num_filters]
                # W is the filter matrix
                W = tf.Variable(tf.truncated_normal(filter_shape, stddev=0.1), name="W")
                b = tf.Variable(tf.constant(0.1, shape=[num_filters]), name="b")
                conv = tf.nn.conv2d(
                    self.embedded_chars_expanded,
                    W,
                    strides=[1, 1, 1, 1],
                    padding="VALID",
                    name="conv"
                )

                # Apply nonlinearity
                h = tf.nn.relu(tf.nn.bias_add(conv, b), name="relu")

                # Max-pooling layer over the outputs

                print(sequence_lengths[i] - filter_size + 1)
                print(h)

                pooled = tf.nn.max_pool(
                    h,
                    ksize=[1, sequence_lengths[i] - filter_size + 1, 1, 1],
                    strides=[1, 1, 1, 1],
                    padding="VALID",
                    name="pool"
                )

                pooled = tf.reshape(pooled, [-1, 1, 1, num_filters])

                print(pooled)

                pooled_outputs.append(pooled)

        # Combine all of the pooled features
        num_filters_total = num_filters * len(filter_sizes)

        max_shape = tf.reduce_max(pooled_outputs, 1)
        print("shapes")
        print([p.get_shape() for p in pooled_outputs])

        # pooled_outputs = [tf.pad(p, [[0, int(max_shape.get_shape()[0]) - int(p.get_shape()[0])], [0, 0], [0, 0], [0, 0]]) for p in pooled_outputs]
        # pooled_outputs = [tf.reshape(p, [-1, 1, 1, num_filters]) for p in pooled_outputs]

        # pooled_outputs = [tf.reshape(out, [-1, 1, 1, self.max_length]) for out in pooled_outputs]

        self.h_pool = tf.concat(3, pooled_outputs)
        self.h_pool_flat = tf.reshape(self.h_pool, [-1, num_filters_total])
        print("here")
        print(self.h_pool_flat)
        self.h_pool_flat = tf.reshape(self.h_pool, [max(sequence_lengths), num_filters_total])

        # Add dropout
        with tf.name_scope("dropout"):
            # casted = tf.cast(self.dropout_keep_prob, tf.int32)
            self.h_drop = tf.nn.dropout(self.h_pool_flat, self.dropout_keep_prob)
            self.h_drop = tf.reshape(self.h_drop, [-1, num_filters_total])

        # Do raw predictions (no softmax)
        with tf.name_scope("output"):
            W = tf.Variable(tf.truncated_normal([num_filters_total, num_classes], stddev=0.1), name="W")
            b = tf.Variable(tf.constant(0.1, shape=[num_classes]), name="b")
            # xw_plus_b(...) is just Wx + b matmul alias
            self.scores = tf.nn.xw_plus_b(self.h_drop, W, b, name="scores")
            self.predictions = tf.argmax(self.scores, 1, name="predictions")

        # Calculate mean cross-entropy loss
        with tf.name_scope("loss"):
            # softmax_cross_entropy_with_logits(...) calculates cross-entropy loss
            losses = tf.nn.softmax_cross_entropy_with_logits(self.scores, self.input_y)
            '''print("here")
            print(losses.get_shape())
            print(self.scores.get_shape())
            print(self.input_y.get_shape())'''
            self.loss = tf.reduce_mean(losses)

        # Calculate accuracy
        with tf.name_scope("accuracy"):
            correct_predictions = tf.equal(self.predictions, tf.argmax(self.input_y, 1))
            self.accuracy = tf.reduce_mean(tf.cast(correct_predictions, "float"), name="accuracy")
我使用的是有标签的数据集。我当前遇到的错误是:

InvalidArgumentError (see above for traceback): input[1,0] mismatch: 5888 vs. 4864
     [[Node: gradients/concat_grad/ConcatOffset = ConcatOffset[N=3, _device="/job:localhost/replica:0/task:0/cpu:0"](concat/concat_dim, gradients/concat_grad/ShapeN, gradients/concat_grad/ShapeN:1, gradients/concat_grad/ShapeN:2)]]
如何修复此代码,以便在合并后(同时保持合并动态)将所有张量规格化为相同的大小,并使代码运行到完成?


对不起,所有的随机评论行和打印和东西,但我已经广泛地尝试使这项工作

这里有三件事需要注意

  • max pooling
    k-max pooling
    是两种不同的操作 最大池从池窗口检索最大值激活,而k-max池从池窗口检索k个最大值

  • Tensorflow目前还没有为k-max池提供API。那个 您现在尝试的是最大池操作,而不是k-max 池操作

  • 据我所知,tensorflow不提供处理导致矩阵大小不同的池的功能。因此,您可以使用和使用k-max池


  • 尽管tensorflow不直接提供k-max池,但我认为tf.nn.top_k可能会帮助您构建该op。

    检查此问题以了解keras实现
    InvalidArgumentError (see above for traceback): input[1,0] mismatch: 5888 vs. 4864
         [[Node: gradients/concat_grad/ConcatOffset = ConcatOffset[N=3, _device="/job:localhost/replica:0/task:0/cpu:0"](concat/concat_dim, gradients/concat_grad/ShapeN, gradients/concat_grad/ShapeN:1, gradients/concat_grad/ShapeN:2)]]