<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def revnet(inputs, hparams, reuse=None):
 """Uses Tensor2Tensor memory optimized RevNet block to build a RevNet. Args: inputs: [NxHxWx3] tensor of input images to the model. hparams: HParams object that contains the following parameters, in addition to the parameters contained in the basic_params1() object in the common_hparams module: num_channels_first - A Python list where each element represents the depth of the first and third convolutional layers in the bottleneck residual unit for a given block. num_channels_second - A Python list where each element represents the depth of the second convolutional layer in the bottleneck residual unit for a given block. num_layers_per_block - A Python list containing the number of RevNet layers for each block. first_batch_norm - A Python list containing booleans representing the presence of a batch norm layer at the beginning of a given block. strides - A Python list containing integers representing the stride of the residual function for each block. num_channels_init_block - An integer representing the number of channels for the convolutional layer in the initial block. dimension - A string (either "2d" or "3d") that decides if the RevNet is 2-dimensional or 3-dimensional. reuse: Whether to reuse the default variable scope. Returns: [batch_size, hidden_dim] pre-logits tensor from the bottleneck RevNet. """

  training = hparams.mode == tf.estimator.ModeKeys.TRAIN
  with tf.variable_scope('RevNet', reuse=reuse):
    x1, x2 = init(inputs,
                  num_channels=hparams.num_channels_init_block,
                  dim=hparams.dim,
                  kernel_size=hparams.init_kernel_size,
                  maxpool=hparams.init_maxpool,
                  stride=hparams.init_stride,
                  training=training)
    for block_num in range(len(hparams.num_layers_per_block)):
      block = {'depth': hparams.num_channels[block_num],
               'num_layers': hparams.num_layers_per_block[block_num],
               'first_batch_norm': hparams.first_batch_norm[block_num],
               'stride': hparams.strides[block_num],
               'bottleneck': hparams.bottleneck}
      x1, x2 = unit(x1, x2, block_num, dim=hparams.dim, training=training,
                    **block)
    pre_logits = final_block(x1, x2, dim=hparams.dim, training=training)
    return pre_logits