# -*- coding:utf-8 -*-
import tensorflow as tf


class CNN:

    def __init__(self, save_or_load_path=None, trainable=True, learning_rate = 0.00002,timestep=9,road=189,predstep=1):
        self.trainable = trainable
        self.learning_rate = learning_rate
        self.road = road
        self.input_size = timestep * road
        self.output_size = predstep * road
        self.bottom = tf.placeholder(tf.float32, shape=[None, self.input_size], name='input')  # 25*2*6
        self.target = tf.placeholder(tf.float32, shape=[None, self.output_size], name='target')
        self.timestep = timestep

    def weight_variable(self,shape):
        initial = tf.truncated_normal(shape, stddev=0.1)
        return tf.Variable(initial)

    def bias_variable(self,shape):
        initial = tf.truncated_normal(shape, stddev=0.1)
        return initial

    def conv2d(self,x, W):
        return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

    def conv1d(self,x, W):
        return tf.nn.conv1d(x, W, stride=2, padding='SAME')

    def max_pool_2x2(self,x):
        return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')

    def build_CNN(self, ):

        # conv first
        bottom = tf.reshape(self.bottom, [-1, self.road, self.timestep, 1])
        W_conv1 = self.weight_variable([3, 3, 1, 64])
        b_conv1 = self.bias_variable([64])
        h_conv1 = tf.nn.elu(self.conv2d(bottom, W_conv1) + b_conv1)
        h_pool1 = self.max_pool_2x2(h_conv1)

        h_flat3 = tf.reshape(h_pool1, [-1, 95 * 5 * 64])
        W_fc2 = self.weight_variable([95 * 5  * 64, 1200])
        b_fc2 = self.bias_variable([1200])
        h = tf.nn.elu(tf.matmul(h_flat3, W_fc2) + b_fc2)
        # h_flat3 = tf.reshape(h_pool3, [-1, 400])
        W_fc2 = self.weight_variable([1200, self.output_size])
        b_fc2 = self.bias_variable([self.output_size])
        self.predict = tf.nn.elu(tf.matmul(h, W_fc2) + b_fc2)


        global_step = tf.Variable(0, trainable=False)
        self.learning_rate = 0.0002 #tf.train.exponential_decay(0.001,  global_step,  500, 0.9,staircase=True)
        self.loss = tf.reduce_mean(tf.squared_difference(self.target, self.predict))
        self.accuracy = 1. - tf.reduce_mean(abs(self.target-self.predict)/self.target)
        self.trainop = tf.train.AdamOptimizer(self.learning_rate).minimize(self.loss, global_step=global_step)
        # self.trainop = tf.train.RMSPropOptimizer(self.learning_rate, 0.99, 0.0, 1e-6).minimize(self.loss)
        return self.predict



