Лес дерева глубоких решений: AxisEreror: ось 1 выходит за границы массива измерения 1 - PullRequest
0 голосов
/ 17 февраля 2020

return ufun c .reduce (obj, axis, dtype, out, ** passkwargs) AxisError: ось 1 выходит за границы массива измерения 1

DEPTH = 3  # Depth of a tree
N_LEAF = 2 ** (DEPTH + 1)  # Number of leaf node
N_LABEL = 10  # Number of classes
N_TREE = 5  # Number of trees (ensemble)
N_BATCH = 128  # Number of data points per mini-batch
num_epochs = 1
def init_weights(shape):
    return tf.Variable(tf.random_normal(shape, stddev=0.01))

def init_prob_weights(shape, minval=-5, maxval=5):
    return tf.Variable(tf.random_uniform(shape, minval, maxval))

Модель; Создайте лес и верните выходные данные леса нейронных решений:

    decision_p_e: decision node routing probability for all ensemble
        If we number all nodes in the tree sequentially from top to bottom,
        left to right, decision_p contains
        [d(0), d(1), d(2), ..., d(2^n - 2)] where d(1) is the probability
        of going left at the root node, d(2) is that of the left child of
        the root node.
def model(X, w, w2, w3, w4_e, w_d_e, w_l_e, p_keep_conv, p_keep_hidden):



    assert (len(w4_e) == len(w_d_e))
    assert (len(w4_e) == len(w_l_e))

    l1a = tf.nn.relu(tf.nn.conv2d(X, w, [1, 1, 1, 1], 'SAME'))
    l1 = tf.nn.max_pool(l1a, ksize=[1, 2, 2, 1],
                        strides=[1, 2, 2, 1], padding='SAME')
    l1 = tf.nn.dropout(l1, p_keep_conv)

    l2a = tf.nn.relu(tf.nn.conv2d(l1, w2, [1, 1, 1, 1], 'SAME'))
    l2 = tf.nn.max_pool(l2a, ksize=[1, 2, 2, 1],
                        strides=[1, 2, 2, 1], padding='SAME')
    l2 = tf.nn.dropout(l2, p_keep_conv)

    l3a = tf.nn.relu(tf.nn.conv2d(l2, w3, [1, 1, 1, 1], 'SAME'))
    l3 = tf.nn.max_pool(l3a, ksize=[1, 2, 2, 1],
                        strides=[1, 2, 2, 1], padding='SAME')

    l3 = tf.reshape(l3, [-1, w4_e[0].get_shape().as_list()[0]])
    l3 = tf.nn.dropout(l3, p_keep_conv)

    decision_p_e = []
    leaf_p_e = []
    for w4, w_d, w_l in zip(w4_e, w_d_e, w_l_e):
        l4 = tf.nn.relu(tf.matmul(l3, w4))
        l4 = tf.nn.dropout(l4, p_keep_hidden)

        decision_p = tf.nn.sigmoid(tf.matmul(l4, w_d))
        leaf_p = tf.nn.softmax(w_l)

        decision_p_e.append(decision_p)
        leaf_p_e.append(leaf_p)

    return decision_p_e, leaf_p_e

Основной класс

class TFRandomForestTrain(ClassifierNeuralNetwork, ClassifierGradients, Classifier):
    def __init__(self, batch_0_indices, session, num_classes, defences=None, channel_index=3, clip_values=None,
                 preprocessing=(0, 1)):
        import tensorflow as tf
        if tf.__version__[0] == '2':
            import tensorflow.compat.v1 as tf
            tf.disable_eager_execution()
        super(TFRandomForestTrain, self).__init__(clip_values=clip_values,
                                                  channel_index=channel_index,
                                                  preprocessing=preprocessing,
                                                  defences=defences)

        self.session = session
        self.num_classes = num_classes
    Input X, output Y
        self.X = tf.placeholder("float", [N_BATCH, 28, 28, 1], name='X')
        self.Y = tf.placeholder("float", [N_BATCH, N_LABEL], name='Y')

