# Path: selfsup/util.py
# class DummyDict(object):
#     def __init__(self):
#         pass
#     def __getitem__(self, item):
#         return DummyDict()
#     def __setitem__(self, item, value):
#         return DummyDict()
#     def get(self, item, default=None):
#         if default is None:
#             return DummyDict()
#         else:
#             return default
# 
# Path: selfsup/ops.py
# def max_pool(x, size, stride=None, name=None, info=DummyDict(), padding='SAME'):
# def avg_pool(x, size, stride=None, name=None, info=DummyDict(), padding='SAME'):
# def dropout(x, drop_prob, phase_test=None, name=None, info=DummyDict()):
# def scale(x, name=None, value=1.0):
# def inner(x, channels, info=DummyDict(), stddev=None,
#           activation=tf.nn.relu, name=None):
# def atrous_avg_pool(value, size, rate, padding, name=None, info=DummyDict()):
# def conv(x, channels, size=3, strides=1, activation=tf.nn.relu, name=None, padding='SAME',
#          info=DummyDict(), output_shape=None):
# def upconv(x, channels, size=3, strides=1, output_shape=None, activation=tf.nn.relu, name=None, padding='SAME',
#          info=DummyDict()):
#             W = tf.get_variable('weights', shape, dtype=tf.float32,
#                                 initializer=W_init)
#         W = tf.get_variable(name + '/weights', shape, dtype=tf.float32,
#                             initializer=W_init)
#         W = tf.get_variable(name + '/weights', shape, dtype=tf.float32,
#                             initializer=W_init)
# 
# Path: selfsup/caffe.py
# def to_caffe(tfW, name=None, shape=None, color_layer='', conv_fc_transitionals=None, info=DummyDict()):
# def from_caffe(cfW, name=None, color_layer='', conv_fc_transitionals=None, info=DummyDict()):
# def load_caffemodel(path, session, prefix='', ignore=set(),
#                     conv_fc_transitionals=None, renamed_layers=DummyDict(),
#                     color_layer='', verbose=False, pre_adjust_batch_norm=False):
#     def find_weights(name, which='weights'):
# def save_caffemodel(path, session, layers, prefix='',
#                     conv_fc_transitionals=None, color_layer='', verbose=False,
#                     save_batch_norm=False, lax_naming=False):
#     def find_weights(name, which='weights'):
#     def find_batch_norm(name, which='mean'):
#                     W = from_caffe(data[key]['0'], name=key, info=info,
#                                    conv_fc_transitionals=conv_fc_transitionals,
#                                    color_layer=color_layer)
#                         W = W.reshape(weights.get_shape().as_list())


import tensorflow as tf
import functools
import numpy as np
import sys
from selfsup.util import DummyDict
from selfsup import ops, caffe
    assert c_i%group==0
    assert c_o%group==0
    convolve = lambda i, k: tf.nn.conv2d(i, k, [1, s_h, s_w, 1], padding=padding)

    if group==1:
        conv = convolve(input, kernel)
    else:
        input_groups = tf.split(input, group, 3)
        kernel_groups = tf.split(kernel, group, 3)
        output_groups = [convolve(i, k) for i,k in zip(input_groups, kernel_groups)]
        conv = tf.concat(output_groups, 3)
    return  tf.reshape(tf.nn.bias_add(conv, biases), [-1]+conv.get_shape().as_list()[1:])


def build_network(x, info=DummyDict(), parameters={}, hole=1,
                  phase_test=None, convolutional=False, final_layer=True,
                  activation=tf.nn.relu,
                  pre_adjust_batch_norm=False, well_behaved_size=False,
                  use_lrn=True, prefix='', use_dropout=True):

    # Set up AlexNet
    #conv = functools.partial(alex_conv, size=3, parameters=parameters,
                             #info=info, pre_adjust_batch_norm=pre_adjust_batch_norm)
    #pool = functools.partial(ops.max_pool, info=info)
    if use_dropout:
        dropout = functools.partial(ops.dropout, phase_test=phase_test, info=info)
    else:
        def dropout(x, *args, **kwargs):
            return x