class CNN15:
    def __init__(self, save_or_load_path=None, trainable=True, learning_rate = 0.00002,timestep=9,road=189,predstep=3):
        self.trainable = trainable
        self.learning_rate = learning_rate
        self.road = road
        self.input_size = timestep * road
        self.output_size = predstep * road
        self.bottom = tf.placeholder(tf.float32, shape=[None, self.input_size], name='input')  # 25*2*6
        self.target = tf.placeholder(tf.float32, shape=[None, self.output_size], name='target')
        self.timestep = timestep

    def weight_variable(self,shape):
        initial = tf.truncated_normal(shape, stddev=0.1)
        return tf.Variable(initial)

    def bias_variable(self,shape):
        initial = tf.truncated_normal(shape, stddev=0.1)
        return initial

    def conv2d(self,x, W):
        return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

    def conv1d(self,x, W):
        return tf.nn.conv1d(x, W, stride=2, padding='SAME')

    def max_pool_2x2(self,x):
        return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')

    def build_CNN(self, ):

        # conv first
        bottom = tf.reshape(self.bottom, [-1, self.road, self.timestep, 1])
        W_conv1 = self.weight_variable([3, 3, 1, 64])
        b_conv1 = self.bias_variable([64])
        h_conv1 = tf.nn.elu(self.conv2d(bottom, W_conv1) + b_conv1)
        h_pool1 = self.max_pool_2x2(h_conv1)

        h_flat3 = tf.reshape(h_pool1, [-1, 95 * 5 * 64])
        W_fc2 = self.weight_variable([95 * 5  * 64, 1200])
        b_fc2 = self.bias_variable([1200])
        h = tf.nn.elu(tf.matmul(h_flat3, W_fc2) + b_fc2)
        # h_flat3 = tf.reshape(h_pool3, [-1, 400])
        W_fc2 = self.weight_variable([1200, self.output_size])
        b_fc2 = self.bias_variable([self.output_size])
        self.predict = tf.nn.elu(tf.matmul(h, W_fc2) + b_fc2)


        global_step = tf.Variable(0, trainable=False)
        self.learning_rate = 0.0002 #tf.train.exponential_decay(0.001,  global_step,  500, 0.9,staircase=True)
        self.loss = tf.reduce_mean(tf.squared_difference(self.target, self.predict))
        self.accuracy = 1. - tf.reduce_mean(abs(self.target-self.predict)/self.target)
        self.trainop = tf.train.AdamOptimizer(self.learning_rate).minimize(self.loss, global_step=global_step)
        # self.trainop = tf.train.RMSPropOptimizer(self.learning_rate, 0.99, 0.0, 1e-6).minimize(self.loss)
        return self.predict




class CNN30:
    def __init__(self, save_or_load_path=None, trainable=True, learning_rate=0.00002,timestep=9,road=189,predstep=6):
        self.trainable = trainable
        self.learning_rate = learning_rate
        self.road = road
        self.input_size = timestep * road
        self.output_size = predstep * road
        self.bottom = tf.placeholder(tf.float32, shape=[None, self.input_size], name='input')  # 25*2*6
        self.target = tf.placeholder(tf.float32, shape=[None, self.output_size], name='target')
        self.timestep = timestep

    def weight_variable(self,shape):
        initial = tf.truncated_normal(shape, stddev=0.1)
        return tf.Variable(initial)

    def bias_variable(self,shape):
        initial = tf.truncated_normal(shape, stddev=0.1)
        return initial

    def conv2d(self,x, W):
        return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

    def conv1d(self,x, W):
        return tf.nn.conv1d(x, W, stride=2, padding='SAME')

    def max_pool_2x2(self,x):
        return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')


    def build_CNN(self, ):
        # conv first
        bottom = tf.reshape(self.bottom, [-1, self.road, self.timestep, 1])
        W_conv1 = self.weight_variable([3, 3, 1, 64])
        b_conv1 = self.bias_variable([64])
        h_conv1 = tf.nn.elu(self.conv2d(bottom, W_conv1) + b_conv1)
        h_pool1 = self.max_pool_2x2(h_conv1)

        h_flat3 = tf.reshape(h_pool1, [-1, 95 * 5 * 64])
        W_fc2 = self.weight_variable([95 * 5 * 64, 1200])
        b_fc2 = self.bias_variable([1200])
        h = tf.nn.elu(tf.matmul(h_flat3, W_fc2) + b_fc2)
        # h_flat3 = tf.reshape(h_pool3, [-1, 400])
        W_fc2 = self.weight_variable([1200, self.output_size])
        b_fc2 = self.bias_variable([self.output_size])
        self.predict = tf.nn.elu(tf.matmul(h, W_fc2) + b_fc2)

        global_step = tf.Variable(0, trainable=False)
        self.learning_rate = 0.0002  # tf.train.exponential_decay(0.001,  global_step,  500, 0.9,staircase=True)
        self.loss = tf.reduce_mean(tf.squared_difference(self.target, self.predict))
        self.accuracy = 1. - tf.reduce_mean(abs(self.target - self.predict) / self.target)
        self.trainop = tf.train.AdamOptimizer(self.learning_rate).minimize(self.loss, global_step=global_step)
        # self.trainop = tf.train.RMSPropOptimizer(self.learning_rate, 0.99, 0.0, 1e-6).minimize(self.loss)
        return self.predict
