From 9219f701a16c2a3e06510138c987d56de108fadf Mon Sep 17 00:00:00 2001 From: Biplov Bhandari Date: Tue, 11 Jun 2024 21:28:43 -0400 Subject: [PATCH] improve readme and bugfix notebooks --- README.md | 223 ++++++- notebook/export_image_for_prediction.ipynb | 44 +- notebook/prediction_dnn.ipynb | 675 ++++++++++---------- notebook/prediction_unet.ipynb | 678 ++++++++++----------- 4 files changed, 882 insertions(+), 738 deletions(-) diff --git a/README.md b/README.md index 75bbbab..c821617 100644 --- a/README.md +++ b/README.md @@ -35,21 +35,21 @@ For quickly running this, we have already prepared and exported the training dat *Note: If you're looking to produce your own datasets, you can follow this [notebook](https://colab.research.google.com/drive/1LCFLeSCu969wIW8TD68-j4hfIu7WiRIK?usp=sharing) which was used to produce these training, testing, and validation datasets provided here.* ```sh -cd DATADIR -!gsutil -m cp -r gs://dl-book/chapter-1/* DATADIR +mkdir DATADIR +gsutil -m cp -r gs://dl-book/chapter-1/dnn_planet_wo_indices/* DATADIR ``` -The folder has several dataset inside it. If you're running a U-Net model, you can use the sub-folder `unet_256x256_planet_wo_indices`; for DNN model, you can use the sub-folder `dnn_planet_wo_indices`. +The parent folder (if you run `gsutil -m cp -r gs://dl-book/chapter-1/* DATADIR`) has several dataset inside it. We use `dnn_planet_wo_indices` here because it is lightweight data and would be much faster to run. If you want to test U-Net model, you can use `unet_256x256_planet_wo_indices` folder instead. Each of these have training, testing, and validation sub-folder inside them. The datadir is constructed as `DATADIR = BASEDIR + DATADIR` \ OUTPUT_DIR (str): The base directory where the output would be saved. -You can then change the `MODEL_TYPE` which you are running. The default is "unet". You can change to "dnn" if you are using that model. +You can then change the `MODEL_TYPE` which you are running. The default is "unet", so we need to change it to "dnn" since we will be training using that model. *Note current version does not expose all the model intracacies through the environment file but future version may include those depending on the need.* ``` -MODEL_TYPE = "unet" +MODEL_TYPE = "dnn" ``` Next define the `FEATURES` and the `LABELS` variables. This dataset was prepared for the rice mapping application that uses before and during growing season information. So for this dataset, here are the example `FEATURES`. Note the `FEATURES` should be in the same format as shown below @@ -65,13 +65,13 @@ blue_during nir_during" ``` -Similarly, since the dataset has a single label, it is going to be +Similarly, since the dataset has a single label, it is going to be as below. If you have mutiple labels, be sure to format them as the `FEATURES` above. ``` -LABELS = ["class"] +LABELS = "class" ``` -The `PATCH_SHAPE` for the training datasets needs to be changed as well: +While the DNN would not need this setting, if you want to run U-Net model, the `PATCH_SHAPE` for the training datasets needs to be changed as well: ``` PATCH_SHAPE = (256, 256) @@ -97,16 +97,211 @@ After all the settings been correctly setup, here's an example of how to use the from aces.config import Config from aces.model_trainer import ModelTrainer -if __name__ == "__main__": - config_file = "config.env" - config = Config(config_file) - trainer = ModelTrainer(config) - trainer.train_model() +config_file = "config.env" +config = Config(config_file) +trainer = ModelTrainer(config) +trainer.train_model() ``` Once the model is finished running, it saves the trained model, evaluate the results on the testing dataset and saves it, produces the plots and saves it, and saves any other needed item on the `MODEL_DIR`, which is constructed as `OUTPUT_DIR + MODEL_DIR_NAME`. -For inference, refer to this [notebook](https://colab.research.google.com/drive/1wfzvIcpkjI4lT1oEADehD_Kp6iJD6hWr?authuser=2#scrollTo=hdFXAWSM7vKQ), scroll to `Inference using Saved U-Net Model` on how to do it. +For inference, you would need to get the images in a right format. To export images in the right way, refer to this [notebook](https://github.com/SERVIR/servir-aces/blob/main/notebook/export_image_for_prediction.ipynb), but for this, we already have the images prepared in the right way. You can download them in a similar manner you downloaded the training datasets. + +```sh +mkdir IMAGEDIR +gsutil -m cp -r gs://dl-book/chapter-1/images/* IMAGEDIR +``` + +There are few more settings that needs to be changed before we run the predictions. One of that would be changing the `OUTPUT_NAME`. This is the name of the output prediction for GEE asset, locally (in TF Format) and gcs output (in TFRecord format). You would also need a GCP Project to push the output from GCS to GEE for the prediction. Similarly, you need GCP Bucket to store your prediction, and finally the EE_OUTPUT_ASSET to the as an output path for the prediction asset. + +``` +OUTPUT_NAME = "prediction_dnn_v1" +GCS_PROJECT = "your-gcs-project" +GCS_BUCKET = "your-bucket" +EE_OUTPUT_ASSET = "your-gee-output-asset-path" +``` + +You will have to run the configuration settings again for the new configuration to take place. + +```python +from aces.config import Config + +config_file = "config.env" +config = Config(config_file, override=True) +``` + +We can then start constructing the actual path for the output file using the `OUTPUT_NAME` as, and print it to view. + +```python +OUTPUT_IMAGE_FILE = str(config.MODEL_DIR / "prediction" / f"{config.OUTPUT_NAME}.TFRecord") +print(f"OUTPUT_IMAGE_FILE: {OUTPUT_IMAGE_FILE}") +``` + +Now let's get all the files inside the `IMAGEDIR`, and then separate out our actual image files and the JSON mixer file. The JSON mixer file inside the `IMAGEDIR` is generated when exporting images from GEE as TFRecords. This is a simple JSON file for defining the georeferencing of the patches. + +```python +import glob + +image_files_list = [] +json_file = None + +for f in glob.glob(f"{IMGDIR}/*"): + if f.endswith(".tfrecord.gz"): + image_files_list.append(f) + elif f.endswith(".json"): + json_file = f + +# Make sure the files are in the right order. +image_files_list.sort() +``` + +Next, we will load the trained model and look at the model summary. The trained model is stored within the trained-model subdirectory in the MODEL_DIR. + +```python +import tensorflow as tf + +print(f"Loading model from {str(config.MODEL_DIR)}/trained-model") +this_model = tf.keras.models.load_model(f"{str(config.MODEL_DIR)}/trained-model") + +print(this_model.summary()) +``` + +Now let's get the relevant info from the JSON mixer file. + +```python +import json + +with open(json_file, encoding='utf-8') as jm: mixer = json.load(jm) + +# Get relevant info from the JSON mixer file. +patch_width = mixer["patchDimensions"][0] +patch_height = mixer["patchDimensions"][1] +patches = mixer["totalPatches"] +patch_dimensions_flat = [patch_width * patch_height, 1] +``` + +Next let's create a TFDataset from our images as: + +```python + +def parse_image(example_proto): + columns = [ + tf.io.FixedLenFeature(shape=patch_dimensions_flat, dtype=tf.float32) for k in config.FEATURES + ] + image_features_dict = dict(zip(config.FEATURES, columns)) + return tf.io.parse_single_example(example_proto, image_features_dict) + + +# Create a dataset from the TFRecord file(s). +image_dataset = tf.data.TFRecordDataset(image_files_list, compression_type="GZIP") +image_dataset = image_dataset.map(parse_image, num_parallel_calls=5) + +# Break our long tensors into many little ones. +image_dataset = image_dataset.flat_map( + lambda features: tf.data.Dataset.from_tensor_slices(features) +) + +# Turn the dictionary in each record into a tuple without a label. +image_dataset = image_dataset.map( + lambda data_dict: (tf.transpose(list(data_dict.values())), ) +) + +image_dataset = image_dataset.batch(patch_width * patch_height) +``` + +Finally, let's perform the prediction. + +```python +predictions = this_model.predict(image_dataset, steps=patches, verbose=1) +print(f"predictions shape: {predictions.shape}") +``` + +Now let's write this predictions on the file. + +```python + +from pathlib import Path +import numpy as np + +# Create the target directory if it doesn't exist +Path(OUTPUT_IMAGE_FILE).parent.mkdir(parents=True, exist_ok=True) + +print(f"Writing predictions to {OUTPUT_IMAGE_FILE} ...") +writer = tf.io.TFRecordWriter(OUTPUT_IMAGE_FILE) + +# Every patch-worth of predictions we"ll dump an example into the output +# file with a single feature that holds our predictions. Since our predictions +# are already in the order of the exported data, the patches we create here +# will also be in the right order. +patch = [[], [], [], [], [], []] + +cur_patch = 1 + +for i, prediction in enumerate(predictions): + patch[0].append(int(np.argmax(prediction))) + patch[1].append(prediction[0][0]) + patch[2].append(prediction[0][1]) + patch[3].append(prediction[0][2]) + patch[4].append(prediction[0][3]) + patch[5].append(prediction[0][4]) + + + if i == 0: + print(f"prediction.shape: {prediction.shape}") + + if (len(patch[0]) == patch_width * patch_height): + if cur_patch % 100 == 0: + print("Done with patch " + str(cur_patch) + " of " + str(patches) + "...") + + example = tf.train.Example( + features=tf.train.Features( + feature={ + "prediction": tf.train.Feature( + int64_list=tf.train.Int64List( + value=patch[0])), + "cropland_etc": tf.train.Feature( + float_list=tf.train.FloatList( + value=patch[1])), + "rice": tf.train.Feature( + float_list=tf.train.FloatList( + value=patch[2])), + "forest": tf.train.Feature( + float_list=tf.train.FloatList( + value=patch[3])), + "urban": tf.train.Feature( + float_list=tf.train.FloatList( + value=patch[4])), + "others_etc": tf.train.Feature( + float_list=tf.train.FloatList( + value=patch[5])), + } + ) + ) + + # Write the example to the file and clear our patch array so it"s ready for + # another batch of class ids + writer.write(example.SerializeToString()) + patch = [[], [], [], [], [], []] + cur_patch += 1 + +writer.close() +``` + +Now we have write the prediction to the `OUTPUT_IMAGE_FILE`. You can upload this to GEE for visualization. To do this, you will need to upload to GCP and then to GEE. + +You can upload to GCP using gsutil. The `OUTPUT_GCS_PATH` can be any path inside the `GCS_BUCKET` (e.g. `OUTPUT_GCS_PATH = f"gs://{config.GCS_BUCKET}/{config.OUTPUT_NAME}.TFRecord"`) + +```sh +gsutil cp "{OUTPUT_IMAGE_FILE}" "{OUTPUT_GCS_PATH}" +``` + +Once the file is available on GCP, you can then upload to earthengine using `earthengine` commnad line. + +```sh +earthengine upload image --asset_id={config.EE_OUTPUT_ASSET}/{config.OUTPUT_NAME} --pyramiding_policy=mode {OUTPUT_GCS_PATH} {json_file} +``` + +***Note: The inferencing is also available on this [notebook](https://github.com/SERVIR/servir-aces/blob/main/notebook/Rice_Mapping_Bhutan_2021.ipynb), scroll to `Inference using Saved U-Net Model` or `Inference using Saved DNN Model` depending upon which model you're using.*** ## Contributing Contributions to ACES are welcome! If you find any issues or have suggestions for improvements, please open an issue or submit a pull request on the GitHub repository. diff --git a/notebook/export_image_for_prediction.ipynb b/notebook/export_image_for_prediction.ipynb index 89e68f3..4457185 100644 --- a/notebook/export_image_for_prediction.ipynb +++ b/notebook/export_image_for_prediction.ipynb @@ -35,12 +35,12 @@ "\n", "\n", " \n", "
\n", - " \n", + " \n", " \"Colab Run in Colab\n", " \n", " \n", - " \n", + " \n", " \"GitHub\n", " View on GitHub\n", " \n", @@ -80,7 +80,7 @@ }, "outputId": "69e0ebee-4713-46b3-8949-ab7f5357457e" }, - "execution_count": 1, + "execution_count": null, "outputs": [ { "output_type": "stream", @@ -168,7 +168,7 @@ "id": "6PvoP9Sgqz4e", "outputId": "e4f5f519-c8ca-4edb-f03f-c694dd5f7469" }, - "execution_count": 2, + "execution_count": null, "outputs": [ { "output_type": "stream", @@ -206,7 +206,7 @@ "metadata": { "id": "jpnfjXRYsYMk" }, - "execution_count": 3, + "execution_count": null, "outputs": [] }, { @@ -322,7 +322,7 @@ "metadata": { "id": "cDmNkw3IoQDo" }, - "execution_count": 4, + "execution_count": null, "outputs": [] }, { @@ -344,7 +344,7 @@ "metadata": { "id": "6ZEUCkx4ohGF" }, - "execution_count": 5, + "execution_count": null, "outputs": [] }, { @@ -363,7 +363,7 @@ "metadata": { "id": "cypqxkVlokHW" }, - "execution_count": 6, + "execution_count": null, "outputs": [] }, { @@ -384,7 +384,7 @@ "metadata": { "id": "cdz2nhA2aV7X" }, - "execution_count": 7, + "execution_count": null, "outputs": [] }, { @@ -399,7 +399,7 @@ "id": "q7ofsYbhrDla", "outputId": "0f9856c6-1b66-405b-9663-c58d08a524ef" }, - "execution_count": 8, + "execution_count": null, "outputs": [ { "output_type": "stream", @@ -430,7 +430,7 @@ "metadata": { "id": "H9ubfz3xatRy" }, - "execution_count": 9, + "execution_count": null, "outputs": [] }, { @@ -441,7 +441,7 @@ "metadata": { "id": "kXdJKFU8aemX" }, - "execution_count": 10, + "execution_count": null, "outputs": [] }, { @@ -474,7 +474,7 @@ "metadata": { "id": "7WACSSYTZtG3" }, - "execution_count": 11, + "execution_count": null, "outputs": [] }, { @@ -495,7 +495,7 @@ "metadata": { "id": "mwHJsVQKZtLO" }, - "execution_count": 12, + "execution_count": null, "outputs": [] }, { @@ -522,7 +522,7 @@ "metadata": { "id": "Z226I2vZ-qla" }, - "execution_count": 13, + "execution_count": null, "outputs": [] }, { @@ -537,7 +537,7 @@ "metadata": { "id": "-gYGm9pW-4yN" }, - "execution_count": 14, + "execution_count": null, "outputs": [] }, { @@ -556,7 +556,7 @@ "metadata": { "id": "BQ_7_9py-40-" }, - "execution_count": 15, + "execution_count": null, "outputs": [] }, { @@ -581,7 +581,7 @@ "id": "wvER7zUj-43q", "outputId": "041eed9f-9521-4bc9-e5f4-7ad32371bf68" }, - "execution_count": 16, + "execution_count": null, "outputs": [ { "output_type": "stream", @@ -613,7 +613,7 @@ "metadata": { "id": "APpHo3rE-46Y" }, - "execution_count": 17, + "execution_count": null, "outputs": [] }, { @@ -634,7 +634,7 @@ "metadata": { "id": "faBUhU9L-48t" }, - "execution_count": 18, + "execution_count": null, "outputs": [] }, { @@ -670,7 +670,7 @@ "id": "JZ9nAMWB-4_k", "outputId": "8cb848bb-b4e9-43fd-b28d-ccbc1cd7002b" }, - "execution_count": 19, + "execution_count": null, "outputs": [ { "output_type": "stream", @@ -742,7 +742,7 @@ "id": "rSKPgNAt-5DC", "outputId": "2c759aa1-5765-4865-d250-0ad2af7d7d9b" }, - "execution_count": 20, + "execution_count": null, "outputs": [ { "output_type": "stream", diff --git a/notebook/prediction_dnn.ipynb b/notebook/prediction_dnn.ipynb index c8bb185..60a95d0 100644 --- a/notebook/prediction_dnn.ipynb +++ b/notebook/prediction_dnn.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { "id": "ur8xi4C7S06n" }, @@ -35,12 +35,12 @@ "\n", "\n", " \n", "
\n", - " \n", + " \n", " \"Colab Run in Colab\n", " \n", " \n", - " \n", + " \n", " \"GitHub\n", " View on GitHub\n", " \n", @@ -61,30 +61,27 @@ }, { "cell_type": "markdown", - "source": [ - "## Setup environment" - ], "metadata": { "id": "EuQkhSxRmiIA" - } + }, + "source": [ + "## Setup environment" + ] }, { "cell_type": "code", - "source": [ - "!pip install servir-aces" - ], + "execution_count": null, "metadata": { - "id": "FuDztFucmhpB", "colab": { "base_uri": "https://localhost:8080/" }, + "id": "FuDztFucmhpB", "outputId": "8c7b5321-638d-40bd-d255-d4ca60e9e1ff" }, - "execution_count": 2, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Collecting servir-aces\n", " Downloading servir_aces-0.0.14-py2.py3-none-any.whl (32 kB)\n", @@ -154,13 +151,14 @@ "Successfully installed python-dotenv-1.0.1 servir-aces-0.0.14\n" ] } + ], + "source": [ + "!pip install servir-aces" ] }, { "cell_type": "code", - "source": [ - "!git clone https://github.com/SERVIR/servir-aces" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -168,11 +166,10 @@ "id": "6PvoP9Sgqz4e", "outputId": "7a30c5b7-0321-4243-c047-fc40602b64cb" }, - "execution_count": 3, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Cloning into 'servir-aces'...\n", "remote: Enumerating objects: 731, done.\u001b[K\n", @@ -183,38 +180,38 @@ "Resolving deltas: 100% (478/478), done.\n" ] } + ], + "source": [ + "!git clone https://github.com/SERVIR/servir-aces" ] }, { "cell_type": "markdown", + "metadata": { + "id": "RukLD6eeq7Fl" + }, "source": [ "Now the repo is downloaded. We will create an environment file file to place point to our training data and customize parameters for the model. To do this, we make a copy of the `.env.example` file provided.\n", "\n", "Under the hood, all the configuration provided via the environment file are parsed as a config object and can be accessed programatically.\n", "\n", "Note current version does not expose all the model intracacies through the environment file but future version may include those depending on the need." - ], - "metadata": { - "id": "RukLD6eeq7Fl" - } + ] }, { "cell_type": "code", - "source": [ - "!cp servir-aces/.env.example servir-aces/config.env" - ], + "execution_count": null, "metadata": { "id": "jpnfjXRYsYMk" }, - "execution_count": 4, - "outputs": [] + "outputs": [], + "source": [ + "!cp servir-aces/.env.example servir-aces/config.env" + ] }, { "cell_type": "code", - "source": [ - "from google.colab import drive\n", - "drive.mount(\"/content/drive\")" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -222,28 +219,34 @@ "id": "mgk98jsYF5xU", "outputId": "d2da714a-7bb6-4b28-a49f-6c1b154a7257" }, - "execution_count": 5, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Mounted at /content/drive\n" ] } + ], + "source": [ + "from google.colab import drive\n", + "drive.mount(\"/content/drive\")" ] }, { "cell_type": "markdown", - "source": [ - "## Setup config file variables" - ], "metadata": { "id": "9wn3sMH9IXKK" - } + }, + "source": [ + "## Setup config file variables" + ] }, { "cell_type": "markdown", + "metadata": { + "id": "ooFqBUY3gS5e" + }, "source": [ "Okay, now we have the `config.env` file, we will use this to provide our environments and parameters.\n", "\n", @@ -253,17 +256,15 @@ "BASEDIR = \"/content/\"\n", "OUTPUT_DIR = \"/content/drive/MyDrive/Colab Notebooks/DL_Book/Chapter_1/output\"\n", "```" - ], - "metadata": { - "id": "ooFqBUY3gS5e" - } + ] }, { "cell_type": "markdown", + "metadata": { + "id": "CEDUshfUi1OY" + }, "source": [ - "For the prediction, we are using growing season and pre-growing season information. Thus, we have 8 optical bands, namely `red_before`, `green_before`, `blue_before`, `nir_before`, `red_during`, `green_during`, `blue_during`, and `nir_during`. In adidition, you can use `USE_ELEVATION` and `USE_S1` config to include the topographic and radar information. Since currently we are not including these, so we won't be settting these config values.\n", - "\n", - "Similarly, we are using 256x256 pixels, so let's also change that. In addition, if you want to keep buffer on the export images buffer for prediction purpose, you can use `KERNEL_BUFFER` to specify that. Half this will extend on the sides of each patch. You can specify the size as tupe (e.g. 72 x 72). If zero is used; it will not buffer. I will keep this to zero one this one.\n", + "For the prediction, we are using growing season and pre-growing season information. Thus, we have 8 optical bands, namely `red_before`, `green_before`, `blue_before`, `nir_before`, `red_during`, `green_during`, `blue_during`, and `nir_during`. In adidition, you can use `USE_ELEVATION` and `USE_S1` config to include the topographic and radar information. Since currently we are not including these, so we won't be settting these config values. Similarly, we are using 256x256 pixels, so let's also change that.\n", "\n", "```\n", "# For model training, USE_ELEVATION extends FEATURES with \"elevation\" & \"slope\"\n", @@ -275,16 +276,14 @@ "USE_S1 = False\n", "\n", "PATCH_SHAPE = (256, 256)\n", - "\n", - "KERNEL_BUFFER = 0\n", "```" - ], - "metadata": { - "id": "CEDUshfUi1OY" - } + ] }, { "cell_type": "markdown", + "metadata": { + "id": "stwnTiy94pzU" + }, "source": [ "Next, we will specify the `MODEL_DIR_NAME`. The `MODEL_DIR` is then constructed as\n", "MODEL_DIR = OUTPUT_DIR / MODEL_DIR_NAME. The `MODEL_DIR_NAME` in my case is `unet_v1`, so we will use that. Similarly, you can specify your output of the file from the prediction using `OUTPUT_NAME` variable. We also need to specify this is the DNN model that we want to run. We have `MODEL_TYPE` parameter for that. Currently, it supports unet, dnn, and cnn (case sensitive) models; default being unet. Make other changes, as appropriate.\n", @@ -308,31 +307,33 @@ "# where the prediction output will be stored\n", "EE_OUTPUT_ASSET = \"projects/servir-ee/assets/dl-book/chapter-1/prediction\"\n", "```" - ], - "metadata": { - "id": "stwnTiy94pzU" - } + ] }, { "cell_type": "markdown", - "source": [ - "## Update the config file programtically" - ], "metadata": { "id": "GXA17oN5A2Ef" - } + }, + "source": [ + "## Update the config file programtically" + ] }, { "cell_type": "markdown", - "source": [ - "Let's make a dictionary so we can change these config settings programatically." - ], "metadata": { "id": "RMA7PH-jvvVr" - } + }, + "source": [ + "Let's make a dictionary so we can change these config settings programatically." + ] }, { "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "9yt3PVFgBGRn" + }, + "outputs": [], "source": [ "BASEDIR = \"/content/\" # @param {type:\"string\"}\n", "OUTPUT_DIR = \"/content/drive/MyDrive/Colab Notebooks/DL_Book/Chapter_1/output\" # @param {type:\"string\"}\n", @@ -342,7 +343,6 @@ "USE_ELEVATION = \"False\" # @param {type:\"string\"}\n", "USE_S1 = \"False\" # @param {type:\"string\"}\n", "PATCH_SHAPE = \"(256, 256)\" # @param {type:\"string\"}\n", - "KERNEL_BUFFER = \"0\" # @param {type:\"string\"}\n", "\n", "MODEL_DIR_NAME = \"dnn_v1\" # @param {type:\"string\"}\n", "OUTPUT_NAME = \"prediction_dnn_v1\" # @param {type:\"string\"}\n", @@ -359,15 +359,15 @@ "# where the prediction output will be stored\n", "EE_OUTPUT_ASSET = \"projects/servir-ee/assets/dl-book/chapter-1/prediction\" # @param {type:\"string\"}\n", "\n" - ], - "metadata": { - "id": "9yt3PVFgBGRn" - }, - "execution_count": 6, - "outputs": [] + ] }, { "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "j3_k_jmBv0xE" + }, + "outputs": [], "source": [ "config_settings = {\n", " \"BASEDIR\" : BASEDIR,\n", @@ -375,7 +375,6 @@ " \"USE_ELEVATION\": USE_ELEVATION,\n", " \"USE_S1\": USE_S1,\n", " \"PATCH_SHAPE\": PATCH_SHAPE,\n", - " \"KERNEL_BUFFER\": KERNEL_BUFFER,\n", " \"MODEL_DIR_NAME\": MODEL_DIR_NAME,\n", " \"OUTPUT_NAME\": OUTPUT_NAME,\n", " \"GCS_PROJECT\": GCS_PROJECT,\n", @@ -385,15 +384,15 @@ " \"GCS_IMAGE_PREFIX\": GCS_IMAGE_PREFIX,\n", " \"EE_OUTPUT_ASSET\": EE_OUTPUT_ASSET,\n", "}\n" - ], - "metadata": { - "id": "j3_k_jmBv0xE" - }, - "execution_count": 7, - "outputs": [] + ] }, { "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "xMAmTIBvvRjW" + }, + "outputs": [], "source": [ "import dotenv\n", "\n", @@ -404,24 +403,24 @@ " key_to_set=config_key,\n", " value_to_set=config_settings[config_key]\n", " )\n" - ], - "metadata": { - "id": "xMAmTIBvvRjW" - }, - "execution_count": 8, - "outputs": [] + ] }, { "cell_type": "markdown", - "source": [ - "## Load config file variables" - ], "metadata": { "id": "lZvJKXATIf9v" - } + }, + "source": [ + "## Load config file variables" + ] }, { "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "id1pU4aCFjR-" + }, + "outputs": [], "source": [ "from aces import Config, EEUtils\n", "\n", @@ -430,18 +429,11 @@ "import tensorflow as tf\n", "import numpy as np\n", "import subprocess\n" - ], - "metadata": { - "id": "id1pU4aCFjR-" - }, - "execution_count": 9, - "outputs": [] + ] }, { "cell_type": "code", - "source": [ - "config = Config(config_file)" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -449,11 +441,10 @@ "id": "R5_vh3SFFe3n", "outputId": "2799462d-1fc6-4793-c195-2b40f15b56ea" }, - "execution_count": 10, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "BASEDIR: /content\n", "DATADIR: /content/data\n", @@ -461,14 +452,14 @@ "using labels: ['class']\n" ] } + ], + "source": [ + "config = Config(config_file)" ] }, { "cell_type": "code", - "source": [ - "OUTPUT_IMAGE_FILE = str(config.MODEL_DIR / \"prediction\" / f\"{config.OUTPUT_NAME}.TFRecord\")\n", - "print(f\"OUTPUT_IMAGE_FILE: {OUTPUT_IMAGE_FILE}\")\n" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -476,36 +467,32 @@ "id": "M26Ze2ZNDP7R", "outputId": "d7808b4f-6d31-4bd1-fc94-c0686bac9439" }, - "execution_count": 11, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "OUTPUT_IMAGE_FILE: /content/drive/MyDrive/Colab Notebooks/DL_Book/Chapter_1/output/dnn_v1/prediction/prediction_dnn_v1.TFRecord\n" ] } + ], + "source": [ + "OUTPUT_IMAGE_FILE = str(config.MODEL_DIR / \"prediction\" / f\"{config.OUTPUT_NAME}.TFRecord\")\n", + "print(f\"OUTPUT_IMAGE_FILE: {OUTPUT_IMAGE_FILE}\")\n" ] }, { "cell_type": "markdown", - "source": [ - "## Get files for export" - ], "metadata": { "id": "GzrIzedTIv9v" - } + }, + "source": [ + "## Get files for export" + ] }, { "cell_type": "code", - "source": [ - "ls = f\"gsutil ls gs://{config.GCS_BUCKET}/{config.GCS_IMAGE_DIR}\"\n", - "print(f\"ls >> : {ls}\")\n", - "\n", - "files_list = subprocess.check_output(ls, shell=True)\n", - "files_list = files_list.decode(\"utf-8\")\n", - "files_list = files_list.split(\"\\n\")" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -513,22 +500,27 @@ "id": "HDJRxeeHDP91", "outputId": "7483e7a2-5259-4514-a96c-52fb3f937e3e" }, - "execution_count": 12, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "ls >> : gsutil ls gs://dl-book/chapter-1/images\n" ] } + ], + "source": [ + "ls = f\"gsutil ls gs://{config.GCS_BUCKET}/{config.GCS_IMAGE_DIR}\"\n", + "print(f\"ls >> : {ls}\")\n", + "\n", + "files_list = subprocess.check_output(ls, shell=True)\n", + "files_list = files_list.decode(\"utf-8\")\n", + "files_list = files_list.split(\"\\n\")" ] }, { "cell_type": "code", - "source": [ - "files_list" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -536,10 +528,8 @@ "id": "0aCleCW6G1-L", "outputId": "f5543391-02a8-4311-ab9f-07baf3f6d4d6" }, - "execution_count": 13, "outputs": [ { - "output_type": "execute_result", "data": { "text/plain": [ "['gs://dl-book/chapter-1/images/',\n", @@ -553,19 +543,18 @@ " '']" ] }, + "execution_count": 13, "metadata": {}, - "execution_count": 13 + "output_type": "execute_result" } + ], + "source": [ + "files_list" ] }, { "cell_type": "code", - "source": [ - "# Get only the files generated by the image export.\n", - "exported_files_list = [s for s in files_list if config.GCS_IMAGE_PREFIX in s]\n", - "\n", - "print(f\"exported_files_list: {exported_files_list}\")" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -573,28 +562,38 @@ "id": "12n86MsSIFip", "outputId": "04a32ae5-4725-47be-accd-bea1a702a5f2" }, - "execution_count": 14, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "exported_files_list: ['gs://dl-book/chapter-1/images/image_202100000.tfrecord.gz', 'gs://dl-book/chapter-1/images/image_202100001.tfrecord.gz', 'gs://dl-book/chapter-1/images/image_202100002.tfrecord.gz', 'gs://dl-book/chapter-1/images/image_202100003.tfrecord.gz', 'gs://dl-book/chapter-1/images/image_202100004.tfrecord.gz', 'gs://dl-book/chapter-1/images/image_202100005.tfrecord.gz', 'gs://dl-book/chapter-1/images/image_2021mixer.json']\n" ] } + ], + "source": [ + "# Get only the files generated by the image export.\n", + "exported_files_list = [s for s in files_list if config.GCS_IMAGE_PREFIX in s]\n", + "\n", + "print(f\"exported_files_list: {exported_files_list}\")" ] }, { "cell_type": "markdown", - "source": [ - "## Get the list of image files and the JSON mixer file." - ], "metadata": { "id": "2XDPadw0ILJ7" - } + }, + "source": [ + "## Get the list of image files and the JSON mixer file." + ] }, { "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "WET_70R1DQA2" + }, + "outputs": [], "source": [ "image_files_list = []\n", "json_file = None\n", @@ -603,32 +602,23 @@ " image_files_list.append(f)\n", " elif f.endswith(\".json\"):\n", " json_file = f" - ], - "metadata": { - "id": "WET_70R1DQA2" - }, - "execution_count": 15, - "outputs": [] + ] }, { "cell_type": "code", - "source": [ - "# Make sure the files are in the right order.\n", - "image_files_list.sort()" - ], + "execution_count": null, "metadata": { "id": "k3GNaHnsG7oV" }, - "execution_count": 16, - "outputs": [] + "outputs": [], + "source": [ + "# Make sure the files are in the right order.\n", + "image_files_list.sort()" + ] }, { "cell_type": "code", - "source": [ - "print(f\"image_files_list: {image_files_list}\")\n", - "\n", - "print(f\"json_file: {json_file}\")" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -636,24 +626,25 @@ "id": "PNcSm43FDQDp", "outputId": "03a80a20-ae50-469e-f688-04a8939b5b5d" }, - "execution_count": 17, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "image_files_list: ['gs://dl-book/chapter-1/images/image_202100000.tfrecord.gz', 'gs://dl-book/chapter-1/images/image_202100001.tfrecord.gz', 'gs://dl-book/chapter-1/images/image_202100002.tfrecord.gz', 'gs://dl-book/chapter-1/images/image_202100003.tfrecord.gz', 'gs://dl-book/chapter-1/images/image_202100004.tfrecord.gz', 'gs://dl-book/chapter-1/images/image_202100005.tfrecord.gz']\n", "json_file: gs://dl-book/chapter-1/images/image_2021mixer.json\n" ] } + ], + "source": [ + "print(f\"image_files_list: {image_files_list}\")\n", + "\n", + "print(f\"json_file: {json_file}\")" ] }, { "cell_type": "code", - "source": [ - "print(f\"Loading model from {str(config.MODEL_DIR)}/trained-model\")\n", - "this_model = tf.keras.models.load_model(f\"{str(config.MODEL_DIR)}/trained-model\")\n" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -661,22 +652,23 @@ "id": "tkrQCptGDQGd", "outputId": "d2f8752c-ecb3-478c-a594-8a39e52d32ac" }, - "execution_count": 18, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Loading model from /content/drive/MyDrive/Colab Notebooks/DL_Book/Chapter_1/output/dnn_v1/trained-model\n" ] } + ], + "source": [ + "print(f\"Loading model from {str(config.MODEL_DIR)}/trained-model\")\n", + "this_model = tf.keras.models.load_model(f\"{str(config.MODEL_DIR)}/trained-model\")\n" ] }, { "cell_type": "code", - "source": [ - "this_model.summary()" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -684,11 +676,10 @@ "id": "ftVjQntTDQJD", "outputId": "1908ec7d-e4ba-441a-8265-9dcc4cc1ef8e" }, - "execution_count": 19, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Model: \"model\"\n", "_________________________________________________________________\n", @@ -721,19 +712,27 @@ "_________________________________________________________________\n" ] } + ], + "source": [ + "this_model.summary()" ] }, { "cell_type": "markdown", - "source": [ - "## Get relevant info from the JSON mixer file." - ], "metadata": { "id": "Ac6sL0faJmLu" - } + }, + "source": [ + "## Get relevant info from the JSON mixer file." + ] }, { "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "o-Ns212ZDQLn" + }, + "outputs": [], "source": [ "cat = f\"gsutil cat {json_file}\"\n", "read_t = subprocess.check_output(cat, shell=True)\n", @@ -747,69 +746,36 @@ "patch_height = mixer[\"patchDimensions\"][1]\n", "patches = mixer[\"totalPatches\"]\n", "patch_dimensions_flat = [patch_width * patch_height, 1]" - ], - "metadata": { - "id": "o-Ns212ZDQLn" - }, - "execution_count": 20, - "outputs": [] + ] }, { "cell_type": "markdown", - "source": [ - "## Load the buffer size for prediction" - ], "metadata": { - "id": "-tFJcYnpJ04y" - } + "id": "3bXJaIDlKD3M" + }, + "source": [ + "## Setup features" + ] }, { "cell_type": "code", - "source": [ - "if config.KERNEL_BUFFER:\n", - " x_buffer = config.KERNEL_BUFFER[0] // 2\n", - " y_buffer = config.KERNEL_BUFFER[1] // 2\n", - "\n", - " buffered_shape = [\n", - " config.PATCH_SHAPE[0] + config.KERNEL_BUFFER[0],\n", - " config.PATCH_SHAPE[1] + config.KERNEL_BUFFER[1],\n", - " ]\n", - "else:\n", - " x_buffer = 0\n", - " y_buffer = 0\n", - " buffered_shape = config.PATCH_SHAPE\n", - "\n", - "print(f\"buffered_shape: {buffered_shape}\")" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, - "id": "ieIGfMCrJ5ka", - "outputId": "2acb6538-a6f2-4378-ef71-1728abd405ea" + "id": "AUHbFYADKIhH", + "outputId": "a9a74389-d142-4bc8-f334-767c2b96f86c" }, - "execution_count": 21, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ - "buffered_shape: (256, 256)\n" + "Config.FEATURES: ['red_before', 'green_before', 'blue_before', 'nir_before', 'red_during', 'green_during', 'blue_during', 'nir_during']\n" ] } - ] - }, - { - "cell_type": "markdown", - "source": [ - "## Setup features" ], - "metadata": { - "id": "3bXJaIDlKD3M" - } - }, - { - "cell_type": "code", "source": [ "if config.USE_ELEVATION:\n", " config.FEATURES.extend([\"elevation\", \"slope\"])\n", @@ -820,36 +786,24 @@ " \"vv_desc_before\", \"vh_desc_before\", \"vv_desc_during\", \"vh_desc_during\"])\n", "\n", "print(f\"Config.FEATURES: {config.FEATURES}\")\n" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "AUHbFYADKIhH", - "outputId": "a9a74389-d142-4bc8-f334-767c2b96f86c" - }, - "execution_count": 22, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Config.FEATURES: ['red_before', 'green_before', 'blue_before', 'nir_before', 'red_during', 'green_during', 'blue_during', 'nir_during']\n" - ] - } ] }, { "cell_type": "markdown", - "source": [ - "### Some useful functions" - ], "metadata": { "id": "WJv7lBJyKgSB" - } + }, + "source": [ + "### Some useful functions" + ] }, { "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "ovVaxx9YKjdP" + }, + "outputs": [], "source": [ "def parse_image(example_proto):\n", " columns = [\n", @@ -857,24 +811,24 @@ " ]\n", " image_features_dict = dict(zip(config.FEATURES, columns))\n", " return tf.io.parse_single_example(example_proto, image_features_dict)\n" - ], - "metadata": { - "id": "ovVaxx9YKjdP" - }, - "execution_count": 23, - "outputs": [] + ] }, { "cell_type": "markdown", - "source": [ - "## Create a dataset" - ], "metadata": { "id": "OZOpx1oWz7sz" - } + }, + "source": [ + "## Create a dataset" + ] }, { "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "bdk8mvK7z_re" + }, + "outputs": [], "source": [ "# Create a dataset from the TFRecord file(s) in Cloud Storage.\n", "image_dataset = tf.data.TFRecordDataset(image_files_list, compression_type=\"GZIP\")\n", @@ -891,28 +845,20 @@ ")\n", "\n", "image_dataset = image_dataset.batch(patch_width * patch_height)\n" - ], - "metadata": { - "id": "bdk8mvK7z_re" - }, - "execution_count": 24, - "outputs": [] + ] }, { "cell_type": "markdown", - "source": [ - "## Perform Inference" - ], "metadata": { "id": "bk6J6dtV0HKV" - } + }, + "source": [ + "## Perform Inference" + ] }, { "cell_type": "code", - "source": [ - "predictions = this_model.predict(image_dataset, steps=patches, verbose=1)\n", - "print(f\"predictions shape: {predictions.shape}\")\n" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -920,43 +866,66 @@ "id": "ngBve5IK0I-j", "outputId": "6a03f20f-fd02-4580-e0ef-1d9634e3e69b" }, - "execution_count": 25, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "252/252 [==============================] - 486s 2s/step\n", "predictions shape: (16515072, 1, 5)\n" ] } + ], + "source": [ + "predictions = this_model.predict(image_dataset, steps=patches, verbose=1)\n", + "print(f\"predictions shape: {predictions.shape}\")\n" ] }, { "cell_type": "markdown", - "source": [ - "## Write Predictions" - ], "metadata": { "id": "b0XXHcwW0SZ4" - } + }, + "source": [ + "## Write Predictions" + ] }, { "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "toZUS6udGkGb" + }, + "outputs": [], "source": [ "from pathlib import Path\n", "\n", "# Create the target directory if it doesn't exist\n", "Path(OUTPUT_IMAGE_FILE).parent.mkdir(parents=True, exist_ok=True)" - ], - "metadata": { - "id": "toZUS6udGkGb" - }, - "execution_count": 26, - "outputs": [] + ] }, { "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "7CSi_UFn0UzA", + "outputId": "4aa3ae7a-ac6f-4bc4-8731-ea6590568716" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Writing predictions to /content/drive/MyDrive/Colab Notebooks/DL_Book/Chapter_1/output/dnn_v1/prediction/prediction_dnn_v1.TFRecord ...\n", + "prediction.shape: (1, 5)\n", + "Done with patch 100 of 252...\n", + "Done with patch 200 of 252...\n" + ] + } + ], "source": [ "print(f\"Writing predictions to {OUTPUT_IMAGE_FILE} ...\")\n", "writer = tf.io.TFRecordWriter(OUTPUT_IMAGE_FILE)\n", @@ -1017,101 +986,75 @@ " cur_patch += 1\n", "\n", "writer.close()" - ], - "metadata": { - "id": "7CSi_UFn0UzA", - "colab": { - "base_uri": "https://localhost:8080/" - }, - "outputId": "4aa3ae7a-ac6f-4bc4-8731-ea6590568716" - }, - "execution_count": null, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Writing predictions to /content/drive/MyDrive/Colab Notebooks/DL_Book/Chapter_1/output/dnn_v1/prediction/prediction_dnn_v1.TFRecord ...\n", - "prediction.shape: (1, 5)\n", - "Done with patch 100 of 252...\n", - "Done with patch 200 of 252...\n" - ] - } ] }, { "cell_type": "markdown", - "source": [ - "## Upload to Google Earth Engine (GEE)" - ], "metadata": { "id": "menoRbWc1WZI" - } + }, + "source": [ + "## Upload to Google Earth Engine (GEE)" + ] }, { "cell_type": "markdown", - "source": [ - "Now we have write the prediction to the `OUTPUT_IMAGE_FILE`. You can upload this to GEE for visualization. To do this, you will need to upload to GCP and then to GEE." - ], "metadata": { "id": "kVmtfYTe0w5Z" - } + }, + "source": [ + "Now we have write the prediction to the `OUTPUT_IMAGE_FILE`. You can upload this to GEE for visualization. To do this, you will need to upload to GCP and then to GEE." + ] }, { "cell_type": "markdown", - "source": [ - "Make sure you have proper permission" - ], "metadata": { "id": "ek37oamcCbGt" - } + }, + "source": [ + "Make sure you have proper permission" + ] }, { "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "rKnzfd0NXC1E" + }, + "outputs": [], "source": [ "# Cloud authentication.\n", "from google.colab import auth\n", "auth.authenticate_user()" - ], - "metadata": { - "id": "rKnzfd0NXC1E" - }, - "execution_count": null, - "outputs": [] + ] }, { "cell_type": "code", - "source": [ - "OUTPUT_GCS_PATH = f\"gs://{config.GCS_BUCKET}/chapter-1/prediction/{config.OUTPUT_NAME}.TFRecord\"\n", - "print(f\"OUTPUT_GCS_PATH: {OUTPUT_GCS_PATH}\")" - ], + "execution_count": null, "metadata": { - "id": "8Eyow_AL9R6e", "colab": { "base_uri": "https://localhost:8080/" }, + "id": "8Eyow_AL9R6e", "outputId": "896d2c97-5637-4602-f092-172676499f4b" }, - "execution_count": null, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "OUTPUT_GCS_PATH: gs://dl-book/chapter-1/prediction/prediction_dnn_v1.TFRecord\n" ] } + ], + "source": [ + "OUTPUT_GCS_PATH = f\"gs://{config.GCS_BUCKET}/chapter-1/prediction/{config.OUTPUT_NAME}.TFRecord\"\n", + "print(f\"OUTPUT_GCS_PATH: {OUTPUT_GCS_PATH}\")" ] }, { "cell_type": "code", - "source": [ - "# upload to gcp\n", - "upload_to_gcp = f'gsutil cp \"{OUTPUT_IMAGE_FILE}\" \"{OUTPUT_GCS_PATH}\"'\n", - "print(f\"upload_to_gcp: {upload_to_gcp}\")\n", - "result = subprocess.check_output(upload_to_gcp, shell=True)\n", - "print(f\"uploading classified image to gcp: {result}\")" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -1119,32 +1062,36 @@ "id": "RDoyR9hS0U1_", "outputId": "70277404-b4ef-48f1-8d93-9cda98cc2e3d" }, - "execution_count": null, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "upload_to_gcp: gsutil cp \"/content/drive/MyDrive/Colab Notebooks/DL_Book/Chapter_1/output/dnn_v1/prediction/prediction_dnn_v1.TFRecord\" \"gs://dl-book/chapter-1/prediction/prediction_dnn_v1.TFRecord\"\n", "uploading classified image to gcp: b''\n" ] } + ], + "source": [ + "# upload to gcp\n", + "upload_to_gcp = f'gsutil cp \"{OUTPUT_IMAGE_FILE}\" \"{OUTPUT_GCS_PATH}\"'\n", + "print(f\"upload_to_gcp: {upload_to_gcp}\")\n", + "result = subprocess.check_output(upload_to_gcp, shell=True)\n", + "print(f\"uploading classified image to gcp: {result}\")" ] }, { "cell_type": "markdown", - "source": [ - "Next we will upload this to the GEE asset." - ], "metadata": { "id": "QdeLBXDfDyWc" - } + }, + "source": [ + "Next we will upload this to the GEE asset." + ] }, { "cell_type": "code", - "source": [ - "config.EE_OUTPUT_ASSET, OUTPUT_GCS_PATH" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -1152,50 +1099,50 @@ "id": "zaabEpmuD5q2", "outputId": "2f10d441-f8f3-4b41-eccc-a292af078374" }, - "execution_count": null, "outputs": [ { - "output_type": "execute_result", "data": { "text/plain": [ "('projects/servir-ee/assets/dl-book/chapter-1/prediction',\n", " 'gs://dl-book/chapter-1/prediction/prediction_dnn_v1.TFRecord')" ] }, + "execution_count": 31, "metadata": {}, - "execution_count": 31 + "output_type": "execute_result" } + ], + "source": [ + "config.EE_OUTPUT_ASSET, OUTPUT_GCS_PATH" ] }, { "cell_type": "markdown", - "source": [ - "Make sure you have proper permission." - ], "metadata": { "id": "F3vVU9lUHZ6S" - } + }, + "source": [ + "Make sure you have proper permission." + ] }, { "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "UCxT0FLqYboq" + }, + "outputs": [], "source": [ "# Import, authenticate and initialize the Earth Engine library.\n", "import ee\n", "ee.Authenticate()\n", "# ee.Initialize(project=f\"{config.GCS_PROJECT}\")\n", "EEUtils.initialize_session(use_highvolume=True, project=config.GCS_PROJECT)" - ], - "metadata": { - "id": "UCxT0FLqYboq" - }, - "execution_count": null, - "outputs": [] + ] }, { "cell_type": "code", - "source": [ - "!earthengine set_project {config.GCS_PROJECT}" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -1203,24 +1150,22 @@ "id": "p8w9iCirYp5L", "outputId": "897af55d-62d7-45e5-863e-cf4fffadd01d" }, - "execution_count": null, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Successfully saved project id\n" ] } + ], + "source": [ + "!earthengine set_project {config.GCS_PROJECT}" ] }, { "cell_type": "code", - "source": [ - "upload_image = f\"earthengine upload image --asset_id={config.EE_OUTPUT_ASSET}/{config.OUTPUT_NAME} --pyramiding_policy=mode {OUTPUT_GCS_PATH} {json_file}\"\n", - "result = subprocess.check_output(upload_image, shell=True)\n", - "print(f\"uploading classified image to earth engine: {result}\")\n" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -1228,39 +1173,43 @@ "id": "ZLJOT49o0U7U", "outputId": "f7244a00-546b-4c3f-ceed-7452c13d998d" }, - "execution_count": null, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "uploading classified image to earth engine: b'Started upload task with ID: DONA7JAK47ZXTNYMQNJLYE34\\n'\n" ] } + ], + "source": [ + "upload_image = f\"earthengine upload image --asset_id={config.EE_OUTPUT_ASSET}/{config.OUTPUT_NAME} --pyramiding_policy=mode {OUTPUT_GCS_PATH} {json_file}\"\n", + "result = subprocess.check_output(upload_image, shell=True)\n", + "print(f\"uploading classified image to earth engine: {result}\")\n" ] }, { "cell_type": "code", - "source": [], + "execution_count": null, "metadata": { "id": "xbGNPeO_LWqw" }, - "execution_count": null, - "outputs": [] + "outputs": [], + "source": [] } ], "metadata": { + "accelerator": "GPU", "colab": { - "provenance": [], "gpuType": "T4", + "provenance": [], "toc_visible": true }, "kernelspec": { "display_name": "Python 3", "name": "python3" - }, - "accelerator": "GPU" + } }, "nbformat": 4, "nbformat_minor": 0 -} \ No newline at end of file +} diff --git a/notebook/prediction_unet.ipynb b/notebook/prediction_unet.ipynb index f37b954..255a24b 100644 --- a/notebook/prediction_unet.ipynb +++ b/notebook/prediction_unet.ipynb @@ -35,12 +35,12 @@ "\n", "\n", " \n", "
\n", - " \n", + " \n", " \"Colab Run in Colab\n", " \n", " \n", - " \n", + " \n", " \"GitHub\n", " View on GitHub\n", " \n", @@ -61,30 +61,27 @@ }, { "cell_type": "markdown", - "source": [ - "## Setup environment" - ], "metadata": { "id": "EuQkhSxRmiIA" - } + }, + "source": [ + "## Setup environment" + ] }, { "cell_type": "code", - "source": [ - "!pip install servir-aces" - ], + "execution_count": 2, "metadata": { - "id": "FuDztFucmhpB", "colab": { "base_uri": "https://localhost:8080/" }, + "id": "FuDztFucmhpB", "outputId": "30878f43-0be2-4981-d9af-32e1343115e0" }, - "execution_count": 2, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Collecting servir-aces\n", " Downloading servir_aces-0.0.14-py2.py3-none-any.whl (32 kB)\n", @@ -154,13 +151,14 @@ "Successfully installed python-dotenv-1.0.1 servir-aces-0.0.14\n" ] } + ], + "source": [ + "!pip install servir-aces" ] }, { "cell_type": "code", - "source": [ - "!git clone https://github.com/SERVIR/servir-aces" - ], + "execution_count": 3, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -168,11 +166,10 @@ "id": "6PvoP9Sgqz4e", "outputId": "b3e310a7-7943-4904-c89d-9d8de4293eaf" }, - "execution_count": 3, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Cloning into 'servir-aces'...\n", "remote: Enumerating objects: 731, done.\u001b[K\n", @@ -183,38 +180,38 @@ "Resolving deltas: 100% (478/478), done.\n" ] } + ], + "source": [ + "!git clone https://github.com/SERVIR/servir-aces" ] }, { "cell_type": "markdown", + "metadata": { + "id": "RukLD6eeq7Fl" + }, "source": [ "Now the repo is downloaded. We will create an environment file file to place point to our training data and customize parameters for the model. To do this, we make a copy of the `.env.example` file provided.\n", "\n", "Under the hood, all the configuration provided via the environment file are parsed as a config object and can be accessed programatically.\n", "\n", "Note current version does not expose all the model intracacies through the environment file but future version may include those depending on the need." - ], - "metadata": { - "id": "RukLD6eeq7Fl" - } + ] }, { "cell_type": "code", - "source": [ - "!cp servir-aces/.env.example servir-aces/config.env" - ], + "execution_count": 4, "metadata": { "id": "jpnfjXRYsYMk" }, - "execution_count": 4, - "outputs": [] + "outputs": [], + "source": [ + "!cp servir-aces/.env.example servir-aces/config.env" + ] }, { "cell_type": "code", - "source": [ - "from google.colab import drive\n", - "drive.mount(\"/content/drive\")" - ], + "execution_count": 5, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -222,28 +219,34 @@ "id": "mgk98jsYF5xU", "outputId": "82828441-891a-4012-b332-89311cacce89" }, - "execution_count": 5, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Mounted at /content/drive\n" ] } + ], + "source": [ + "from google.colab import drive\n", + "drive.mount(\"/content/drive\")" ] }, { "cell_type": "markdown", - "source": [ - "## Setup config file variables" - ], "metadata": { "id": "9wn3sMH9IXKK" - } + }, + "source": [ + "## Setup config file variables" + ] }, { "cell_type": "markdown", + "metadata": { + "id": "ooFqBUY3gS5e" + }, "source": [ "Okay, now we have the `config.env` file, we will use this to provide our environments and parameters.\n", "\n", @@ -253,13 +256,13 @@ "BASEDIR = \"/content/\"\n", "OUTPUT_DIR = \"/content/drive/MyDrive/Colab Notebooks/DL_Book/Chapter_1/output\"\n", "```" - ], - "metadata": { - "id": "ooFqBUY3gS5e" - } + ] }, { "cell_type": "markdown", + "metadata": { + "id": "CEDUshfUi1OY" + }, "source": [ "For the prediction, we are using growing season and pre-growing season information. Thus, we have 8 optical bands, namely `red_before`, `green_before`, `blue_before`, `nir_before`, `red_during`, `green_during`, `blue_during`, and `nir_during`. In adidition, you can use `USE_ELEVATION` and `USE_S1` config to include the topographic and radar information. Since currently we are not including these, so we won't be settting these config values.\n", "\n", @@ -278,13 +281,13 @@ "\n", "KERNEL_BUFFER = 0\n", "```" - ], - "metadata": { - "id": "CEDUshfUi1OY" - } + ] }, { "cell_type": "markdown", + "metadata": { + "id": "stwnTiy94pzU" + }, "source": [ "Next, we will specify the `MODEL_DIR_NAME`. The `MODEL_DIR` is then constructed as\n", "MODEL_DIR = OUTPUT_DIR / MODEL_DIR_NAME. The `MODEL_DIR_NAME` in my case is `unet_v1`, so we will use that. Similarly, you can specify your output of the file from the prediction using `OUTPUT_NAME` variable. Other config to change are `GCS_PROJECT`, `GCS_BUCKET`, `GCS_IMAGE_DIR`, and `GCS_IMAGE_PREFIX` (for prediction image direction, see this [notebook](https://colab.research.google.com/drive/1MZexam3GZKsQySQO9Jk_RPNyyMLmciEq?usp=drive_link)). For exporting our prediction to the GEE Asset, we will use `EE_OUTPUT_ASSET` to update it.\n", @@ -304,31 +307,33 @@ "# where the prediction output will be stored\n", "EE_OUTPUT_ASSET = \"projects/servir-ee/assets/dl-book/chapter-1/prediction\"\n", "```" - ], - "metadata": { - "id": "stwnTiy94pzU" - } + ] }, { "cell_type": "markdown", - "source": [ - "## Update the config file programtically" - ], "metadata": { "id": "0p6d8MQcqtO3" - } + }, + "source": [ + "## Update the config file programtically" + ] }, { "cell_type": "markdown", - "source": [ - "Let's make a dictionary so we can change these config settings programatically." - ], "metadata": { "id": "RMA7PH-jvvVr" - } + }, + "source": [ + "Let's make a dictionary so we can change these config settings programatically." + ] }, { "cell_type": "code", + "execution_count": 6, + "metadata": { + "id": "cFhU_kNQqu2b" + }, + "outputs": [], "source": [ "BASEDIR = \"/content/\" # @param {type:\"string\"}\n", "OUTPUT_DIR = \"/content/drive/MyDrive/Colab Notebooks/DL_Book/Chapter_1/output\" # @param {type:\"string\"}\n", @@ -355,15 +360,15 @@ "# where the prediction output will be stored\n", "EE_OUTPUT_ASSET = \"projects/servir-ee/assets/dl-book/chapter-1/prediction\" # @param {type:\"string\"}\n", "\n" - ], - "metadata": { - "id": "cFhU_kNQqu2b" - }, - "execution_count": 6, - "outputs": [] + ] }, { "cell_type": "code", + "execution_count": 7, + "metadata": { + "id": "j3_k_jmBv0xE" + }, + "outputs": [], "source": [ "config_settings = {\n", " \"BASEDIR\" : BASEDIR,\n", @@ -381,15 +386,15 @@ " \"GCS_IMAGE_PREFIX\": GCS_IMAGE_PREFIX,\n", " \"EE_OUTPUT_ASSET\": EE_OUTPUT_ASSET,\n", "}\n" - ], - "metadata": { - "id": "j3_k_jmBv0xE" - }, - "execution_count": 7, - "outputs": [] + ] }, { "cell_type": "code", + "execution_count": 8, + "metadata": { + "id": "xMAmTIBvvRjW" + }, + "outputs": [], "source": [ "import dotenv\n", "\n", @@ -400,24 +405,24 @@ " key_to_set=config_key,\n", " value_to_set=config_settings[config_key]\n", " )\n" - ], - "metadata": { - "id": "xMAmTIBvvRjW" - }, - "execution_count": 8, - "outputs": [] + ] }, { "cell_type": "markdown", - "source": [ - "## Load config file variables" - ], "metadata": { "id": "lZvJKXATIf9v" - } + }, + "source": [ + "## Load config file variables" + ] }, { "cell_type": "code", + "execution_count": 9, + "metadata": { + "id": "id1pU4aCFjR-" + }, + "outputs": [], "source": [ "from aces import Config, EEUtils\n", "\n", @@ -426,18 +431,11 @@ "import tensorflow as tf\n", "import numpy as np\n", "import subprocess\n" - ], - "metadata": { - "id": "id1pU4aCFjR-" - }, - "execution_count": 9, - "outputs": [] + ] }, { "cell_type": "code", - "source": [ - "config = Config(config_file)" - ], + "execution_count": 10, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -445,11 +443,10 @@ "id": "R5_vh3SFFe3n", "outputId": "b14199f9-c08b-49f6-e0f7-123c8e579450" }, - "execution_count": 10, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "BASEDIR: /content\n", "DATADIR: /content/data\n", @@ -457,14 +454,14 @@ "using labels: ['class']\n" ] } + ], + "source": [ + "config = Config(config_file)" ] }, { "cell_type": "code", - "source": [ - "OUTPUT_IMAGE_FILE = str(config.MODEL_DIR / \"prediction\" / f\"{config.OUTPUT_NAME}.TFRecord\")\n", - "print(f\"OUTPUT_IMAGE_FILE: {OUTPUT_IMAGE_FILE}\")\n" - ], + "execution_count": 11, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -472,36 +469,32 @@ "id": "M26Ze2ZNDP7R", "outputId": "5ef05099-aa02-411f-e455-923b5353106b" }, - "execution_count": 11, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "OUTPUT_IMAGE_FILE: /content/drive/MyDrive/Colab Notebooks/DL_Book/Chapter_1/output/unet_v1/prediction/prediction_unet_v1.TFRecord\n" ] } + ], + "source": [ + "OUTPUT_IMAGE_FILE = str(config.MODEL_DIR / \"prediction\" / f\"{config.OUTPUT_NAME}.TFRecord\")\n", + "print(f\"OUTPUT_IMAGE_FILE: {OUTPUT_IMAGE_FILE}\")\n" ] }, { "cell_type": "markdown", - "source": [ - "## Get files for export" - ], "metadata": { "id": "GzrIzedTIv9v" - } + }, + "source": [ + "## Get files for export" + ] }, { "cell_type": "code", - "source": [ - "ls = f\"gsutil ls gs://{config.GCS_BUCKET}/{config.GCS_IMAGE_DIR}\"\n", - "print(f\"ls >> : {ls}\")\n", - "\n", - "files_list = subprocess.check_output(ls, shell=True)\n", - "files_list = files_list.decode(\"utf-8\")\n", - "files_list = files_list.split(\"\\n\")" - ], + "execution_count": 12, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -509,22 +502,27 @@ "id": "HDJRxeeHDP91", "outputId": "a230db6a-3cfa-4e44-c105-57ccfd81b3d3" }, - "execution_count": 12, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "ls >> : gsutil ls gs://dl-book/chapter-1/images\n" ] } + ], + "source": [ + "ls = f\"gsutil ls gs://{config.GCS_BUCKET}/{config.GCS_IMAGE_DIR}\"\n", + "print(f\"ls >> : {ls}\")\n", + "\n", + "files_list = subprocess.check_output(ls, shell=True)\n", + "files_list = files_list.decode(\"utf-8\")\n", + "files_list = files_list.split(\"\\n\")" ] }, { "cell_type": "code", - "source": [ - "files_list" - ], + "execution_count": 13, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -532,10 +530,8 @@ "id": "0aCleCW6G1-L", "outputId": "0d6ea343-ed6c-4b23-e9fc-bf82991d43ff" }, - "execution_count": 13, "outputs": [ { - "output_type": "execute_result", "data": { "text/plain": [ "['gs://dl-book/chapter-1/images/',\n", @@ -549,19 +545,18 @@ " '']" ] }, + "execution_count": 13, "metadata": {}, - "execution_count": 13 + "output_type": "execute_result" } + ], + "source": [ + "files_list" ] }, { "cell_type": "code", - "source": [ - "# Get only the files generated by the image export.\n", - "exported_files_list = [s for s in files_list if config.GCS_IMAGE_PREFIX in s]\n", - "\n", - "print(f\"exported_files_list: {exported_files_list}\")" - ], + "execution_count": 14, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -569,28 +564,38 @@ "id": "12n86MsSIFip", "outputId": "d917e136-20da-4dc9-9fa8-5de143d97a11" }, - "execution_count": 14, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "exported_files_list: ['gs://dl-book/chapter-1/images/image_202100000.tfrecord.gz', 'gs://dl-book/chapter-1/images/image_202100001.tfrecord.gz', 'gs://dl-book/chapter-1/images/image_202100002.tfrecord.gz', 'gs://dl-book/chapter-1/images/image_202100003.tfrecord.gz', 'gs://dl-book/chapter-1/images/image_202100004.tfrecord.gz', 'gs://dl-book/chapter-1/images/image_202100005.tfrecord.gz', 'gs://dl-book/chapter-1/images/image_2021mixer.json']\n" ] } + ], + "source": [ + "# Get only the files generated by the image export.\n", + "exported_files_list = [s for s in files_list if config.GCS_IMAGE_PREFIX in s]\n", + "\n", + "print(f\"exported_files_list: {exported_files_list}\")" ] }, { "cell_type": "markdown", - "source": [ - "## Get the list of image files and the JSON mixer file." - ], "metadata": { "id": "2XDPadw0ILJ7" - } + }, + "source": [ + "## Get the list of image files and the JSON mixer file." + ] }, { "cell_type": "code", + "execution_count": 15, + "metadata": { + "id": "WET_70R1DQA2" + }, + "outputs": [], "source": [ "image_files_list = []\n", "json_file = None\n", @@ -599,32 +604,23 @@ " image_files_list.append(f)\n", " elif f.endswith(\".json\"):\n", " json_file = f" - ], - "metadata": { - "id": "WET_70R1DQA2" - }, - "execution_count": 15, - "outputs": [] + ] }, { "cell_type": "code", - "source": [ - "# Make sure the files are in the right order.\n", - "image_files_list.sort()" - ], + "execution_count": 16, "metadata": { "id": "k3GNaHnsG7oV" }, - "execution_count": 16, - "outputs": [] + "outputs": [], + "source": [ + "# Make sure the files are in the right order.\n", + "image_files_list.sort()" + ] }, { "cell_type": "code", - "source": [ - "print(f\"image_files_list: {image_files_list}\")\n", - "\n", - "print(f\"json_file: {json_file}\")" - ], + "execution_count": 17, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -632,24 +628,25 @@ "id": "PNcSm43FDQDp", "outputId": "c45b88e4-88f2-4b5c-d77a-f1e3fee4d691" }, - "execution_count": 17, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "image_files_list: ['gs://dl-book/chapter-1/images/image_202100000.tfrecord.gz', 'gs://dl-book/chapter-1/images/image_202100001.tfrecord.gz', 'gs://dl-book/chapter-1/images/image_202100002.tfrecord.gz', 'gs://dl-book/chapter-1/images/image_202100003.tfrecord.gz', 'gs://dl-book/chapter-1/images/image_202100004.tfrecord.gz', 'gs://dl-book/chapter-1/images/image_202100005.tfrecord.gz']\n", "json_file: gs://dl-book/chapter-1/images/image_2021mixer.json\n" ] } + ], + "source": [ + "print(f\"image_files_list: {image_files_list}\")\n", + "\n", + "print(f\"json_file: {json_file}\")" ] }, { "cell_type": "code", - "source": [ - "print(f\"Loading model from {str(config.MODEL_DIR)}/trained-model\")\n", - "this_model = tf.keras.models.load_model(f\"{str(config.MODEL_DIR)}/trained-model\")\n" - ], + "execution_count": 18, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -657,22 +654,23 @@ "id": "tkrQCptGDQGd", "outputId": "ba26f327-61ab-4e72-9d70-63a6d0d30868" }, - "execution_count": 18, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Loading model from /content/drive/MyDrive/Colab Notebooks/DL_Book/Chapter_1/output/unet_v1/trained-model\n" ] } + ], + "source": [ + "print(f\"Loading model from {str(config.MODEL_DIR)}/trained-model\")\n", + "this_model = tf.keras.models.load_model(f\"{str(config.MODEL_DIR)}/trained-model\")\n" ] }, { "cell_type": "code", - "source": [ - "this_model.summary()" - ], + "execution_count": 19, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -680,11 +678,10 @@ "id": "ftVjQntTDQJD", "outputId": "34a5e9fa-c04a-4ae4-a559-28607f5e99d7" }, - "execution_count": 19, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Model: \"unet\"\n", "__________________________________________________________________________________________________\n", @@ -895,19 +892,27 @@ "__________________________________________________________________________________________________\n" ] } + ], + "source": [ + "this_model.summary()" ] }, { "cell_type": "markdown", - "source": [ - "## Get relevant info from the JSON mixer file." - ], "metadata": { "id": "Ac6sL0faJmLu" - } + }, + "source": [ + "## Get relevant info from the JSON mixer file." + ] }, { "cell_type": "code", + "execution_count": 20, + "metadata": { + "id": "o-Ns212ZDQLn" + }, + "outputs": [], "source": [ "cat = f\"gsutil cat {json_file}\"\n", "read_t = subprocess.check_output(cat, shell=True)\n", @@ -921,24 +926,36 @@ "patch_height = mixer[\"patchDimensions\"][1]\n", "patches = mixer[\"totalPatches\"]\n", "patch_dimensions_flat = [patch_width * patch_height, 1]" - ], - "metadata": { - "id": "o-Ns212ZDQLn" - }, - "execution_count": 20, - "outputs": [] + ] }, { "cell_type": "markdown", - "source": [ - "## Load the buffer size for prediction" - ], "metadata": { "id": "-tFJcYnpJ04y" - } + }, + "source": [ + "## Load the buffer size for prediction" + ] }, { "cell_type": "code", + "execution_count": 21, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "ieIGfMCrJ5ka", + "outputId": "c6f8b400-b49a-4d2a-a312-7da05359dc47" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "buffered_shape: (256, 256)\n" + ] + } + ], "source": [ "if config.KERNEL_BUFFER:\n", " x_buffer = config.KERNEL_BUFFER[0] // 2\n", @@ -954,47 +971,20 @@ " buffered_shape = config.PATCH_SHAPE\n", "\n", "print(f\"buffered_shape: {buffered_shape}\")" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "ieIGfMCrJ5ka", - "outputId": "c6f8b400-b49a-4d2a-a312-7da05359dc47" - }, - "execution_count": 21, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "buffered_shape: (256, 256)\n" - ] - } ] }, { "cell_type": "markdown", - "source": [ - "## Setup features" - ], "metadata": { "id": "3bXJaIDlKD3M" - } + }, + "source": [ + "## Setup features" + ] }, { "cell_type": "code", - "source": [ - "if config.USE_ELEVATION:\n", - " config.FEATURES.extend([\"elevation\", \"slope\"])\n", - "\n", - "\n", - "if config.USE_S1:\n", - " config.FEATURES.extend([\"vv_asc_before\", \"vh_asc_before\", \"vv_asc_during\", \"vh_asc_during\",\n", - " \"vv_desc_before\", \"vh_desc_before\", \"vv_desc_during\", \"vh_desc_during\"])\n", - "\n", - "print(f\"Config.FEATURES: {config.FEATURES}\")\n" - ], + "execution_count": 22, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -1002,28 +992,43 @@ "id": "AUHbFYADKIhH", "outputId": "865da146-e652-470b-d852-3bf6b56795ac" }, - "execution_count": 22, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Config.FEATURES: ['red_before', 'green_before', 'blue_before', 'nir_before', 'red_during', 'green_during', 'blue_during', 'nir_during']\n" ] } + ], + "source": [ + "if config.USE_ELEVATION:\n", + " config.FEATURES.extend([\"elevation\", \"slope\"])\n", + "\n", + "\n", + "if config.USE_S1:\n", + " config.FEATURES.extend([\"vv_asc_before\", \"vh_asc_before\", \"vv_asc_during\", \"vh_asc_during\",\n", + " \"vv_desc_before\", \"vh_desc_before\", \"vv_desc_during\", \"vh_desc_during\"])\n", + "\n", + "print(f\"Config.FEATURES: {config.FEATURES}\")\n" ] }, { "cell_type": "markdown", - "source": [ - "### Some useful functions" - ], "metadata": { "id": "WJv7lBJyKgSB" - } + }, + "source": [ + "### Some useful functions" + ] }, { "cell_type": "code", + "execution_count": 23, + "metadata": { + "id": "ovVaxx9YKjdP" + }, + "outputs": [], "source": [ "def parse_image(example_proto):\n", " columns = [\n", @@ -1037,51 +1042,43 @@ " stacked = tf.stack(inputs_list, axis=0)\n", " stacked = tf.transpose(stacked, [1, 2, 0])\n", " return stacked\n" - ], - "metadata": { - "id": "ovVaxx9YKjdP" - }, - "execution_count": 23, - "outputs": [] + ] }, { "cell_type": "markdown", - "source": [ - "## Create a dataset" - ], "metadata": { "id": "OZOpx1oWz7sz" - } + }, + "source": [ + "## Create a dataset" + ] }, { "cell_type": "code", + "execution_count": 24, + "metadata": { + "id": "bdk8mvK7z_re" + }, + "outputs": [], "source": [ "# Create a dataset from the TFRecord file(s) in Cloud Storage.\n", "image_dataset = tf.data.TFRecordDataset(image_files_list, compression_type=\"GZIP\")\n", "image_dataset = image_dataset.map(parse_image, num_parallel_calls=5)\n", "image_dataset = image_dataset.map(to_tuple_image).batch(1)\n" - ], - "metadata": { - "id": "bdk8mvK7z_re" - }, - "execution_count": 24, - "outputs": [] + ] }, { "cell_type": "markdown", - "source": [ - "## Perform Inference" - ], "metadata": { "id": "bk6J6dtV0HKV" - } + }, + "source": [ + "## Perform Inference" + ] }, { "cell_type": "code", - "source": [ - "predictions = this_model.predict(image_dataset, steps=patches, verbose=1)\n", - "print(f\"predictions shape: {predictions.shape}\")\n" - ], + "execution_count": 25, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -1089,43 +1086,71 @@ "id": "ngBve5IK0I-j", "outputId": "0c721579-118c-4344-ba84-b1a1c2044d8d" }, - "execution_count": 25, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "252/252 [==============================] - 20s 57ms/step\n", "predictions shape: (252, 256, 256, 5)\n" ] } + ], + "source": [ + "predictions = this_model.predict(image_dataset, steps=patches, verbose=1)\n", + "print(f\"predictions shape: {predictions.shape}\")\n" ] }, { "cell_type": "markdown", - "source": [ - "## Write Predictions" - ], "metadata": { "id": "b0XXHcwW0SZ4" - } + }, + "source": [ + "## Write Predictions" + ] }, { "cell_type": "code", + "execution_count": 26, + "metadata": { + "id": "Rs8yfBE3wW5o" + }, + "outputs": [], "source": [ "from pathlib import Path\n", "\n", "# Create the target directory if it doesn't exist\n", "Path(OUTPUT_IMAGE_FILE).parent.mkdir(parents=True, exist_ok=True)" - ], - "metadata": { - "id": "Rs8yfBE3wW5o" - }, - "execution_count": 26, - "outputs": [] + ] }, { "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "7CSi_UFn0UzA", + "outputId": "e703f94b-3688-41b6-9b69-dbabfdf6334e" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Writing predictions to /content/drive/MyDrive/Colab Notebooks/DL_Book/Chapter_1/output/unet_v1/prediction/prediction_unet_v1.TFRecord ...\n", + "Starting with patch 0...\n", + "predictionPatch: (256, 256, 5)\n", + "Writing patch 0...\n", + "Writing patch 50...\n", + "Writing patch 100...\n", + "Writing patch 150...\n", + "Writing patch 200...\n", + "Writing patch 250...\n" + ] + } + ], "source": [ "print(f\"Writing predictions to {OUTPUT_IMAGE_FILE} ...\")\n", "writer = tf.io.TFRecordWriter(OUTPUT_IMAGE_FILE)\n", @@ -1174,79 +1199,51 @@ " writer.write(example.SerializeToString())\n", "\n", "writer.close()" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "7CSi_UFn0UzA", - "outputId": "e703f94b-3688-41b6-9b69-dbabfdf6334e" - }, - "execution_count": null, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Writing predictions to /content/drive/MyDrive/Colab Notebooks/DL_Book/Chapter_1/output/unet_v1/prediction/prediction_unet_v1.TFRecord ...\n", - "Starting with patch 0...\n", - "predictionPatch: (256, 256, 5)\n", - "Writing patch 0...\n", - "Writing patch 50...\n", - "Writing patch 100...\n", - "Writing patch 150...\n", - "Writing patch 200...\n", - "Writing patch 250...\n" - ] - } ] }, { "cell_type": "markdown", - "source": [ - "## Upload to Google Earth Engine (GEE)" - ], "metadata": { "id": "menoRbWc1WZI" - } + }, + "source": [ + "## Upload to Google Earth Engine (GEE)" + ] }, { "cell_type": "markdown", - "source": [ - "Now we have write the prediction to the `OUTPUT_IMAGE_FILE`. You can upload this to GEE for visualization. To do this, you will need to upload to GCP and then to GEE." - ], "metadata": { "id": "kVmtfYTe0w5Z" - } + }, + "source": [ + "Now we have write the prediction to the `OUTPUT_IMAGE_FILE`. You can upload this to GEE for visualization. To do this, you will need to upload to GCP and then to GEE." + ] }, { "cell_type": "markdown", - "source": [ - "Make sure you have proper permission" - ], "metadata": { "id": "ek37oamcCbGt" - } + }, + "source": [ + "Make sure you have proper permission" + ] }, { "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "rKnzfd0NXC1E" + }, + "outputs": [], "source": [ "# Cloud authentication.\n", "from google.colab import auth\n", "auth.authenticate_user()" - ], - "metadata": { - "id": "rKnzfd0NXC1E" - }, - "execution_count": null, - "outputs": [] + ] }, { "cell_type": "code", - "source": [ - "OUTPUT_GCS_PATH = f\"gs://{config.GCS_BUCKET}/chapter-1/prediction/{config.OUTPUT_NAME}.TFRecord\"\n", - "print(f\"OUTPUT_GCS_PATH: {OUTPUT_GCS_PATH}\")" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -1254,26 +1251,23 @@ "id": "8Eyow_AL9R6e", "outputId": "4bc9fcb9-174a-4817-f9d3-eb5bbfe10e4f" }, - "execution_count": null, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "OUTPUT_GCS_PATH: gs://dl-book/chapter-1/prediction/prediction_unet_v1.TFRecord\n" ] } + ], + "source": [ + "OUTPUT_GCS_PATH = f\"gs://{config.GCS_BUCKET}/chapter-1/prediction/{config.OUTPUT_NAME}.TFRecord\"\n", + "print(f\"OUTPUT_GCS_PATH: {OUTPUT_GCS_PATH}\")" ] }, { "cell_type": "code", - "source": [ - "# upload to gcp\n", - "upload_to_gcp = f'gsutil cp \"{OUTPUT_IMAGE_FILE}\" \"{OUTPUT_GCS_PATH}\"'\n", - "print(f\"upload_to_gcp: {upload_to_gcp}\")\n", - "result = subprocess.check_output(upload_to_gcp, shell=True)\n", - "print(f\"uploading classified image to gcp: {result}\")" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -1281,32 +1275,36 @@ "id": "RDoyR9hS0U1_", "outputId": "ca648a31-1b24-4882-c1cf-365040288aed" }, - "execution_count": null, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "upload_to_gcp: gsutil cp \"/content/drive/MyDrive/Colab Notebooks/DL_Book/Chapter_1/output/unet_v1/prediction/prediction_unet_v1.TFRecord\" \"gs://dl-book/chapter-1/prediction/prediction_unet_v1.TFRecord\"\n", "uploading classified image to gcp: b''\n" ] } + ], + "source": [ + "# upload to gcp\n", + "upload_to_gcp = f'gsutil cp \"{OUTPUT_IMAGE_FILE}\" \"{OUTPUT_GCS_PATH}\"'\n", + "print(f\"upload_to_gcp: {upload_to_gcp}\")\n", + "result = subprocess.check_output(upload_to_gcp, shell=True)\n", + "print(f\"uploading classified image to gcp: {result}\")" ] }, { "cell_type": "markdown", - "source": [ - "Next we will upload this to the GEE asset." - ], "metadata": { "id": "QdeLBXDfDyWc" - } + }, + "source": [ + "Next we will upload this to the GEE asset." + ] }, { "cell_type": "code", - "source": [ - "config.EE_OUTPUT_ASSET, OUTPUT_GCS_PATH" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -1314,50 +1312,50 @@ "id": "zaabEpmuD5q2", "outputId": "9c8a6041-c112-4127-b3c2-dbfcc2d2c87c" }, - "execution_count": null, "outputs": [ { - "output_type": "execute_result", "data": { "text/plain": [ "('projects/servir-ee/assets/dl-book/chapter-1/prediction',\n", " 'gs://dl-book/chapter-1/prediction/prediction_unet_v1.TFRecord')" ] }, + "execution_count": 31, "metadata": {}, - "execution_count": 31 + "output_type": "execute_result" } + ], + "source": [ + "config.EE_OUTPUT_ASSET, OUTPUT_GCS_PATH" ] }, { "cell_type": "markdown", - "source": [ - "Make sure you have proper permission." - ], "metadata": { "id": "F3vVU9lUHZ6S" - } + }, + "source": [ + "Make sure you have proper permission." + ] }, { "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "UCxT0FLqYboq" + }, + "outputs": [], "source": [ "# Import, authenticate and initialize the Earth Engine library.\n", "import ee\n", "ee.Authenticate()\n", "# ee.Initialize(project=f\"{config.GCS_PROJECT}\")\n", "EEUtils.initialize_session(use_highvolume=True, project=config.GCS_PROJECT)\n" - ], - "metadata": { - "id": "UCxT0FLqYboq" - }, - "execution_count": null, - "outputs": [] + ] }, { "cell_type": "code", - "source": [ - "!earthengine set_project {config.GCS_PROJECT}" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -1365,24 +1363,22 @@ "id": "p8w9iCirYp5L", "outputId": "f79c8c1f-b690-4944-d7bd-afb6145459ff" }, - "execution_count": null, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Successfully saved project id\n" ] } + ], + "source": [ + "!earthengine set_project {config.GCS_PROJECT}" ] }, { "cell_type": "code", - "source": [ - "upload_image = f\"earthengine upload image --asset_id={config.EE_OUTPUT_ASSET}/{config.OUTPUT_NAME} --pyramiding_policy=mode {OUTPUT_GCS_PATH} {json_file}\"\n", - "result = subprocess.check_output(upload_image, shell=True)\n", - "print(f\"uploading classified image to earth engine: {result}\")\n" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -1390,30 +1386,34 @@ "id": "ZLJOT49o0U7U", "outputId": "5f2f2da2-f257-42c7-bef4-15d20c0c12c5" }, - "execution_count": null, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "uploading classified image to earth engine: b'Started upload task with ID: EC4KXAWNTUH2MFR6YEWTPVE7\\n'\n" ] } + ], + "source": [ + "upload_image = f\"earthengine upload image --asset_id={config.EE_OUTPUT_ASSET}/{config.OUTPUT_NAME} --pyramiding_policy=mode {OUTPUT_GCS_PATH} {json_file}\"\n", + "result = subprocess.check_output(upload_image, shell=True)\n", + "print(f\"uploading classified image to earth engine: {result}\")\n" ] } ], "metadata": { + "accelerator": "GPU", "colab": { - "provenance": [], "gpuType": "T4", + "provenance": [], "toc_visible": true }, "kernelspec": { "display_name": "Python 3", "name": "python3" - }, - "accelerator": "GPU" + } }, "nbformat": 4, "nbformat_minor": 0 -} \ No newline at end of file +}