Инициализация веса

       self.w = init_weights([3, 3, 1, 32])
       self.w2 = init_weights([3, 3, 32, 64])
       self.w3 = init_weights([3, 3, 64, 128])

       self.w4_ensemble = []
       self.w_d_ensemble = []
       self.w_l_ensemble = []
       for i in range(N_TREE):
           self.w4_ensemble.append(init_weights([128 * 4 * 4, 625]))
           self.w_d_ensemble.append(init_prob_weights([625, N_LEAF], -1, 1))
           self.w_l_ensemble.append(init_prob_weights([N_LEAF, N_LABEL], -2, 2))

       self.p_keep_conv = tf.placeholder("float")
       self.p_keep_hidden = tf.placeholder("float")


       # With the probability decision_p, route a sample to the right branch
       self.decision_p_e, self.leaf_p_e = model(self.X, self.w, self.w2, self.w3, self.w4_ensemble, self.w_d_ensemble,
                                                self.w_l_ensemble, self.p_keep_conv, self.p_keep_hidden)

       self.flat_decision_p_e = []

       # iterate over each tree
       for decision_p in self.decision_p_e:
           # Compute the complement of d, which is 1 - d
           # where d is the sigmoid of fully connected output
           decision_p_comp = tf.subtract(tf.ones_like(decision_p), decision_p)

           # Concatenate both d, 1-d
           decision_p_pack = tf.stack([decision_p, decision_p_comp])

           # Flatten/vectorize the decision probabilities for efficient indexing
           self.flat_decision_p = tf.reshape(decision_p_pack, [-1])
           self.flat_decision_p_e.append(self.flat_decision_p)

Инициализация переменных

        in_repeat = N_LEAF / 2
        out_repeat = N_BATCH
        # N_LEAF = float(N_LEAF)
        # N_BATCH = float(N_BATCH)
        # Let N_BATCH * N_LEAF be N_D. flat_decision_p[N_D] will return 1-d of the
        # first root node in the first tree.
        batch_complement_indices = \
            np.array([[0] * int(in_repeat), [N_BATCH * N_LEAF] * int(in_repeat)]
                     * out_repeat).reshape(N_BATCH, N_LEAF)

        # First define the routing probabilities d for root nodes
        self.mu_e = []

        # iterate over each tree
        for i, flat_decision_p in enumerate(self.flat_decision_p_e):
            mu = tf.gather(flat_decision_p,
                           tf.add(batch_0_indices, batch_complement_indices))
            self.mu_e.append(mu)

        # from the second layer to the last layer, we make the decision nodes
        for d in range(1, DEPTH + 1):
            indices = tf.range(2 ** d, 2 ** (d + 1)) - 1
            tile_indices = tf.reshape(tf.tile(tf.expand_dims(indices, 1),
                                              [1, 2 ** (DEPTH - d + 1)]), [1, -1])
            batch_indices = tf.add(batch_0_indices, tf.tile(tile_indices, [N_BATCH, 1]))

            in_repeat = in_repeat / 2
            out_repeat = out_repeat * 2

            # Again define the indices that picks d and 1-d for the node
            batch_complement_indices = \
                np.array([[0] * int(in_repeat), [N_BATCH * N_LEAF] * int(in_repeat)]
                         * out_repeat).reshape(N_BATCH, N_LEAF)

            mu_e_update = []
            for mu, flat_decision_p in zip(self.mu_e, self.flat_decision_p_e):
                mu = tf.multiply(mu, tf.gather(flat_decision_p,
                                               tf.add(batch_indices, batch_complement_indices)))
                mu_e_update.append(mu)

            self.mu_e = mu_e_update


        self.py_x_e = []
        for mu, leaf_p in zip(self.mu_e, self.leaf_p_e):
            # average all the leaf p
            py_x_tree = tf.reduce_mean(
                tf.multiply(tf.tile(tf.expand_dims(mu, 2), [1, 1, N_LABEL]),
                            tf.tile(tf.expand_dims(leaf_p, 0), [N_BATCH, 1, 1])), 1)
            self.py_x_e.append(py_x_tree)

        self.py_x_e = tf.stack(self.py_x_e)
        self.py_x = tf.reduce_mean(self.py_x_e, 0)
    Define cost and optimization method 
        # cross entropy loss
        self.cost = tf.reduce_mean(-tf.multiply(tf.log(self.py_x), self.Y))

        # cost = tf.reduce_mean(tf.nn.cross_entropy_with_logits(py_x, Y))
        self.train_step = tf.train.AdamOptimizer(0.001, 0.9).minimize(self.cost)
        self.predict_tensor = tf.argmax(self.py_x, 1)   

    def fit(self, trX, trY, teX, teY, tr_p_keep_conv=0.8, tr_p_keep_hidden=0.5, te_p_keep_conv=1.0,
            te_p_keep_hidden=1.0, num_epochs=num_epochs):
        self.session.run(tf.initialize_all_variables())
        for i in range(num_epochs):
            # One epoch
            for start, end in zip(range(0, len(trX), N_BATCH), range(N_BATCH, len(trX), N_BATCH)):
                self.session.run(self.train_step, feed_dict={self.X: trX[start:end], self.Y: trY[start:end],
                                                             self.p_keep_conv: tr_p_keep_conv,
                                                             self.p_keep_hidden: tr_p_keep_hidden})

            # Result on the test set
            results = []
            for start, end in zip(range(0, len(teX), N_BATCH), range(N_BATCH, len(teX), N_BATCH)):
                results.extend(np.argmax(teY[start:end], axis=1) ==
                               self.session.run(self.predict_tensor,
                                                feed_dict={self.X: teX[start:end], self.p_keep_conv: te_p_keep_conv,
                                                           self.p_keep_hidden: te_p_keep_hidden}))
                print('Epoch: %d, Test Accuracy: %f' % (i + 1, np.mean(results)))

    def _predict(self, X, te_p_keep_conv, te_p_keep_hidden, batch_size=N_BATCH):
        for start, end in zip(range(0, len(X), batch_size), range(batch_size, len(X), batch_size)):
            results = self.session.run(self.predict_tensor, feed_dict={self.X: X[start:end],
                                                                       self.p_keep_conv: te_p_keep_conv,
                                                                       self.p_keep_hidden: te_p_keep_hidden})
            yield results

    def predict(self, X, te_p_keep_conv=1.0, te_p_keep_hidden=1.0, batch_size=N_BATCH, **kwargs):
        predictions = []
        for preds in self._predict(X, te_p_keep_conv, te_p_keep_hidden, batch_size=N_BATCH):
            predictions.extend(preds)
        #predictions = np.array(predictions)
        return predictions


    @property
    def layer_names(self):
        pass

    def get_activations(self, x, layer, batch_size):
        pass

    def set_learning_phase(self, train):
        pass

    def class_gradient(self, x, label=None, **kwargs):
        pass

    def loss_gradient(self, x, y, **kwargs):
        pass

    def nb_classes(self):
        return self.num_classes

    def save(self, filename, path=None):
        pass