[((391, 462), 'tensorflow.placeholder', 'tf.placeholder', (['tf.float32'], {'shape': '[None, self.input_size]', 'name': '"""input"""'}), "(tf.float32, shape=[None, self.input_size], name='input')\n", (405, 462), True, 'import tensorflow as tf\n'), ((495, 568), 'tensorflow.placeholder', 'tf.placeholder', (['tf.float32'], {'shape': '[None, self.output_size]', 'name': '"""target"""'}), "(tf.float32, shape=[None, self.output_size], name='target')\n", (509, 568), True, 'import tensorflow as tf\n'), ((658, 696), 'tensorflow.truncated_normal', 'tf.truncated_normal', (['shape'], {'stddev': '(0.1)'}), '(shape, stddev=0.1)\n', (677, 696), True, 'import tensorflow as tf\n'), ((712, 732), 'tensorflow.Variable', 'tf.Variable', (['initial'], {}), '(initial)\n', (723, 732), True, 'import tensorflow as tf\n'), ((787, 825), 'tensorflow.truncated_normal', 'tf.truncated_normal', (['shape'], {'stddev': '(0.1)'}), '(shape, stddev=0.1)\n', (806, 825), True, 'import tensorflow as tf\n'), ((892, 948), 'tensorflow.nn.conv2d', 'tf.nn.conv2d', (['x', 'W'], {'strides': '[1, 1, 1, 1]', 'padding': '"""SAME"""'}), "(x, W, strides=[1, 1, 1, 1], padding='SAME')\n", (904, 948), True, 'import tensorflow as tf\n'), ((992, 1036), 'tensorflow.nn.conv1d', 'tf.nn.conv1d', (['x', 'W'], {'stride': '(2)', 'padding': '"""SAME"""'}), "(x, W, stride=2, padding='SAME')\n", (1004, 1036), True, 'import tensorflow as tf\n'), ((1083, 1158), 'tensorflow.nn.max_pool', 'tf.nn.max_pool', (['x'], {'ksize': '[1, 2, 2, 1]', 'strides': '[1, 2, 2, 1]', 'padding': '"""SAME"""'}), "(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')\n", (1097, 1158), True, 'import tensorflow as tf\n'), ((1226, 1284), 'tensorflow.reshape', 'tf.reshape', (['self.bottom', '[-1, self.road, self.timestep, 1]'], {}), '(self.bottom, [-1, self.road, self.timestep, 1])\n', (1236, 1284), True, 'import tensorflow as tf\n'), ((1514, 1552), 'tensorflow.reshape', 'tf.reshape', (['h_pool1', '[-1, 95 * 5 * 64]'], {}), '(h_pool1, [-1, 95 * 5 * 64])\n', (1524, 1552), True, 'import tensorflow as tf\n'), ((1967, 1998), 'tensorflow.Variable', 'tf.Variable', (['(0)'], {'trainable': '(False)'}), '(0, trainable=False)\n', (1978, 1998), True, 'import tensorflow as tf\n'), ((2875, 2946), 'tensorflow.placeholder', 'tf.placeholder', (['tf.float32'], {'shape': '[None, self.input_size]', 'name': '"""input"""'}), "(tf.float32, shape=[None, self.input_size], name='input')\n", (2889, 2946), True, 'import tensorflow as tf\n'), ((2979, 3052), 'tensorflow.placeholder', 'tf.placeholder', (['tf.float32'], {'shape': '[None, self.output_size]', 'name': '"""target"""'}), "(tf.float32, shape=[None, self.output_size], name='target')\n", (2993, 3052), True, 'import tensorflow as tf\n'), ((3142, 3180), 'tensorflow.truncated_normal', 'tf.truncated_normal', (['shape'], {'stddev': '(0.1)'}), '(shape, stddev=0.1)\n', (3161, 3180), True, 'import tensorflow as tf\n'), ((3196, 3216), 'tensorflow.Variable', 'tf.Variable', (['initial'], {}), '(initial)\n', (3207, 3216), True, 'import tensorflow as tf\n'), ((3271, 3309), 'tensorflow.truncated_normal', 'tf.truncated_normal', (['shape'], {'stddev': '(0.1)'}), '(shape, stddev=0.1)\n', (3290, 3309), True, 'import tensorflow as tf\n'), ((3376, 3432), 'tensorflow.nn.conv2d', 'tf.nn.conv2d', (['x', 'W'], {'strides': '[1, 1, 1, 1]', 'padding': '"""SAME"""'}), "(x, W, strides=[1, 1, 1, 1], padding='SAME')\n", (3388, 3432), True, 'import tensorflow as tf\n'), ((3476, 3520), 'tensorflow.nn.conv1d', 'tf.nn.conv1d', (['x', 'W'], {'stride': '(2)', 'padding': '"""SAME"""'}), "(x, W, stride=2, padding='SAME')\n", (3488, 3520), True, 'import tensorflow as tf\n'), ((3567, 3642), 'tensorflow.nn.max_pool', 'tf.nn.max_pool', (['x'], {'ksize': '[1, 2, 2, 1]', 'strides': '[1, 2, 2, 1]', 'padding': '"""SAME"""'}), "(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')\n", (3581, 3642), True, 'import tensorflow as tf\n'), ((3710, 3768), 'tensorflow.reshape', 'tf.reshape', (['self.bottom', '[-1, self.road, self.timestep, 1]'], {}), '(self.bottom, [-1, self.road, self.timestep, 1])\n', (3720, 3768), True, 'import tensorflow as tf\n'), ((3998, 4036), 'tensorflow.reshape', 'tf.reshape', (['h_pool1', '[-1, 95 * 5 * 64]'], {}), '(h_pool1, [-1, 95 * 5 * 64])\n', (4008, 4036), True, 'import tensorflow as tf\n'), ((4451, 4482), 'tensorflow.Variable', 'tf.Variable', (['(0)'], {'trainable': '(False)'}), '(0, trainable=False)\n', (4462, 4482), True, 'import tensorflow as tf\n'), ((5358, 5429), 'tensorflow.placeholder', 'tf.placeholder', (['tf.float32'], {'shape': '[None, self.input_size]', 'name': '"""input"""'}), "(tf.float32, shape=[None, self.input_size], name='input')\n", (5372, 5429), True, 'import tensorflow as tf\n'), ((5462, 5535), 'tensorflow.placeholder', 'tf.placeholder', (['tf.float32'], {'shape': '[None, self.output_size]', 'name': '"""target"""'}), "(tf.float32, shape=[None, self.output_size], name='target')\n", (5476, 5535), True, 'import tensorflow as tf\n'), ((5625, 5663), 'tensorflow.truncated_normal', 'tf.truncated_normal', (['shape'], {'stddev': '(0.1)'}), '(shape, stddev=0.1)\n', (5644, 5663), True, 'import tensorflow as tf\n'), ((5679, 5699), 'tensorflow.Variable', 'tf.Variable', (['initial'], {}), '(initial)\n', (5690, 5699), True, 'import tensorflow as tf\n'), ((5754, 5792), 'tensorflow.truncated_normal', 'tf.truncated_normal', (['shape'], {'stddev': '(0.1)'}), '(shape, stddev=0.1)\n', (5773, 5792), True, 'import tensorflow as tf\n'), ((5859, 5915), 'tensorflow.nn.conv2d', 'tf.nn.conv2d', (['x', 'W'], {'strides': '[1, 1, 1, 1]', 'padding': '"""SAME"""'}), "(x, W, strides=[1, 1, 1, 1], padding='SAME')\n", (5871, 5915), True, 'import tensorflow as tf\n'), ((5959, 6003), 'tensorflow.nn.conv1d', 'tf.nn.conv1d', (['x', 'W'], {'stride': '(2)', 'padding': '"""SAME"""'}), "(x, W, stride=2, padding='SAME')\n", (5971, 6003), True, 'import tensorflow as tf\n'), ((6050, 6125), 'tensorflow.nn.max_pool', 'tf.nn.max_pool', (['x'], {'ksize': '[1, 2, 2, 1]', 'strides': '[1, 2, 2, 1]', 'padding': '"""SAME"""'}), "(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')\n", (6064, 6125), True, 'import tensorflow as tf\n'), ((6193, 6251), 'tensorflow.reshape', 'tf.reshape', (['self.bottom', '[-1, self.road, self.timestep, 1]'], {}), '(self.bottom, [-1, self.road, self.timestep, 1])\n', (6203, 6251), True, 'import tensorflow as tf\n'), ((6481, 6519), 'tensorflow.reshape', 'tf.reshape', (['h_pool1', '[-1, 95 * 5 * 64]'], {}), '(h_pool1, [-1, 95 * 5 * 64])\n', (6491, 6519), True, 'import tensorflow as tf\n'), ((6932, 6963), 'tensorflow.Variable', 'tf.Variable', (['(0)'], {'trainable': '(False)'}), '(0, trainable=False)\n', (6943, 6963), True, 'import tensorflow as tf\n'), ((2145, 2193), 'tensorflow.squared_difference', 'tf.squared_difference', (['self.target', 'self.predict'], {}), '(self.target, self.predict)\n', (2166, 2193), True, 'import tensorflow as tf\n'), ((4629, 4677), 'tensorflow.squared_difference', 'tf.squared_difference', (['self.target', 'self.predict'], {}), '(self.target, self.predict)\n', (4650, 4677), True, 'import tensorflow as tf\n'), ((7112, 7160), 'tensorflow.squared_difference', 'tf.squared_difference', (['self.target', 'self.predict'], {}), '(self.target, self.predict)\n', (7133, 7160), True, 'import tensorflow as tf\n'), ((1677, 1702), 'tensorflow.matmul', 'tf.matmul', (['h_flat3', 'W_fc2'], {}), '(h_flat3, W_fc2)\n', (1686, 1702), True, 'import tensorflow as tf\n'), ((1914, 1933), 'tensorflow.matmul', 'tf.matmul', (['h', 'W_fc2'], {}), '(h, W_fc2)\n', (1923, 1933), True, 'import tensorflow as tf\n'), ((2305, 2347), 'tensorflow.train.AdamOptimizer', 'tf.train.AdamOptimizer', (['self.learning_rate'], {}), '(self.learning_rate)\n', (2327, 2347), True, 'import tensorflow as tf\n'), ((4161, 4186), 'tensorflow.matmul', 'tf.matmul', (['h_flat3', 'W_fc2'], {}), '(h_flat3, W_fc2)\n', (4170, 4186), True, 'import tensorflow as tf\n'), ((4398, 4417), 'tensorflow.matmul', 'tf.matmul', (['h', 'W_fc2'], {}), '(h, W_fc2)\n', (4407, 4417), True, 'import tensorflow as tf\n'), ((4789, 4831), 'tensorflow.train.AdamOptimizer', 'tf.train.AdamOptimizer', (['self.learning_rate'], {}), '(self.learning_rate)\n', (4811, 4831), True, 'import tensorflow as tf\n'), ((6643, 6668), 'tensorflow.matmul', 'tf.matmul', (['h_flat3', 'W_fc2'], {}), '(h_flat3, W_fc2)\n', (6652, 6668), True, 'import tensorflow as tf\n'), ((6880, 6899), 'tensorflow.matmul', 'tf.matmul', (['h', 'W_fc2'], {}), '(h, W_fc2)\n', (6889, 6899), True, 'import tensorflow as tf\n'), ((7276, 7318), 'tensorflow.train.AdamOptimizer', 'tf.train.AdamOptimizer', (['self.learning_rate'], {}), '(self.learning_rate)\n', (7298, 7318), True, 'import tensorflow as tf\n')]