diff --git a/lucid/modelzoo/caffe_models/AlexNet.py b/lucid/modelzoo/caffe_models/AlexNet.py index 72d2d42a..b635d411 100644 --- a/lucid/modelzoo/caffe_models/AlexNet.py +++ b/lucid/modelzoo/caffe_models/AlexNet.py @@ -33,7 +33,8 @@ class AlexNet_caffe(Model): # http://jaina.cs.ucdavis.edu/datasets/adv/imagenet/alexnet_frozen.pb # but it seems more polite and reliable to host our own. model_path = 'gs://modelzoo/AlexNet.pb' - labels_path = 'gs://modelzoo/ImageNet_labels_caffe.txt' + labels_path = 'gs://modelzoo/labels/ImageNet_standard.txt' + dataset = 'ImageNet' image_shape = [227, 227, 3] is_BGR = True image_value_range = (-IMAGENET_MEAN_BGR, 255-IMAGENET_MEAN_BGR) @@ -60,7 +61,8 @@ class AlexNet_caffe_Places365(Model): """ model_path = 'gs://modelzoo/AlexNet_caffe_places365.pb' - labels_path = 'gs://modelzoo/InceptionV1_caffe_places365-labels.txt' + labels_path = 'gs://modelzoo/labels/Places365.txt' + dataset = 'Places365' image_shape = [227, 227, 3] is_BGR = True image_value_range = (-IMAGENET_MEAN_BGR, 255-IMAGENET_MEAN_BGR) diff --git a/lucid/modelzoo/caffe_models/InceptionV1.py b/lucid/modelzoo/caffe_models/InceptionV1.py index 3d0b3715..b976d196 100644 --- a/lucid/modelzoo/caffe_models/InceptionV1.py +++ b/lucid/modelzoo/caffe_models/InceptionV1.py @@ -27,7 +27,8 @@ class InceptionV1_caffe(Model): and then ported to TensorFlow using caffe-tensorflow. """ model_path = 'gs://modelzoo/InceptionV1_caffe.pb' - labels_path = 'gs://modelzoo/InceptionV1_caffe-labels.txt' + labels_path = 'gs://modelzoo/labels/ImageNet_standard.txt' + dataset = 'ImageNet' image_shape = [224, 224, 3] is_BGR = True image_value_range = (-IMAGENET_MEAN_BGR, 255-IMAGENET_MEAN_BGR) @@ -60,10 +61,11 @@ class InceptionV1_caffe_Places205(Model): and then ported to TensorFlow using caffe-tensorflow. """ model_path = 'gs://modelzoo/InceptionV1_caffe_places205.pb' - labels_path = 'gs://modelzoo/InceptionV1_caffe_places205-labels.txt' + labels_path = 'gs://modelzoo/labels/Places205.txt' + dataset = 'Places205' image_shape = [224, 224, 3] - # range based on emperical testing - image_value_range = (-1,1) + is_BGR = True + image_value_range = (-IMAGENET_MEAN_BGR, 255-IMAGENET_MEAN_BGR) input_name = 'data' layers = [ @@ -93,8 +95,8 @@ class InceptionV1_caffe_Places365(Model): and then ported to TensorFlow using caffe-tensorflow. """ model_path = 'gs://modelzoo/InceptionV1_caffe_places365.pb' - # TODO - check labels match predictions - labels_path = 'gs://modelzoo/InceptionV1_caffe_places365-labels.txt' + labels_path = 'gs://modelzoo/labels/Places365.txt' + dataset = 'Places365' image_shape = [224, 224, 3] # What is the correct input range??? is_BGR = True diff --git a/lucid/modelzoo/caffe_models/__init__.py b/lucid/modelzoo/caffe_models/__init__.py index 1fa91d01..27597d11 100644 --- a/lucid/modelzoo/caffe_models/__init__.py +++ b/lucid/modelzoo/caffe_models/__init__.py @@ -22,3 +22,10 @@ del print_function del IMAGENET_MEAN_BGR + +# in Python 2 only, list comprehensions leak bound vars to a broader scope +try: + del _obj + del _name +except: + pass diff --git a/lucid/modelzoo/caffe_models/others.py b/lucid/modelzoo/caffe_models/others.py index b043a30b..8ad3ad1a 100644 --- a/lucid/modelzoo/caffe_models/others.py +++ b/lucid/modelzoo/caffe_models/others.py @@ -24,7 +24,8 @@ class CaffeNet_caffe(Model): """ model_path = 'gs://modelzoo/CaffeNet_caffe.pb' - labels_path = 'gs://modelzoo/ImageNet_labels_caffe.txt' + labels_path = 'gs://modelzoo/labels/ImageNet_standard.txt' + dataset = 'ImageNet' image_shape = [227, 227, 3] is_BGR = True image_value_range = (-IMAGENET_MEAN_BGR, 255-IMAGENET_MEAN_BGR) @@ -51,7 +52,8 @@ class VGG16_caffe(Model): and convert it with caffe-tensorflow. """ model_path = 'gs://modelzoo/VGG16_caffe.pb' - labels_path = 'gs://modelzoo/InceptionV1_caffe-labels.txt' + labels_path = 'gs://modelzoo/labels/ImageNet_standard.txt' + dataset = 'ImageNet' image_shape = [224, 224, 3] is_BGR = True image_value_range = (-IMAGENET_MEAN_BGR, 255-IMAGENET_MEAN_BGR) @@ -89,7 +91,8 @@ class VGG19_caffe(Model): and convert it with caffe-tensorflow. """ model_path = 'gs://modelzoo/VGG19_caffe.pb' - labels_path = 'gs://modelzoo/InceptionV1_caffe-labels.txt' + labels_path = 'gs://modelzoo/labels/ImageNet_standard.txt' + dataset = 'ImageNet' image_shape = [224, 224, 3] is_BGR = True image_value_range = (-IMAGENET_MEAN_BGR, 255-IMAGENET_MEAN_BGR) diff --git a/lucid/modelzoo/other_models/InceptionV1.py b/lucid/modelzoo/other_models/InceptionV1.py index a8a7e011..88bbabcf 100644 --- a/lucid/modelzoo/other_models/InceptionV1.py +++ b/lucid/modelzoo/other_models/InceptionV1.py @@ -49,7 +49,8 @@ class InceptionV1(Model): minor implementation differences (such as eliding the heads). """ model_path = 'gs://modelzoo/InceptionV1.pb' - labels_path = 'gs://modelzoo/InceptionV1-labels.txt' + labels_path = 'gs://modelzoo/labels/ImageNet_alternate.txt' + dataset = 'ImageNet' image_shape = [224, 224, 3] image_value_range = (-117, 255-117) input_name = 'input:0' diff --git a/lucid/modelzoo/other_models/__init__.py b/lucid/modelzoo/other_models/__init__.py index 480c8e6d..8131a895 100644 --- a/lucid/modelzoo/other_models/__init__.py +++ b/lucid/modelzoo/other_models/__init__.py @@ -15,3 +15,10 @@ __all__ = [_name for _name, _obj in list(globals().items()) if isinstance(_obj, type) and issubclass(_obj, _Model) and _obj is not _Model] + +# in Python 2 only, list comprehensions leak bound vars to a broader scope +try: + del _obj + del _name +except: + pass diff --git a/lucid/modelzoo/slim_models/Inception.py b/lucid/modelzoo/slim_models/Inception.py index 25cd7029..8bacd3cc 100644 --- a/lucid/modelzoo/slim_models/Inception.py +++ b/lucid/modelzoo/slim_models/Inception.py @@ -28,7 +28,8 @@ class InceptionV1_slim(Model): """ model_path = 'gs://modelzoo/InceptionV1_slim.pb' - labels_path = 'gs://modelzoo/InceptionV1-labels.txt' #TODO + labels_path = 'gs://modelzoo/labels/ImageNet_standard_with_dummy.txt' + dataset = 'ImageNet' image_shape = [224, 224, 3] # inpute range taken from: # https://github.com/tensorflow/models/blob/master/research/slim/preprocessing/inception_preprocessing.py#L280 @@ -63,7 +64,8 @@ class InceptionV2_slim(Model): """ model_path = 'gs://modelzoo/InceptionV2_slim.pb' - labels_path = 'gs://modelzoo/InceptionV1-labels.txt' #TODO + labels_path = 'gs://modelzoo/labels/ImageNet_standard_with_dummy.txt' + dataset = 'ImageNet' image_shape = [224, 224, 3] # inpute range taken from: # https://github.com/tensorflow/models/blob/master/research/slim/preprocessing/inception_preprocessing.py#L280 @@ -99,7 +101,8 @@ class InceptionV3_slim(Model): """ model_path = 'gs://modelzoo/InceptionV3_slim.pb' - labels_path = 'gs://modelzoo/InceptionV1-labels.txt' + labels_path = 'gs://modelzoo/labels/ImageNet_standard_with_dummy.txt' + dataset = 'ImageNet' image_shape = [299, 299, 3] # inpute range taken from: # https://github.com/tensorflow/models/blob/master/research/slim/preprocessing/inception_preprocessing.py#L280 @@ -138,7 +141,8 @@ class InceptionV4_slim(Model): """ model_path = 'gs://modelzoo/InceptionV4_slim.pb' - labels_path = 'gs://modelzoo/InceptionV1-labels.txt' #TODO + labels_path = 'gs://modelzoo/labels/ImageNet_standard_with_dummy.txt' + dataset = 'ImageNet' image_shape = [299, 299, 3] # inpute range taken from: # https://github.com/tensorflow/models/blob/master/research/slim/preprocessing/inception_preprocessing.py#L280 @@ -183,7 +187,8 @@ class InceptionResnetV2_slim(Model): """ model_path = 'gs://modelzoo/InceptionResnetV2_slim.pb' - labels_path = 'gs://modelzoo/InceptionV1-labels.txt' #TODO + labels_path = 'gs://modelzoo/labels/ImageNet_standard_with_dummy.txt' + dataset = 'ImageNet' image_shape = [299, 299, 3] # inpute range taken from: # https://github.com/tensorflow/models/blob/master/research/slim/preprocessing/inception_preprocessing.py#L280 diff --git a/lucid/modelzoo/slim_models/ResNetV1.py b/lucid/modelzoo/slim_models/ResNetV1.py index 8d659048..40e8c529 100644 --- a/lucid/modelzoo/slim_models/ResNetV1.py +++ b/lucid/modelzoo/slim_models/ResNetV1.py @@ -25,48 +25,35 @@ class ResnetV1_50_slim(Model): """ model_path = 'gs://modelzoo/ResnetV1_50_slim.pb' - labels_path = 'gs://modelzoo/InceptionV1-labels.txt' #TODO + labels_path = 'gs://modelzoo/labels/ImageNet_standard.txt' + dataset = 'ImageNet' image_shape = [224, 224, 3] - # inpute range taken from: - # https://github.com/tensorflow/models/blob/master/research/slim/preprocessing/inception_preprocessing.py#L280 - image_value_range = (-1, 1) - input_name = 'input' + + image_value_range = (-117, 255-117) # Inferred by testing, may not be exactly right + input_name = 'input' + + # In ResNetV1, each add (joining the residual branch) is followed by a Relu + # this seems to be the natural "layer" position layers = [ - {'type': 'conv', 'name': 'resnet_v1_50/conv1/Relu', 'size': 64} , - {'type': 'conv', 'name': 'resnet_v1_50/block1/unit_1/bottleneck_v1/add', 'size': 256} , - {'type': 'conv', 'name': 'resnet_v1_50/block1/unit_1/bottleneck_v1/Relu', 'size': 256} , - {'type': 'conv', 'name': 'resnet_v1_50/block1/unit_2/bottleneck_v1/add', 'size': 256} , - {'type': 'conv', 'name': 'resnet_v1_50/block1/unit_2/bottleneck_v1/Relu', 'size': 256} , - {'type': 'conv', 'name': 'resnet_v1_50/block1/unit_3/bottleneck_v1/add', 'size': 256} , - {'type': 'conv', 'name': 'resnet_v1_50/block1/unit_3/bottleneck_v1/Relu', 'size': 256} , - {'type': 'conv', 'name': 'resnet_v1_50/block2/unit_1/bottleneck_v1/add', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_50/block2/unit_1/bottleneck_v1/Relu', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_50/block2/unit_2/bottleneck_v1/add', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_50/block2/unit_2/bottleneck_v1/Relu', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_50/block2/unit_3/bottleneck_v1/add', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_50/block2/unit_3/bottleneck_v1/Relu', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_50/block2/unit_4/bottleneck_v1/add', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_50/block2/unit_4/bottleneck_v1/Relu', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_50/block3/unit_1/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_50/block3/unit_1/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_50/block3/unit_2/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_50/block3/unit_2/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_50/block3/unit_3/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_50/block3/unit_3/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_50/block3/unit_4/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_50/block3/unit_4/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_50/block3/unit_5/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_50/block3/unit_5/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_50/block3/unit_6/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_50/block3/unit_6/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_50/block4/unit_1/bottleneck_v1/add', 'size': 2048} , - {'type': 'conv', 'name': 'resnet_v1_50/block4/unit_1/bottleneck_v1/Relu', 'size': 2048} , - {'type': 'conv', 'name': 'resnet_v1_50/block4/unit_2/bottleneck_v1/add', 'size': 2048} , - {'type': 'conv', 'name': 'resnet_v1_50/block4/unit_2/bottleneck_v1/Relu', 'size': 2048} , - {'type': 'conv', 'name': 'resnet_v1_50/block4/unit_3/bottleneck_v1/add', 'size': 2048} , - {'type': 'conv', 'name': 'resnet_v1_50/block4/unit_3/bottleneck_v1/Relu', 'size': 2048} , - {'type': 'dense', 'name': 'resnet_v1_50/predictions/Softmax', 'size': 1000} , + {'type': 'conv', 'name': 'resnet_v1_50/conv1/Relu', 'size': 64}, + {'type': 'conv', 'name': 'resnet_v1_50/block1/unit_1/bottleneck_v1/Relu', 'size': 256}, + {'type': 'conv', 'name': 'resnet_v1_50/block1/unit_2/bottleneck_v1/Relu', 'size': 256}, + {'type': 'conv', 'name': 'resnet_v1_50/block1/unit_3/bottleneck_v1/Relu', 'size': 256}, + {'type': 'conv', 'name': 'resnet_v1_50/block2/unit_1/bottleneck_v1/Relu', 'size': 512}, + {'type': 'conv', 'name': 'resnet_v1_50/block2/unit_2/bottleneck_v1/Relu', 'size': 512}, + {'type': 'conv', 'name': 'resnet_v1_50/block2/unit_3/bottleneck_v1/Relu', 'size': 512}, + {'type': 'conv', 'name': 'resnet_v1_50/block2/unit_4/bottleneck_v1/Relu', 'size': 512}, + {'type': 'conv', 'name': 'resnet_v1_50/block3/unit_1/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_50/block3/unit_2/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_50/block3/unit_3/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_50/block3/unit_4/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_50/block3/unit_5/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_50/block3/unit_6/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_50/block4/unit_1/bottleneck_v1/Relu', 'size': 2048}, + {'type': 'conv', 'name': 'resnet_v1_50/block4/unit_2/bottleneck_v1/Relu', 'size': 2048}, + {'type': 'conv', 'name': 'resnet_v1_50/block4/unit_3/bottleneck_v1/Relu', 'size': 2048}, + {'type': 'dense', 'name': 'resnet_v1_50/predictions/Softmax', 'size': 1000}, ] @@ -78,82 +65,50 @@ class ResnetV1_101_slim(Model): """ model_path = 'gs://modelzoo/ResnetV1_101_slim.pb' - labels_path = 'gs://modelzoo/InceptionV1-labels.txt' #TODO + labels_path = 'gs://modelzoo/labels/ImageNet_standard.txt' + dataset = 'ImageNet' image_shape = [224, 224, 3] - # inpute range taken from: - # https://github.com/tensorflow/models/blob/master/research/slim/preprocessing/inception_preprocessing.py#L280 - image_value_range = (-1, 1) + image_value_range = (-117, 255-117) # Inferred by testing, may not be exactly right input_name = 'input' + # In ResNetV1, each add (joining the residual branch) is followed by a Relu + # this seems to be the natural "layer" position layers = [ - {'type': 'conv', 'name': 'resnet_v1_101/conv1/Relu', 'size': 64} , - {'type': 'conv', 'name': 'resnet_v1_101/block1/unit_1/bottleneck_v1/add', 'size': 256} , - {'type': 'conv', 'name': 'resnet_v1_101/block1/unit_1/bottleneck_v1/Relu', 'size': 256} , - {'type': 'conv', 'name': 'resnet_v1_101/block1/unit_2/bottleneck_v1/add', 'size': 256} , - {'type': 'conv', 'name': 'resnet_v1_101/block1/unit_2/bottleneck_v1/Relu', 'size': 256} , - {'type': 'conv', 'name': 'resnet_v1_101/block1/unit_3/bottleneck_v1/add', 'size': 256} , - {'type': 'conv', 'name': 'resnet_v1_101/block1/unit_3/bottleneck_v1/Relu', 'size': 256} , - {'type': 'conv', 'name': 'resnet_v1_101/block2/unit_1/bottleneck_v1/add', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_101/block2/unit_1/bottleneck_v1/Relu', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_101/block2/unit_2/bottleneck_v1/add', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_101/block2/unit_2/bottleneck_v1/Relu', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_101/block2/unit_3/bottleneck_v1/add', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_101/block2/unit_3/bottleneck_v1/Relu', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_101/block2/unit_4/bottleneck_v1/add', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_101/block2/unit_4/bottleneck_v1/Relu', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_1/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_1/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_2/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_2/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_3/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_3/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_4/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_4/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_5/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_5/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_6/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_6/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_7/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_7/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_8/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_8/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_9/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_9/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_10/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_10/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_11/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_11/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_12/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_12/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_13/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_13/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_14/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_14/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_15/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_15/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_16/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_16/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_17/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_17/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_18/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_18/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_19/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_19/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_20/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_20/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_21/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_21/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_22/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_22/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_23/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_23/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_101/block4/unit_1/bottleneck_v1/add', 'size': 2048} , - {'type': 'conv', 'name': 'resnet_v1_101/block4/unit_1/bottleneck_v1/Relu', 'size': 2048} , - {'type': 'conv', 'name': 'resnet_v1_101/block4/unit_2/bottleneck_v1/add', 'size': 2048} , - {'type': 'conv', 'name': 'resnet_v1_101/block4/unit_2/bottleneck_v1/Relu', 'size': 2048} , - {'type': 'conv', 'name': 'resnet_v1_101/block4/unit_3/bottleneck_v1/add', 'size': 2048} , - {'type': 'conv', 'name': 'resnet_v1_101/block4/unit_3/bottleneck_v1/Relu', 'size': 2048} , - {'type': 'dense', 'name': 'resnet_v1_101/predictions/Softmax', 'size': 1000} , + {'type': 'conv', 'name': 'resnet_v1_101/conv1/Relu', 'size': 64}, + {'type': 'conv', 'name': 'resnet_v1_101/block1/unit_1/bottleneck_v1/Relu', 'size': 256}, + {'type': 'conv', 'name': 'resnet_v1_101/block1/unit_2/bottleneck_v1/Relu', 'size': 256}, + {'type': 'conv', 'name': 'resnet_v1_101/block1/unit_3/bottleneck_v1/Relu', 'size': 256}, + {'type': 'conv', 'name': 'resnet_v1_101/block2/unit_1/bottleneck_v1/Relu', 'size': 512}, + {'type': 'conv', 'name': 'resnet_v1_101/block2/unit_2/bottleneck_v1/Relu', 'size': 512}, + {'type': 'conv', 'name': 'resnet_v1_101/block2/unit_3/bottleneck_v1/Relu', 'size': 512}, + {'type': 'conv', 'name': 'resnet_v1_101/block2/unit_4/bottleneck_v1/Relu', 'size': 512}, + {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_1/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_2/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_3/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_4/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_5/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_6/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_7/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_8/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_9/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_10/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_11/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_12/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_13/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_14/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_15/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_16/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_17/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_18/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_19/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_20/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_21/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_22/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_101/block3/unit_23/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_101/block4/unit_1/bottleneck_v1/Relu', 'size': 2048}, + {'type': 'conv', 'name': 'resnet_v1_101/block4/unit_2/bottleneck_v1/Relu', 'size': 2048}, + {'type': 'conv', 'name': 'resnet_v1_101/block4/unit_3/bottleneck_v1/Relu', 'size': 2048}, + {'type': 'dense', 'name': 'resnet_v1_101/predictions/Softmax', 'size': 1000}, ] @@ -166,115 +121,66 @@ class ResnetV1_152_slim(Model): """ model_path = 'gs://modelzoo/ResnetV1_152_slim.pb' - labels_path = 'gs://modelzoo/InceptionV1-labels.txt' #TODO + labels_path = 'gs://modelzoo/labels/ImageNet_standard.txt' + dataset = 'ImageNet' image_shape = [224, 224, 3] - # inpute range taken from: - # https://github.com/tensorflow/models/blob/master/research/slim/preprocessing/inception_preprocessing.py#L280 - image_value_range = (-1, 1) + image_value_range = (-117, 255-117) # Inferred by testing, may not be exactly right input_name = 'input' - + + # In ResNetV1, each add (joining the residual branch) is followed by a Relu + # this seems to be the natural "layer" position layers = [ - {'type': 'conv', 'name': 'resnet_v1_152/conv1/Relu', 'size': 64} , - {'type': 'conv', 'name': 'resnet_v1_152/block1/unit_1/bottleneck_v1/add', 'size': 256} , - {'type': 'conv', 'name': 'resnet_v1_152/block1/unit_1/bottleneck_v1/Relu', 'size': 256} , - {'type': 'conv', 'name': 'resnet_v1_152/block1/unit_2/bottleneck_v1/add', 'size': 256} , - {'type': 'conv', 'name': 'resnet_v1_152/block1/unit_2/bottleneck_v1/Relu', 'size': 256} , - {'type': 'conv', 'name': 'resnet_v1_152/block1/unit_3/bottleneck_v1/add', 'size': 256} , - {'type': 'conv', 'name': 'resnet_v1_152/block1/unit_3/bottleneck_v1/Relu', 'size': 256} , - {'type': 'conv', 'name': 'resnet_v1_152/block2/unit_1/bottleneck_v1/add', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_152/block2/unit_1/bottleneck_v1/Relu', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_152/block2/unit_2/bottleneck_v1/add', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_152/block2/unit_2/bottleneck_v1/Relu', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_152/block2/unit_3/bottleneck_v1/add', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_152/block2/unit_3/bottleneck_v1/Relu', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_152/block2/unit_4/bottleneck_v1/add', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_152/block2/unit_4/bottleneck_v1/Relu', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_152/block2/unit_5/bottleneck_v1/add', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_152/block2/unit_5/bottleneck_v1/Relu', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_152/block2/unit_6/bottleneck_v1/add', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_152/block2/unit_6/bottleneck_v1/Relu', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_152/block2/unit_7/bottleneck_v1/add', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_152/block2/unit_7/bottleneck_v1/Relu', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_152/block2/unit_8/bottleneck_v1/add', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_152/block2/unit_8/bottleneck_v1/Relu', 'size': 512} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_1/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_1/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_2/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_2/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_3/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_3/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_4/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_4/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_5/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_5/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_6/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_6/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_7/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_7/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_8/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_8/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_9/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_9/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_10/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_10/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_11/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_11/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_12/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_12/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_13/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_13/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_14/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_14/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_15/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_15/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_16/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_16/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_17/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_17/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_18/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_18/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_19/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_19/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_20/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_20/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_21/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_21/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_22/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_22/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_23/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_23/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_24/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_24/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_25/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_25/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_26/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_26/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_27/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_27/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_28/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_28/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_29/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_29/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_30/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_30/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_31/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_31/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_32/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_32/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_33/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_33/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_34/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_34/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_35/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_35/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_36/bottleneck_v1/add', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_36/bottleneck_v1/Relu', 'size': 1024} , - {'type': 'conv', 'name': 'resnet_v1_152/block4/unit_1/bottleneck_v1/add', 'size': 2048} , - {'type': 'conv', 'name': 'resnet_v1_152/block4/unit_1/bottleneck_v1/Relu', 'size': 2048} , - {'type': 'conv', 'name': 'resnet_v1_152/block4/unit_2/bottleneck_v1/add', 'size': 2048} , - {'type': 'conv', 'name': 'resnet_v1_152/block4/unit_2/bottleneck_v1/Relu', 'size': 2048} , - {'type': 'conv', 'name': 'resnet_v1_152/block4/unit_3/bottleneck_v1/add', 'size': 2048} , - {'type': 'conv', 'name': 'resnet_v1_152/block4/unit_3/bottleneck_v1/Relu', 'size': 2048} , - {'type': 'dense', 'name': 'resnet_v1_152/predictions/Softmax', 'size': 1000} , + {'type': 'conv', 'name': 'resnet_v1_152/conv1/Relu', 'size': 64}, + {'type': 'conv', 'name': 'resnet_v1_152/block1/unit_1/bottleneck_v1/Relu', 'size': 256}, + {'type': 'conv', 'name': 'resnet_v1_152/block1/unit_2/bottleneck_v1/Relu', 'size': 256}, + {'type': 'conv', 'name': 'resnet_v1_152/block1/unit_3/bottleneck_v1/Relu', 'size': 256}, + {'type': 'conv', 'name': 'resnet_v1_152/block2/unit_1/bottleneck_v1/Relu', 'size': 512}, + {'type': 'conv', 'name': 'resnet_v1_152/block2/unit_2/bottleneck_v1/Relu', 'size': 512}, + {'type': 'conv', 'name': 'resnet_v1_152/block2/unit_3/bottleneck_v1/Relu', 'size': 512}, + {'type': 'conv', 'name': 'resnet_v1_152/block2/unit_4/bottleneck_v1/Relu', 'size': 512}, + {'type': 'conv', 'name': 'resnet_v1_152/block2/unit_5/bottleneck_v1/Relu', 'size': 512}, + {'type': 'conv', 'name': 'resnet_v1_152/block2/unit_6/bottleneck_v1/Relu', 'size': 512}, + {'type': 'conv', 'name': 'resnet_v1_152/block2/unit_7/bottleneck_v1/Relu', 'size': 512}, + {'type': 'conv', 'name': 'resnet_v1_152/block2/unit_8/bottleneck_v1/Relu', 'size': 512}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_1/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_2/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_3/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_4/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_5/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_6/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_7/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_8/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_9/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_10/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_11/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_12/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_13/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_14/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_15/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_16/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_17/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_18/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_19/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_20/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_21/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_22/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_23/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_24/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_25/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_26/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_27/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_28/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_29/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_30/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_31/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_32/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_33/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_34/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_35/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block3/unit_36/bottleneck_v1/Relu', 'size': 1024}, + {'type': 'conv', 'name': 'resnet_v1_152/block4/unit_1/bottleneck_v1/Relu', 'size': 2048}, + {'type': 'conv', 'name': 'resnet_v1_152/block4/unit_2/bottleneck_v1/Relu', 'size': 2048}, + {'type': 'conv', 'name': 'resnet_v1_152/block4/unit_3/bottleneck_v1/Relu', 'size': 2048}, + {'type': 'dense', 'name': 'resnet_v1_152/predictions/Softmax', 'size': 1000}, ] diff --git a/lucid/modelzoo/slim_models/ResNetV2.py b/lucid/modelzoo/slim_models/ResNetV2.py index 661706ba..4223beb1 100644 --- a/lucid/modelzoo/slim_models/ResNetV2.py +++ b/lucid/modelzoo/slim_models/ResNetV2.py @@ -28,7 +28,8 @@ class ResnetV2_50_slim(Model): """ model_path = 'gs://modelzoo/ResnetV2_50_slim.pb' - labels_path = 'gs://modelzoo/InceptionV1-labels.txt' #TODO + labels_path = 'gs://modelzoo/labels/ImageNet_standard_with_dummy.txt' + dataset = 'ImageNet' image_shape = [224, 224, 3] # inpute range taken from: # https://github.com/tensorflow/models/blob/master/research/slim/preprocessing/inception_preprocessing.py#L280 @@ -72,7 +73,8 @@ class ResnetV2_101_slim(Model): """ model_path = 'gs://modelzoo/ResnetV2_101_slim.pb' - labels_path = 'gs://modelzoo/InceptionV1-labels.txt' #TODO + labels_path = 'gs://modelzoo/labels/ImageNet_standard_with_dummy.txt' + dataset = 'ImageNet' image_shape = [224, 224, 3] # inpute range taken from: # https://github.com/tensorflow/models/blob/master/research/slim/preprocessing/inception_preprocessing.py#L280 @@ -133,7 +135,8 @@ class ResnetV2_152_slim(Model): """ model_path = 'gs://modelzoo/ResnetV2_152_slim.pb' - labels_path = 'gs://modelzoo/InceptionV1-labels.txt' #TODO + labels_path = 'gs://modelzoo/labels/ImageNet_standard_with_dummy.txt' + dataset = 'ImageNet' image_shape = [224, 224, 3] # inpute range taken from: # https://github.com/tensorflow/models/blob/master/research/slim/preprocessing/inception_preprocessing.py#L280 diff --git a/lucid/modelzoo/slim_models/__init__.py b/lucid/modelzoo/slim_models/__init__.py index 35851b3d..bf8fef0b 100644 --- a/lucid/modelzoo/slim_models/__init__.py +++ b/lucid/modelzoo/slim_models/__init__.py @@ -24,3 +24,10 @@ del print_function del IMAGENET_MEAN + +# in Python 2 only, list comprehensions leak bound vars to a broader scope +try: + del _obj + del _name +except: + pass diff --git a/lucid/modelzoo/slim_models/others.py b/lucid/modelzoo/slim_models/others.py index 6738c5c4..a43a2f1a 100644 --- a/lucid/modelzoo/slim_models/others.py +++ b/lucid/modelzoo/slim_models/others.py @@ -17,81 +17,87 @@ from lucid.modelzoo.vision_base import Model, IMAGENET_MEAN -class VGG16_slim(Model): - """VGG16 as implemented by the TensorFlow slim framework. - - VGG16 was introduced by Simonyan & Zisserman (2014): - https://arxiv.org/pdf/1409.1556.pdf - This function provides the pre-trained reimplementation from TF slim: - https://github.com/tensorflow/models/tree/master/research/slim - We believe the weights were actually trained in caffe and ported. - """ - - model_path = 'gs://modelzoo/VGG16_slim.pb' - labels_path = 'gs://modelzoo/InceptionV1-labels.txt' #TODO - image_shape = [224, 224, 3] - # inpute range taken from: - # https://github.com/tensorflow/models/blob/master/research/slim/preprocessing/inception_preprocessing.py#L280 - image_value_range = (-1, 1) - input_name = 'input' - - layers = [ - {'type': 'conv', 'name': 'vgg_16/conv1/conv1_1/Relu', 'size': 64} , - {'type': 'conv', 'name': 'vgg_16/conv1/conv1_2/Relu', 'size': 64} , - {'type': 'conv', 'name': 'vgg_16/conv2/conv2_1/Relu', 'size': 128} , - {'type': 'conv', 'name': 'vgg_16/conv2/conv2_2/Relu', 'size': 128} , - {'type': 'conv', 'name': 'vgg_16/conv3/conv3_1/Relu', 'size': 256} , - {'type': 'conv', 'name': 'vgg_16/conv3/conv3_2/Relu', 'size': 256} , - {'type': 'conv', 'name': 'vgg_16/conv3/conv3_3/Relu', 'size': 256} , - {'type': 'conv', 'name': 'vgg_16/conv4/conv4_1/Relu', 'size': 512} , - {'type': 'conv', 'name': 'vgg_16/conv4/conv4_2/Relu', 'size': 512} , - {'type': 'conv', 'name': 'vgg_16/conv4/conv4_3/Relu', 'size': 512} , - {'type': 'conv', 'name': 'vgg_16/conv5/conv5_1/Relu', 'size': 512} , - {'type': 'conv', 'name': 'vgg_16/conv5/conv5_2/Relu', 'size': 512} , - {'type': 'conv', 'name': 'vgg_16/conv5/conv5_3/Relu', 'size': 512} , - {'type': 'conv', 'name': 'vgg_16/fc6/Relu', 'size': 4096} , - {'type': 'conv', 'name': 'vgg_16/fc7/Relu', 'size': 4096} , - ] - - -class VGG19_slim(Model): - """VGG19 as implemented by the TensorFlow slim framework. - - VGG19 was introduced by Simonyan & Zisserman (2014): - https://arxiv.org/pdf/1409.1556.pdf - This function provides the pre-trained reimplementation from TF slim: - https://github.com/tensorflow/models/tree/master/research/slim - We believe the weights were actually trained in caffe and ported. - """ - - model_path = 'gs://modelzoo/VGG19_slim.pb' - labels_path = 'gs://modelzoo/InceptionV1-labels.txt' #TODO - image_shape = [224, 224, 3] - # inpute range taken from: - # https://github.com/tensorflow/models/blob/master/research/slim/preprocessing/inception_preprocessing.py#L280 - image_value_range = (-1, 1) - input_name = 'input' - - layers = [ - {'type': 'conv', 'name': 'vgg_19/conv1/conv1_1/Relu', 'size': 64} , - {'type': 'conv', 'name': 'vgg_19/conv1/conv1_2/Relu', 'size': 64} , - {'type': 'conv', 'name': 'vgg_19/conv2/conv2_1/Relu', 'size': 128} , - {'type': 'conv', 'name': 'vgg_19/conv2/conv2_2/Relu', 'size': 128} , - {'type': 'conv', 'name': 'vgg_19/conv3/conv3_1/Relu', 'size': 256} , - {'type': 'conv', 'name': 'vgg_19/conv3/conv3_2/Relu', 'size': 256} , - {'type': 'conv', 'name': 'vgg_19/conv3/conv3_3/Relu', 'size': 256} , - {'type': 'conv', 'name': 'vgg_19/conv3/conv3_4/Relu', 'size': 256} , - {'type': 'conv', 'name': 'vgg_19/conv4/conv4_1/Relu', 'size': 512} , - {'type': 'conv', 'name': 'vgg_19/conv4/conv4_2/Relu', 'size': 512} , - {'type': 'conv', 'name': 'vgg_19/conv4/conv4_3/Relu', 'size': 512} , - {'type': 'conv', 'name': 'vgg_19/conv4/conv4_4/Relu', 'size': 512} , - {'type': 'conv', 'name': 'vgg_19/conv5/conv5_1/Relu', 'size': 512} , - {'type': 'conv', 'name': 'vgg_19/conv5/conv5_2/Relu', 'size': 512} , - {'type': 'conv', 'name': 'vgg_19/conv5/conv5_3/Relu', 'size': 512} , - {'type': 'conv', 'name': 'vgg_19/conv5/conv5_4/Relu', 'size': 512} , - {'type': 'conv', 'name': 'vgg_19/fc6/Relu', 'size': 4096} , - {'type': 'conv', 'name': 'vgg_19/fc7/Relu', 'size': 4096} , - ] +## Commenting out slim implementations of VGG16 and VGG19 because: +## +## * They are supposed to be ports of the caffe implementation, +## which we also provide. +## * We can't determine the correct input range or whether they are BGR. +## * They do no provide a softmax layer, leaving us no clear way to test them. +## + +# class VGG16_slim(Model): +# """VGG16 as implemented by the TensorFlow slim framework. +# +# VGG16 was introduced by Simonyan & Zisserman (2014): +# https://arxiv.org/pdf/1409.1556.pdf +# This function provides the pre-trained reimplementation from TF slim: +# https://github.com/tensorflow/models/tree/master/research/slim +# We believe the weights were actually trained in caffe and ported. +# """ +# +# model_path = 'gs://modelzoo/VGG16_slim.pb' +# labels_path = 'gs://modelzoo/labels/ImageNet_standard_with_dummy.txt' #TODO +# dataset = 'ImageNet' +# image_shape = [224, 224, 3] +# image_value_range = (-1, 1) +# input_name = 'input' +# +# layers = [ +# {'type': 'conv', 'name': 'vgg_16/conv1/conv1_1/Relu', 'size': 64} , +# {'type': 'conv', 'name': 'vgg_16/conv1/conv1_2/Relu', 'size': 64} , +# {'type': 'conv', 'name': 'vgg_16/conv2/conv2_1/Relu', 'size': 128} , +# {'type': 'conv', 'name': 'vgg_16/conv2/conv2_2/Relu', 'size': 128} , +# {'type': 'conv', 'name': 'vgg_16/conv3/conv3_1/Relu', 'size': 256} , +# {'type': 'conv', 'name': 'vgg_16/conv3/conv3_2/Relu', 'size': 256} , +# {'type': 'conv', 'name': 'vgg_16/conv3/conv3_3/Relu', 'size': 256} , +# {'type': 'conv', 'name': 'vgg_16/conv4/conv4_1/Relu', 'size': 512} , +# {'type': 'conv', 'name': 'vgg_16/conv4/conv4_2/Relu', 'size': 512} , +# {'type': 'conv', 'name': 'vgg_16/conv4/conv4_3/Relu', 'size': 512} , +# {'type': 'conv', 'name': 'vgg_16/conv5/conv5_1/Relu', 'size': 512} , +# {'type': 'conv', 'name': 'vgg_16/conv5/conv5_2/Relu', 'size': 512} , +# {'type': 'conv', 'name': 'vgg_16/conv5/conv5_3/Relu', 'size': 512} , +# {'type': 'conv', 'name': 'vgg_16/fc6/Relu', 'size': 4096} , +# {'type': 'conv', 'name': 'vgg_16/fc7/Relu', 'size': 4096} , +# ] + + +# class VGG19_slim(Model): +# """VGG19 as implemented by the TensorFlow slim framework. +# +# VGG19 was introduced by Simonyan & Zisserman (2014): +# https://arxiv.org/pdf/1409.1556.pdf +# This function provides the pre-trained reimplementation from TF slim: +# https://github.com/tensorflow/models/tree/master/research/slim +# We believe the weights were actually trained in caffe and ported. +# """ +# +# model_path = 'gs://modelzoo/VGG19_slim.pb' +# labels_path = 'gs://modelzoo/labels/ImageNet_standard_with_dummy.txt' #TODO +# dataset = 'ImageNet' +# image_shape = [224, 224, 3] +# image_value_range = (-1, 1) +# input_name = 'input' +# +# layers = [ +# {'type': 'conv', 'name': 'vgg_19/conv1/conv1_1/Relu', 'size': 64} , +# {'type': 'conv', 'name': 'vgg_19/conv1/conv1_2/Relu', 'size': 64} , +# {'type': 'conv', 'name': 'vgg_19/conv2/conv2_1/Relu', 'size': 128} , +# {'type': 'conv', 'name': 'vgg_19/conv2/conv2_2/Relu', 'size': 128} , +# {'type': 'conv', 'name': 'vgg_19/conv3/conv3_1/Relu', 'size': 256} , +# {'type': 'conv', 'name': 'vgg_19/conv3/conv3_2/Relu', 'size': 256} , +# {'type': 'conv', 'name': 'vgg_19/conv3/conv3_3/Relu', 'size': 256} , +# {'type': 'conv', 'name': 'vgg_19/conv3/conv3_4/Relu', 'size': 256} , +# {'type': 'conv', 'name': 'vgg_19/conv4/conv4_1/Relu', 'size': 512} , +# {'type': 'conv', 'name': 'vgg_19/conv4/conv4_2/Relu', 'size': 512} , +# {'type': 'conv', 'name': 'vgg_19/conv4/conv4_3/Relu', 'size': 512} , +# {'type': 'conv', 'name': 'vgg_19/conv4/conv4_4/Relu', 'size': 512} , +# {'type': 'conv', 'name': 'vgg_19/conv5/conv5_1/Relu', 'size': 512} , +# {'type': 'conv', 'name': 'vgg_19/conv5/conv5_2/Relu', 'size': 512} , +# {'type': 'conv', 'name': 'vgg_19/conv5/conv5_3/Relu', 'size': 512} , +# {'type': 'conv', 'name': 'vgg_19/conv5/conv5_4/Relu', 'size': 512} , +# {'type': 'conv', 'name': 'vgg_19/fc6/Relu', 'size': 4096} , +# {'type': 'conv', 'name': 'vgg_19/fc7/Relu', 'size': 4096} , +# ] class MobilenetV1_slim(Model): @@ -102,7 +108,8 @@ class MobilenetV1_slim(Model): """ model_path = 'gs://modelzoo/MobilenetV1_slim.pb' - labels_path = 'gs://modelzoo/InceptionV1-labels.txt' #TODO + labels_path = 'gs://modelzoo/labels/ImageNet_standard_with_dummy.txt' #TODO + dataset = 'ImageNet' image_shape = [224, 224, 3] # inpute range taken from: # https://github.com/tensorflow/models/blob/master/research/slim/preprocessing/inception_preprocessing.py#L280 @@ -119,7 +126,8 @@ class MobilenetV1_050_slim(Model): """ model_path = 'gs://modelzoo/MobilenetV1050_slim.pb' - labels_path = 'gs://modelzoo/InceptionV1-labels.txt' #TODO + labels_path = 'gs://modelzoo/labels/ImageNet_standard_with_dummy.txt' #TODO + dataset = 'ImageNet' image_shape = [224, 224, 3] # inpute range taken from: # https://github.com/tensorflow/models/blob/master/research/slim/preprocessing/inception_preprocessing.py#L280 @@ -136,7 +144,8 @@ class MobilenetV1_025_slim(Model): """ model_path = 'gs://modelzoo/MobilenetV1025_slim.pb' - labels_path = 'gs://modelzoo/InceptionV1-labels.txt' #TODO + labels_path = 'gs://modelzoo/labels/ImageNet_standard_with_dummy.txt' #TODO + dataset = 'ImageNet' image_shape = [224, 224, 3] # inpute range taken from: # https://github.com/tensorflow/models/blob/master/research/slim/preprocessing/inception_preprocessing.py#L280 @@ -153,7 +162,8 @@ class NasnetMobile_slim(Model): """ model_path = 'gs://modelzoo/NasnetMobile_slim.pb' - labels_path = 'gs://modelzoo/InceptionV1-labels.txt' #TODO + labels_path = 'gs://modelzoo/labels/ImageNet_standard_with_dummy.txt' #TODO + dataset = 'ImageNet' image_shape = [224, 224, 3] # inpute range taken from: # https://github.com/tensorflow/models/blob/master/research/slim/preprocessing/inception_preprocessing.py#L280 @@ -170,7 +180,8 @@ class NasnetLarge_slim(Model): """ model_path = 'gs://modelzoo/NasnetLarge_slim.pb' - labels_path = 'gs://modelzoo/InceptionV1-labels.txt' #TODO + labels_path = 'gs://modelzoo/labels/ImageNet_standard_with_dummy.txt' #TODO + dataset = 'ImageNet' image_shape = [331, 331, 3] # inpute range taken from: # https://github.com/tensorflow/models/blob/master/research/slim/preprocessing/inception_preprocessing.py#L280 @@ -187,7 +198,8 @@ class PnasnetLarge_slim(Model): """ model_path = 'gs://modelzoo/PnasnetLarge_slim.pb' - labels_path = 'gs://modelzoo/InceptionV1-labels.txt' #TODO + labels_path = 'gs://modelzoo/labels/ImageNet_standard_with_dummy.txt' #TODO + dataset = 'ImageNet' image_shape = [331, 331, 3] # inpute range taken from: # https://github.com/tensorflow/models/blob/master/research/slim/preprocessing/inception_preprocessing.py#L280 @@ -204,7 +216,8 @@ class PnasnetMobile_slim(Model): """ model_path = 'gs://modelzoo/PnasnetMobile_slim.pb' - labels_path = 'gs://modelzoo/InceptionV1-labels.txt' #TODO + labels_path = 'gs://modelzoo/labels/ImageNet_standard_with_dummy.txt' #TODO + dataset = 'ImageNet' image_shape = [224, 224, 3] # inpute range taken from: # https://github.com/tensorflow/models/blob/master/research/slim/preprocessing/inception_preprocessing.py#L280 diff --git a/lucid/modelzoo/util.py b/lucid/modelzoo/util.py index 48f30e2a..958c1f4b 100644 --- a/lucid/modelzoo/util.py +++ b/lucid/modelzoo/util.py @@ -39,6 +39,8 @@ def load_graphdef(model_url, reset_device=True): except DecodeError: cache_path = local_cache_path(model_url) log.error("Could not decode graphdef protobuf. Maybe check if you have a corrupted file cached at {}?".format(cache_path)) + raise RuntimeError('Could not load_graphdef!') + if reset_device: for n in graph_def.node: n.device = "" diff --git a/lucid/modelzoo/vision_models.py b/lucid/modelzoo/vision_models.py index 2c0f8f26..bcbdf26c 100644 --- a/lucid/modelzoo/vision_models.py +++ b/lucid/modelzoo/vision_models.py @@ -29,3 +29,10 @@ __all__ = [_name for _name, _obj in list(globals().items()) if isinstance(_obj, type) and issubclass(_obj, Model)] + +# in Python 2 only, list comprehensions leak bound vars to a broader scope +try: + del _obj + del _name +except: + pass diff --git a/lucid/recipes/caricature.py b/lucid/recipes/caricature.py new file mode 100644 index 00000000..42363713 --- /dev/null +++ b/lucid/recipes/caricature.py @@ -0,0 +1,61 @@ +import numpy as np +import tensorflow as tf +import scipy.ndimage as nd + +import lucid.modelzoo.vision_models as models +import lucid.optvis.objectives as objectives +import lucid.optvis.param as param +import lucid.optvis.render as render +import lucid.optvis.transform as transform +from lucid.misc.io import show, load +from lucid.misc.io.reading import read + +def imgToModelSize(arr, model): + W = model.image_shape[0] + w, h, _ = arr.shape + s = float(W) / min(w,h) + arr = nd.zoom(arr, [s, s, 1], mode="nearest") + w, h, _ = arr.shape + dw, dh = (w-W)//2, (h-W)//3 + return arr[dw:dw+W, dh:dh+W] + + +@objectives.wrap_objective +def dot_compare(layer, batch=1, cossim_pow=0): + def inner(T): + dot = tf.reduce_sum(T(layer)[batch] * T(layer)[0]) + mag = tf.sqrt(tf.reduce_sum(T(layer)[0]**2)) + cossim = dot / (1e-6 + mag) + cossim = tf.maximum(0.1, cossim) + return dot * cossim ** cossim_pow + return inner + +def feature_inversion(img, model, layer=None, n_steps=512, cossim_pow=0.0): + with tf.Graph().as_default(), tf.Session() as sess: + img = imgToModelSize(img, model) + + objective = objectives.Objective.sum([ + 1.0 * dot_compare(layer, cossim_pow=cossim_pow), + objectives.blur_input_each_step(), + ]) + + t_input = tf.placeholder(tf.float32, img.shape) + param_f = param.image(img.shape[0], decorrelate=True, fft=True, alpha=False) + param_f = tf.stack([param_f[0], t_input]) + + transforms = [ + transform.pad(8, mode='constant', constant_value=.5), + transform.jitter(8), + transform.random_scale([0.9, 0.95, 1.05, 1.1] + [1]*4), + transform.random_rotate(range(-5, 5) + [0]*5), + transform.jitter(2), + ] + + T = render.make_vis_T(model, objective, param_f, transforms=transforms) + loss, vis_op, t_image = T("loss"), T("vis_op"), T("input") + + tf.global_variables_initializer().run() + for i in range(n_steps): _ = sess.run([vis_op], {t_input: img}) + + result = t_image.eval(feed_dict={t_input: img}) + show(result[0]) diff --git a/tests/modelzoo/test_vision_models.py b/tests/modelzoo/test_vision_models.py index 921f59c2..c1a7604a 100644 --- a/tests/modelzoo/test_vision_models.py +++ b/tests/modelzoo/test_vision_models.py @@ -43,6 +43,19 @@ def test_consistent_namespaces(): assert difference == 'Model' or difference.startswith("__") +@pytest.mark.parametrize("name,model_class", models_map.items()) +def test_model_properties(name, model_class): + assert hasattr(model_class, "model_path") + assert model_class.model_path.endswith(".pb") + assert hasattr(model_class, "labels_path") + assert model_class.labels_path.endswith(".txt") + assert hasattr(model_class, "dataset") + assert hasattr(model_class, "image_shape") + assert len(model_class.image_shape) == 3 + assert hasattr(model_class, "image_value_range") + assert hasattr(model_class, "input_name") + assert hasattr(model_class, "layers") + @pytest.mark.slow @pytest.mark.parametrize("name,model_class", models_map.items()) def test_model_layers_shapes(name, model_class):