{"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":"markdown","source":"# [Thanks to the starter kernel provided by @tlorieul](https://www.kaggle.com/code/tlorieul/geolifeclef2022-data-loading-and-visualization)","metadata":{}},{"cell_type":"code","source":"CUDA_LAUNCH_BLOCKING=\"1\"","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:41:26.055667Z","iopub.execute_input":"2022-04-17T15:41:26.055945Z","iopub.status.idle":"2022-04-17T15:41:26.060543Z","shell.execute_reply.started":"2022-04-17T15:41:26.055914Z","shell.execute_reply":"2022-04-17T15:41:26.059234Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install pretrainedmodels","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:41:26.069045Z","iopub.execute_input":"2022-04-17T15:41:26.069253Z","iopub.status.idle":"2022-04-17T15:41:35.226254Z","shell.execute_reply.started":"2022-04-17T15:41:26.069229Z","shell.execute_reply":"2022-04-17T15:41:35.225407Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch.nn as nn\nimport torch.optim as optim\nfrom torchvision import datasets, transforms\nimport torch.nn.functional as F\nimport pretrainedmodels","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:41:35.228448Z","iopub.execute_input":"2022-04-17T15:41:35.228710Z","iopub.status.idle":"2022-04-17T15:41:35.234745Z","shell.execute_reply.started":"2022-04-17T15:41:35.228682Z","shell.execute_reply":"2022-04-17T15:41:35.233976Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%pylab inline --no-import-all\n\nimport os\nfrom pathlib import Path\n\nimport pandas as pd\n\n\n# Change this path to adapt to where you downloaded the data\nDATA_PATH = Path(\"../input/geolifeclef-2022-lifeclef-2022-fgvc9\")\n\n# Create the path to save submission files\nSUBMISSION_PATH = Path(\"submissions\")\nos.makedirs(SUBMISSION_PATH, exist_ok=True)\n\n# Clone the GitHub repository\n!rm -rf GLC\n!git clone https://github.com/maximiliense/GLC","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:41:35.236690Z","iopub.execute_input":"2022-04-17T15:41:35.237490Z","iopub.status.idle":"2022-04-17T15:41:38.125603Z","shell.execute_reply.started":"2022-04-17T15:41:35.237419Z","shell.execute_reply":"2022-04-17T15:41:38.124774Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import skimage.io\nfrom skimage.io import imread\nimport tifffile \nimport matplotlib\nimport matplotlib.pyplot as plt\nfrom matplotlib.patches import Patch\nfrom tqdm.notebook import tqdm\n\nimport cv2\nimport shutil, json\n\nimport tensorflow as tf\n\nimport glob, os\nimport seaborn as sns\nimport gc, pandas as pd, numpy as np\nimport warnings\nfrom warnings import WarningMessage, filterwarnings","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:41:38.128234Z","iopub.execute_input":"2022-04-17T15:41:38.129039Z","iopub.status.idle":"2022-04-17T15:41:38.135299Z","shell.execute_reply.started":"2022-04-17T15:41:38.128985Z","shell.execute_reply":"2022-04-17T15:41:38.134581Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\ndevice = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:41:38.136654Z","iopub.execute_input":"2022-04-17T15:41:38.137170Z","iopub.status.idle":"2022-04-17T15:41:38.148152Z","shell.execute_reply.started":"2022-04-17T15:41:38.137134Z","shell.execute_reply":"2022-04-17T15:41:38.147374Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_obs_fr_train = pd.read_csv(DATA_PATH / \"observations\" / \"observations_fr_train.csv\", sep=\";\", index_col=\"observation_id\", nrows = 10000)\ndf_obs_us_train = pd.read_csv(DATA_PATH / \"observations\" / \"observations_us_train.csv\", sep=\";\", index_col=\"observation_id\", nrows=10000)\n\ndf_obs_train = pd.concat((df_obs_fr_train, df_obs_us_train))\n\nobs_id_train = df_obs_train.index.values\n\nprint(\"Number of observations for testing: {}\".format(len(df_obs_train)))\n\ndf_obs_train.head()","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:41:38.150963Z","iopub.execute_input":"2022-04-17T15:41:38.151725Z","iopub.status.idle":"2022-04-17T15:41:38.193844Z","shell.execute_reply.started":"2022-04-17T15:41:38.151687Z","shell.execute_reply":"2022-04-17T15:41:38.193078Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_obs_train.longitude.isnull().sum()","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:41:38.195363Z","iopub.execute_input":"2022-04-17T15:41:38.195854Z","iopub.status.idle":"2022-04-17T15:41:38.203806Z","shell.execute_reply.started":"2022-04-17T15:41:38.195816Z","shell.execute_reply":"2022-04-17T15:41:38.202733Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from GLC.data_loading.environmental_raster import PatchExtractor\nfrom pathlib import Path\n#from GLC.data_loading.common import load_patch\n\n\nfrom torch.utils.data import Dataset, DataLoader","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:41:38.205343Z","iopub.execute_input":"2022-04-17T15:41:38.205798Z","iopub.status.idle":"2022-04-17T15:41:38.213034Z","shell.execute_reply.started":"2022-04-17T15:41:38.205754Z","shell.execute_reply":"2022-04-17T15:41:38.212242Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# plot environmental rasters","metadata":{}},{"cell_type":"code","source":"extractor_bio = PatchExtractor(DATA_PATH / \"rasters\", size=256)\nextractor_bio.add_all_bioclimatic_rasters()\nextractor_bio.append('sndppt')\nprint(\"Number of rasters: {}\".format(len(extractor_bio)))","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:41:38.216372Z","iopub.execute_input":"2022-04-17T15:41:38.217434Z","iopub.status.idle":"2022-04-17T15:41:59.983507Z","shell.execute_reply.started":"2022-04-17T15:41:38.217206Z","shell.execute_reply":"2022-04-17T15:41:59.982727Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = plt.figure(figsize=(14, 10))\nextractor_bio.plot((43.61, 3.88), fig=fig)","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:41:59.986678Z","iopub.execute_input":"2022-04-17T15:41:59.986927Z","iopub.status.idle":"2022-04-17T15:42:04.061769Z","shell.execute_reply.started":"2022-04-17T15:41:59.986894Z","shell.execute_reply":"2022-04-17T15:42:04.061157Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# another lat,long position\nfig = plt.figure(figsize=(14, 10))\nextractor_bio.plot((46.783695,2.072855), fig=fig)","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:04.062786Z","iopub.execute_input":"2022-04-17T15:42:04.063144Z","iopub.status.idle":"2022-04-17T15:42:08.006200Z","shell.execute_reply.started":"2022-04-17T15:42:04.063109Z","shell.execute_reply":"2022-04-17T15:42:08.005557Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"bio_batches = extractor_bio[(46.783695,2.072855)]\n","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:08.007203Z","iopub.execute_input":"2022-04-17T15:42:08.007547Z","iopub.status.idle":"2022-04-17T15:42:08.015052Z","shell.execute_reply.started":"2022-04-17T15:42:08.007517Z","shell.execute_reply":"2022-04-17T15:42:08.014101Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Arrays shape: {}\".format([p.shape for p in bio_batches]))\nprint(\"Data types: {}\".format([p.dtype for p in bio_batches]))","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:08.017229Z","iopub.execute_input":"2022-04-17T15:42:08.017598Z","iopub.status.idle":"2022-04-17T15:42:08.024732Z","shell.execute_reply.started":"2022-04-17T15:42:08.017555Z","shell.execute_reply":"2022-04-17T15:42:08.024019Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#bio_tuple = tuple(bio_batches)","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:08.026729Z","iopub.execute_input":"2022-04-17T15:42:08.026982Z","iopub.status.idle":"2022-04-17T15:42:08.031174Z","shell.execute_reply.started":"2022-04-17T15:42:08.026949Z","shell.execute_reply":"2022-04-17T15:42:08.030313Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.imshow(bio_batches[0])","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:08.032983Z","iopub.execute_input":"2022-04-17T15:42:08.033324Z","iopub.status.idle":"2022-04-17T15:42:08.243511Z","shell.execute_reply.started":"2022-04-17T15:42:08.033212Z","shell.execute_reply":"2022-04-17T15:42:08.242868Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#gc.collect()","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:08.244753Z","iopub.execute_input":"2022-04-17T15:42:08.245196Z","iopub.status.idle":"2022-04-17T15:42:08.248425Z","shell.execute_reply.started":"2022-04-17T15:42:08.245161Z","shell.execute_reply":"2022-04-17T15:42:08.247796Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**BDTICM**: Absolute depth to bedrock cm\n\n**BLDFIE**: Bulk density (fine earth) kg/m3\n\n**CECSOL**: Cation Exchange Capacity of soil cmolc/kg\n\n**CLYPPT**: Weight percentage of the clay particles (<0.0002 mm) percentage\n\n**ORCDRC**: Soil organic carbon content permille\n\n**PHIHOX**: pH index measured in water solution pH\n\n**SLTPPT**: Weight percentage of the silt particles (0.0002–0.05 mm) percentage\n\n**SNDPPT**: Weight percentage of the sand particles (0.05–2 mm) percentage","metadata":{}},{"cell_type":"markdown","source":"# We can use either extractor_bio or extractor_p","metadata":{}},{"cell_type":"code","source":"\"\"\"\nextractor_p = PatchExtractor(DATA_PATH / \"rasters\", size=256)\nextractor_p.append('bdticm')\nextractor_p.append('bldfie')\nextractor_p.append('cecsol')\nextractor_p.append('clyppt')\n\nextractor_p.append('phihox')\nextractor_p.append('orcdrc')\nextractor_p.append('sltppt')\n\n#extractor_p.append('sndppt')\n\"\"\"","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:08.249938Z","iopub.execute_input":"2022-04-17T15:42:08.250427Z","iopub.status.idle":"2022-04-17T15:42:08.260209Z","shell.execute_reply.started":"2022-04-17T15:42:08.250391Z","shell.execute_reply":"2022-04-17T15:42:08.259488Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#extractor_p.append('sndppt')","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:08.262068Z","iopub.execute_input":"2022-04-17T15:42:08.262567Z","iopub.status.idle":"2022-04-17T15:42:08.269724Z","shell.execute_reply.started":"2022-04-17T15:42:08.262531Z","shell.execute_reply":"2022-04-17T15:42:08.269017Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Pedologic factors for Montpellier region, Fr","metadata":{}},{"cell_type":"code","source":"#fig = plt.figure(figsize=(10, 10))\n#extractor_p.plot((43.61, 3.88), fig=fig)","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:08.271351Z","iopub.execute_input":"2022-04-17T15:42:08.271564Z","iopub.status.idle":"2022-04-17T15:42:08.278219Z","shell.execute_reply.started":"2022-04-17T15:42:08.271540Z","shell.execute_reply":"2022-04-17T15:42:08.277500Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# build dataset, dataloader","metadata":{}},{"cell_type":"code","source":"from albumentations import (\n    HorizontalFlip, VerticalFlip, IAAPerspective, ShiftScaleRotate, CLAHE, RandomRotate90,\n    Transpose, ShiftScaleRotate, Blur, OpticalDistortion, GridDistortion, HueSaturationValue,\n    IAAAdditiveGaussianNoise, GaussNoise, MotionBlur, MedianBlur, IAAPiecewiseAffine, RandomResizedCrop,\n    IAASharpen, IAAEmboss, RandomBrightnessContrast, Flip, OneOf, Compose, Normalize, Cutout, CoarseDropout, ShiftScaleRotate, CenterCrop, Resize\n)\n\nfrom albumentations.pytorch import ToTensorV2\n\ndef get_train_transforms():\n    return Compose([\n            #RandomResizedCrop(256, 256),\n            #Transpose(p=0.5),\n            HorizontalFlip(p=0.5),\n            VerticalFlip(p=0.5),\n            #ShiftScaleRotate(p=0.5),\n            #HueSaturationValue(hue_shift_limit=0.2, sat_shift_limit=0.2, val_shift_limit=0.2, p=0.5),\n            #RandomBrightnessContrast(brightness_limit=(-0.1,0.1), contrast_limit=(-0.1, 0.1), p=0.5),\n            Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225], max_pixel_value=255.0, p=1.0),\n            #CoarseDropout(p=0.5),\n            #Cutout(p=0.5),\n            ToTensorV2(p=1.0),\n        ], p=1.)\n  \n        \ndef get_valid_transforms():\n    return Compose([\n            CenterCrop(256,256, p=1.),\n            #Resize(CFG['img_size'], CFG['img_size']),\n            Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225], max_pixel_value=255.0, p=1.0),\n            ToTensorV2(p=1.0),\n        ], p=1.)","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:08.279731Z","iopub.execute_input":"2022-04-17T15:42:08.280302Z","iopub.status.idle":"2022-04-17T15:42:08.291178Z","shell.execute_reply.started":"2022-04-17T15:42:08.280255Z","shell.execute_reply":"2022-04-17T15:42:08.290308Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_patch(\n    observation_id,\n    patches_path,\n    *,\n    data=\"all\",\n    landcover_mapping=None,\n    return_arrays=True\n):\n    \"\"\"Loads the patch data associated to an observation id\n    Parameters\n    ----------\n    observation_id : integer\n        Identifier of the observation.\n    patches_path : string / pathlib.Path\n        Path to the folder containing all the patches.\n    data : string or list of string\n        Specifies what data to load, possible values: 'all', 'rgb', 'near_ir', 'landcover' or 'altitude'.\n    landcover_mapping : 1d array-like\n        Facultative mapping of landcover codes, useful to align France and US codes.\n    return_arrays : boolean\n        If True, returns all the patches as Numpy arrays (no PIL.Image returned).\n    Returns\n    -------\n    patches : tuple of size 4 containing 2d array-like objects\n        Returns a tuple containing all the patches in the following order: RGB, Near-IR, altitude and landcover.\n    \"\"\"\n    observation_id = str(observation_id)\n\n    region_id = observation_id[0]\n    if region_id == \"1\":\n        region = \"patches-fr\"\n    elif region_id == \"2\":\n        region = \"patches-us\"\n    else:\n        raise ValueError(\n            \"Incorrect 'observation_id' {}, can not extract region id from it\".format(\n                observation_id\n            )\n        )\n\n    subfolder1 = observation_id[-2:]\n    subfolder2 = observation_id[-4:-2]\n\n    filename = Path(patches_path) / region / subfolder1 / subfolder2 / observation_id\n\n    patches = []\n\n    if data == \"all\":\n        data = [\"rgb\", \"near_ir\", \"landcover\", \"altitude\"]\n\n    if \"rgb\" in data:\n        rgb_filename = filename.with_name(filename.stem + \"_rgb.jpg\")\n        rgb_patch = Image.open(rgb_filename)\n        if return_arrays:\n            rgb_patch = np.asarray(rgb_patch)\n        patches.append(rgb_patch)\n\n    if \"near_ir\" in data:\n        near_ir_filename = filename.with_name(filename.stem + \"_near_ir.jpg\")\n        near_ir_patch = Image.open(near_ir_filename)\n        if return_arrays:\n            near_ir_patch = np.asarray(near_ir_patch)\n        patches.append(near_ir_patch)\n\n    if \"altitude\" in data:\n        altitude_filename = filename.with_name(filename.stem + \"_altitude.tif\")\n        altitude_patch = tifffile.imread(altitude_filename)\n        patches.append(altitude_patch)\n\n    if \"landcover\" in data:\n        landcover_filename = filename.with_name(filename.stem + \"_landcover.tif\")\n        landcover_patch = tifffile.imread(landcover_filename)\n        #print (landcover_filename)\n        if landcover_mapping is not None:\n            landcover_patch = landcover_mapping[landcover_patch]\n        patches.append(landcover_patch)\n\n    return patches","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:08.292644Z","iopub.execute_input":"2022-04-17T15:42:08.293031Z","iopub.status.idle":"2022-04-17T15:42:08.307061Z","shell.execute_reply.started":"2022-04-17T15:42:08.292980Z","shell.execute_reply":"2022-04-17T15:42:08.306384Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#https://github.com/maximiliense/GLC/blob/master/data_loading/pytorch_dataset.py\nclass GeoLifeCLEF2022Dataset(Dataset):\n    \"\"\"Pytorch dataset handler for GeoLifeCLEF 2022 dataset.\n    Parameters\n    ----------\n    root : string or pathlib.Path\n        Root directory of dataset.\n    subset : string, either \"train\", \"val\", \"train+val\" or \"test\"\n        Use the given subset (\"train+val\" is the complete training data).\n    region : string, either \"both\", \"fr\" or \"us\"\n        Load the observations of both France and US or only a single region.\n    patch_data : string or list of string\n        Specifies what type of patch data to load, possible values: 'all', 'rgb', 'near_ir', 'landcover' or 'altitude'.\n    use_rasters : boolean (optional)\n        If True, extracts patches from environmental rasters.\n    patch_extractor : PatchExtractor object (optional)\n        Patch extractor to use if rasters are used.\n    transform : callable (optional)\n        A function/transform that takes a list of arrays and returns a transformed version.\n    target_transform : callable (optional)\n        A function/transform that takes in the target and transforms it.\n    \"\"\"\n\n    def __init__(\n        self,\n        root,\n        subset,\n        *,\n        region=\"both\",\n        patch_data=\"all\",\n        use_rasters=True,\n        patch_extractor=None,\n        transform=None,\n        target_transform=None\n    ):\n        self.root = Path(root)\n        self.subset = subset\n        self.region = region\n        self.patch_data = patch_data\n        self.transform = transform\n        self.target_transform = target_transform\n\n        possible_subsets = [\"train\", \"val\", \"train+val\", \"test\"]\n        if subset not in possible_subsets:\n            raise ValueError(\n                \"Possible values for 'subset' are: {} (given {})\".format(\n                    possible_subsets, subset\n                )\n            )\n\n        possible_regions = [\"both\", \"fr\", \"us\"]\n        if region not in possible_regions:\n            raise ValueError(\n                \"Possible values for 'region' are: {} (given {})\".format(\n                    possible_regions, region\n                )\n            )\n\n        if subset == \"test\":\n            subset_file_suffix = \"test\"\n            self.training_data = False\n        else:\n            subset_file_suffix = \"train\"\n            self.training_data = True\n\n        df_fr = pd.read_csv(\n            self.root\n            / \"observations\"\n            / \"observations_fr_{}.csv\".format(subset_file_suffix),\n            sep=\";\",\n            index_col=\"observation_id\",nrows = 50000\n        )\n        df_us = pd.read_csv(\n            self.root\n            / \"observations\"\n            / \"observations_us_{}.csv\".format(subset_file_suffix),\n            sep=\";\",\n            index_col=\"observation_id\",nrows =50000\n        )\n\n        if region == \"both\":\n            df = pd.concat((df_fr, df_us))\n        elif region == \"fr\":\n            df = df_fr\n        elif region == \"us\":\n            df = df_us\n\n        if self.training_data and subset != \"train+val\":\n            ind = df.index[df[\"subset\"] == subset]\n            df = df.loc[ind]\n\n        self.observation_ids = df.index\n        self.coordinates = df[[\"latitude\", \"longitude\"]].values\n\n        if self.training_data:\n            self.targets =df.species_id.values #torch.tensor(df[\"species_id\"].values, dtype = torch.long)\n        else:\n            self.targets = None\n\n        # FIXME: add back landcover one hot encoding?\n        # self.one_hot_size = 34\n        # self.one_hot = np.eye(self.one_hot_size)\n\n        if use_rasters:\n            if patch_extractor is None:\n                #from .environmental_raster import PatchExtractor\n\n                patch_extractor = PatchExtractor(self.root / \"rasters\", size=256)\n                patch_extractor.add_all_rasters()\n\n            self.patch_extractor = patch_extractor\n        else:\n            self.patch_extractor = None\n\n    def __len__(self):\n        return len(self.observation_ids)\n\n    def __getitem__(self, index):\n        latitude = self.coordinates[index][0]\n        longitude = self.coordinates[index][1]\n        observation_id = self.observation_ids[index]\n        try:\n            \n            patches = load_patch(\n                observation_id, self.root, data=self.patch_data\n            )\n        except ValueError:\n            pass\n            \n        patches = torch.Tensor(patches)\n        # FIXME: add back landcover one hot encoding?\n        # lc = patches[3]\n        # lc_one_hot = np.zeros((self.one_hot_size,lc.shape[0], lc.shape[1]))\n        # row_index = np.arange(lc.shape[0]).reshape(lc.shape[0], 1)\n        # col_index = np.tile(np.arange(lc.shape[1]), (lc.shape[0], 1))\n        # lc_one_hot[lc, row_index, col_index] = 1\n\n        # Extracting patch from rasters\n        if self.patch_extractor is not None:\n            # this will have all the bioclimatic or pedologic rasters for the specific lat, long position\n            print (observation_id, latitude, longitude)\n            environmental_patches = self.patch_extractor[(latitude, longitude)]\n            #patches = patches + torch.from_numpy(np.array(environmental_patches))\n            # convert list to pytorch tensor\n            #print (patches[0].size, patches[1].size, patches[2].size, patches[3].size)   #196608 65536 65536 65536\n            #patches =  tf.ragged.constant(patches)\n            # convert numpy to pytorch tensor\n            #environmental_patches = torch.from_numpy(environmental_patches)\n            #print (patches.shape)\n            #print (environmental_patches.shape)  # 20,256,256\n            patches = patches + torch.Tensor(environmental_patches)\n            \n\n\n        # Concatenate all patches into a single tensor\n        if len(patches) == 1:\n            patches = patches[0]\n\n        if self.transform:\n            patches = self.transform(patches)\n            #patches = self.transform(image=patches)[\"image\"]\n            #print (patches.shape)\n\n        if self.training_data:\n            target = self.targets[index]\n\n            if self.target_transform:\n                target = self.target_transform(target)\n\n            return patches, target\n        else:\n            return patches","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:08.308843Z","iopub.execute_input":"2022-04-17T15:42:08.309156Z","iopub.status.idle":"2022-04-17T15:42:08.333983Z","shell.execute_reply.started":"2022-04-17T15:42:08.309119Z","shell.execute_reply":"2022-04-17T15:42:08.333273Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### note : landcover + 20 rasters","metadata":{}},{"cell_type":"code","source":"\ndataset = GeoLifeCLEF2022Dataset(DATA_PATH,subset = \"train\", \n                                 region = 'both', \n                                 patch_data = 'landcover', \\\n                                 use_rasters = True,\\\n                                 #transform = get_train_transforms(),\\\n                                 transform = None,\\\n                                 patch_extractor = extractor_bio )\n","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:08.335042Z","iopub.execute_input":"2022-04-17T15:42:08.335259Z","iopub.status.idle":"2022-04-17T15:42:08.452864Z","shell.execute_reply.started":"2022-04-17T15:42:08.335218Z","shell.execute_reply":"2022-04-17T15:42:08.452150Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_size = int(0.8 * len(dataset))\nval_size = len(dataset) - train_size","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:08.454336Z","iopub.execute_input":"2022-04-17T15:42:08.454589Z","iopub.status.idle":"2022-04-17T15:42:08.458946Z","shell.execute_reply.started":"2022-04-17T15:42:08.454556Z","shell.execute_reply":"2022-04-17T15:42:08.458142Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#len(np.unique(df_obs.species_id[:200].values))","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:08.460561Z","iopub.execute_input":"2022-04-17T15:42:08.460829Z","iopub.status.idle":"2022-04-17T15:42:08.468074Z","shell.execute_reply.started":"2022-04-17T15:42:08.460794Z","shell.execute_reply":"2022-04-17T15:42:08.467297Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#len(np.unique(dataset.targets))","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:08.469421Z","iopub.execute_input":"2022-04-17T15:42:08.469674Z","iopub.status.idle":"2022-04-17T15:42:08.476051Z","shell.execute_reply.started":"2022-04-17T15:42:08.469640Z","shell.execute_reply":"2022-04-17T15:42:08.475320Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset, val_dataset = torch.utils.data.random_split(dataset, [train_size, val_size])\ntrain_loader = DataLoader(train_dataset, batch_size=16,num_workers = 0,shuffle = True,drop_last=True)\nval_loader = DataLoader(val_dataset, batch_size=16, num_workers = 0,shuffle = False,drop_last=True)","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:08.477701Z","iopub.execute_input":"2022-04-17T15:42:08.477950Z","iopub.status.idle":"2022-04-17T15:42:08.492318Z","shell.execute_reply.started":"2022-04-17T15:42:08.477919Z","shell.execute_reply":"2022-04-17T15:42:08.491638Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_patch,target  = iter(train_loader).next()\nplt.figure(figsize=(10, 12))\nprint (image_patch.shape)\n##### convert 1 ch image to 3 ch, use for near_ir, lancover, altitude images\n#https://stackoverflow.com/questions/51995977/how-can-i-use-a-pre-trained-neural-network-with-grayscale-images/51996037#51996037\n#rgb_batch = np.repeat(image_patch[..., np.newaxis], 3, -1)\n#print (rgb_batch[i])\n#print(rgb_batch.shape)  # (64, 224, 224, 3)\n#print(target)\nprint (target.shape)\nfor i in range(16):\n\n#for i, data in enumerate(train_loader):\n    #image_batch , label_batch = data\n    ax = plt.subplot(4, 4, i + 1)\n    # for rgb\n    #image = image_patch[i].numpy().astype(\"uint8\")\n    # near_ir\n    #image=rgb_batch[i].numpy().astype(\"uint8\")\n    # plt.imshow(image)\n    # tif\n    #image = rgb_batch[i]\n    plt.imshow(image_patch[i][0,:,:])\n    label = target[i].numpy()\n    plt.title(label)\n    plt.axis(\"off\")\nplt.tight_layout()\n","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:08.496646Z","iopub.execute_input":"2022-04-17T15:42:08.496838Z","iopub.status.idle":"2022-04-17T15:42:10.177862Z","shell.execute_reply.started":"2022-04-17T15:42:08.496815Z","shell.execute_reply":"2022-04-17T15:42:10.177199Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Simple model","metadata":{}},{"cell_type":"code","source":"#df_obs_fr['species_id'][:50]","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:10.179256Z","iopub.execute_input":"2022-04-17T15:42:10.179693Z","iopub.status.idle":"2022-04-17T15:42:10.183396Z","shell.execute_reply.started":"2022-04-17T15:42:10.179658Z","shell.execute_reply":"2022-04-17T15:42:10.182484Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from torchvision.models.resnet import ResNet, BasicBlock","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:10.184717Z","iopub.execute_input":"2022-04-17T15:42:10.185107Z","iopub.status.idle":"2022-04-17T15:42:10.194821Z","shell.execute_reply.started":"2022-04-17T15:42:10.185071Z","shell.execute_reply":"2022-04-17T15:42:10.193985Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"N_classes = 17036\nclass ResNetGeolife(ResNet):\n    def __init__(self):\n        super().__init__(BasicBlock, [3, 4, 6, 3], num_classes=N_classes)\n\n        self.conv1 = nn.Conv2d(20, 64, kernel_size=7, stride=1, padding=3, bias=False)\n\n        \nnet = ResNetGeolife().to(device)","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:10.196378Z","iopub.execute_input":"2022-04-17T15:42:10.196870Z","iopub.status.idle":"2022-04-17T15:42:15.010374Z","shell.execute_reply.started":"2022-04-17T15:42:10.196831Z","shell.execute_reply":"2022-04-17T15:42:15.009656Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#len(dataset.targets)-1","metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"execution":{"iopub.status.busy":"2022-04-17T15:42:15.011658Z","iopub.execute_input":"2022-04-17T15:42:15.011908Z","iopub.status.idle":"2022-04-17T15:42:15.014889Z","shell.execute_reply.started":"2022-04-17T15:42:15.011875Z","shell.execute_reply":"2022-04-17T15:42:15.014245Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#model =Resnet18(in_channels = 3, pretrained=False,  num_classes =17036)#len(np.unique(dataset.targets))-1)","metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"execution":{"iopub.status.busy":"2022-04-17T15:42:15.016084Z","iopub.execute_input":"2022-04-17T15:42:15.016474Z","iopub.status.idle":"2022-04-17T15:42:15.026564Z","shell.execute_reply.started":"2022-04-17T15:42:15.016440Z","shell.execute_reply":"2022-04-17T15:42:15.025753Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"optimizer = torch.optim.Adam(net.parameters(),lr = 0.001)\n\ndevice = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\nmodel = net.to(device)\n\ndef loss_fn(preds, labels):\n    #print (preds)\n    #print(labels)\n    loss = nn.CrossEntropyLoss()(preds, labels)\n    #loss = nn.BCEWithLogitsLoss()\n    return loss","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:15.029437Z","iopub.execute_input":"2022-04-17T15:42:15.029837Z","iopub.status.idle":"2022-04-17T15:42:15.039666Z","shell.execute_reply.started":"2022-04-17T15:42:15.029798Z","shell.execute_reply":"2022-04-17T15:42:15.038922Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#import torchvision.transforms as transforms","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:15.041216Z","iopub.execute_input":"2022-04-17T15:42:15.041501Z","iopub.status.idle":"2022-04-17T15:42:15.045325Z","shell.execute_reply.started":"2022-04-17T15:42:15.041459Z","shell.execute_reply":"2022-04-17T15:42:15.044537Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#https://www.kaggle.com/code/drcapa/esc-50-eda-pytorch\ndef train(model, optimizer,  train_loader, val_loader, epochs=2, device='cpu'):\n    for epoch in range(epochs):\n        training_loss = 0.0\n        valid_loss = 0.0\n        model.train()\n        for batch in train_loader:\n            optimizer.zero_grad()\n            inputs, targets = batch\n            inputs = inputs.float()\n            #inputs = inputs.to(device)\n            #targets = targets.float()\n            targets = targets.to(device)\n            #batch_samples = inputs.size(0)\n\n            #inputs = inputs.view(batch_samples, inputs.size(1))\n            inputs_m, inputs_s = inputs.mean(), inputs.std()\n            inputs = (inputs - inputs_m) / inputs_s\n            # for near_ir img\n            #inputs = np.repeat(inputs[..., np.newaxis], 3, -1)\n            \n            #if inputs.size(1) > 3:\n            #    inputs = inputs.permute(0,3,2,1)\n                #print(inputs.shape, inputs.size(1))\n            inputs = inputs.to(device)\n            \n            \n            output = model(inputs) \n            #print (output.shape)\n            #print(targets)\n            loss = nn.CrossEntropyLoss(ignore_index = -1)\n            loss = loss(output, targets)\n            \n            optimizer.zero_grad()\n            loss.backward()\n            optimizer.step()\n            #training_loss += loss.data.item()*inputs.size(0)\n            training_loss += loss.item() \n        training_loss /= len(train_loader.dataset)\n        \n        model.eval()\n        num_correct = 0\n        num_examples = 0\n        for batch in val_loader:\n            inputs, targets = batch\n            inputs = inputs.float()\n            \n            inputs_m, inputs_s = inputs.mean(), inputs.std()\n            inputs = (inputs - inputs_m) / inputs_s\n            \n            #inputs = np.repeat(inputs[..., np.newaxis], 3, -1)\n            #if inputs.size(1) > 3:\n            #    inputs = inputs.permute(0,3,2,1)\n                \n            inputs = inputs.to(device)\n            #inputs = inputs.to(device)\n            targets = targets.to(device)\n            output = model(inputs)\n            loss = loss_fn(output, targets)\n            #valid_loss += loss.data.item()*inputs.size(0)\n            valid_loss += loss.item() \n            correct = torch.eq(torch.max(F.softmax(output, dim=1), dim=1)[1], targets)\n           \n            num_correct += torch.sum(correct).item()\n            \n            num_examples += correct.shape[0]\n           \n        valid_loss /= len(val_loader.dataset)\n        \n        try:\n            x =  num_correct/num_examples\n        except ZeroDivisionError:\n            x = 0\n        print('Epoch: {}, Training Loss: {:.2f}, Validation Loss: {:.2f}, '\n              'accuracy = {:.2f}'.format(epoch+1, training_loss, valid_loss, x))\n","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:15.046771Z","iopub.execute_input":"2022-04-17T15:42:15.047202Z","iopub.status.idle":"2022-04-17T15:42:15.062519Z","shell.execute_reply.started":"2022-04-17T15:42:15.047163Z","shell.execute_reply":"2022-04-17T15:42:15.061776Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"gc.collect()","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:15.063978Z","iopub.execute_input":"2022-04-17T15:42:15.064407Z","iopub.status.idle":"2022-04-17T15:42:15.312333Z","shell.execute_reply.started":"2022-04-17T15:42:15.064369Z","shell.execute_reply":"2022-04-17T15:42:15.311472Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train(model.to(device), optimizer, train_loader, val_loader, epochs=2, device=device)","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:15.313554Z","iopub.execute_input":"2022-04-17T15:42:15.314191Z","iopub.status.idle":"2022-04-17T15:42:26.338030Z","shell.execute_reply.started":"2022-04-17T15:42:15.314145Z","shell.execute_reply":"2022-04-17T15:42:26.336741Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Lets find the above error cause","metadata":{}},{"cell_type":"code","source":"df_obs_train[df_obs_train.index==20065615] #20065615 #20050902\n\nfig = plt.figure(figsize=(14, 10))\n#extractor_bio.plot((40.87572 , -124.07787), fig=fig) #20065615\nextractor_bio.plot((40.856445, -124.097336), fig = fig) #20064477 \n\n#extractor_bio.plot((51.017408, 2.133926), fig=fig) # obs id 10228153","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:26.339379Z","iopub.status.idle":"2022-04-17T15:42:26.339797Z","shell.execute_reply.started":"2022-04-17T15:42:26.339571Z","shell.execute_reply":"2022-04-17T15:42:26.339593Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"PATH = './torchvision_resnet_lc_envrasters.bin'\ntorch.save(net.state_dict(), PATH)","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:26.341104Z","iopub.status.idle":"2022-04-17T15:42:26.342335Z","shell.execute_reply.started":"2022-04-17T15:42:26.342074Z","shell.execute_reply":"2022-04-17T15:42:26.342101Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Loading test patch","metadata":{}},{"cell_type":"code","source":"test_dataset = GeoLifeCLEF2022Dataset(DATA_PATH,subset = \"test\", \n                                 region = 'both', \n                                 patch_data = 'landcover', \\\n                                 use_rasters = True,\\\n                                 transform = None,\\\n                                 patch_extractor = extractor_bio\n                                 )","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:26.343587Z","iopub.status.idle":"2022-04-17T15:42:26.344214Z","shell.execute_reply.started":"2022-04-17T15:42:26.343968Z","shell.execute_reply":"2022-04-17T15:42:26.343992Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=1, shuffle = False)","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:26.345431Z","iopub.status.idle":"2022-04-17T15:42:26.346068Z","shell.execute_reply.started":"2022-04-17T15:42:26.345818Z","shell.execute_reply":"2022-04-17T15:42:26.345841Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#test_loader.sampler.num_samples","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:26.347268Z","iopub.status.idle":"2022-04-17T15:42:26.347893Z","shell.execute_reply.started":"2022-04-17T15:42:26.347660Z","shell.execute_reply":"2022-04-17T15:42:26.347684Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_patch  = iter(test_loader).next()\nplt.figure(figsize=(10, 12))\n#print (image_patch.shape)\n##### convert 2 ch image to 3 ch, use for near_ir, lancover, altitude images\n#https://stackoverflow.com/questions/51995977/how-can-i-use-a-pre-trained-neural-network-with-grayscale-images/51996037#51996037\nrgb_batch = np.repeat(image_patch[..., np.newaxis], 3, -1)\n#print (rgb_batch[i])\nprint(rgb_batch.shape)  # (64, 224, 224, 3)\n#print(target)\n#print (target.shape)\nfor i in range(16):\n\n#for i, data in enumerate(train_loader):\n    #image_batch , label_batch = data\n    ax = plt.subplot(4, 4, i + 1)\n    # for rgb\n    #image = image_patch[i].numpy().astype(\"uint8\")\n    # near_ir\n    #image=rgb_batch[i].numpy().astype(\"uint8\")\n    # plt.imshow(image)\n    # tif\n    image = rgb_batch[i]\n    plt.imshow(image[:,:,0])\n    #label = target[i].numpy()\n    #plt.title(label)\n    plt.axis(\"off\")\nplt.tight_layout()\n\n","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:26.349151Z","iopub.status.idle":"2022-04-17T15:42:26.349775Z","shell.execute_reply.started":"2022-04-17T15:42:26.349542Z","shell.execute_reply":"2022-04-17T15:42:26.349566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def test_inference (model, dl):\n  correct_prediction = 0\n  total_prediction = 0\n  PREDS = []\n  #LABELS = []\n  model.eval()\n  # Disable gradient updates\n  with torch.no_grad():\n    for data in tqdm(iter(dl)):\n      # Get the input features , and put them on the GPU\n      inputs = data[0]\n      inputs = inputs.float()\n      # Normalize the inputs\n      #inputs_m, inputs_s = inputs.mean(), inputs.std()\n      #inputs = (inputs - inputs_m) / inputs_s\n      #print (inputs.shape)\n      inputs = np.repeat(inputs[..., np.newaxis], 3, -1)\n      inputs = inputs.unsqueeze(0)\n      #print (inputs.shape)\n      if inputs.size(1) > 3:\n        inputs = inputs.permute(0, 3, 1,2)\n\n        inputs = inputs.to(device)\n      # Get predictions\n      outputs = model(inputs)\n\n      # Get the predicted class with the highest score\n      _, prediction = torch.max(outputs,1)\n      PREDS.append(prediction.view(-1).cpu().detach().numpy())\n\n\n      \n  PREDS = np.concatenate(PREDS)\n  #LABELS = np.concatenate(LABELS)\n  \n  #preds_df = pd.DataFrame({'song_id':LABELS, 'genre_id':PREDS})\n  return (PREDS)","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:26.350990Z","iopub.status.idle":"2022-04-17T15:42:26.351635Z","shell.execute_reply.started":"2022-04-17T15:42:26.351399Z","shell.execute_reply":"2022-04-17T15:42:26.351423Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#model.to(device)\n#model.load_state_dict(torch.load(file))\n#print (f'Predicting test set using weight ....  {file}')\npreds = test_inference(model, test_loader)","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:26.352833Z","iopub.status.idle":"2022-04-17T15:42:26.353472Z","shell.execute_reply.started":"2022-04-17T15:42:26.353227Z","shell.execute_reply":"2022-04-17T15:42:26.353251Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#first_30_species = np.arange(30)\n#s_pred = np.tile(first_30_species[None], (len(df_obs_test), 1))","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:26.354650Z","iopub.status.idle":"2022-04-17T15:42:26.355311Z","shell.execute_reply.started":"2022-04-17T15:42:26.355050Z","shell.execute_reply":"2022-04-17T15:42:26.355074Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_obs_fr_test = pd.read_csv(DATA_PATH / \"observations\" / \"observations_fr_test.csv\", sep=\";\", index_col=\"observation_id\", nrows = 10000)\ndf_obs_us_test = pd.read_csv(DATA_PATH / \"observations\" / \"observations_us_test.csv\", sep=\";\", index_col=\"observation_id\", nrows=10000)\n\ndf_obs_test = pd.concat((df_obs_fr_test, df_obs_us_test))\n\nobs_id_test = df_obs_test.index.values\n\nprint(\"Number of observations for testing: {}\".format(len(df_obs_test)))\n\ndf_obs_test.head()","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:26.356509Z","iopub.status.idle":"2022-04-17T15:42:26.357148Z","shell.execute_reply.started":"2022-04-17T15:42:26.356895Z","shell.execute_reply":"2022-04-17T15:42:26.356920Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from GLC.submission import generate_submission_file\nhelp(generate_submission_file)","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:26.358406Z","iopub.status.idle":"2022-04-17T15:42:26.359032Z","shell.execute_reply.started":"2022-04-17T15:42:26.358784Z","shell.execute_reply":"2022-04-17T15:42:26.358807Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Compute baseline on the test set\n#s_pred = batch_predict(predict_func, X_test, batch_size=1024)\n\n# Generate the submission file\n#generate_submission_file(SUBMISSION_PATH / \"random_forest_on_environmental_vectors.csv\", df_obs_test.index, s_pred)","metadata":{"execution":{"iopub.status.busy":"2022-04-17T15:42:26.360221Z","iopub.status.idle":"2022-04-17T15:42:26.360843Z","shell.execute_reply.started":"2022-04-17T15:42:26.360611Z","shell.execute_reply":"2022-04-17T15:42:26.360634Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"* Version 1 : near_ir\n* Version 2 : landcover\n* Version 3 : altitude   10000 images, 80-20 split, 2 epochs, nn.crossentrophy loss, lr = 0.001\n* Version 4 : rasters - bioclimatic + pedologic \n* version 5 : - error\n","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}