# Path: baselines/deepq/prediction/tfacvp/tf_ops.py
# def ReLu(x, name, reuse=False):
#     with tf.variable_scope(name, reuse=reuse) as scope:
#         l = tf.nn.relu(x)
#     return l
# 
# def Conv2D(x, filter_shape, out_dim, strides, padding, name, reuse=False):
#     # x: input tensor (float32)[n, w, h, c]
#     # filter_shape: conv2d filter (int)[w, h]
#     # out_dim: output channels (int)
#     # strides: conv2d stride size (int)
#     # padding: padding type (str)
#     # name: variable scope (str)
#            
#     with tf.variable_scope(name, reuse=reuse) as scope:
#         in_dim = x.get_shape()[-1]
#         w = tf.get_variable('w', shape=filter_shape + [in_dim, out_dim], initializer=tf.contrib.layers.xavier_initializer_conv2d(uniform=True))
#         b = tf.get_variable('b', shape=[out_dim], initializer=tf.constant_initializer(0.0))
#         l = tf.nn.conv2d(x, w, strides=[1, strides, strides, 1], padding=padding, name='conv2d')
#         l = tf.nn.bias_add(l, b, name='bias_add')
#     return l
# 
# def FC(x, out_dim, name, initializer=tf.contrib.layers.xavier_initializer(uniform=True), reuse=False):
#     # x: input tensor (float32)[n, in_dim]
#     # out_dim: output channels (int)
#     # name: variable scope (str)
# 
#     x = tf.contrib.layers.flatten(x)
#     with tf.variable_scope(name, reuse=reuse) as scope:
#         in_dim = x.get_shape()[-1]
#         w = tf.get_variable('w', shape=[in_dim, out_dim], initializer=initializer)
#         b = tf.get_variable('b', shape=[out_dim], initializer=tf.constant_initializer(0.0))
#         l = tf.add(tf.matmul(x, w), b, name='add')
#     return l
# 
# def Deconv2D(x, filter_shape, output_shape, out_dim, strides, padding, name, reuse=False):
#     # x: input tensor (float32) [n, w, h, c]
#     # filter_shape: conv2d filter (int)[w, h]
#     # out_dim: output channels (int)
#     # strides: conv2d stride size (int)
#     # padding: padding type (str)
#     # name: variable scope (str)
# 
#     with tf.variable_scope(name, reuse=reuse) as scope:
#         in_dim = x.get_shape()[-1]
#         w = tf.get_variable('w', shape=filter_shape + [out_dim, in_dim], initializer=tf.contrib.layers.xavier_initializer_conv2d(uniform=True))
#         b = tf.get_variable('b', shape=[out_dim], initializer=tf.constant_initializer(0.0))
#         l = tf.nn.conv2d_transpose(x, w, output_shape=output_shape, strides=[1, strides, strides, 1], padding=padding, name='deconv2d')
#         l = tf.nn.bias_add(l, b, name='bias_add')
#     return l


import tensorflow as tf
import numpy as np
import re
from .tf_ops import ReLu, Conv2D, FC, Deconv2D

        if self.is_train:
            self._create_optimizer()
        if with_summary:
            self._create_summary()

    def _create_input(self, inputs):
        # inputs: if None, use tf.placeholder as input
        #         if not None, expected inputs is a dict
        if inputs == None:
            self.inputs = {'s_t': tf.placeholder(dtype=tf.float32, shape=[None, 84, 84, (NUM_CHANNELS * NUM_FRAMES)]),
                       'a_t': tf.placeholder(dtype=tf.int32, shape=[None, self.num_act]),
                       'x_t_1': tf.placeholder(dtype=tf.float32, shape=[None, 84, 84, (NUM_CHANNELS)])}
        else:
            assert type(inputs) is dict
            self.inputs = inputs

    def _create_model(self):
        self.encode = self._create_encoder(self.inputs['s_t'])
        self.act_embed = self._create_action_embedding(self.inputs['a_t'])
        self.decode = self._create_decoder(self.encode, self.act_embed)

    def _create_output(self):
        self.output = self.decode

    def _create_loss(self):
        lamb = self.loss_args['lamb'] if self.loss_args else 0.0
        with tf.variable_scope('loss', reuse=not self.is_train) as scope:
            t = self.inputs['x_t_1']
            penalty = tf.reduce_sum(lamb * tf.stack([tf.nn.l2_loss(var) for var in tf.trainable_variables()]), name='regularization')

