{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Introduction\n* InChI descirbes many molecular information in terms of layers of information.\n* So one of approach to construct InChI descriptions is to determine all layers one by one.\n* At first, I determine chiralities of chemical substances, which is provided by InChI layers starting with prefix \"s\".\n* The dataset used in this code are avairable from [here](https://www.kaggle.com/wineplanetary/bms-arranged-label), which is produced by [this notebook](https://www.kaggle.com/wineplanetary/understanding-inchi-format-and-arrange-train-label)\n\n## Chirality\n* A stereochemical layer have a type of stereochemistry information, which always have a prefix \"s\".\n* Stereochemistry sublayer (perhaps) shows a chemical substance have chirality.\n* I determine stereochemistry information in the first place by CNN.\n![chirality (from wikipedia)](https://upload.wikimedia.org/wikipedia/commons/thumb/4/4a/Zwitterion-Alanine.png/1920px-Zwitterion-Alanine.png)\nimage from wikipedia\n\n\n## References and Acknowledgements\n* Dataset\n * https://www.kaggle.com/wineplanetary/bms-arranged-label\n* Notebook\n * https://www.kaggle.com/wineplanetary/understanding-inchi-format-and-arrange-train-label\n* Others\n * https://ja.wikipedia.org/wiki/InChI"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"!pip install albumentations\n!pip install -U efficientnet","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nimport glob\nimport json\nimport random\nimport itertools\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom sklearn.metrics import accuracy_score\nfrom sklearn.model_selection import train_test_split\n\nimport tensorflow as tf\n\nimport keras\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.experimental import CosineDecay\nfrom tensorflow.keras.callbacks import ModelCheckpoint\nfrom tensorflow.keras.losses import BinaryCrossentropy\nfrom tensorflow.keras.applications import EfficientNetB4\nfrom tensorflow.keras.models import Sequential, load_model\nfrom tensorflow.keras.layers import GlobalAveragePooling2D, Dense\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\nimport albumentations as A","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class CFG:\n    seed = 12345\n    norm_mean = [0.485, 0.456, 0.406]\n    norm_std = [0.229, 0.224, 0.225]\n    batch_size = 16\n    init_lr = 1e-3\n    epochs = 3\n    img_size = 380\n    class_mode = \"binary\"\n    n_CLASS = 2\n    interpolation = \"nearest\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# seed\ntf.random.set_seed(CFG.seed)\nnp.random.seed(CFG.seed)\nrandom.seed(CFG.seed)\nos.environ[\"PYTHONHASHSEED\"] = str(CFG.seed)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_dir = \"../input/bms-molecular-translation/train\"\nchbtmspath = \"../input/bms-arranged-label/arranged_bms_train_labels.csv\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_org = pd.read_csv(chbtmspath)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data = data_org[[\"image_path\"]].copy()\ndata[\"label\"] = data_org[\"s_flg\"].astype(\"str\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# I was truncate data to 50000 due to the calculation time, but more data would be increase your accuracy\ntrue_data = data[data[\"label\"] == \"1\"]\nfalse_data = data[data[\"label\"] == \"0\"].sample(n=true_data.shape[0], random_state=CFG.seed)\ndata = pd.concat([true_data, false_data], ignore_index=True).sample(n=50000, random_state=CFG.seed)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_augumentation = A.Compose([\n                        A.Normalize(mean=CFG.norm_mean, std=CFG.norm_std, max_pixel_value=255, p=1.0),\n])\n\nval_augumentation = A.Compose([\n                        A.Normalize(mean=CFG.norm_mean, std=CFG.norm_std, max_pixel_value=255, p=1.0),\n])\n\n\ndef train_trans_func(image):\n    image = train_augumentation(image=image.astype(np.uint8))[\"image\"]\n    return image\n\ndef val_trans_func(image):\n    image = val_augumentation(image=image.astype(np.uint8))[\"image\"]\n    return image","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"datagen_train = ImageDataGenerator(preprocessing_function = train_trans_func)\ndatagen_val = ImageDataGenerator(preprocessing_function = val_trans_func)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def create_train_set(train):\n    train_set = datagen_train.flow_from_dataframe(train,\n                                 directory = None,\n                                 seed = CFG.seed,\n                                 x_col = \"image_path\",\n                                 y_col = \"label\",\n                                 target_size = (CFG.img_size, CFG.img_size),\n                                 class_mode = CFG.class_mode,\n                                 interpolation = CFG.interpolation,\n                                 shuffle = True,\n                                 batch_size = CFG.batch_size)\n    return train_set\n    \ndef create_val_set(val):\n    val_set = datagen_val.flow_from_dataframe(val,\n                                 directory = None,\n                                 seed=CFG.seed,\n                                 x_col = \"image_path\",\n                                 y_col = \"label\",\n                                 target_size = (CFG.img_size, CFG.img_size),\n                                 class_mode = CFG.class_mode,\n                                 interpolation = CFG.interpolation,\n                                 shuffle = True,\n                                 batch_size = CFG.batch_size)\n    return val_set","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train, val = train_test_split(data, \n                              test_size=0.05,\n                              random_state=CFG.seed,\n                              stratify=data[\"label\"])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"valid_set = create_val_set(val)\ntrain_set = create_train_set(train)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def create_model():\n    model = Sequential()\n    model.add(EfficientNetB4(input_shape = (CFG.img_size, CFG.img_size, 3), \n                             include_top=False,\n                             weights = \"imagenet\",\n                             drop_connect_rate=0.6))\n    model.add(GlobalAveragePooling2D())\n    model.add(Dense(1, activation=\"sigmoid\"))\n    return model\n\nmodel = create_model()\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"step_size_train = train_set.n // train_set.batch_size\nstep_size_valid = valid_set.n // valid_set.batch_size","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = create_model()\n    \nloss = BinaryCrossentropy(from_logits = False,\n                          name=\"binary_crossentropy\")\n\nlr = CosineDecay(initial_learning_rate = CFG.init_lr,\n                 decay_steps = step_size_train * CFG.epochs)\n\nmodel.compile(optimizer = Adam(learning_rate=lr),\n              loss=loss,\n              metrics=[\"binary_accuracy\"])\n\ncheckpoint_cb = ModelCheckpoint(\"bms_s_best_model.h5\",\n                                save_best_only=True,\n                                monitor=\"val_loss\",\n                                mode=\"min\")\n\n# history = model.fit(train_set,\n#                     validation_data = valid_set,\n#                     epochs = CFG.epochs,\n#                     batch_size = CFG.batch_size,\n#                     steps_per_epoch = step_size_train,\n#                     validation_steps = step_size_valid,\n#                     callbacks=[checkpoint_cb])\n\n# model.save(\"bms_s_model.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}