{"cells":[{"metadata":{"trusted":true,"_uuid":"f5c4cb64fd9a397ae679599a68cf72c929d06d39"},"cell_type":"code","source":"import os\nimport re\nimport numpy as np\nimport pandas as pd\nfrom matplotlib import pyplot as plt\nimport cv2\nfrom PIL import Image\nfrom imgaug import augmenters as iaa\nimport requests\nfrom bs4 import BeautifulSoup\nfrom io import BytesIO\nfrom glob import glob\nfrom tqdm import tqdm\nfrom sklearn.utils import shuffle\nfrom itertools import chain\nfrom collections import Counter\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\nprint(os.listdir('../input'))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# From https://www.proteinatlas.org/download/subcellular_location.tsv.zip\nsubcellular_location = pd.read_csv('../input/external-data-for-protein-atlas/subcellular_location.tsv', sep=\"\\t\", index_col = None)\n\n# Get urls\nurls = []\nfor name in subcellular_location[['Gene', 'Gene name']].values:  \n    name = '-'.join(name)\n    url = ('https://www.proteinatlas.org/'+name+'/antibody#ICC')\n    urls.append(url)\n    \ndef get_html(url):\n    response = requests.get(url)\n    return response.text\n    \ndef load_img(url):\n    html = get_html(url)\n    soup = BeautifulSoup(html, 'lxml')\n    links = []\n    for a in soup.findAll('a', {'class':'colorbox'}, href=True):\n        if '_selected' in  a['href']:\n            links.append(''.join(('https://www.proteinatlas.org'+a['href']).split('_medium')))\n    i = 0\n    for link in set(links):\n        try:\n            name = url.split('/')[-2]        \n            response = requests.get(link)\n            img = Image.open(BytesIO(response.content))\n            if np.array(img)[:,:,0].mean()<70:\n                img.save('external_data/'+name+'_'+str(i)+'.png')\n                i+=1\n        except:\n            pass","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0d10768ce112009d2606ce71c0df88caf3ee6c89"},"cell_type":"code","source":"subcellular_location.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ea6c9aab5bc390982c05da34cf1f3f42adf57194"},"cell_type":"code","source":"# Pages with images\nurls[:10]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"36eb77809052c0a912c8be63404e3e28cf2a2f68"},"cell_type":"code","source":"label_names = {\n    0:  \"Nucleoplasm\", \n    1:  \"Nuclear membrane\",   \n    2:  \"Nucleoli\",   \n    3:  \"Nucleoli fibrillar center\" ,  \n    4:  \"Nuclear speckles\",\n    5:  \"Nuclear bodies\",\n    6:  \"Endoplasmic reticulum\",   \n    7:  \"Golgi apparatus\",\n    8:  \"Peroxisomes\",\n    9:  \"Endosomes\",\n    10:  \"Lysosomes\",\n    11:  \"Intermediate filaments\",   \n    12:  \"Actin filaments\",\n    13:  \"Focal adhesion sites\",   \n    14:  \"Microtubules\",\n    15:  \"Microtubule ends\",   \n    16:  \"Cytokinetic bridge\",   \n    17:  \"Mitotic spindle\",\n    18:  \"Microtubule organizing center\",  \n    19:  \"Centrosome\",\n    20:  \"Lipid droplets\",   \n    21:  \"Plasma membrane\",   \n    22:  \"Cell junctions\", \n    23:  \"Mitochondria\",\n    24:  \"Aggresome\",\n    25:  \"Cytosol\",\n    26:  \"Cytoplasmic bodies\",   \n    27:  \"Rods & rings\"\n}\n\nall_label_names = {\n    0:  \"Nucleoplasm\", \n    1:  \"Nuclear membrane\",   \n    2:  \"Nucleoli\",   \n    3:  \"Nucleoli fibrillar center\" ,  \n    4:  \"Nuclear speckles\",\n    5:  \"Nuclear bodies\",\n    6:  \"Endoplasmic reticulum\",   \n    7:  \"Golgi apparatus\",\n    8:  \"Peroxisomes\",\n    9:  \"Endosomes\",\n    10:  \"Lysosomes\",\n    11:  \"Intermediate filaments\",   \n    12:  \"Actin filaments\",\n    13:  \"Focal adhesion sites\",   \n    14:  \"Microtubules\",\n    15:  \"Microtubule ends\",   \n    16:  \"Cytokinetic bridge\",   \n    17:  \"Mitotic spindle\",\n    18:  \"Microtubule organizing center\",  \n    19:  \"Centrosome\",\n    20:  \"Lipid droplets\",   \n    21:  \"Plasma membrane\",   \n    22:  \"Cell junctions\", \n    23:  \"Mitochondria\",\n    24:  \"Aggresome\",\n    25:  \"Cytosol\",\n    26:  \"Cytoplasmic bodies\",   \n    27:  \"Rods & rings\",\n    # new classes          \n    28: \"Vesicles\",\n    29: \"Nucleus\",\n    30: \"Midbody\",\n    31: \"Cell Junctions\",\n    32: \"Midbody ring\",\n    33: \"Cleavage furrow\"\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"571222d59e4afd80917220f39b0bd837630e63c0"},"cell_type":"code","source":"all_names = []\nfor j in tqdm(range(len(subcellular_location))):\n    names = np.array(subcellular_location[['Enhanced', 'Supported', 'Approved', 'Uncertain']].values[j])\n    names = [name for name in names if str(name) != 'nan']\n    split_names = []\n    for i in range(len(names)):\n        split_names = split_names + (names[i].split(';'))\n    all_names.append(split_names)\nsubcellular_location['names'] = all_names","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"eb52c9de01181818a0fb8b7fafeacc197aa8875b"},"cell_type":"code","source":"img = Image.open(glob('../input/external-data-for-protein-atlas/external_data/*')[1])\nprint(img.size)\nimg","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4b6b2fb6c4884fb32ae7cfb7034f2bb0273a00c5"},"cell_type":"code","source":"# Only old names\ndata_list = []\nfor i in tqdm(range(len(subcellular_location))):\n    im_name  = subcellular_location['Gene'].values[i]+'-'+subcellular_location['Gene name'].values[i]\n    for im in glob('../input/external-data-for-protein-atlas/external_data/'+im_name+'*'):\n        labels = []\n        for name in subcellular_location['names'].values[i]:\n            try:\n                if name == 'Rods & Rings': name = \"Rods & rings\"\n                labels.append(list(label_names.values()).index(name))          \n            except:\n                pass\n        if len(labels)>0:\n            data_list.append([im.split('/')[-1].split('.png')[0], subcellular_location['names'].values[i], labels])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2e9cc57279b86e17ebc47f03a9e57c781cb3ec0f"},"cell_type":"code","source":"data = pd.DataFrame(data_list, columns = ['Id', 'Names', 'Target'])\ndata.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c93abcef6a0b0c765f362a3f161f6323712ce273"},"cell_type":"code","source":"len(data)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b9b4feb015243f698a08258bfb25082a9333f9d7"},"cell_type":"code","source":"SIZE = 604\nepochs = 16\nbatch_size = 16","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6013838096aaef3ef75a7e889cc979df2d75d90e"},"cell_type":"code","source":"# Load dataset info\npath_to_train = '../input/external-data-for-protein-atlas/external_data/'\n\ntrain_dataset_info = []\nfor name, labels in zip(data['Id'], data['Target']): \n    train_dataset_info.append({\n        'path':os.path.join(path_to_train, name),\n        'labels':np.array([int(label) for label in labels])})\ntrain_dataset_info = np.array(train_dataset_info)\ntrain_dataset_info[0]['path']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ea9ac1a53f8f66c0beb520a8768d81bce8d417a2"},"cell_type":"code","source":"# Create generator\nclass data_generator:\n    \n    def create_train(dataset_info, batch_size, shape, augument=True):\n        while True:\n            dataset_info = shuffle(dataset_info)\n            for start in range(0, len(dataset_info), batch_size):\n                end = min(start + batch_size, len(dataset_info))\n                batch_images = []\n                X_train_batch = dataset_info[start:end]\n                batch_labels = np.zeros((len(X_train_batch), 28))\n                for i in range(len(X_train_batch)):\n                    image = data_generator.load_image(\n                        X_train_batch[i]['path'], shape)  \n                    if augument:\n                        image = data_generator.augment(image)\n                    batch_images.append(image/255.)\n                    batch_labels[i][X_train_batch[i]['labels']] = 1\n                try:\n                    yield np.array(batch_images, np.float32), batch_labels\n                except:\n                    pass\n                \n    def load_image(path, shape):\n        image_rgb = Image.open(path+'.png')\n        image_rgba = image_rgb.convert('RGBA')\n        image = cv2.resize(np.array(image_rgba), (shape[0], shape[1]))\n        return image\n\n    def augment(image):\n        augment_img = iaa.Sequential([\n            iaa.OneOf([\n                iaa.Affine(rotate=0),\n                iaa.Affine(rotate=90),\n                iaa.Affine(rotate=180),\n                iaa.Affine(rotate=270),\n                iaa.Fliplr(0.5),\n                iaa.Flipud(0.5),\n            ])], random_order=True)\n        image_aug = augment_img.augment_image(image)\n        return image_aug","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a22b54be1e7b557e3c8f2442e032d3372f0556cc"},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\n# Split data into train, valid\nindexes = np.arange(train_dataset_info.shape[0])\nnp.random.shuffle(indexes)\ntrain_indexes, valid_indexes = train_test_split(indexes, test_size=0.15, random_state=21)\n\n# Create train and valid data generetors\ntrain_generator = data_generator.create_train(\n    train_dataset_info[train_indexes], batch_size, (SIZE, SIZE, 4), augument=True)\nvalidation_generator = data_generator.create_train(\n    train_dataset_info[valid_indexes], 32, (SIZE, SIZE, 4), augument=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7e293cdc18d5e9f50b373c905d4fc4c3cfd5f8a4"},"cell_type":"code","source":"import keras\nfrom keras.layers.merge import concatenate\nfrom keras.models import Sequential, Model\nfrom keras.layers import Input, Dense, Dropout, Flatten, BatchNormalization, Conv2D, MaxPooling2D\nfrom keras.applications.xception import Xception\nfrom keras import metrics\nfrom keras.optimizers import Adam \n\n# Model    \ndef create_model(input_shape, n_out):\n    input_tensor = Input(shape=input_shape)\n    \n    ### For External\n    base_model = Xception(include_top=False,\n                   weights='imagenet', \n                   input_shape=(299, 299, 3),\n                   pooling='avg')\n    x = BatchNormalization()(input_tensor)\n    x = Conv2D(32, kernel_size=(3,3), activation='relu')(x) \n    x = BatchNormalization()(x)\n    x = Conv2D(32, kernel_size=(3,3), activation='relu')(x) \n    x = BatchNormalization()(x)\n    x = Conv2D(3, kernel_size=(3,3), activation='relu')(x) \n    x = BatchNormalization()(x)\n    x = MaxPooling2D(pool_size=(2,2))(x)\n    x = base_model(x) \n    x = Dense(1024, activation='relu')(x)\n    x = Dense(1024, activation='relu')(x)\n    output = Dense(n_out, activation='sigmoid')(x)\n    model = Model(input_tensor, output)\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"10dc0915fbafc261dd9be5a69f2615c24a1d88dd"},"cell_type":"code","source":"# Train external and save weight, then create new model for real data and load external weight.\n\nmodel = create_model(\n    input_shape=(SIZE, SIZE, 4), \n    n_out=28)\n\n# Train all layers\nfor layer in model.layers:\n    layer.trainable = True\n    \nmodel.summary()\n    \nmodel.compile(loss='binary_crossentropy',\n            optimizer=Adam(lr=1e-4),\n            metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"06fb1d21ee4b5eb3ee3dc7417c1282b64f35ffe6"},"cell_type":"code","source":"from keras.callbacks import ModelCheckpoint\n\ncheckpointer = ModelCheckpoint(filepath='external_weights.h5', verbose=1, save_best_only=True)\nmodel.fit_generator(\n    train_generator,\n    steps_per_epoch=np.ceil(float(len(train_indexes)) / float(batch_size)),\n    validation_data=validation_generator,\n    validation_steps=np.ceil(float(len(valid_indexes)) / float(batch_size)),\n    epochs=epochs, verbose=1, callbacks=[checkpointer])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b2fa7bade691355383b61bb31ae1f07125796124"},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}