//  [python]
def _build_sampler(self):
        """Build the sampler ops and the log_prob ops.

        For sampler, the architecture sequence is randomly sampled, and only sample one architecture at each call to
        fill in self.sample_arc
        """
        anchors = []
        anchors_w_1 = []

        arc_seq = []
        hidden_states = []
        entropys = []
        probs_ = []
        log_probs = []
        skip_count = []
        skip_penaltys = []

        prev_c = [tf.zeros([1, self.lstm_size], tf.float32) for _ in
                  range(self.lstm_num_layers)]
        prev_h = [tf.zeros([1, self.lstm_size], tf.float32) for _ in
                  range(self.lstm_num_layers)]

        inputs = self.g_emb
        skip_targets = tf.constant([1.0 - self.skip_target, self.skip_target],
                                   dtype=tf.float32)
        skip_conn_record = []

        for layer_id in range(self.num_layers):
            # STEP 1: for each layer, sample operations first
            next_c, next_h = stack_lstm(inputs, prev_c, prev_h, self.w_lstm)
            prev_c, prev_h = next_c, next_h
            hidden_states.append(prev_h)

            logit = tf.matmul(next_h[-1], self.w_soft["start"][layer_id])  # out_filter x 1
            if self.temperature is not None:
                logit /= self.temperature
            if self.tanh_constant is not None:
                logit = self.tanh_constant * tf.tanh(logit)
            probs_.append(tf.nn.softmax(logit))
            start = tf.random.categorical(logit, 1)
            start = tf.to_int32(start)
            start = tf.reshape(start, [1])
            arc_seq.append(start)
            log_prob = tf.nn.sparse_softmax_cross_entropy_with_logits(
                logits=logit, labels=start)
            log_probs.append(log_prob)
            entropy = tf.stop_gradient(log_prob * tf.exp(-log_prob))
            entropys.append(entropy)
            # inputs: get a row slice of [out_filter[i], lstm_size]
            inputs = tf.nn.embedding_lookup(self.w_emb["start"][layer_id], start)
            # END STEP 1

            # STEP 2: sample the connections, unless the first layer
            # the number `skip` of each layer grows as layer_id grows
            if self.with_skip_connection:
                if layer_id > 0:
                    next_c, next_h = stack_lstm(inputs, prev_c, prev_h, self.w_lstm)
                    prev_c, prev_h = next_c, next_h
                    hidden_states.append(prev_h)

                    query = tf.concat(anchors_w_1, axis=0)  # layer_id x lstm_size
                    # w_attn_2: lstm_size x lstm_size
                    query = tf.tanh(query + tf.matmul(next_h[-1], self.w_attn_2))  # query: layer_id x lstm_size
                    # P(Layer j is an input to layer i) = sigmoid(v^T %*% tanh(W_prev ∗ h_j + W_curr ∗ h_i))
                    query = tf.matmul(query, self.v_attn)  # query: layer_id x 1
                    if self.skip_connection_unique_connection:
                        mask = tf.stop_gradient(tf.reduce_sum(tf.stack(skip_conn_record), axis=0))
                        mask = tf.slice(mask, begin=[0], size=[layer_id])
                        mask1 = tf.greater(mask, 0)
                        query = tf.where(mask1, y=query, x=tf.fill(tf.shape(query), -10000.))
                    logit = tf.concat([-query, query], axis=1)  # logit: layer_id x 2
                    if self.temperature is not None:
                        logit /= self.temperature
                    if self.tanh_constant is not None:
                        logit = self.tanh_constant * tf.tanh(logit)

                    probs_.append(tf.expand_dims(tf.nn.softmax(logit), axis=0))
                    skip = tf.random.categorical(logit, 1)  # layer_id x 1 of booleans
                    skip = tf.to_int32(skip)
                    skip = tf.reshape(skip, [layer_id])
                    arc_seq.append(skip)
                    skip_conn_record.append(
                        tf.concat([tf.cast(skip, tf.float32), tf.zeros(self.num_layers - layer_id)], axis=0))

                    skip_prob = tf.sigmoid(logit)
                    kl = skip_prob * tf.log(skip_prob / skip_targets)
                    kl = tf.reduce_sum(kl)
                    skip_penaltys.append(kl)

                    log_prob = tf.nn.sparse_softmax_cross_entropy_with_logits(
                        logits=logit, labels=skip)
                    log_probs.append(tf.reshape(tf.reduce_sum(log_prob), [-1]))

                    entropy = tf.stop_gradient(
                        tf.reshape(tf.reduce_sum(log_prob * tf.exp(-log_prob)), [-1]))
                    entropys.append(entropy)

                    skip = tf.to_float(skip)
                    skip = tf.reshape(skip, [1, layer_id])
                    skip_count.append(tf.reduce_sum(skip))
                    inputs = tf.matmul(skip, tf.concat(anchors, axis=0))
                    inputs /= (1.0 + tf.reduce_sum(skip))
                else:
                    skip_conn_record.append(tf.zeros(self.num_layers, 1))

                anchors.append(next_h[-1])
                # next_h: 1 x lstm_size
                # anchors_w_1: 1 x lstm_size
                anchors_w_1.append(tf.matmul(next_h[-1], self.w_attn_1))
                # added Sep.28.2019; removed as inputs for next layer, Nov.21.2019
                # next_c, next_h = stack_lstm(inputs, prev_c, prev_h, self.w_lstm)
                # prev_c, prev_h = next_c, next_h
                # hidden_states.append(prev_h)

            # END STEP 2

        # for DEBUG use
        self.anchors = anchors
        self.anchors_w_1 = anchors_w_1
        self.sample_hidden_states = hidden_states

        # for class attr.
        arc_seq = tf.concat(arc_seq, axis=0)
        self.sample_arc = tf.reshape(arc_seq, [-1])
        entropys = tf.stack(entropys)
        self.sample_entropy = tf.reduce_sum(entropys)
        log_probs = tf.stack(log_probs)
        self.sample_log_prob = tf.reduce_sum(log_probs)
        skip_count = tf.stack(skip_count)
        self.skip_count = tf.reduce_sum(skip_count)
        skip_penaltys = tf.stack(skip_penaltys)
        self.skip_penaltys = tf.reduce_mean(skip_penaltys)
        self.sample_probs = probs_