Мы обучили модель на наборе данных MNIST

if __name__ == '__main__':

    # Load dataset

    mnist = input_data.read_data_sets("MNIST/", one_hot=True)
    trX, trY = mnist.train.images, mnist.train.labels
    teX, teY = mnist.test.images, mnist.test.labels

    #from art.utils import load_mnist
    #(trX, trY), (teX, teY), min_pixel_value, max_pixel_value = load_mnist()
    trX = trX.reshape(-1, 28, 28, 1)
    teX = teX.reshape(-1, 28, 28, 1)

    # Create session
    sess = tf.Session()
    sess.run(tf.initialize_all_variables())

    # 0 index of each data instance in a mini-batch
    batch_0_indices = \
        tf.tile(tf.expand_dims(tf.range(0, N_BATCH * N_LEAF, N_LEAF), 1),
                [1, N_LEAF])

    classifier = TFRandomForestTrain(batch_0_indices, session=sess, num_classes=10)
    classifier.fit(trX=trX, trY=trY, teX=teX, teY=teY)



    # To predict, first get the X and then feed it to the predict function
    predictions = classifier.predict(teX)
    print(f'Number of predictions: {len(predictions)}')
    ```

      return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
    AxisEreror: axis 1 is out of bounds for array of dimension 1

Ошибка начинается со строки ниже

    attack = FastGradientMethod(classifier=classifier, eps=0.2)
    x_test_adv = attack.generate(x=teX)

    return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
    AxisError: axis 1 is out of bounds for array of dimension 1```



...