I want to make random forest classification on Sentinel-2 composites to extract crop types. The first part of the script provided below (dealing with the pre-processing of Sentinel-2 data) works just fine.

The problem arises when I try to generate stratified random sample to use as training pixels. For the stratification I used a tiff file uploaded in Assets (the variable named "training_image"). The file is in UTM projection and no data value 0 is used as a mask. The Sentinel-2 composite images also have mask (of clouds and of non-agricultural land). I would like to have 1000 points per class (23 classes) but I know that so many points may cause memory problems in GEE. So I tried with just 5 points per class. Nevertheless, I get "Computation time out" error.
Here is the script:

// Define periods of analysis
var startdate1 = '2017-10-01';
var enddate1 = '2017-11-30';

var startdate2 = '2018-04-01';
var enddate2 = '2018-05-31';

var startdate3 = '2018-06-01';
var enddate3 = '2018-07-31';

// Define geograpic domain
var geometry = bg_border.geometry();

// Preprocess Sentinel-2 data

// cloud function to remove clouds
 function maskS2clouds(image){
  var qa = image.select('QA60');

  // Bits 10 and 11 are clouds and cirrus, respectively.
  var cloudBitMask = 1 << 10;
  var cirrusBitMask = 1 << 11;

  // Both flags should be set to zero, indicating clear conditions.
  var mask = qa.bitwiseAnd(cloudBitMask).eq(0)

  return image.updateMask(mask).divide(10000);

//////////////////PERIOD1-OCT-NOV 2017////////////////////////////////////

// filter Sentinel-2 data
var Sentinel2_period1 = S2.filterBounds(geometry).filterDate(startdate1, enddate1)
                  // Pre-filter to get less cloudy granules.
                  .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 10));
// remove the clouds
var S2_nocloud_period1 = Sentinel2_period1.map(maskS2clouds);
// take the median
var st2median_period1 = S2_nocloud_period1.median();
// select only bands B2-B8, B11 and B12
var S2_period1 = st2median_period1.select('B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B8', 'B11', 'B12');

//////////////////PERIOD2-APR-MAY 2018////////////////////////////////////

// filter Sentinel-2 data
var Sentinel2_period2 = S2.filterBounds(geometry).filterDate(startdate2, enddate2)
                  // Pre-filter to get less cloudy granules.
                  .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 10));
// remove the clouds
var S2_nocloud_period2 = Sentinel2_period2.map(maskS2clouds);
// take the median
var st2median_period2 = S2_nocloud_period2.median();
// select only bands B2-B8, B11 and B12
var S2_period2 = st2median_period2.select('B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B8', 'B11', 'B12')

//////////////////PERIOD3-JUN-JUL 2018////////////////////////////////////

// filter Sentinel-2 data
var Sentinel2_period3 = S2.filterBounds(geometry).filterDate(startdate3, enddate3)
                  // Pre-filter to get less cloudy granules.
                  .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 10));
// remove the clouds
var S2_nocloud_period3 = Sentinel2_period3.map(maskS2clouds);
// take the median
var st2median_period3 = S2_nocloud_period3.median();
// select only bands B2-B8, B11 and B12
var S2_period3 = st2median_period3.select('B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B8', 'B11', 'B12');

// Combine the bands from the three periods
// into one image and clip over geometry
var input_img_S2 = S2_period1.addBands([S2_period2, S2_period3])
                .rename(['P1_B2', 'P1_B3', 'P1_B4', 'P1_B5', 'P1_B6', 'P1_B7', 'P1_B8', 'P1_B11',
                'P1_B12', 'P2_B2', 'P2_B3', 'P2_B4', 'P2_B5', 'P2_B6', 'P2_B7', 'P2_B8', 'P2_B11',
                'P2_B12', 'P3_B2', 'P3_B3', 'P3_B4', 'P3_B5', 'P3_B6', 'P3_B7', 'P3_B8', 'P3_B11',

//Update mask - agricultural land only
var input_img_S2m = input_img_S2.updateMask(agri_land_image);

// Add to the map
var visParams = {bands: ['P1_B8', 'P2_B8', 'P3_B8'], max: 0.5};
Map.addLayer(input_img_S2m, visParams, 'Sentinel-2 data', false);

// Now the real classification
var palette = ["#3ccf97", "#82a7eb", "#b7ea3f", "#ad47dc", "#efa34d", "#4121e0",
               "#c668cb", "#c7ce44", "#2fa5ee", "#73cdc1", "#ca6c9e", "#767ed3",
               "#dc0f0f", "#d47890", "#de4913", "#de4913", "#5bca45", "#e1c86e",
               "#33e642", "#8f62c9", "#a1ef64", "#ef1ec2", "#25d3ed"];

Map.addLayer(training_image, {min: 1, max: 23, palette: palette}, 'training image', false);

var samples = input_img_S2m.addBands(training_image).stratifiedSample({
  numPoints: 5, 
  classBand: "b1", 
  scale: 20,
  projection: "EPSG:32635", 
  tileScale: 4,
  geometries: true,

What can be the reason for this error message? Here is a link to the script: https://code.earthengine.google.com/1cb0374fbca783e90cd115983c9107f8

1 Answer 1


If you don't need the clip(), don't use it. If you don't care about projection, don't specify it. If you don't receive the 'User memory limit exceeded' error, don't specify tileScale. Even with all those changes, it wouldn't be surprising to see a time out, which will be thrown by the code editor after five minutes if your computation isn't done. You should Export the result, as discussed in this doc.

  • I specified the projection (which is the projection of the class raster) because I thought this is important to get the accurate class for each generated point. I do not know really if I need it. Thanks for pointing out the export option.
    – ABC
    Nov 27, 2019 at 13:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.