{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import tensorflow as tf\nimport tensorflow.keras as keras\nfrom tensorflow.data.experimental import AUTOTUNE\n\nimport os\nimport datetime\nimport random\n\nfrom glob import glob","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class cfg:\n    # data_path = 'data/ILSVRC/Data/CLS-LOC/train'\n    train_path = '../input/imagenetmini-1000/imagenet-mini/train'\n    valid_path = '../input/imagenetmini-1000/imagenet-mini/val'\n\n\n    number_of_classes = 1000\n    # number_of_classes = 7\n\n    filters = [64] * 3 + [128] * 4 + [256] * 6 + [512] * 3\n    # filters = [64] * 1 + [128] * 2 + [256] * 2 + [512] * 1\n    downsample_factor = 64\n\n    IMG_SIZE = 7 * downsample_factor\n    batch_size = 32\n    learning_rate = .01","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class input_data:\n    def construct_dataset(path, batch=cfg.batch_size, infinite=False):\n        def get_image(filename):\n            image = tf.io.read_file(filename)\n            image = tf.image.decode_jpeg(image, channels=3)\n            image = tf.image.resize_with_crop_or_pad(image, cfg.IMG_SIZE, cfg.IMG_SIZE)\n            return image\n\n        def configure_for_performance(ds):\n            ds = ds.shuffle(buffer_size=1000)\n            ds = ds.batch(batch)\n            if infinite:\n                ds = ds.repeat()\n            ds = ds.prefetch(buffer_size=AUTOTUNE)\n            return ds\n\n        def one_hot(label):\n            return tf.one_hot(label, len(classes))\n\n\n    #     classes = ['n01644900', 'n01847000', 'n01990800', 'n02108000', 'n02111500', 'n04200800', 'n07614500',]\n    #     filenames = glob(path + '/*00/*')\n\n        classes = os.listdir(path)\n        filenames = glob(path + '/*/*')\n        random.shuffle(filenames)\n        labels = [classes.index(name.split('/')[-2]) for name in filenames]\n\n        filenames_ds = tf.data.Dataset.from_tensor_slices(filenames)\n        images_ds = filenames_ds.map(get_image, num_parallel_calls=AUTOTUNE)\n        labels_ds = tf.data.Dataset.from_tensor_slices(labels).map(one_hot, num_parallel_calls=AUTOTUNE)\n\n        ds = tf.data.Dataset.zip((images_ds, labels_ds))\n        ds = configure_for_performance(ds)\n\n        return ds","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class layers:\n    class ResidualUnit(keras.layers.Layer):\n        def __init__(self, filters, strides, activation='relu', **kwargs):\n            super().__init__(**kwargs)\n\n            self.activation = keras.activations.get(activation)\n            self.layers = [\n                keras.layers.Conv2D(filters, 3, strides, padding='same', use_bias=False),\n                keras.layers.BatchNormalization(),\n                self.activation,\n                keras.layers.Conv2D(filters, 3, 1, padding='same', use_bias=False),\n                keras.layers.BatchNormalization(),\n            ]\n\n            if strides == 1:\n                self.skip = []\n            else:\n                self.skip = [\n                    keras.layers.Conv2D(filters, 1, strides, padding='same', use_bias=False),\n                    keras.layers.BatchNormalization(),\n                ]\n\n\n        def __call__(self, inputs):\n            Z = Z_skip = inputs\n            for layer in self.layers:\n                Z = layer(Z)\n            for layer in self.skip:\n                Z_skip = layer(Z_skip)\n            return self.activation(Z + Z_skip)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def build_model():\n    model = keras.models.Sequential()\n    model.add(keras.layers.Conv2D(64, 7, strides=2, padding='same', input_shape=(None, None, 3)))\n    model.add(keras.layers.BatchNormalization())\n    model.add(keras.layers.Activation('relu'))\n    model.add(keras.layers.MaxPool2D(pool_size=3, strides=2, padding=\"same\"))\n\n    prev_filters = cfg.filters[0]\n    for filters in cfg.filters:\n        strides = 1 if filters == prev_filters else 2\n        model.add(layers.ResidualUnit(filters, strides))\n\n    model.add(keras.layers.GlobalAveragePooling2D())\n    model.add(keras.layers.Flatten())\n    model.add(keras.layers.Dense(cfg.number_of_classes, 'softmax'))\n\n    model.compile(optimizer=keras.optimizers.SGD(learning_rate=cfg.learning_rate,\n                                                 momentum=.9,\n                                                 nesterov=True),\n                  loss=tf.keras.losses.CategoricalCrossentropy(),\n                  metrics=['accuracy', 'top_k_categorical_accuracy'],\n                  steps_per_execution=4)\n\n    return model","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = build_model()\n# model.summary()\n\ntrain = input_data.construct_dataset(cfg.train_path, infinite=True)\nvalid = input_data.construct_dataset(cfg.valid_path)\n\n\nlog_dir = 'logs/' + datetime.datetime.now().strftime('%Y-%m-%d_%H:%M:%S')\ntensor_board = keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1)\nlr_schedule = tf.keras.callbacks.ReduceLROnPlateau(patience=4)\n\nmodel.fit(train, \n          batch_size=cfg.batch_size, \n          validation_data=valid,\n          epochs=300, \n          steps_per_epoch=200,\n          callbacks=[tensor_board, lr_schedule])","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}