# Path: selfsup/util.py
# class DummyDict(object):
#     def __init__(self):
#         pass
#     def __getitem__(self, item):
#         return DummyDict()
#     def __setitem__(self, item, value):
#         return DummyDict()
#     def get(self, item, default=None):
#         if default is None:
#             return DummyDict()
#         else:
#             return default
# 
# Path: selfsup/ops.py
# def max_pool(x, size, stride=None, name=None, info=DummyDict(), padding='SAME'):
# def avg_pool(x, size, stride=None, name=None, info=DummyDict(), padding='SAME'):
# def dropout(x, drop_prob, phase_test=None, name=None, info=DummyDict()):
# def scale(x, name=None, value=1.0):
# def inner(x, channels, info=DummyDict(), stddev=None,
#           activation=tf.nn.relu, name=None):
# def atrous_avg_pool(value, size, rate, padding, name=None, info=DummyDict()):
# def conv(x, channels, size=3, strides=1, activation=tf.nn.relu, name=None, padding='SAME',
#          info=DummyDict(), output_shape=None):
# def upconv(x, channels, size=3, strides=1, output_shape=None, activation=tf.nn.relu, name=None, padding='SAME',
#          info=DummyDict()):
#             W = tf.get_variable('weights', shape, dtype=tf.float32,
#                                 initializer=W_init)
#         W = tf.get_variable(name + '/weights', shape, dtype=tf.float32,
#                             initializer=W_init)
#         W = tf.get_variable(name + '/weights', shape, dtype=tf.float32,
#                             initializer=W_init)
# 
# Path: selfsup/caffe.py
# def to_caffe(tfW, name=None, shape=None, color_layer='', conv_fc_transitionals=None, info=DummyDict()):
# def from_caffe(cfW, name=None, color_layer='', conv_fc_transitionals=None, info=DummyDict()):
# def load_caffemodel(path, session, prefix='', ignore=set(),
#                     conv_fc_transitionals=None, renamed_layers=DummyDict(),
#                     color_layer='', verbose=False, pre_adjust_batch_norm=False):
#     def find_weights(name, which='weights'):
# def save_caffemodel(path, session, layers, prefix='',
#                     conv_fc_transitionals=None, color_layer='', verbose=False,
#                     save_batch_norm=False, lax_naming=False):
#     def find_weights(name, which='weights'):
#     def find_batch_norm(name, which='mean'):
#                     W = from_caffe(data[key]['0'], name=key, info=info,
#                                    conv_fc_transitionals=conv_fc_transitionals,
#                                    color_layer=color_layer)
#                         W = W.reshape(weights.get_shape().as_list())


# Path: selfsup/model/alex.py
import tensorflow as tf
import functools
import numpy as np
import sys
from selfsup.util import DummyDict
from selfsup import ops, caffe

    assert c_i%group==0
    assert c_o%group==0
    convolve = lambda i, k: tf.nn.conv2d(i, k, [1, s_h, s_w, 1], padding=padding)

    if group==1:
        conv = convolve(input, kernel)
    else:
        input_groups = tf.split(input, group, 3)
        kernel_groups = tf.split(kernel, group, 3)
        output_groups = [convolve(i, k) for i,k in zip(input_groups, kernel_groups)]
        conv = tf.concat(output_groups, 3)
    return  tf.reshape(tf.nn.bias_add(conv, biases), [-1]+conv.get_shape().as_list()[1:])


def build_network(x, info=DummyDict(), parameters={}, hole=1,
                  phase_test=None, convolutional=False, final_layer=True,
                  activation=tf.nn.relu,
                  pre_adjust_batch_norm=False, well_behaved_size=False,
                  use_lrn=True, prefix='', use_dropout=True):

    # Set up AlexNet
    #conv = functools.partial(alex_conv, size=3, parameters=parameters,
                             #info=info, pre_adjust_batch_norm=pre_adjust_batch_norm)
    #pool = functools.partial(ops.max_pool, info=info)
    if use_dropout:
        dropout = functools.partial(ops.dropout, phase_test=phase_test, info=info)
    else:
        def dropout(x, *args, **kwargs):
            return x


    def add_info(name, z, pre=None, info=DummyDict()):