{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport tensorflow as tf\nimport matplotlib.pyplot as plt\nfrom matplotlib import image\nfrom matplotlib import pyplot\nimport os\nimport cv2\nimport random\nimport concurrent.futures\nimport time\nimport sklearn\nprint(tf.__version__)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"resolver = tf.distribute.cluster_resolver.TPUClusterResolver(tpu='')\ntf.config.experimental_connect_to_cluster(resolver)\n# This is the TPU initialization code that has to be at the beginning.\ntf.tpu.experimental.initialize_tpu_system(resolver)\nprint(\"All devices: \", tf.config.list_logical_devices('TPU'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train = pd.read_csv(\"../input/hpa-single-cell-image-classification/train.csv\", dtype=str)\ntrain['image_name'] = [i+\"_green.png\" for i in train['ID'].values]\ntrain.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"label_list=[\"Nucleoplasm\", \"Nuclear membrane\", \"Nucleoli\", \"Nucleoli fibrillar center\", \"Nuclear speckles\",\\\n            \"Nuclear bodies\", \"Endoplasmic reticulum\", \"Golgi apparatus\", \"Intermediate filaments\", \\\n            \"Actin filaments\", \"Microtubules\", \"Mitotic spindle\", \"Centrosome\", \"Plasma membrane\", \\\n            \"Mitochondria\", \"Aggresome\", \"Cytosol\", \"Vesicles and punctate cytosolic patterns\", \"Negative\"\n           ]\nimg_names = train[\"image_name\"]\ndef cvt_multi_labels(labellist, splitter='|'):\n    labels = []\n    for label in labellist:\n        l=np.zeros(len(label_list))\n        for ele in label:\n            if(ele != splitter):\n                l[int(ele)]=1\n        labels.append(list(l))\n    return labels\n\nlabels = cvt_multi_labels(train['Label'])\ndef myfunc():\n    return 0.5\nc = list(zip(img_names, labels))\nrandom.shuffle(c, myfunc)\nimg_names, labels = zip(*c)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"IMSIZE = 256\ndef read_img(image):\n    img = tf.keras.preprocessing.image.load_img(image, color_mode='rgb', target_size=(IMSIZE, IMSIZE))\n    return img\ndef prepare_dataset(namelist, labels, path):\n    start = time.time()\n    labels = np.array(labels)\n    labels = tf.convert_to_tensor(labels)\n    labels = tf.cast(labels, tf.int8)\n    namelist = [os.path.join(path, ele) for ele in namelist]\n    imgs = []\n    with concurrent.futures.ThreadPoolExecutor(max_workers = 16) as executor:\n        i = 0\n        for value in executor.map(read_img, namelist):\n            i+=1\n            print(\"\\rFetching: [{}/{}]\".format(i, len(namelist)), end=\"\", flush=True)\n            imgs.append(value)\n        imgs = np.stack(imgs)\n        imgs = tf.convert_to_tensor(imgs)\n    print(\"\\nExecution time: \",time.time() - start, \"s\")\n    return imgs, labels\n ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"with tf.device('/cpu:0'):\n    path = '../input/hpa-single-cell-image-classification/train'\n    TRAIN_SIZE = 10000\n    VAL_SIZE = 2000\n    train_images, train_labels = prepare_dataset(img_names[:TRAIN_SIZE], labels[:TRAIN_SIZE], path)\n    val_images, val_labels = prepare_dataset(img_names[TRAIN_SIZE:VAL_SIZE+TRAIN_SIZE], \\\n                                             labels[TRAIN_SIZE:VAL_SIZE+TRAIN_SIZE], path)\nprint(\"Training Image tensor shape\", train_images.shape)\nprint(\"Training Labels tensor shape\", train_labels.shape)\nprint(\"Testing Image tensor shape\", val_images.shape)\nprint(\"Tesing Labels tensor shape\", val_labels.shape)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"SEED = 100\nrandom_rotation = tf.keras.layers.experimental.preprocessing.RandomRotation(3.142/2, seed=SEED)\nrandom_flip = tf.keras.layers.experimental.preprocessing.RandomFlip(mode=\"horizontal_and_vertical\", seed=SEED)\nrandom_zoom = tf.keras.layers.experimental.preprocessing.RandomZoom((0, 0.25), seed=SEED)\nrandom_translate = tf.keras.layers.experimental.preprocessing.RandomTranslation((-0, 0.25), (-0, 0.25), seed=SEED)\n\nwith tf.device('/cpu:0'):\n    BATCH_SIZE = 128\n    train_dataset = tf.data.Dataset.from_tensor_slices((tf.cast(train_images, tf.uint8), tf.cast(train_labels, tf.uint8))).batch(BATCH_SIZE)\n    train_dataset = train_dataset.prefetch(buffer_size = tf.data.AUTOTUNE).shuffle(TRAIN_SIZE)\n    del train_images, train_labels\n    val_dataset = tf.data.Dataset.from_tensor_slices((tf.cast(val_images, tf.uint8), tf.cast(val_labels, tf.uint8))).batch(16)\n    val_dataset = train_dataset.prefetch(buffer_size = tf.data.AUTOTUNE).shuffle(VAL_SIZE)\n    del val_images, val_labels\ndef normalize_train(imgs, label):\n    imgs = random_rotation.call(imgs)\n    imgs = random_flip.call(imgs)\n    imgs = random_zoom.call(imgs)\n    imgs = random_translate.call(imgs)\n    return tf.cast(imgs, tf.float16)/255, label\ndef normalize_val(imgs, label):\n    return tf.cast(imgs, tf.float16)/255, label\ntrain_dataset = train_dataset.map(normalize_train, num_parallel_calls=4)\nval_dataset = val_dataset.map(normalize_val, num_parallel_calls=4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"strategy = tf.distribute.experimental.TPUStrategy(resolver)\nwith strategy.scope():\n    base_model = tf.keras.applications.MobileNetV2(include_top=False, input_shape=(256,256,3),\\\n                                                   weights='imagenet', pooling = 'max')\n    model = tf.keras.Sequential([\n        base_model,\n        tf.keras.layers.Dense(19, activation='sigmoid')\n    ])\n    optimizer = tf.keras.optimizers.Adam(0.0001)\nloss_object = tf.keras.losses.BinaryCrossentropy(from_logits=True, reduction=tf.keras.losses.Reduction.NONE)\ntrain_loss_history = []\nval_loss_history = []\ndist_train_dataset = strategy.experimental_distribute_dataset(train_dataset)\ndist_val_dataset = strategy.experimental_distribute_dataset(val_dataset)\nepoch_auc = tf.keras.metrics.AUC(num_thresholds=200, multi_label=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.metrics import accuracy_score\ndef compute_loss(labels, predictions):\n    per_example_loss = loss_object(labels, predictions)\n    return tf.nn.compute_average_loss(per_example_loss, global_batch_size=BATCH_SIZE)\ndef compute_acc(labels, predictions):\n    return accuracy_score(labels, predictions)\ndef train_step(inputs):\n    images, labels = inputs\n    with tf.GradientTape() as tape:\n        logits = model(images, training=True)\n        loss_value = compute_loss(labels, logits)\n        epoch_auc.update_state(labels, logits)\n        auc = epoch_auc.result()\n    train_loss_history.append(loss_value)\n    grads = tape.gradient(loss_value, model.trainable_variables)\n    optimizer.apply_gradients(zip(grads, model.trainable_variables))\n    return loss_value, auc\n@tf.function\ndef distributed_train_step(dist_inputs):\n    per_replica_losses, per_replica_auc = strategy.run(train_step, args=(dist_inputs,))\n    loss = strategy.reduce(tf.distribute.ReduceOp.SUM, per_replica_losses,\n                         axis=None)\n    auc = strategy.reduce(tf.distribute.ReduceOp.SUM, per_replica_auc,\n                         axis=None)\n    return loss, auc\ndef val_step(inputs):\n    images, labels = inputs\n    with tf.GradientTape() as tape:\n        logits = model(images, training=False)\n        loss_value = compute_loss(labels, logits)\n        epoch_auc.update_state(labels, logits)\n        auc = epoch_auc.result()\n    val_loss_history.append(loss_value)\n    return loss_value, auc\n@tf.function\ndef distributed_val_step(dist_inputs):\n    per_replica_losses, per_replica_auc = strategy.run(val_step, args=(dist_inputs,))\n    loss = strategy.reduce(tf.distribute.ReduceOp.SUM, per_replica_losses,\n                         axis=None)\n    auc = strategy.reduce(tf.distribute.ReduceOp.SUM, per_replica_auc,\n                         axis=None)\n    return loss, auc\ndef train(epochs):\n    for epoch in range(epochs):\n        start = time.time()\n        i = 0\n        print ('\\nEpoch {}/{} '.format(epoch+1, epochs))\n        for data in dist_train_dataset:\n            loss, auc = distributed_train_step(data)\n            \n            percent = float(i+1) * 100 / len(train_dataset)\n            arrow   = '-' * int(percent/100 * 10 - 1) + '>'\n            spaces  = ' ' * (10 - len(arrow))\n            print('\\rTraining: [%s%s] %d %% - Training Loss: %f - Training AUC: %f'% (arrow, spaces, percent, loss, auc), end='', flush=True)\n            i += 1\n        i = 0\n        print(\" -\", int(time.time()-start), \"s\", end=\"\")\n        print()\n        start = time.time()\n        for data in dist_val_dataset:\n            loss, auc = distributed_val_step(data)\n            percent = float(i+1) * 100 / len(val_dataset)\n            arrow   = '-' * int(percent/100 * 10 - 1) + '>'\n            spaces  = ' ' * (10 - len(arrow))\n            print('\\rValidate: [%s%s] %d %% - Validation Loss: %f - Validation AUC: %f'% (arrow, spaces, percent, loss, auc), end='', flush=True)\n            i += 1\n        print(\" -\", int(time.time()-start), \"s\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train(15)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.save('./mobilenetv2.h5')","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}