# Path: baselines/deepq/prediction/tfacvp/tf_ops.py
# def ReLu(x, name, reuse=False):
#     with tf.variable_scope(name, reuse=reuse) as scope:
#         l = tf.nn.relu(x)
#     return l
# 
# def Conv2D(x, filter_shape, out_dim, strides, padding, name, reuse=False):
#     # x: input tensor (float32)[n, w, h, c]
#     # filter_shape: conv2d filter (int)[w, h]
#     # out_dim: output channels (int)
#     # strides: conv2d stride size (int)
#     # padding: padding type (str)
#     # name: variable scope (str)
#            
#     with tf.variable_scope(name, reuse=reuse) as scope:
#         in_dim = x.get_shape()[-1]
#         w = tf.get_variable('w', shape=filter_shape + [in_dim, out_dim], initializer=tf.contrib.layers.xavier_initializer_conv2d(uniform=True))
#         b = tf.get_variable('b', shape=[out_dim], initializer=tf.constant_initializer(0.0))
#         l = tf.nn.conv2d(x, w, strides=[1, strides, strides, 1], padding=padding, name='conv2d')
#         l = tf.nn.bias_add(l, b, name='bias_add')
#     return l
# 
# def FC(x, out_dim, name, initializer=tf.contrib.layers.xavier_initializer(uniform=True), reuse=False):
#     # x: input tensor (float32)[n, in_dim]
#     # out_dim: output channels (int)
#     # name: variable scope (str)
# 
#     x = tf.contrib.layers.flatten(x)
#     with tf.variable_scope(name, reuse=reuse) as scope:
#         in_dim = x.get_shape()[-1]
#         w = tf.get_variable('w', shape=[in_dim, out_dim], initializer=initializer)
#         b = tf.get_variable('b', shape=[out_dim], initializer=tf.constant_initializer(0.0))
#         l = tf.add(tf.matmul(x, w), b, name='add')
#     return l
# 
# def Deconv2D(x, filter_shape, output_shape, out_dim, strides, padding, name, reuse=False):
#     # x: input tensor (float32) [n, w, h, c]
#     # filter_shape: conv2d filter (int)[w, h]
#     # out_dim: output channels (int)
#     # strides: conv2d stride size (int)
#     # padding: padding type (str)
#     # name: variable scope (str)
# 
#     with tf.variable_scope(name, reuse=reuse) as scope:
#         in_dim = x.get_shape()[-1]
#         w = tf.get_variable('w', shape=filter_shape + [out_dim, in_dim], initializer=tf.contrib.layers.xavier_initializer_conv2d(uniform=True))
#         b = tf.get_variable('b', shape=[out_dim], initializer=tf.constant_initializer(0.0))
#         l = tf.nn.conv2d_transpose(x, w, output_shape=output_shape, strides=[1, strides, strides, 1], padding=padding, name='deconv2d')
#         l = tf.nn.bias_add(l, b, name='bias_add')
#     return l


# Path: baselines/deepq/prediction/tfacvp/old_model.py
import tensorflow as tf
import numpy as np
import re
from .tf_ops import ReLu, Conv2D, FC, Deconv2D


        if self.is_train:
            self._create_optimizer()
        if with_summary:
            self._create_summary()

    def _create_input(self, inputs):
        # inputs: if None, use tf.placeholder as input
        #         if not None, expected inputs is a dict
        if inputs == None:
            self.inputs = {'s_t': tf.placeholder(dtype=tf.float32, shape=[None, 84, 84, (NUM_CHANNELS * NUM_FRAMES)]),
                       'a_t': tf.placeholder(dtype=tf.int32, shape=[None, self.num_act]),
                       'x_t_1': tf.placeholder(dtype=tf.float32, shape=[None, 84, 84, (NUM_CHANNELS)])}
        else:
            assert type(inputs) is dict
            self.inputs = inputs

    def _create_model(self):
        self.encode = self._create_encoder(self.inputs['s_t'])
        self.act_embed = self._create_action_embedding(self.inputs['a_t'])
        self.decode = self._create_decoder(self.encode, self.act_embed)

    def _create_output(self):
        self.output = self.decode

    def _create_loss(self):
        lamb = self.loss_args['lamb'] if self.loss_args else 0.0
        with tf.variable_scope('loss', reuse=not self.is_train) as scope:
            t = self.inputs['x_t_1']
            penalty = tf.reduce_sum(lamb * tf.stack([tf.nn.l2_loss(var) for var in tf.trainable_variables()]), name='regularization')

            self.loss = tf.reduce_mean(tf.nn.l2_loss(self.output - t, name='l2') + penalty)