Crop type mapping with deep learning
A guide for using deep-learning based semantic segmentation to map crop types in satellite imagery.
- Install eo-flow
- Download data
- Import required libraries
- Preprocess data
- Import eo-flow modules
- Convert EOPatch data to tfrecords
- Augment the data
- Configure the model hyperparameters
- Train model
- Predict with the trained model
- Evaluate the trained model
- Visualize predicted crop type maps
The AOI we will be working with is located in South Africa. We will use data from the 2019 Zindi Farm Pin Crop Detection Challenge and an abridged pipeline from Sinergise's eo-flow. The architecture we will use is the TensorFlow based TFCN.
!pip install git+https://github.com/sentinel-hub/eo-flow
Make an account on Zindi and proceed to https://zindi.africa/competitions/farm-pin-crop-detection-challenge/data to download the training and testing shapefiles: train.zip and test.zip
import os
# Jupyter notebook related
%reload_ext autoreload
%autoreload 2
%matplotlib inline
%pylab inline
# Basics of Python data handling and visualization
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from mpl_toolkits.axes_grid1 import make_axes_locatable
import pandas as pd
from shapely.geometry import Polygon
# Basics of GIS
import geopandas as gpd
# The core of this example
from eolearn.core import EOTask, EOPatch, LinearWorkflow, FeatureType, OverwritePermission, LoadFromDisk, SaveToDisk
from eolearn.io import S2L1CWCSInput, ExportToTiff
from eolearn.mask import AddCloudMaskTask, get_s2_pixel_cloud_detector, AddValidDataMaskTask
from eolearn.geometry import VectorToRaster, PointSamplingTask, ErosionTask
from eolearn.features import LinearInterpolation, SimpleFilterTask
from sentinelhub import BBoxSplitter, BBox, CRS, CustomUrlParam
# Machine learning
import lightgbm as lgb
from sklearn.externals import joblib
from sklearn import metrics
from sklearn import preprocessing
# Misc
import pickle
import sys
import os
import datetime
import itertools
from tqdm import tqdm_notebook as tqdm
import enum
1) Generate convex hull geometries enveloping the training and testing shapefiles, to serve as AOI geometries used when generating EOPatches with Sentinel 2 imagery.
2) Split the AOI into smaller tiles
3) Fill EOPatches with data, to include:
- L1C list of select bands [B02, B03, B04, B08, B11, B12], corresponding to [B, G, R, NIR, SWIR1, SWIR2] wavelengths.
- Cloud probability map and cloud mask from SentinelHub
- NDVI, NDWI, euclidean NORM information, which we will calculate
- A mask of pixel validity, derived from the acquired Senitnel data and cloud coverage information. We define a valid pixel if its metadata: IS_DATA == True, CLOUD_MASK == 0 (1 indicates that pixel was identified to be occluded by cloud)
import tensorflow as tf
import json
from eoflow.models import TFCNModel
from eoflow.input.eopatch import eopatch_dataset
from eoflow.input.operations import augment_data, cache_dataset, extract_subpatches
from eoflow.utils import create_dirs
tfrecord is TensorFlow's dataset format optimized for ML workflows
Horizontal and vertical flips
To include:
- learning rate
- number of classes
- loss
- metrics
- number of iterations and/or epochs (training cycles)
We will calculate Intersection over Union as a measure for the quality of our model.