tutorials/R/03-Training-Serving-CARET-Models.ipynb (2,366 lines of code) (raw):

{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Training and Serving CARET models using AI Platform Custom Containers and Cloud Run\n", "## Overview\n", "\n", "This notebook illustrates how to use [CARET](https://topepo.github.io/caret/) R package to build an ML model to estimate the baby's weight given a number of factors, using the [BigQuery natality dataset](https://console.cloud.google.com/bigquery?p=bigquery-public-data&d=samples&t=natality&page=table&_ga=2.99329886.-1705629017.1551465326&_gac=1.109796023.1561476396.CI2rz-z4hOMCFc6RhQods4oEXA). We use [AI Platform Training](https://cloud.google.com/ml-engine/docs/tensorflow/training-overview) with **Custom Containers** to train the TensorFlow model at scale. Rhen use the [Cloud Run](https://cloud.google.com/run/docs/) to serve the trained model as a Web API for online predictions.\n", "\n", "R is one of the most widely used programming languages for statistical modeling, which has a large and active community of data scientists and ML professional. \n", "With over 10,000 packages in the open-source repository of CRAN, R caters to all statistical data analysis applications, ML, and visualisation.\n", "\n", "\n", "## Dataset\n", "The dataset used in this tutorial is natality data, which describes all United States births registered in the 50 States, the District of Columbia, and New York City from 1969 to 2008, with more than 137 million records.\n", "The dataset is available in [BigQuery public dataset](https://console.cloud.google.com/bigquery?p=bigquery-public-data&d=samples&t=natality&page=table&_ga=2.99329886.-1705629017.1551465326&_gac=1.109796023.1561476396.CI2rz-z4hOMCFc6RhQods4oEXA). We use the data extracted from BigQuery and stored as CSV in Cloud Storage (GCS) in the [Exploratory Data Analysis](01_EDA-with-R-and-BigQuery) notebook.\n", "\n", "In this notebook, we focus on Exploratory Data Analysis, while the goal is to predict the baby's weight given a number of factors about the pregnancy and the baby's mother.\n", "\n", "## Objective\n", "The goal of this tutorial is to:\n", "1. Create a CARET regression model\n", "2. Train the CARET model using on AI Platform Training with custom R container\n", "3. Implement a Web API wrapper to the trained model using Plumber R package\n", "4. Build Docker container image for the prediction Web API\n", "5. Deploy the prediction Web API container image model on Cloud Run\n", "6. Invoke the deployed Web API for predictions.\n", "7. Use the AI Platform Notebooks to drive the workflow.\n", "\n", "\n", "\n", "## Costs\n", "This tutorial uses billable components of Google Cloud Platform (GCP):\n", "1. Create a TensorFlow premade Estimator trainer using R interface\n", "2. Train and export the Estimator on AI Platform Training using the cloudml APIs\n", "3. Deploy the exported model to AI Platform prediction using the cloudml APIs\n", "4. Invoke the deployed model API for predictions.\n", "5. Use the AI Platform Notebooks to drive the workflow.\n", "\n", "\n", "Learn about GCP pricing, use the [Pricing Calculator](https://cloud.google.com/products/calculator/) to generate a cost estimate based on your projected usage.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 0. Setup" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ " _ \n", "platform x86_64-pc-linux-gnu \n", "arch x86_64 \n", "os linux-gnu \n", "system x86_64, linux-gnu \n", "status \n", "major 3 \n", "minor 5.1 \n", "year 2018 \n", "month 07 \n", "day 02 \n", "svn rev 74947 \n", "language R \n", "version.string R version 3.5.1 (2018-07-02)\n", "nickname Feather Spray " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "version" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Install and import the required libraries. \n", "\n", "This may take several minutes if not installed already..." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Updating HTML index of packages in '.Library'\n", "Making 'packages.html' ... done\n" ] } ], "source": [ "install.packages(c(\"caret\"))" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Loading required package: lattice\n", "Loading required package: ggplot2\n" ] } ], "source": [ "library(caret) # used to build a regression model" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Set your `PROJECT_ID`, `BUCKET_NAME`, and `REGION`" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "# Set the project id\n", "PROJECT_ID <- \"r-on-gcp\"\n", "\n", "# Set yout GCS bucket\n", "BUCKET_NAME <- \"r-on-gcp\"\n", "\n", "# Set your training and model deployment region\n", "REGION <- 'europe-west1'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1. Building a CARET Regression Model" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1.1. Load data\n", "\n", "If you run the [Exploratory Data Analysis](01_EDA-with-R-and-BigQuery) Notebook, you should have the **train_data.csv** and **eval_data.csv** files uploaded to GCS. You can download them to train your model locally using the following cell. However, if you have the files available locally, you can skip the following cell." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1] \"gsutil cp -r gs://r-on-gcp/data/*_data.csv data/\"\n" ] }, { "data": { "text/html": [], "text/latex": [], "text/markdown": [], "text/plain": [ "character(0)" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "dir.create(file.path('data'), showWarnings = FALSE)\n", "gcs_data_dir <- paste0(\"gs://\", BUCKET_NAME, \"/data/*_data.csv\")\n", "command <- paste(\"gsutil cp -r\", gcs_data_dir, \"data/\")\n", "print(command)\n", "system(command, intern = TRUE)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "train_file <- \"data/train_data.csv\"\n", "eval_file <- \"data/eval_data.csv\"\n", "header <- c(\n", " \"weight_pounds\", \n", " \"is_male\", \"mother_age\", \"mother_race\", \"plurality\", \"gestation_weeks\", \n", " \"mother_married\", \"cigarette_use\", \"alcohol_use\", \n", " \"key\")\n", "\n", "target <- \"weight_pounds\"\n", "key <- \"key\"\n", "features <- setdiff(header, c(target, key))\n", "\n", "train_data <- read.table(train_file, col.names = header, sep=\",\")\n", "eval_data <- read.table(eval_file, col.names = header, sep=\",\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1.2. Train the model\n", "In this example, we will train an XGboost Tree model for regression." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1] \"Training the model...\"\n", "[1] \"Model is trained.\"\n" ] } ], "source": [ "trainControl <- trainControl(method = 'boot', number = 10)\n", "hyper_parameters <- expand.grid(\n", " nrounds = 100,\n", " max_depth = 6,\n", " eta = 0.3,\n", " gamma = 0,\n", " colsample_bytree = 1,\n", " min_child_weight = 1,\n", " subsample = 1\n", ")\n", " \n", "print('Training the model...')\n", "\n", "model <- train(\n", " y=train_data$weight_pounds, \n", " x=train_data[, features], \n", " preProc = c(\"center\", \"scale\"),\n", " method='xgbTree', \n", " trControl=trainControl,\n", " tuneGrid=hyper_parameters\n", ")\n", "\n", "print('Model is trained.')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1.2. Evaluate the model" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "eXtreme Gradient Boosting \n", "\n", "7708 samples\n", " 8 predictor\n", "\n", "Pre-processing: centered (4), scaled (4), ignore (4) \n", "Resampling: Bootstrapped (10 reps) \n", "Summary of sample sizes: 7708, 7708, 7708, 7708, 7708, 7708, ... \n", "Resampling results:\n", "\n", " RMSE Rsquared MAE \n", " 1.094446 0.2985824 0.8440141\n", "\n", "Tuning parameter 'nrounds' was held constant at a value of 100\n", "Tuning\n", " held constant at a value of 1\n", "Tuning parameter 'subsample' was held\n", " constant at a value of 1" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "eval(model)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1.3. Save the trained model" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "model_dir <- \"models\"\n", "model_name <- \"caret_babyweight_estimator\"" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "# Saving the trained model\n", "dir.create(model_dir, showWarnings = FALSE)\n", "dir.create(file.path(model_dir, model_name), showWarnings = FALSE)\n", "saveRDS(model, file.path(model_dir, model_name, \"trained_model.rds\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1.4. Implementing a model prediction function\n", "This is an implementation of wrapper function to the model to perform prediction. The function expects a list of instances in a JSON format, and returns a list of predictions (estimated weights). This prediction function implementation will be used when serving the model as a Web API for online predictions. " ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1] \"Estimated weight(s): 4.5\" \"Estimated weight(s): 2.57\"\n" ] } ], "source": [ "xgbtree <- readRDS(file.path(model_dir, model_name, \"trained_model.rds\"))\n", "\n", "estimate_babyweights <- function(instances_json){\n", " library(\"rjson\")\n", " instances <- jsonlite::fromJSON(instances_json)\n", " df_instances <- data.frame(instances)\n", " # fix data types\n", " boolean_columns <- c(\"is_male\", \"mother_married\", \"cigarette_use\", \"alcohol_use\")\n", " for(col in boolean_columns){\n", " df_instances[[col]] <- as.logical(df_instances[[col]])\n", " }\n", " \n", " estimates <- predict(xgbtree, df_instances)\n", " return(estimates) \n", "}\n", "\n", "instances_json <- '\n", "[\n", " {\n", " \"is_male\": \"TRUE\",\n", " \"mother_age\": 28,\n", " \"mother_race\": 8,\n", " \"plurality\": 1,\n", " \"gestation_weeks\": 28,\n", " \"mother_married\": \"TRUE\",\n", " \"cigarette_use\": \"FALSE\",\n", " \"alcohol_use\": \"FALSE\"\n", " },\n", " {\n", " \"is_male\": \"FALSE\",\n", " \"mother_age\": 38,\n", " \"mother_race\": 18,\n", " \"plurality\": 1,\n", " \"gestation_weeks\": 28,\n", " \"mother_married\": \"TRUE\",\n", " \"cigarette_use\": \"TRUE\",\n", " \"alcohol_use\": \"TRUE\"\n", " }\n", "]\n", "'\n", "\n", "estimate <- round(estimate_babyweights(instances_json), digits = 2)\n", "print(paste(\"Estimated weight(s):\", estimate))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3. Submit a Training Job to AI Platform with Custom Containers\n", "In order to train your CARET model in at scale using AI Platform Training, you need to implement your training logic in an R script file, containerize it in a Docker image, and submit the Docker image to AI Platform Training.\n", "\n", "The [src/caret/training](src/caret/training) directory includes the following code files:\n", "1. [model_trainer.R](src/caret/training/model_trainer.R) - This is the implementation of the CARET model training logic.\n", "1. [Dockerfile](src/caret/training/Dockerfile) - This is the definition of the Docker container image to run the **model_trainer.R** script.\n", "\n", "To submit the training job with the custom container to AI Platform, you need to do the following steps:\n", "1. set your PROJECT_ID and BUCKET_NAME in training/model_trainer.R, and PROJECT_ID in training/Dockerfile so that the first line reads \"FROM gcr.io/[PROJECT_ID]/caret_base\"\n", "2. **Build** a Docker container image with that runs the model_trainer.R\n", "3. **Push** the Docker container image to **Container Registry**.\n", "4. **Submit** an **AI Platform Training** job with the **custom container**." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3.1. Build and Push the Docker container image.\n", "#### A - Build base image\n", "This can take several minutes ..." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1] \"gcr.io/r-on-gcp/caret_base\"\n" ] }, { "data": { "text/html": [ "'/home/jupyter/cloudml-samples/notebooks/R/src/caret'" ], "text/latex": [ "'/home/jupyter/cloudml-samples/notebooks/R/src/caret'" ], "text/markdown": [ "'/home/jupyter/cloudml-samples/notebooks/R/src/caret'" ], "text/plain": [ "[1] \"/home/jupyter/cloudml-samples/notebooks/R/src/caret\"" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "[1] \"Building the base Docker container image...\"\n", "[1] \"docker build -f Dockerfile --tag gcr.io/r-on-gcp/caret_base ./\"\n" ] }, { "data": { "text/html": [ "<ol class=list-inline>\n", "\t<li><span style=white-space:pre-wrap>'Sending build context to Docker daemon 11.26kB\\r\\r'</span></li>\n", "\t<li>'Step 1/2 : FROM gcr.io/deeplearning-platform-release/r-cpu'</li>\n", "\t<li>' ---&gt; ecba7177e2c2'</li>\n", "\t<li>'Step 2/2 : RUN R -e \"install.packages(c(\\'readr\\', \\'caret\\', \\'xgboost\\', \\'rjson\\', \\'plumber\\'), repos=\\'http://cran.rstudio.com/\\')\"'</li>\n", "\t<li>' ---&gt; Using cache'</li>\n", "\t<li>' ---&gt; 23896e0a8a18'</li>\n", "\t<li>'Successfully built 23896e0a8a18'</li>\n", "\t<li>'Successfully tagged gcr.io/r-on-gcp/caret_base:latest'</li>\n", "</ol>\n" ], "text/latex": [ "\\begin{enumerate*}\n", "\\item 'Sending build context to Docker daemon 11.26kB\\textbackslash{}r\\textbackslash{}r'\n", "\\item 'Step 1/2 : FROM gcr.io/deeplearning-platform-release/r-cpu'\n", "\\item ' ---> ecba7177e2c2'\n", "\\item 'Step 2/2 : RUN R -e \"install.packages(c(\\textbackslash{}'readr\\textbackslash{}', \\textbackslash{}'caret\\textbackslash{}', \\textbackslash{}'xgboost\\textbackslash{}', \\textbackslash{}'rjson\\textbackslash{}', \\textbackslash{}'plumber\\textbackslash{}'), repos=\\textbackslash{}'http://cran.rstudio.com/\\textbackslash{}')\"'\n", "\\item ' ---> Using cache'\n", "\\item ' ---> 23896e0a8a18'\n", "\\item 'Successfully built 23896e0a8a18'\n", "\\item 'Successfully tagged gcr.io/r-on-gcp/caret\\_base:latest'\n", "\\end{enumerate*}\n" ], "text/markdown": [ "1. <span style=white-space:pre-wrap>'Sending build context to Docker daemon 11.26kB\\r\\r'</span>\n", "2. 'Step 1/2 : FROM gcr.io/deeplearning-platform-release/r-cpu'\n", "3. ' ---&gt; ecba7177e2c2'\n", "4. 'Step 2/2 : RUN R -e \"install.packages(c(\\'readr\\', \\'caret\\', \\'xgboost\\', \\'rjson\\', \\'plumber\\'), repos=\\'http://cran.rstudio.com/\\')\"'\n", "5. ' ---&gt; Using cache'\n", "6. ' ---&gt; 23896e0a8a18'\n", "7. 'Successfully built 23896e0a8a18'\n", "8. 'Successfully tagged gcr.io/r-on-gcp/caret_base:latest'\n", "\n", "\n" ], "text/plain": [ "[1] \"Sending build context to Docker daemon 11.26kB\\r\\r\" \n", "[2] \"Step 1/2 : FROM gcr.io/deeplearning-platform-release/r-cpu\" \n", "[3] \" ---> ecba7177e2c2\" \n", "[4] \"Step 2/2 : RUN R -e \\\"install.packages(c('readr', 'caret', 'xgboost', 'rjson', 'plumber'), repos='http://cran.rstudio.com/')\\\"\"\n", "[5] \" ---> Using cache\" \n", "[6] \" ---> 23896e0a8a18\" \n", "[7] \"Successfully built 23896e0a8a18\" \n", "[8] \"Successfully tagged gcr.io/r-on-gcp/caret_base:latest\" " ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "[1] \"Pushing the baseDocker container image...\"\n", "[1] \"gcloud docker -- push gcr.io/r-on-gcp/caret_base\"\n" ] }, { "data": { "text/html": [ "<ol class=list-inline>\n", "\t<li>'The push refers to repository [gcr.io/r-on-gcp/caret_base]'</li>\n", "\t<li>'74186bfe1b58: Preparing'</li>\n", "\t<li>'0ce62bef372e: Preparing'</li>\n", "\t<li>'ac80f37c61e8: Preparing'</li>\n", "\t<li>'d35b581063f9: Preparing'</li>\n", "\t<li>'2cdc3d03b403: Preparing'</li>\n", "\t<li>'842c821f54eb: Preparing'</li>\n", "\t<li>'81c79e512da5: Preparing'</li>\n", "\t<li>'071617594623: Preparing'</li>\n", "\t<li>'2eee26189b5e: Preparing'</li>\n", "\t<li>'473763e23878: Preparing'</li>\n", "\t<li>'8ff58362bc10: Preparing'</li>\n", "\t<li>'c5890df75ecc: Preparing'</li>\n", "\t<li>'1fb17ae4fc11: Preparing'</li>\n", "\t<li>'0aaa26768f46: Preparing'</li>\n", "\t<li>'fd5276389b8a: Preparing'</li>\n", "\t<li>'56ac87b2a469: Preparing'</li>\n", "\t<li>'140ce133886c: Preparing'</li>\n", "\t<li>'b20d335c2af7: Preparing'</li>\n", "\t<li>'e4dc9a88747b: Preparing'</li>\n", "\t<li>'027d71a0bd0a: Preparing'</li>\n", "\t<li>'2bcd744f68d7: Preparing'</li>\n", "\t<li>'75e70aa52609: Preparing'</li>\n", "\t<li>'dda151859818: Preparing'</li>\n", "\t<li>'fbd2732ad777: Preparing'</li>\n", "\t<li>'ba9de9d8475e: Preparing'</li>\n", "\t<li>'842c821f54eb: Waiting'</li>\n", "\t<li>'81c79e512da5: Waiting'</li>\n", "\t<li>'071617594623: Waiting'</li>\n", "\t<li>'2eee26189b5e: Waiting'</li>\n", "\t<li>'473763e23878: Waiting'</li>\n", "\t<li>'8ff58362bc10: Waiting'</li>\n", "\t<li>'c5890df75ecc: Waiting'</li>\n", "\t<li>'1fb17ae4fc11: Waiting'</li>\n", "\t<li>'0aaa26768f46: Waiting'</li>\n", "\t<li>'fd5276389b8a: Waiting'</li>\n", "\t<li>'56ac87b2a469: Waiting'</li>\n", "\t<li>'140ce133886c: Waiting'</li>\n", "\t<li>'b20d335c2af7: Waiting'</li>\n", "\t<li>'e4dc9a88747b: Waiting'</li>\n", "\t<li>'027d71a0bd0a: Waiting'</li>\n", "\t<li>'2bcd744f68d7: Waiting'</li>\n", "\t<li>'75e70aa52609: Waiting'</li>\n", "\t<li>'dda151859818: Waiting'</li>\n", "\t<li>'fbd2732ad777: Waiting'</li>\n", "\t<li>'ba9de9d8475e: Waiting'</li>\n", "\t<li>'74186bfe1b58: Layer already exists'</li>\n", "\t<li>'0ce62bef372e: Layer already exists'</li>\n", "\t<li>'2cdc3d03b403: Layer already exists'</li>\n", "\t<li>'d35b581063f9: Layer already exists'</li>\n", "\t<li>'ac80f37c61e8: Layer already exists'</li>\n", "\t<li>'842c821f54eb: Layer already exists'</li>\n", "\t<li>'81c79e512da5: Layer already exists'</li>\n", "\t<li>'071617594623: Layer already exists'</li>\n", "\t<li>'473763e23878: Layer already exists'</li>\n", "\t<li>'2eee26189b5e: Layer already exists'</li>\n", "\t<li>'c5890df75ecc: Layer already exists'</li>\n", "\t<li>'8ff58362bc10: Layer already exists'</li>\n", "\t<li>'1fb17ae4fc11: Layer already exists'</li>\n", "\t<li>'0aaa26768f46: Layer already exists'</li>\n", "\t<li>'fd5276389b8a: Layer already exists'</li>\n", "\t<li>'56ac87b2a469: Layer already exists'</li>\n", "\t<li>'140ce133886c: Layer already exists'</li>\n", "\t<li>'e4dc9a88747b: Layer already exists'</li>\n", "\t<li>'b20d335c2af7: Layer already exists'</li>\n", "\t<li>'027d71a0bd0a: Layer already exists'</li>\n", "\t<li>'2bcd744f68d7: Layer already exists'</li>\n", "\t<li>'fbd2732ad777: Layer already exists'</li>\n", "\t<li>'75e70aa52609: Layer already exists'</li>\n", "\t<li>'ba9de9d8475e: Layer already exists'</li>\n", "\t<li>'dda151859818: Layer already exists'</li>\n", "\t<li>'latest: digest: sha256:43f66f157027aced3c583006c2606a6eac66a891edea82422f345f8fcf6c1e4f size: 5552'</li>\n", "</ol>\n" ], "text/latex": [ "\\begin{enumerate*}\n", "\\item 'The push refers to repository {[}gcr.io/r-on-gcp/caret\\_base{]}'\n", "\\item '74186bfe1b58: Preparing'\n", "\\item '0ce62bef372e: Preparing'\n", "\\item 'ac80f37c61e8: Preparing'\n", "\\item 'd35b581063f9: Preparing'\n", "\\item '2cdc3d03b403: Preparing'\n", "\\item '842c821f54eb: Preparing'\n", "\\item '81c79e512da5: Preparing'\n", "\\item '071617594623: Preparing'\n", "\\item '2eee26189b5e: Preparing'\n", "\\item '473763e23878: Preparing'\n", "\\item '8ff58362bc10: Preparing'\n", "\\item 'c5890df75ecc: Preparing'\n", "\\item '1fb17ae4fc11: Preparing'\n", "\\item '0aaa26768f46: Preparing'\n", "\\item 'fd5276389b8a: Preparing'\n", "\\item '56ac87b2a469: Preparing'\n", "\\item '140ce133886c: Preparing'\n", "\\item 'b20d335c2af7: Preparing'\n", "\\item 'e4dc9a88747b: Preparing'\n", "\\item '027d71a0bd0a: Preparing'\n", "\\item '2bcd744f68d7: Preparing'\n", "\\item '75e70aa52609: Preparing'\n", "\\item 'dda151859818: Preparing'\n", "\\item 'fbd2732ad777: Preparing'\n", "\\item 'ba9de9d8475e: Preparing'\n", "\\item '842c821f54eb: Waiting'\n", "\\item '81c79e512da5: Waiting'\n", "\\item '071617594623: Waiting'\n", "\\item '2eee26189b5e: Waiting'\n", "\\item '473763e23878: Waiting'\n", "\\item '8ff58362bc10: Waiting'\n", "\\item 'c5890df75ecc: Waiting'\n", "\\item '1fb17ae4fc11: Waiting'\n", "\\item '0aaa26768f46: Waiting'\n", "\\item 'fd5276389b8a: Waiting'\n", "\\item '56ac87b2a469: Waiting'\n", "\\item '140ce133886c: Waiting'\n", "\\item 'b20d335c2af7: Waiting'\n", "\\item 'e4dc9a88747b: Waiting'\n", "\\item '027d71a0bd0a: Waiting'\n", "\\item '2bcd744f68d7: Waiting'\n", "\\item '75e70aa52609: Waiting'\n", "\\item 'dda151859818: Waiting'\n", "\\item 'fbd2732ad777: Waiting'\n", "\\item 'ba9de9d8475e: Waiting'\n", "\\item '74186bfe1b58: Layer already exists'\n", "\\item '0ce62bef372e: Layer already exists'\n", "\\item '2cdc3d03b403: Layer already exists'\n", "\\item 'd35b581063f9: Layer already exists'\n", "\\item 'ac80f37c61e8: Layer already exists'\n", "\\item '842c821f54eb: Layer already exists'\n", "\\item '81c79e512da5: Layer already exists'\n", "\\item '071617594623: Layer already exists'\n", "\\item '473763e23878: Layer already exists'\n", "\\item '2eee26189b5e: Layer already exists'\n", "\\item 'c5890df75ecc: Layer already exists'\n", "\\item '8ff58362bc10: Layer already exists'\n", "\\item '1fb17ae4fc11: Layer already exists'\n", "\\item '0aaa26768f46: Layer already exists'\n", "\\item 'fd5276389b8a: Layer already exists'\n", "\\item '56ac87b2a469: Layer already exists'\n", "\\item '140ce133886c: Layer already exists'\n", "\\item 'e4dc9a88747b: Layer already exists'\n", "\\item 'b20d335c2af7: Layer already exists'\n", "\\item '027d71a0bd0a: Layer already exists'\n", "\\item '2bcd744f68d7: Layer already exists'\n", "\\item 'fbd2732ad777: Layer already exists'\n", "\\item '75e70aa52609: Layer already exists'\n", "\\item 'ba9de9d8475e: Layer already exists'\n", "\\item 'dda151859818: Layer already exists'\n", "\\item 'latest: digest: sha256:43f66f157027aced3c583006c2606a6eac66a891edea82422f345f8fcf6c1e4f size: 5552'\n", "\\end{enumerate*}\n" ], "text/markdown": [ "1. 'The push refers to repository [gcr.io/r-on-gcp/caret_base]'\n", "2. '74186bfe1b58: Preparing'\n", "3. '0ce62bef372e: Preparing'\n", "4. 'ac80f37c61e8: Preparing'\n", "5. 'd35b581063f9: Preparing'\n", "6. '2cdc3d03b403: Preparing'\n", "7. '842c821f54eb: Preparing'\n", "8. '81c79e512da5: Preparing'\n", "9. '071617594623: Preparing'\n", "10. '2eee26189b5e: Preparing'\n", "11. '473763e23878: Preparing'\n", "12. '8ff58362bc10: Preparing'\n", "13. 'c5890df75ecc: Preparing'\n", "14. '1fb17ae4fc11: Preparing'\n", "15. '0aaa26768f46: Preparing'\n", "16. 'fd5276389b8a: Preparing'\n", "17. '56ac87b2a469: Preparing'\n", "18. '140ce133886c: Preparing'\n", "19. 'b20d335c2af7: Preparing'\n", "20. 'e4dc9a88747b: Preparing'\n", "21. '027d71a0bd0a: Preparing'\n", "22. '2bcd744f68d7: Preparing'\n", "23. '75e70aa52609: Preparing'\n", "24. 'dda151859818: Preparing'\n", "25. 'fbd2732ad777: Preparing'\n", "26. 'ba9de9d8475e: Preparing'\n", "27. '842c821f54eb: Waiting'\n", "28. '81c79e512da5: Waiting'\n", "29. '071617594623: Waiting'\n", "30. '2eee26189b5e: Waiting'\n", "31. '473763e23878: Waiting'\n", "32. '8ff58362bc10: Waiting'\n", "33. 'c5890df75ecc: Waiting'\n", "34. '1fb17ae4fc11: Waiting'\n", "35. '0aaa26768f46: Waiting'\n", "36. 'fd5276389b8a: Waiting'\n", "37. '56ac87b2a469: Waiting'\n", "38. '140ce133886c: Waiting'\n", "39. 'b20d335c2af7: Waiting'\n", "40. 'e4dc9a88747b: Waiting'\n", "41. '027d71a0bd0a: Waiting'\n", "42. '2bcd744f68d7: Waiting'\n", "43. '75e70aa52609: Waiting'\n", "44. 'dda151859818: Waiting'\n", "45. 'fbd2732ad777: Waiting'\n", "46. 'ba9de9d8475e: Waiting'\n", "47. '74186bfe1b58: Layer already exists'\n", "48. '0ce62bef372e: Layer already exists'\n", "49. '2cdc3d03b403: Layer already exists'\n", "50. 'd35b581063f9: Layer already exists'\n", "51. 'ac80f37c61e8: Layer already exists'\n", "52. '842c821f54eb: Layer already exists'\n", "53. '81c79e512da5: Layer already exists'\n", "54. '071617594623: Layer already exists'\n", "55. '473763e23878: Layer already exists'\n", "56. '2eee26189b5e: Layer already exists'\n", "57. 'c5890df75ecc: Layer already exists'\n", "58. '8ff58362bc10: Layer already exists'\n", "59. '1fb17ae4fc11: Layer already exists'\n", "60. '0aaa26768f46: Layer already exists'\n", "61. 'fd5276389b8a: Layer already exists'\n", "62. '56ac87b2a469: Layer already exists'\n", "63. '140ce133886c: Layer already exists'\n", "64. 'e4dc9a88747b: Layer already exists'\n", "65. 'b20d335c2af7: Layer already exists'\n", "66. '027d71a0bd0a: Layer already exists'\n", "67. '2bcd744f68d7: Layer already exists'\n", "68. 'fbd2732ad777: Layer already exists'\n", "69. '75e70aa52609: Layer already exists'\n", "70. 'ba9de9d8475e: Layer already exists'\n", "71. 'dda151859818: Layer already exists'\n", "72. 'latest: digest: sha256:43f66f157027aced3c583006c2606a6eac66a891edea82422f345f8fcf6c1e4f size: 5552'\n", "\n", "\n" ], "text/plain": [ " [1] \"The push refers to repository [gcr.io/r-on-gcp/caret_base]\" \n", " [2] \"74186bfe1b58: Preparing\" \n", " [3] \"0ce62bef372e: Preparing\" \n", " [4] \"ac80f37c61e8: Preparing\" \n", " [5] \"d35b581063f9: Preparing\" \n", " [6] \"2cdc3d03b403: Preparing\" \n", " [7] \"842c821f54eb: Preparing\" \n", " [8] \"81c79e512da5: Preparing\" \n", " [9] \"071617594623: Preparing\" \n", "[10] \"2eee26189b5e: Preparing\" \n", "[11] \"473763e23878: Preparing\" \n", "[12] \"8ff58362bc10: Preparing\" \n", "[13] \"c5890df75ecc: Preparing\" \n", "[14] \"1fb17ae4fc11: Preparing\" \n", "[15] \"0aaa26768f46: Preparing\" \n", "[16] \"fd5276389b8a: Preparing\" \n", "[17] \"56ac87b2a469: Preparing\" \n", "[18] \"140ce133886c: Preparing\" \n", "[19] \"b20d335c2af7: Preparing\" \n", "[20] \"e4dc9a88747b: Preparing\" \n", "[21] \"027d71a0bd0a: Preparing\" \n", "[22] \"2bcd744f68d7: Preparing\" \n", "[23] \"75e70aa52609: Preparing\" \n", "[24] \"dda151859818: Preparing\" \n", "[25] \"fbd2732ad777: Preparing\" \n", "[26] \"ba9de9d8475e: Preparing\" \n", "[27] \"842c821f54eb: Waiting\" \n", "[28] \"81c79e512da5: Waiting\" \n", "[29] \"071617594623: Waiting\" \n", "[30] \"2eee26189b5e: Waiting\" \n", "[31] \"473763e23878: Waiting\" \n", "[32] \"8ff58362bc10: Waiting\" \n", "[33] \"c5890df75ecc: Waiting\" \n", "[34] \"1fb17ae4fc11: Waiting\" \n", "[35] \"0aaa26768f46: Waiting\" \n", "[36] \"fd5276389b8a: Waiting\" \n", "[37] \"56ac87b2a469: Waiting\" \n", "[38] \"140ce133886c: Waiting\" \n", "[39] \"b20d335c2af7: Waiting\" \n", "[40] \"e4dc9a88747b: Waiting\" \n", "[41] \"027d71a0bd0a: Waiting\" \n", "[42] \"2bcd744f68d7: Waiting\" \n", "[43] \"75e70aa52609: Waiting\" \n", "[44] \"dda151859818: Waiting\" \n", "[45] \"fbd2732ad777: Waiting\" \n", "[46] \"ba9de9d8475e: Waiting\" \n", "[47] \"74186bfe1b58: Layer already exists\" \n", "[48] \"0ce62bef372e: Layer already exists\" \n", "[49] \"2cdc3d03b403: Layer already exists\" \n", "[50] \"d35b581063f9: Layer already exists\" \n", "[51] \"ac80f37c61e8: Layer already exists\" \n", "[52] \"842c821f54eb: Layer already exists\" \n", "[53] \"81c79e512da5: Layer already exists\" \n", "[54] \"071617594623: Layer already exists\" \n", "[55] \"473763e23878: Layer already exists\" \n", "[56] \"2eee26189b5e: Layer already exists\" \n", "[57] \"c5890df75ecc: Layer already exists\" \n", "[58] \"8ff58362bc10: Layer already exists\" \n", "[59] \"1fb17ae4fc11: Layer already exists\" \n", "[60] \"0aaa26768f46: Layer already exists\" \n", "[61] \"fd5276389b8a: Layer already exists\" \n", "[62] \"56ac87b2a469: Layer already exists\" \n", "[63] \"140ce133886c: Layer already exists\" \n", "[64] \"e4dc9a88747b: Layer already exists\" \n", "[65] \"b20d335c2af7: Layer already exists\" \n", "[66] \"027d71a0bd0a: Layer already exists\" \n", "[67] \"2bcd744f68d7: Layer already exists\" \n", "[68] \"fbd2732ad777: Layer already exists\" \n", "[69] \"75e70aa52609: Layer already exists\" \n", "[70] \"ba9de9d8475e: Layer already exists\" \n", "[71] \"dda151859818: Layer already exists\" \n", "[72] \"latest: digest: sha256:43f66f157027aced3c583006c2606a6eac66a891edea82422f345f8fcf6c1e4f size: 5552\"" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "'/home/jupyter/cloudml-samples/notebooks/R'" ], "text/latex": [ "'/home/jupyter/cloudml-samples/notebooks/R'" ], "text/markdown": [ "'/home/jupyter/cloudml-samples/notebooks/R'" ], "text/plain": [ "[1] \"/home/jupyter/cloudml-samples/notebooks/R\"" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Create base image\n", "base_image_url <- paste0(\"gcr.io/\", PROJECT_ID, \"/caret_base\")\n", "print(base_image_url)\n", "\n", "setwd(\"src/caret\")\n", "getwd()\n", "\n", "print(\"Building the base Docker container image...\")\n", "command <- paste0(\"docker build -f Dockerfile --tag \", base_image_url, \" ./\")\n", "print(command)\n", "system(command, intern = TRUE)\n", "\n", "print(\"Pushing the baseDocker container image...\")\n", "command <- paste0(\"gcloud docker -- push \", base_image_url)\n", "print(command)\n", "system(command, intern = TRUE)\n", "\n", "setwd(\"../..\")\n", "getwd()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### B - Build trainer image" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1] \"gcr.io/r-on-gcp/caret_babyweight_estimator_training\"\n" ] }, { "data": { "text/html": [ "'/home/jupyter/cloudml-samples/notebooks/R/src/caret/training'" ], "text/latex": [ "'/home/jupyter/cloudml-samples/notebooks/R/src/caret/training'" ], "text/markdown": [ "'/home/jupyter/cloudml-samples/notebooks/R/src/caret/training'" ], "text/plain": [ "[1] \"/home/jupyter/cloudml-samples/notebooks/R/src/caret/training\"" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "[1] \"Building the Docker container image...\"\n", "[1] \"docker build -f Dockerfile --tag gcr.io/r-on-gcp/caret_babyweight_estimator_training ./\"\n" ] }, { "data": { "text/html": [ "<ol class=list-inline>\n", "\t<li><span style=white-space:pre-wrap>'Sending build context to Docker daemon 5.632kB\\r\\r'</span></li>\n", "\t<li>'Step 1/5 : FROM gcr.io/r-on-gcp/caret_base'</li>\n", "\t<li>' ---&gt; 23896e0a8a18'</li>\n", "\t<li>'Step 2/5 : RUN mkdir -p /root'</li>\n", "\t<li>' ---&gt; Running in dfffccca5b17'</li>\n", "\t<li>'Removing intermediate container dfffccca5b17'</li>\n", "\t<li>' ---&gt; 8e3b3ba4b7bc'</li>\n", "\t<li>'Step 3/5 : COPY model_trainer.R /root'</li>\n", "\t<li>' ---&gt; 83f6807f8116'</li>\n", "\t<li>'Step 4/5 : WORKDIR /root'</li>\n", "\t<li>' ---&gt; Running in 80a3ac026ce4'</li>\n", "\t<li>'Removing intermediate container 80a3ac026ce4'</li>\n", "\t<li>' ---&gt; 06415782e550'</li>\n", "\t<li>'Step 5/5 : CMD [\"Rscript\", \"model_trainer.R\"]'</li>\n", "\t<li>' ---&gt; Running in a35a45de623a'</li>\n", "\t<li>'Removing intermediate container a35a45de623a'</li>\n", "\t<li>' ---&gt; dee0b504a5e1'</li>\n", "\t<li>'Successfully built dee0b504a5e1'</li>\n", "\t<li>'Successfully tagged gcr.io/r-on-gcp/caret_babyweight_estimator_training:latest'</li>\n", "</ol>\n" ], "text/latex": [ "\\begin{enumerate*}\n", "\\item 'Sending build context to Docker daemon 5.632kB\\textbackslash{}r\\textbackslash{}r'\n", "\\item 'Step 1/5 : FROM gcr.io/r-on-gcp/caret\\_base'\n", "\\item ' ---> 23896e0a8a18'\n", "\\item 'Step 2/5 : RUN mkdir -p /root'\n", "\\item ' ---> Running in dfffccca5b17'\n", "\\item 'Removing intermediate container dfffccca5b17'\n", "\\item ' ---> 8e3b3ba4b7bc'\n", "\\item 'Step 3/5 : COPY model\\_trainer.R /root'\n", "\\item ' ---> 83f6807f8116'\n", "\\item 'Step 4/5 : WORKDIR /root'\n", "\\item ' ---> Running in 80a3ac026ce4'\n", "\\item 'Removing intermediate container 80a3ac026ce4'\n", "\\item ' ---> 06415782e550'\n", "\\item 'Step 5/5 : CMD {[}\"Rscript\", \"model\\_trainer.R\"{]}'\n", "\\item ' ---> Running in a35a45de623a'\n", "\\item 'Removing intermediate container a35a45de623a'\n", "\\item ' ---> dee0b504a5e1'\n", "\\item 'Successfully built dee0b504a5e1'\n", "\\item 'Successfully tagged gcr.io/r-on-gcp/caret\\_babyweight\\_estimator\\_training:latest'\n", "\\end{enumerate*}\n" ], "text/markdown": [ "1. <span style=white-space:pre-wrap>'Sending build context to Docker daemon 5.632kB\\r\\r'</span>\n", "2. 'Step 1/5 : FROM gcr.io/r-on-gcp/caret_base'\n", "3. ' ---&gt; 23896e0a8a18'\n", "4. 'Step 2/5 : RUN mkdir -p /root'\n", "5. ' ---&gt; Running in dfffccca5b17'\n", "6. 'Removing intermediate container dfffccca5b17'\n", "7. ' ---&gt; 8e3b3ba4b7bc'\n", "8. 'Step 3/5 : COPY model_trainer.R /root'\n", "9. ' ---&gt; 83f6807f8116'\n", "10. 'Step 4/5 : WORKDIR /root'\n", "11. ' ---&gt; Running in 80a3ac026ce4'\n", "12. 'Removing intermediate container 80a3ac026ce4'\n", "13. ' ---&gt; 06415782e550'\n", "14. 'Step 5/5 : CMD [\"Rscript\", \"model_trainer.R\"]'\n", "15. ' ---&gt; Running in a35a45de623a'\n", "16. 'Removing intermediate container a35a45de623a'\n", "17. ' ---&gt; dee0b504a5e1'\n", "18. 'Successfully built dee0b504a5e1'\n", "19. 'Successfully tagged gcr.io/r-on-gcp/caret_babyweight_estimator_training:latest'\n", "\n", "\n" ], "text/plain": [ " [1] \"Sending build context to Docker daemon 5.632kB\\r\\r\" \n", " [2] \"Step 1/5 : FROM gcr.io/r-on-gcp/caret_base\" \n", " [3] \" ---> 23896e0a8a18\" \n", " [4] \"Step 2/5 : RUN mkdir -p /root\" \n", " [5] \" ---> Running in dfffccca5b17\" \n", " [6] \"Removing intermediate container dfffccca5b17\" \n", " [7] \" ---> 8e3b3ba4b7bc\" \n", " [8] \"Step 3/5 : COPY model_trainer.R /root\" \n", " [9] \" ---> 83f6807f8116\" \n", "[10] \"Step 4/5 : WORKDIR /root\" \n", "[11] \" ---> Running in 80a3ac026ce4\" \n", "[12] \"Removing intermediate container 80a3ac026ce4\" \n", "[13] \" ---> 06415782e550\" \n", "[14] \"Step 5/5 : CMD [\\\"Rscript\\\", \\\"model_trainer.R\\\"]\" \n", "[15] \" ---> Running in a35a45de623a\" \n", "[16] \"Removing intermediate container a35a45de623a\" \n", "[17] \" ---> dee0b504a5e1\" \n", "[18] \"Successfully built dee0b504a5e1\" \n", "[19] \"Successfully tagged gcr.io/r-on-gcp/caret_babyweight_estimator_training:latest\"" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "[1] \"Pushing the Docker container image...\"\n", "[1] \"gcloud docker -- push gcr.io/r-on-gcp/caret_babyweight_estimator_training\"\n" ] }, { "data": { "text/html": [ "<ol class=list-inline>\n", "\t<li>'The push refers to repository [gcr.io/r-on-gcp/caret_babyweight_estimator_training]'</li>\n", "\t<li>'6dfd17fccb17: Preparing'</li>\n", "\t<li>'74186bfe1b58: Preparing'</li>\n", "\t<li>'0ce62bef372e: Preparing'</li>\n", "\t<li>'ac80f37c61e8: Preparing'</li>\n", "\t<li>'d35b581063f9: Preparing'</li>\n", "\t<li>'2cdc3d03b403: Preparing'</li>\n", "\t<li>'842c821f54eb: Preparing'</li>\n", "\t<li>'81c79e512da5: Preparing'</li>\n", "\t<li>'071617594623: Preparing'</li>\n", "\t<li>'2eee26189b5e: Preparing'</li>\n", "\t<li>'473763e23878: Preparing'</li>\n", "\t<li>'8ff58362bc10: Preparing'</li>\n", "\t<li>'c5890df75ecc: Preparing'</li>\n", "\t<li>'1fb17ae4fc11: Preparing'</li>\n", "\t<li>'0aaa26768f46: Preparing'</li>\n", "\t<li>'fd5276389b8a: Preparing'</li>\n", "\t<li>'56ac87b2a469: Preparing'</li>\n", "\t<li>'140ce133886c: Preparing'</li>\n", "\t<li>'b20d335c2af7: Preparing'</li>\n", "\t<li>'e4dc9a88747b: Preparing'</li>\n", "\t<li>'027d71a0bd0a: Preparing'</li>\n", "\t<li>'2bcd744f68d7: Preparing'</li>\n", "\t<li>'75e70aa52609: Preparing'</li>\n", "\t<li>'dda151859818: Preparing'</li>\n", "\t<li>'fbd2732ad777: Preparing'</li>\n", "\t<li>'ba9de9d8475e: Preparing'</li>\n", "\t<li>'2cdc3d03b403: Waiting'</li>\n", "\t<li>'842c821f54eb: Waiting'</li>\n", "\t<li>'81c79e512da5: Waiting'</li>\n", "\t<li>'071617594623: Waiting'</li>\n", "\t<li>'2eee26189b5e: Waiting'</li>\n", "\t<li>'473763e23878: Waiting'</li>\n", "\t<li>'8ff58362bc10: Waiting'</li>\n", "\t<li>'c5890df75ecc: Waiting'</li>\n", "\t<li>'1fb17ae4fc11: Waiting'</li>\n", "\t<li>'0aaa26768f46: Waiting'</li>\n", "\t<li>'fd5276389b8a: Waiting'</li>\n", "\t<li>'56ac87b2a469: Waiting'</li>\n", "\t<li>'140ce133886c: Waiting'</li>\n", "\t<li>'b20d335c2af7: Waiting'</li>\n", "\t<li>'e4dc9a88747b: Waiting'</li>\n", "\t<li>'027d71a0bd0a: Waiting'</li>\n", "\t<li>'2bcd744f68d7: Waiting'</li>\n", "\t<li>'75e70aa52609: Waiting'</li>\n", "\t<li>'dda151859818: Waiting'</li>\n", "\t<li>'fbd2732ad777: Waiting'</li>\n", "\t<li>'ba9de9d8475e: Waiting'</li>\n", "\t<li>'ac80f37c61e8: Layer already exists'</li>\n", "\t<li>'0ce62bef372e: Layer already exists'</li>\n", "\t<li>'d35b581063f9: Layer already exists'</li>\n", "\t<li>'74186bfe1b58: Layer already exists'</li>\n", "\t<li>'2cdc3d03b403: Layer already exists'</li>\n", "\t<li>'842c821f54eb: Layer already exists'</li>\n", "\t<li>'81c79e512da5: Layer already exists'</li>\n", "\t<li>'071617594623: Layer already exists'</li>\n", "\t<li>'2eee26189b5e: Layer already exists'</li>\n", "\t<li>'473763e23878: Layer already exists'</li>\n", "\t<li>'8ff58362bc10: Layer already exists'</li>\n", "\t<li>'c5890df75ecc: Layer already exists'</li>\n", "\t<li>'1fb17ae4fc11: Layer already exists'</li>\n", "\t<li>'0aaa26768f46: Layer already exists'</li>\n", "\t<li>'fd5276389b8a: Layer already exists'</li>\n", "\t<li>'56ac87b2a469: Layer already exists'</li>\n", "\t<li>'e4dc9a88747b: Layer already exists'</li>\n", "\t<li>'b20d335c2af7: Layer already exists'</li>\n", "\t<li>'140ce133886c: Layer already exists'</li>\n", "\t<li>'027d71a0bd0a: Layer already exists'</li>\n", "\t<li>'2bcd744f68d7: Layer already exists'</li>\n", "\t<li>'dda151859818: Layer already exists'</li>\n", "\t<li>'75e70aa52609: Layer already exists'</li>\n", "\t<li>'fbd2732ad777: Layer already exists'</li>\n", "\t<li>'ba9de9d8475e: Layer already exists'</li>\n", "\t<li>'6dfd17fccb17: Pushed'</li>\n", "\t<li>'latest: digest: sha256:a8c86b3024e96e75e2425832c323130a8e0843779e946921a3073bd4cbe3cb79 size: 5760'</li>\n", "</ol>\n" ], "text/latex": [ "\\begin{enumerate*}\n", "\\item 'The push refers to repository {[}gcr.io/r-on-gcp/caret\\_babyweight\\_estimator\\_training{]}'\n", "\\item '6dfd17fccb17: Preparing'\n", "\\item '74186bfe1b58: Preparing'\n", "\\item '0ce62bef372e: Preparing'\n", "\\item 'ac80f37c61e8: Preparing'\n", "\\item 'd35b581063f9: Preparing'\n", "\\item '2cdc3d03b403: Preparing'\n", "\\item '842c821f54eb: Preparing'\n", "\\item '81c79e512da5: Preparing'\n", "\\item '071617594623: Preparing'\n", "\\item '2eee26189b5e: Preparing'\n", "\\item '473763e23878: Preparing'\n", "\\item '8ff58362bc10: Preparing'\n", "\\item 'c5890df75ecc: Preparing'\n", "\\item '1fb17ae4fc11: Preparing'\n", "\\item '0aaa26768f46: Preparing'\n", "\\item 'fd5276389b8a: Preparing'\n", "\\item '56ac87b2a469: Preparing'\n", "\\item '140ce133886c: Preparing'\n", "\\item 'b20d335c2af7: Preparing'\n", "\\item 'e4dc9a88747b: Preparing'\n", "\\item '027d71a0bd0a: Preparing'\n", "\\item '2bcd744f68d7: Preparing'\n", "\\item '75e70aa52609: Preparing'\n", "\\item 'dda151859818: Preparing'\n", "\\item 'fbd2732ad777: Preparing'\n", "\\item 'ba9de9d8475e: Preparing'\n", "\\item '2cdc3d03b403: Waiting'\n", "\\item '842c821f54eb: Waiting'\n", "\\item '81c79e512da5: Waiting'\n", "\\item '071617594623: Waiting'\n", "\\item '2eee26189b5e: Waiting'\n", "\\item '473763e23878: Waiting'\n", "\\item '8ff58362bc10: Waiting'\n", "\\item 'c5890df75ecc: Waiting'\n", "\\item '1fb17ae4fc11: Waiting'\n", "\\item '0aaa26768f46: Waiting'\n", "\\item 'fd5276389b8a: Waiting'\n", "\\item '56ac87b2a469: Waiting'\n", "\\item '140ce133886c: Waiting'\n", "\\item 'b20d335c2af7: Waiting'\n", "\\item 'e4dc9a88747b: Waiting'\n", "\\item '027d71a0bd0a: Waiting'\n", "\\item '2bcd744f68d7: Waiting'\n", "\\item '75e70aa52609: Waiting'\n", "\\item 'dda151859818: Waiting'\n", "\\item 'fbd2732ad777: Waiting'\n", "\\item 'ba9de9d8475e: Waiting'\n", "\\item 'ac80f37c61e8: Layer already exists'\n", "\\item '0ce62bef372e: Layer already exists'\n", "\\item 'd35b581063f9: Layer already exists'\n", "\\item '74186bfe1b58: Layer already exists'\n", "\\item '2cdc3d03b403: Layer already exists'\n", "\\item '842c821f54eb: Layer already exists'\n", "\\item '81c79e512da5: Layer already exists'\n", "\\item '071617594623: Layer already exists'\n", "\\item '2eee26189b5e: Layer already exists'\n", "\\item '473763e23878: Layer already exists'\n", "\\item '8ff58362bc10: Layer already exists'\n", "\\item 'c5890df75ecc: Layer already exists'\n", "\\item '1fb17ae4fc11: Layer already exists'\n", "\\item '0aaa26768f46: Layer already exists'\n", "\\item 'fd5276389b8a: Layer already exists'\n", "\\item '56ac87b2a469: Layer already exists'\n", "\\item 'e4dc9a88747b: Layer already exists'\n", "\\item 'b20d335c2af7: Layer already exists'\n", "\\item '140ce133886c: Layer already exists'\n", "\\item '027d71a0bd0a: Layer already exists'\n", "\\item '2bcd744f68d7: Layer already exists'\n", "\\item 'dda151859818: Layer already exists'\n", "\\item '75e70aa52609: Layer already exists'\n", "\\item 'fbd2732ad777: Layer already exists'\n", "\\item 'ba9de9d8475e: Layer already exists'\n", "\\item '6dfd17fccb17: Pushed'\n", "\\item 'latest: digest: sha256:a8c86b3024e96e75e2425832c323130a8e0843779e946921a3073bd4cbe3cb79 size: 5760'\n", "\\end{enumerate*}\n" ], "text/markdown": [ "1. 'The push refers to repository [gcr.io/r-on-gcp/caret_babyweight_estimator_training]'\n", "2. '6dfd17fccb17: Preparing'\n", "3. '74186bfe1b58: Preparing'\n", "4. '0ce62bef372e: Preparing'\n", "5. 'ac80f37c61e8: Preparing'\n", "6. 'd35b581063f9: Preparing'\n", "7. '2cdc3d03b403: Preparing'\n", "8. '842c821f54eb: Preparing'\n", "9. '81c79e512da5: Preparing'\n", "10. '071617594623: Preparing'\n", "11. '2eee26189b5e: Preparing'\n", "12. '473763e23878: Preparing'\n", "13. '8ff58362bc10: Preparing'\n", "14. 'c5890df75ecc: Preparing'\n", "15. '1fb17ae4fc11: Preparing'\n", "16. '0aaa26768f46: Preparing'\n", "17. 'fd5276389b8a: Preparing'\n", "18. '56ac87b2a469: Preparing'\n", "19. '140ce133886c: Preparing'\n", "20. 'b20d335c2af7: Preparing'\n", "21. 'e4dc9a88747b: Preparing'\n", "22. '027d71a0bd0a: Preparing'\n", "23. '2bcd744f68d7: Preparing'\n", "24. '75e70aa52609: Preparing'\n", "25. 'dda151859818: Preparing'\n", "26. 'fbd2732ad777: Preparing'\n", "27. 'ba9de9d8475e: Preparing'\n", "28. '2cdc3d03b403: Waiting'\n", "29. '842c821f54eb: Waiting'\n", "30. '81c79e512da5: Waiting'\n", "31. '071617594623: Waiting'\n", "32. '2eee26189b5e: Waiting'\n", "33. '473763e23878: Waiting'\n", "34. '8ff58362bc10: Waiting'\n", "35. 'c5890df75ecc: Waiting'\n", "36. '1fb17ae4fc11: Waiting'\n", "37. '0aaa26768f46: Waiting'\n", "38. 'fd5276389b8a: Waiting'\n", "39. '56ac87b2a469: Waiting'\n", "40. '140ce133886c: Waiting'\n", "41. 'b20d335c2af7: Waiting'\n", "42. 'e4dc9a88747b: Waiting'\n", "43. '027d71a0bd0a: Waiting'\n", "44. '2bcd744f68d7: Waiting'\n", "45. '75e70aa52609: Waiting'\n", "46. 'dda151859818: Waiting'\n", "47. 'fbd2732ad777: Waiting'\n", "48. 'ba9de9d8475e: Waiting'\n", "49. 'ac80f37c61e8: Layer already exists'\n", "50. '0ce62bef372e: Layer already exists'\n", "51. 'd35b581063f9: Layer already exists'\n", "52. '74186bfe1b58: Layer already exists'\n", "53. '2cdc3d03b403: Layer already exists'\n", "54. '842c821f54eb: Layer already exists'\n", "55. '81c79e512da5: Layer already exists'\n", "56. '071617594623: Layer already exists'\n", "57. '2eee26189b5e: Layer already exists'\n", "58. '473763e23878: Layer already exists'\n", "59. '8ff58362bc10: Layer already exists'\n", "60. 'c5890df75ecc: Layer already exists'\n", "61. '1fb17ae4fc11: Layer already exists'\n", "62. '0aaa26768f46: Layer already exists'\n", "63. 'fd5276389b8a: Layer already exists'\n", "64. '56ac87b2a469: Layer already exists'\n", "65. 'e4dc9a88747b: Layer already exists'\n", "66. 'b20d335c2af7: Layer already exists'\n", "67. '140ce133886c: Layer already exists'\n", "68. '027d71a0bd0a: Layer already exists'\n", "69. '2bcd744f68d7: Layer already exists'\n", "70. 'dda151859818: Layer already exists'\n", "71. '75e70aa52609: Layer already exists'\n", "72. 'fbd2732ad777: Layer already exists'\n", "73. 'ba9de9d8475e: Layer already exists'\n", "74. '6dfd17fccb17: Pushed'\n", "75. 'latest: digest: sha256:a8c86b3024e96e75e2425832c323130a8e0843779e946921a3073bd4cbe3cb79 size: 5760'\n", "\n", "\n" ], "text/plain": [ " [1] \"The push refers to repository [gcr.io/r-on-gcp/caret_babyweight_estimator_training]\" \n", " [2] \"6dfd17fccb17: Preparing\" \n", " [3] \"74186bfe1b58: Preparing\" \n", " [4] \"0ce62bef372e: Preparing\" \n", " [5] \"ac80f37c61e8: Preparing\" \n", " [6] \"d35b581063f9: Preparing\" \n", " [7] \"2cdc3d03b403: Preparing\" \n", " [8] \"842c821f54eb: Preparing\" \n", " [9] \"81c79e512da5: Preparing\" \n", "[10] \"071617594623: Preparing\" \n", "[11] \"2eee26189b5e: Preparing\" \n", "[12] \"473763e23878: Preparing\" \n", "[13] \"8ff58362bc10: Preparing\" \n", "[14] \"c5890df75ecc: Preparing\" \n", "[15] \"1fb17ae4fc11: Preparing\" \n", "[16] \"0aaa26768f46: Preparing\" \n", "[17] \"fd5276389b8a: Preparing\" \n", "[18] \"56ac87b2a469: Preparing\" \n", "[19] \"140ce133886c: Preparing\" \n", "[20] \"b20d335c2af7: Preparing\" \n", "[21] \"e4dc9a88747b: Preparing\" \n", "[22] \"027d71a0bd0a: Preparing\" \n", "[23] \"2bcd744f68d7: Preparing\" \n", "[24] \"75e70aa52609: Preparing\" \n", "[25] \"dda151859818: Preparing\" \n", "[26] \"fbd2732ad777: Preparing\" \n", "[27] \"ba9de9d8475e: Preparing\" \n", "[28] \"2cdc3d03b403: Waiting\" \n", "[29] \"842c821f54eb: Waiting\" \n", "[30] \"81c79e512da5: Waiting\" \n", "[31] \"071617594623: Waiting\" \n", "[32] \"2eee26189b5e: Waiting\" \n", "[33] \"473763e23878: Waiting\" \n", "[34] \"8ff58362bc10: Waiting\" \n", "[35] \"c5890df75ecc: Waiting\" \n", "[36] \"1fb17ae4fc11: Waiting\" \n", "[37] \"0aaa26768f46: Waiting\" \n", "[38] \"fd5276389b8a: Waiting\" \n", "[39] \"56ac87b2a469: Waiting\" \n", "[40] \"140ce133886c: Waiting\" \n", "[41] \"b20d335c2af7: Waiting\" \n", "[42] \"e4dc9a88747b: Waiting\" \n", "[43] \"027d71a0bd0a: Waiting\" \n", "[44] \"2bcd744f68d7: Waiting\" \n", "[45] \"75e70aa52609: Waiting\" \n", "[46] \"dda151859818: Waiting\" \n", "[47] \"fbd2732ad777: Waiting\" \n", "[48] \"ba9de9d8475e: Waiting\" \n", "[49] \"ac80f37c61e8: Layer already exists\" \n", "[50] \"0ce62bef372e: Layer already exists\" \n", "[51] \"d35b581063f9: Layer already exists\" \n", "[52] \"74186bfe1b58: Layer already exists\" \n", "[53] \"2cdc3d03b403: Layer already exists\" \n", "[54] \"842c821f54eb: Layer already exists\" \n", "[55] \"81c79e512da5: Layer already exists\" \n", "[56] \"071617594623: Layer already exists\" \n", "[57] \"2eee26189b5e: Layer already exists\" \n", "[58] \"473763e23878: Layer already exists\" \n", "[59] \"8ff58362bc10: Layer already exists\" \n", "[60] \"c5890df75ecc: Layer already exists\" \n", "[61] \"1fb17ae4fc11: Layer already exists\" \n", "[62] \"0aaa26768f46: Layer already exists\" \n", "[63] \"fd5276389b8a: Layer already exists\" \n", "[64] \"56ac87b2a469: Layer already exists\" \n", "[65] \"e4dc9a88747b: Layer already exists\" \n", "[66] \"b20d335c2af7: Layer already exists\" \n", "[67] \"140ce133886c: Layer already exists\" \n", "[68] \"027d71a0bd0a: Layer already exists\" \n", "[69] \"2bcd744f68d7: Layer already exists\" \n", "[70] \"dda151859818: Layer already exists\" \n", "[71] \"75e70aa52609: Layer already exists\" \n", "[72] \"fbd2732ad777: Layer already exists\" \n", "[73] \"ba9de9d8475e: Layer already exists\" \n", "[74] \"6dfd17fccb17: Pushed\" \n", "[75] \"latest: digest: sha256:a8c86b3024e96e75e2425832c323130a8e0843779e946921a3073bd4cbe3cb79 size: 5760\"" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "'/home/jupyter/cloudml-samples/notebooks/R'" ], "text/latex": [ "'/home/jupyter/cloudml-samples/notebooks/R'" ], "text/markdown": [ "'/home/jupyter/cloudml-samples/notebooks/R'" ], "text/plain": [ "[1] \"/home/jupyter/cloudml-samples/notebooks/R\"" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "training_image_url <- paste0(\"gcr.io/\", PROJECT_ID, \"/\", model_name, \"_training\")\n", "print(training_image_url)\n", "\n", "setwd(\"src/caret/training\")\n", "getwd()\n", "\n", "print(\"Building the Docker container image...\")\n", "command <- paste0(\"docker build -f Dockerfile --tag \", training_image_url, \" ./\")\n", "print(command)\n", "system(command, intern = TRUE)\n", "\n", "print(\"Pushing the Docker container image...\")\n", "command <- paste0(\"gcloud docker -- push \", training_image_url)\n", "print(command)\n", "system(command, intern = TRUE)\n", "\n", "setwd(\"../../..\")\n", "getwd()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### C- Verifying uploaded images to Container Registry" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/html": [ "<ol class=list-inline>\n", "\t<li>'NAME'</li>\n", "\t<li>'gcr.io/r-on-gcp/caret_babyweight_estimator_training'</li>\n", "\t<li>'gcr.io/r-on-gcp/caret_base'</li>\n", "</ol>\n" ], "text/latex": [ "\\begin{enumerate*}\n", "\\item 'NAME'\n", "\\item 'gcr.io/r-on-gcp/caret\\_babyweight\\_estimator\\_training'\n", "\\item 'gcr.io/r-on-gcp/caret\\_base'\n", "\\end{enumerate*}\n" ], "text/markdown": [ "1. 'NAME'\n", "2. 'gcr.io/r-on-gcp/caret_babyweight_estimator_training'\n", "3. 'gcr.io/r-on-gcp/caret_base'\n", "\n", "\n" ], "text/plain": [ "[1] \"NAME\" \n", "[2] \"gcr.io/r-on-gcp/caret_babyweight_estimator_training\"\n", "[3] \"gcr.io/r-on-gcp/caret_base\" " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "command <- paste0(\"gcloud container images list --repository=gcr.io/\", PROJECT_ID)\n", "system(command, intern = TRUE)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3.2. Submit an AI Plaform Training job with the custom container. " ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1] \"gcloud beta ai-platform jobs submit training train_caret_contrainer_20190725_131432 --master-image-uri=gcr.io/r-on-gcp/caret_babyweight_estimator_training --scale-tier=BASIC --region=europe-west1\"\n" ] }, { "data": { "text/html": [ "<ol class=list-inline>\n", "\t<li>'jobId: train_caret_contrainer_20190725_131432'</li>\n", "\t<li>'state: QUEUED'</li>\n", "</ol>\n" ], "text/latex": [ "\\begin{enumerate*}\n", "\\item 'jobId: train\\_caret\\_contrainer\\_20190725\\_131432'\n", "\\item 'state: QUEUED'\n", "\\end{enumerate*}\n" ], "text/markdown": [ "1. 'jobId: train_caret_contrainer_20190725_131432'\n", "2. 'state: QUEUED'\n", "\n", "\n" ], "text/plain": [ "[1] \"jobId: train_caret_contrainer_20190725_131432\"\n", "[2] \"state: QUEUED\" " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "job_name <- paste0(\"train_caret_contrainer_\", format(Sys.time(), \"%Y%m%d_%H%M%S\"))\n", "\n", "command = paste0(\"gcloud beta ai-platform jobs submit training \", job_name, \n", " \" --master-image-uri=\", training_image_url,\n", " \" --scale-tier=BASIC\", \n", " \" --region=\", REGION\n", ")\n", "print(command)\n", "\n", "system(command, intern = TRUE)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Verify the trained model in GCS after the job finishes" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/html": [ "'gs://r-on-gcp/models/caret_babyweight_estimator/trained_model.rds'" ], "text/latex": [ "'gs://r-on-gcp/models/caret\\_babyweight\\_estimator/trained\\_model.rds'" ], "text/markdown": [ "'gs://r-on-gcp/models/caret_babyweight_estimator/trained_model.rds'" ], "text/plain": [ "[1] \"gs://r-on-gcp/models/caret_babyweight_estimator/trained_model.rds\"" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "model_name <- 'caret_babyweight_estimator'\n", "gcs_model_dir <- paste0(\"gs://\", BUCKET_NAME, \"/models/\", model_name)\n", "command <- paste0(\"gsutil ls \", gcs_model_dir)\n", "system(command, intern = TRUE)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4. Deploy the trained model to Cloud Run\n", "In order to serve the trained CARET model as a Web API, you need to wrap it with a prediction function, as serve this prediction function as a REST API. Then you containerize this Web API and deploy it in Cloud Run.\n", "\n", "The [src/caret/serving](src/caret/serving) directory includes the following code files:\n", "1. [model_prediction.R](src/caret/serving/model_prediction.R) - This script downloads the trained model from GCS and loads (only once). It includes **estimate** function, which accepts instances in JSON format, and return the of baby weight estimate for each instance.\n", "2. [model_api.R](src/caret/serving/model_prediction.R) - This is a [plumber](https://www.rplumber.io/) Web API that runs **model_prediction.R**.\n", "3. [Dockerfile](src/caret/serving/Dockerfile) - This is the definition of Docker container image that runs the **model_api.R**\n", "\n", "To deploy the prediction Web API to Cloud Run, you need to do the following steps:\n", "1. set your PROJECT_ID and BUCKET_NAME in serving/model_prediction.R, and PROJECT_ID in serving/Dockerfile so that the first line reads \"FROM gcr.io/[PROJECT_ID]/caret_base\"\n", "2. **Build** the Docker container image for the prediction API.\n", "3. **Push** the Docker container image to **Cloud Registry**.\n", "4. Enable the Cloud Run API if not enabled yet, click \"Enable\" at https://console.developers.google.com/apis/api/run.googleapis.com/overview .\n", "5. **Deploy** the Docker container to **Cloud Run**. \n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### (Optional) 4.0. Upload the trained model to GCS\n", "If you train your model using the model_trainer.R in AI Platform, it will upload the saved model to GCS. However, if you only train your model locally and have your saved model locally, you need to upload it to GCS." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "model_name <- 'caret_babyweight_estimator'\n", "gcs_model_dir = paste0(\"gs://\", BUCKET_NAME, \"/models/\", model_name, \"/\")\n", "command <- paste0(\"gsutil cp -r models/\", model_name ,\"/* \",gcs_model_dir)\n", "print(command)\n", "system(command, intern = TRUE)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.1. Build and Push prediction Docker container image" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1] \"gcr.io/r-on-gcp/caret_babyweight_estimator_serving\"\n" ] }, { "data": { "text/html": [ "'/home/jupyter/cloudml-samples/notebooks/R/src/caret/serving'" ], "text/latex": [ "'/home/jupyter/cloudml-samples/notebooks/R/src/caret/serving'" ], "text/markdown": [ "'/home/jupyter/cloudml-samples/notebooks/R/src/caret/serving'" ], "text/plain": [ "[1] \"/home/jupyter/cloudml-samples/notebooks/R/src/caret/serving\"" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "[1] \"Building the Docker container image...\"\n", "[1] \"docker build -f Dockerfile --tag gcr.io/r-on-gcp/caret_babyweight_estimator_serving ./\"\n" ] }, { "data": { "text/html": [ "<ol class=list-inline>\n", "\t<li><span style=white-space:pre-wrap>'Sending build context to Docker daemon 4.608kB\\r\\r'</span></li>\n", "\t<li>'Step 1/8 : FROM gcr.io/r-on-gcp/caret_base'</li>\n", "\t<li>' ---&gt; 23896e0a8a18'</li>\n", "\t<li>'Step 2/8 : RUN mkdir -p /root'</li>\n", "\t<li>' ---&gt; Using cache'</li>\n", "\t<li>' ---&gt; 8e3b3ba4b7bc'</li>\n", "\t<li>'Step 3/8 : COPY model_prediction.R /root'</li>\n", "\t<li>' ---&gt; f67f31f717e0'</li>\n", "\t<li>'Step 4/8 : COPY model_api.R /root'</li>\n", "\t<li>' ---&gt; a49939cb55d7'</li>\n", "\t<li>'Step 5/8 : WORKDIR /root'</li>\n", "\t<li>' ---&gt; Running in 1437d0489563'</li>\n", "\t<li>'Removing intermediate container 1437d0489563'</li>\n", "\t<li>' ---&gt; 6b86e65e04ed'</li>\n", "\t<li>'Step 6/8 : ENV PORT 8080'</li>\n", "\t<li>' ---&gt; Running in d4a9076afbea'</li>\n", "\t<li>'Removing intermediate container d4a9076afbea'</li>\n", "\t<li>' ---&gt; f4289e2b1454'</li>\n", "\t<li>'Step 7/8 : EXPOSE 8080'</li>\n", "\t<li>' ---&gt; Running in fbd3dba8910a'</li>\n", "\t<li>'Removing intermediate container fbd3dba8910a'</li>\n", "\t<li>' ---&gt; f8c3268385e9'</li>\n", "\t<li>'Step 8/8 : ENTRYPOINT [\"Rscript\", \"model_api.R\"]'</li>\n", "\t<li>' ---&gt; Running in f15f02eb590b'</li>\n", "\t<li>'Removing intermediate container f15f02eb590b'</li>\n", "\t<li>' ---&gt; af322a627dbd'</li>\n", "\t<li>'Successfully built af322a627dbd'</li>\n", "\t<li>'Successfully tagged gcr.io/r-on-gcp/caret_babyweight_estimator_serving:latest'</li>\n", "</ol>\n" ], "text/latex": [ "\\begin{enumerate*}\n", "\\item 'Sending build context to Docker daemon 4.608kB\\textbackslash{}r\\textbackslash{}r'\n", "\\item 'Step 1/8 : FROM gcr.io/r-on-gcp/caret\\_base'\n", "\\item ' ---> 23896e0a8a18'\n", "\\item 'Step 2/8 : RUN mkdir -p /root'\n", "\\item ' ---> Using cache'\n", "\\item ' ---> 8e3b3ba4b7bc'\n", "\\item 'Step 3/8 : COPY model\\_prediction.R /root'\n", "\\item ' ---> f67f31f717e0'\n", "\\item 'Step 4/8 : COPY model\\_api.R /root'\n", "\\item ' ---> a49939cb55d7'\n", "\\item 'Step 5/8 : WORKDIR /root'\n", "\\item ' ---> Running in 1437d0489563'\n", "\\item 'Removing intermediate container 1437d0489563'\n", "\\item ' ---> 6b86e65e04ed'\n", "\\item 'Step 6/8 : ENV PORT 8080'\n", "\\item ' ---> Running in d4a9076afbea'\n", "\\item 'Removing intermediate container d4a9076afbea'\n", "\\item ' ---> f4289e2b1454'\n", "\\item 'Step 7/8 : EXPOSE 8080'\n", "\\item ' ---> Running in fbd3dba8910a'\n", "\\item 'Removing intermediate container fbd3dba8910a'\n", "\\item ' ---> f8c3268385e9'\n", "\\item 'Step 8/8 : ENTRYPOINT {[}\"Rscript\", \"model\\_api.R\"{]}'\n", "\\item ' ---> Running in f15f02eb590b'\n", "\\item 'Removing intermediate container f15f02eb590b'\n", "\\item ' ---> af322a627dbd'\n", "\\item 'Successfully built af322a627dbd'\n", "\\item 'Successfully tagged gcr.io/r-on-gcp/caret\\_babyweight\\_estimator\\_serving:latest'\n", "\\end{enumerate*}\n" ], "text/markdown": [ "1. <span style=white-space:pre-wrap>'Sending build context to Docker daemon 4.608kB\\r\\r'</span>\n", "2. 'Step 1/8 : FROM gcr.io/r-on-gcp/caret_base'\n", "3. ' ---&gt; 23896e0a8a18'\n", "4. 'Step 2/8 : RUN mkdir -p /root'\n", "5. ' ---&gt; Using cache'\n", "6. ' ---&gt; 8e3b3ba4b7bc'\n", "7. 'Step 3/8 : COPY model_prediction.R /root'\n", "8. ' ---&gt; f67f31f717e0'\n", "9. 'Step 4/8 : COPY model_api.R /root'\n", "10. ' ---&gt; a49939cb55d7'\n", "11. 'Step 5/8 : WORKDIR /root'\n", "12. ' ---&gt; Running in 1437d0489563'\n", "13. 'Removing intermediate container 1437d0489563'\n", "14. ' ---&gt; 6b86e65e04ed'\n", "15. 'Step 6/8 : ENV PORT 8080'\n", "16. ' ---&gt; Running in d4a9076afbea'\n", "17. 'Removing intermediate container d4a9076afbea'\n", "18. ' ---&gt; f4289e2b1454'\n", "19. 'Step 7/8 : EXPOSE 8080'\n", "20. ' ---&gt; Running in fbd3dba8910a'\n", "21. 'Removing intermediate container fbd3dba8910a'\n", "22. ' ---&gt; f8c3268385e9'\n", "23. 'Step 8/8 : ENTRYPOINT [\"Rscript\", \"model_api.R\"]'\n", "24. ' ---&gt; Running in f15f02eb590b'\n", "25. 'Removing intermediate container f15f02eb590b'\n", "26. ' ---&gt; af322a627dbd'\n", "27. 'Successfully built af322a627dbd'\n", "28. 'Successfully tagged gcr.io/r-on-gcp/caret_babyweight_estimator_serving:latest'\n", "\n", "\n" ], "text/plain": [ " [1] \"Sending build context to Docker daemon 4.608kB\\r\\r\" \n", " [2] \"Step 1/8 : FROM gcr.io/r-on-gcp/caret_base\" \n", " [3] \" ---> 23896e0a8a18\" \n", " [4] \"Step 2/8 : RUN mkdir -p /root\" \n", " [5] \" ---> Using cache\" \n", " [6] \" ---> 8e3b3ba4b7bc\" \n", " [7] \"Step 3/8 : COPY model_prediction.R /root\" \n", " [8] \" ---> f67f31f717e0\" \n", " [9] \"Step 4/8 : COPY model_api.R /root\" \n", "[10] \" ---> a49939cb55d7\" \n", "[11] \"Step 5/8 : WORKDIR /root\" \n", "[12] \" ---> Running in 1437d0489563\" \n", "[13] \"Removing intermediate container 1437d0489563\" \n", "[14] \" ---> 6b86e65e04ed\" \n", "[15] \"Step 6/8 : ENV PORT 8080\" \n", "[16] \" ---> Running in d4a9076afbea\" \n", "[17] \"Removing intermediate container d4a9076afbea\" \n", "[18] \" ---> f4289e2b1454\" \n", "[19] \"Step 7/8 : EXPOSE 8080\" \n", "[20] \" ---> Running in fbd3dba8910a\" \n", "[21] \"Removing intermediate container fbd3dba8910a\" \n", "[22] \" ---> f8c3268385e9\" \n", "[23] \"Step 8/8 : ENTRYPOINT [\\\"Rscript\\\", \\\"model_api.R\\\"]\" \n", "[24] \" ---> Running in f15f02eb590b\" \n", "[25] \"Removing intermediate container f15f02eb590b\" \n", "[26] \" ---> af322a627dbd\" \n", "[27] \"Successfully built af322a627dbd\" \n", "[28] \"Successfully tagged gcr.io/r-on-gcp/caret_babyweight_estimator_serving:latest\"" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "[1] \"Pushing the Docker container image...\"\n", "[1] \"gcloud docker -- push gcr.io/r-on-gcp/caret_babyweight_estimator_serving\"\n" ] }, { "data": { "text/html": [ "<ol class=list-inline>\n", "\t<li>'The push refers to repository [gcr.io/r-on-gcp/caret_babyweight_estimator_serving]'</li>\n", "\t<li>'ff4c31850eb9: Preparing'</li>\n", "\t<li>'788543d979fc: Preparing'</li>\n", "\t<li>'74186bfe1b58: Preparing'</li>\n", "\t<li>'0ce62bef372e: Preparing'</li>\n", "\t<li>'ac80f37c61e8: Preparing'</li>\n", "\t<li>'d35b581063f9: Preparing'</li>\n", "\t<li>'2cdc3d03b403: Preparing'</li>\n", "\t<li>'842c821f54eb: Preparing'</li>\n", "\t<li>'81c79e512da5: Preparing'</li>\n", "\t<li>'071617594623: Preparing'</li>\n", "\t<li>'2eee26189b5e: Preparing'</li>\n", "\t<li>'473763e23878: Preparing'</li>\n", "\t<li>'8ff58362bc10: Preparing'</li>\n", "\t<li>'c5890df75ecc: Preparing'</li>\n", "\t<li>'1fb17ae4fc11: Preparing'</li>\n", "\t<li>'0aaa26768f46: Preparing'</li>\n", "\t<li>'fd5276389b8a: Preparing'</li>\n", "\t<li>'56ac87b2a469: Preparing'</li>\n", "\t<li>'140ce133886c: Preparing'</li>\n", "\t<li>'b20d335c2af7: Preparing'</li>\n", "\t<li>'e4dc9a88747b: Preparing'</li>\n", "\t<li>'027d71a0bd0a: Preparing'</li>\n", "\t<li>'2bcd744f68d7: Preparing'</li>\n", "\t<li>'75e70aa52609: Preparing'</li>\n", "\t<li>'dda151859818: Preparing'</li>\n", "\t<li>'fbd2732ad777: Preparing'</li>\n", "\t<li>'ba9de9d8475e: Preparing'</li>\n", "\t<li>'d35b581063f9: Waiting'</li>\n", "\t<li>'2cdc3d03b403: Waiting'</li>\n", "\t<li>'842c821f54eb: Waiting'</li>\n", "\t<li>'81c79e512da5: Waiting'</li>\n", "\t<li>'071617594623: Waiting'</li>\n", "\t<li>'2eee26189b5e: Waiting'</li>\n", "\t<li>'473763e23878: Waiting'</li>\n", "\t<li>'8ff58362bc10: Waiting'</li>\n", "\t<li>'c5890df75ecc: Waiting'</li>\n", "\t<li>'1fb17ae4fc11: Waiting'</li>\n", "\t<li>'0aaa26768f46: Waiting'</li>\n", "\t<li>'fd5276389b8a: Waiting'</li>\n", "\t<li>'56ac87b2a469: Waiting'</li>\n", "\t<li>'140ce133886c: Waiting'</li>\n", "\t<li>'b20d335c2af7: Waiting'</li>\n", "\t<li>'e4dc9a88747b: Waiting'</li>\n", "\t<li>'027d71a0bd0a: Waiting'</li>\n", "\t<li>'2bcd744f68d7: Waiting'</li>\n", "\t<li>'75e70aa52609: Waiting'</li>\n", "\t<li>'dda151859818: Waiting'</li>\n", "\t<li>'fbd2732ad777: Waiting'</li>\n", "\t<li>'ba9de9d8475e: Waiting'</li>\n", "\t<li>'0ce62bef372e: Layer already exists'</li>\n", "\t<li>'ac80f37c61e8: Layer already exists'</li>\n", "\t<li>'74186bfe1b58: Layer already exists'</li>\n", "\t<li>'d35b581063f9: Layer already exists'</li>\n", "\t<li>'2cdc3d03b403: Layer already exists'</li>\n", "\t<li>'842c821f54eb: Layer already exists'</li>\n", "\t<li>'81c79e512da5: Layer already exists'</li>\n", "\t<li>'071617594623: Layer already exists'</li>\n", "\t<li>'2eee26189b5e: Layer already exists'</li>\n", "\t<li>'473763e23878: Layer already exists'</li>\n", "\t<li>'8ff58362bc10: Layer already exists'</li>\n", "\t<li>'c5890df75ecc: Layer already exists'</li>\n", "\t<li>'1fb17ae4fc11: Layer already exists'</li>\n", "\t<li>'fd5276389b8a: Layer already exists'</li>\n", "\t<li>'0aaa26768f46: Layer already exists'</li>\n", "\t<li>'56ac87b2a469: Layer already exists'</li>\n", "\t<li>'140ce133886c: Layer already exists'</li>\n", "\t<li>'b20d335c2af7: Layer already exists'</li>\n", "\t<li>'e4dc9a88747b: Layer already exists'</li>\n", "\t<li>'027d71a0bd0a: Layer already exists'</li>\n", "\t<li>'2bcd744f68d7: Layer already exists'</li>\n", "\t<li>'75e70aa52609: Layer already exists'</li>\n", "\t<li>'dda151859818: Layer already exists'</li>\n", "\t<li>'fbd2732ad777: Layer already exists'</li>\n", "\t<li>'ba9de9d8475e: Layer already exists'</li>\n", "\t<li>'ff4c31850eb9: Pushed'</li>\n", "\t<li>'788543d979fc: Pushed'</li>\n", "\t<li>'latest: digest: sha256:745024f961a369f01d8b97f4d8b423cae7c884f7eaf7e3c8f840212140587830 size: 5966'</li>\n", "</ol>\n" ], "text/latex": [ "\\begin{enumerate*}\n", "\\item 'The push refers to repository {[}gcr.io/r-on-gcp/caret\\_babyweight\\_estimator\\_serving{]}'\n", "\\item 'ff4c31850eb9: Preparing'\n", "\\item '788543d979fc: Preparing'\n", "\\item '74186bfe1b58: Preparing'\n", "\\item '0ce62bef372e: Preparing'\n", "\\item 'ac80f37c61e8: Preparing'\n", "\\item 'd35b581063f9: Preparing'\n", "\\item '2cdc3d03b403: Preparing'\n", "\\item '842c821f54eb: Preparing'\n", "\\item '81c79e512da5: Preparing'\n", "\\item '071617594623: Preparing'\n", "\\item '2eee26189b5e: Preparing'\n", "\\item '473763e23878: Preparing'\n", "\\item '8ff58362bc10: Preparing'\n", "\\item 'c5890df75ecc: Preparing'\n", "\\item '1fb17ae4fc11: Preparing'\n", "\\item '0aaa26768f46: Preparing'\n", "\\item 'fd5276389b8a: Preparing'\n", "\\item '56ac87b2a469: Preparing'\n", "\\item '140ce133886c: Preparing'\n", "\\item 'b20d335c2af7: Preparing'\n", "\\item 'e4dc9a88747b: Preparing'\n", "\\item '027d71a0bd0a: Preparing'\n", "\\item '2bcd744f68d7: Preparing'\n", "\\item '75e70aa52609: Preparing'\n", "\\item 'dda151859818: Preparing'\n", "\\item 'fbd2732ad777: Preparing'\n", "\\item 'ba9de9d8475e: Preparing'\n", "\\item 'd35b581063f9: Waiting'\n", "\\item '2cdc3d03b403: Waiting'\n", "\\item '842c821f54eb: Waiting'\n", "\\item '81c79e512da5: Waiting'\n", "\\item '071617594623: Waiting'\n", "\\item '2eee26189b5e: Waiting'\n", "\\item '473763e23878: Waiting'\n", "\\item '8ff58362bc10: Waiting'\n", "\\item 'c5890df75ecc: Waiting'\n", "\\item '1fb17ae4fc11: Waiting'\n", "\\item '0aaa26768f46: Waiting'\n", "\\item 'fd5276389b8a: Waiting'\n", "\\item '56ac87b2a469: Waiting'\n", "\\item '140ce133886c: Waiting'\n", "\\item 'b20d335c2af7: Waiting'\n", "\\item 'e4dc9a88747b: Waiting'\n", "\\item '027d71a0bd0a: Waiting'\n", "\\item '2bcd744f68d7: Waiting'\n", "\\item '75e70aa52609: Waiting'\n", "\\item 'dda151859818: Waiting'\n", "\\item 'fbd2732ad777: Waiting'\n", "\\item 'ba9de9d8475e: Waiting'\n", "\\item '0ce62bef372e: Layer already exists'\n", "\\item 'ac80f37c61e8: Layer already exists'\n", "\\item '74186bfe1b58: Layer already exists'\n", "\\item 'd35b581063f9: Layer already exists'\n", "\\item '2cdc3d03b403: Layer already exists'\n", "\\item '842c821f54eb: Layer already exists'\n", "\\item '81c79e512da5: Layer already exists'\n", "\\item '071617594623: Layer already exists'\n", "\\item '2eee26189b5e: Layer already exists'\n", "\\item '473763e23878: Layer already exists'\n", "\\item '8ff58362bc10: Layer already exists'\n", "\\item 'c5890df75ecc: Layer already exists'\n", "\\item '1fb17ae4fc11: Layer already exists'\n", "\\item 'fd5276389b8a: Layer already exists'\n", "\\item '0aaa26768f46: Layer already exists'\n", "\\item '56ac87b2a469: Layer already exists'\n", "\\item '140ce133886c: Layer already exists'\n", "\\item 'b20d335c2af7: Layer already exists'\n", "\\item 'e4dc9a88747b: Layer already exists'\n", "\\item '027d71a0bd0a: Layer already exists'\n", "\\item '2bcd744f68d7: Layer already exists'\n", "\\item '75e70aa52609: Layer already exists'\n", "\\item 'dda151859818: Layer already exists'\n", "\\item 'fbd2732ad777: Layer already exists'\n", "\\item 'ba9de9d8475e: Layer already exists'\n", "\\item 'ff4c31850eb9: Pushed'\n", "\\item '788543d979fc: Pushed'\n", "\\item 'latest: digest: sha256:745024f961a369f01d8b97f4d8b423cae7c884f7eaf7e3c8f840212140587830 size: 5966'\n", "\\end{enumerate*}\n" ], "text/markdown": [ "1. 'The push refers to repository [gcr.io/r-on-gcp/caret_babyweight_estimator_serving]'\n", "2. 'ff4c31850eb9: Preparing'\n", "3. '788543d979fc: Preparing'\n", "4. '74186bfe1b58: Preparing'\n", "5. '0ce62bef372e: Preparing'\n", "6. 'ac80f37c61e8: Preparing'\n", "7. 'd35b581063f9: Preparing'\n", "8. '2cdc3d03b403: Preparing'\n", "9. '842c821f54eb: Preparing'\n", "10. '81c79e512da5: Preparing'\n", "11. '071617594623: Preparing'\n", "12. '2eee26189b5e: Preparing'\n", "13. '473763e23878: Preparing'\n", "14. '8ff58362bc10: Preparing'\n", "15. 'c5890df75ecc: Preparing'\n", "16. '1fb17ae4fc11: Preparing'\n", "17. '0aaa26768f46: Preparing'\n", "18. 'fd5276389b8a: Preparing'\n", "19. '56ac87b2a469: Preparing'\n", "20. '140ce133886c: Preparing'\n", "21. 'b20d335c2af7: Preparing'\n", "22. 'e4dc9a88747b: Preparing'\n", "23. '027d71a0bd0a: Preparing'\n", "24. '2bcd744f68d7: Preparing'\n", "25. '75e70aa52609: Preparing'\n", "26. 'dda151859818: Preparing'\n", "27. 'fbd2732ad777: Preparing'\n", "28. 'ba9de9d8475e: Preparing'\n", "29. 'd35b581063f9: Waiting'\n", "30. '2cdc3d03b403: Waiting'\n", "31. '842c821f54eb: Waiting'\n", "32. '81c79e512da5: Waiting'\n", "33. '071617594623: Waiting'\n", "34. '2eee26189b5e: Waiting'\n", "35. '473763e23878: Waiting'\n", "36. '8ff58362bc10: Waiting'\n", "37. 'c5890df75ecc: Waiting'\n", "38. '1fb17ae4fc11: Waiting'\n", "39. '0aaa26768f46: Waiting'\n", "40. 'fd5276389b8a: Waiting'\n", "41. '56ac87b2a469: Waiting'\n", "42. '140ce133886c: Waiting'\n", "43. 'b20d335c2af7: Waiting'\n", "44. 'e4dc9a88747b: Waiting'\n", "45. '027d71a0bd0a: Waiting'\n", "46. '2bcd744f68d7: Waiting'\n", "47. '75e70aa52609: Waiting'\n", "48. 'dda151859818: Waiting'\n", "49. 'fbd2732ad777: Waiting'\n", "50. 'ba9de9d8475e: Waiting'\n", "51. '0ce62bef372e: Layer already exists'\n", "52. 'ac80f37c61e8: Layer already exists'\n", "53. '74186bfe1b58: Layer already exists'\n", "54. 'd35b581063f9: Layer already exists'\n", "55. '2cdc3d03b403: Layer already exists'\n", "56. '842c821f54eb: Layer already exists'\n", "57. '81c79e512da5: Layer already exists'\n", "58. '071617594623: Layer already exists'\n", "59. '2eee26189b5e: Layer already exists'\n", "60. '473763e23878: Layer already exists'\n", "61. '8ff58362bc10: Layer already exists'\n", "62. 'c5890df75ecc: Layer already exists'\n", "63. '1fb17ae4fc11: Layer already exists'\n", "64. 'fd5276389b8a: Layer already exists'\n", "65. '0aaa26768f46: Layer already exists'\n", "66. '56ac87b2a469: Layer already exists'\n", "67. '140ce133886c: Layer already exists'\n", "68. 'b20d335c2af7: Layer already exists'\n", "69. 'e4dc9a88747b: Layer already exists'\n", "70. '027d71a0bd0a: Layer already exists'\n", "71. '2bcd744f68d7: Layer already exists'\n", "72. '75e70aa52609: Layer already exists'\n", "73. 'dda151859818: Layer already exists'\n", "74. 'fbd2732ad777: Layer already exists'\n", "75. 'ba9de9d8475e: Layer already exists'\n", "76. 'ff4c31850eb9: Pushed'\n", "77. '788543d979fc: Pushed'\n", "78. 'latest: digest: sha256:745024f961a369f01d8b97f4d8b423cae7c884f7eaf7e3c8f840212140587830 size: 5966'\n", "\n", "\n" ], "text/plain": [ " [1] \"The push refers to repository [gcr.io/r-on-gcp/caret_babyweight_estimator_serving]\" \n", " [2] \"ff4c31850eb9: Preparing\" \n", " [3] \"788543d979fc: Preparing\" \n", " [4] \"74186bfe1b58: Preparing\" \n", " [5] \"0ce62bef372e: Preparing\" \n", " [6] \"ac80f37c61e8: Preparing\" \n", " [7] \"d35b581063f9: Preparing\" \n", " [8] \"2cdc3d03b403: Preparing\" \n", " [9] \"842c821f54eb: Preparing\" \n", "[10] \"81c79e512da5: Preparing\" \n", "[11] \"071617594623: Preparing\" \n", "[12] \"2eee26189b5e: Preparing\" \n", "[13] \"473763e23878: Preparing\" \n", "[14] \"8ff58362bc10: Preparing\" \n", "[15] \"c5890df75ecc: Preparing\" \n", "[16] \"1fb17ae4fc11: Preparing\" \n", "[17] \"0aaa26768f46: Preparing\" \n", "[18] \"fd5276389b8a: Preparing\" \n", "[19] \"56ac87b2a469: Preparing\" \n", "[20] \"140ce133886c: Preparing\" \n", "[21] \"b20d335c2af7: Preparing\" \n", "[22] \"e4dc9a88747b: Preparing\" \n", "[23] \"027d71a0bd0a: Preparing\" \n", "[24] \"2bcd744f68d7: Preparing\" \n", "[25] \"75e70aa52609: Preparing\" \n", "[26] \"dda151859818: Preparing\" \n", "[27] \"fbd2732ad777: Preparing\" \n", "[28] \"ba9de9d8475e: Preparing\" \n", "[29] \"d35b581063f9: Waiting\" \n", "[30] \"2cdc3d03b403: Waiting\" \n", "[31] \"842c821f54eb: Waiting\" \n", "[32] \"81c79e512da5: Waiting\" \n", "[33] \"071617594623: Waiting\" \n", "[34] \"2eee26189b5e: Waiting\" \n", "[35] \"473763e23878: Waiting\" \n", "[36] \"8ff58362bc10: Waiting\" \n", "[37] \"c5890df75ecc: Waiting\" \n", "[38] \"1fb17ae4fc11: Waiting\" \n", "[39] \"0aaa26768f46: Waiting\" \n", "[40] \"fd5276389b8a: Waiting\" \n", "[41] \"56ac87b2a469: Waiting\" \n", "[42] \"140ce133886c: Waiting\" \n", "[43] \"b20d335c2af7: Waiting\" \n", "[44] \"e4dc9a88747b: Waiting\" \n", "[45] \"027d71a0bd0a: Waiting\" \n", "[46] \"2bcd744f68d7: Waiting\" \n", "[47] \"75e70aa52609: Waiting\" \n", "[48] \"dda151859818: Waiting\" \n", "[49] \"fbd2732ad777: Waiting\" \n", "[50] \"ba9de9d8475e: Waiting\" \n", "[51] \"0ce62bef372e: Layer already exists\" \n", "[52] \"ac80f37c61e8: Layer already exists\" \n", "[53] \"74186bfe1b58: Layer already exists\" \n", "[54] \"d35b581063f9: Layer already exists\" \n", "[55] \"2cdc3d03b403: Layer already exists\" \n", "[56] \"842c821f54eb: Layer already exists\" \n", "[57] \"81c79e512da5: Layer already exists\" \n", "[58] \"071617594623: Layer already exists\" \n", "[59] \"2eee26189b5e: Layer already exists\" \n", "[60] \"473763e23878: Layer already exists\" \n", "[61] \"8ff58362bc10: Layer already exists\" \n", "[62] \"c5890df75ecc: Layer already exists\" \n", "[63] \"1fb17ae4fc11: Layer already exists\" \n", "[64] \"fd5276389b8a: Layer already exists\" \n", "[65] \"0aaa26768f46: Layer already exists\" \n", "[66] \"56ac87b2a469: Layer already exists\" \n", "[67] \"140ce133886c: Layer already exists\" \n", "[68] \"b20d335c2af7: Layer already exists\" \n", "[69] \"e4dc9a88747b: Layer already exists\" \n", "[70] \"027d71a0bd0a: Layer already exists\" \n", "[71] \"2bcd744f68d7: Layer already exists\" \n", "[72] \"75e70aa52609: Layer already exists\" \n", "[73] \"dda151859818: Layer already exists\" \n", "[74] \"fbd2732ad777: Layer already exists\" \n", "[75] \"ba9de9d8475e: Layer already exists\" \n", "[76] \"ff4c31850eb9: Pushed\" \n", "[77] \"788543d979fc: Pushed\" \n", "[78] \"latest: digest: sha256:745024f961a369f01d8b97f4d8b423cae7c884f7eaf7e3c8f840212140587830 size: 5966\"" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "'/home/jupyter/cloudml-samples/notebooks/R'" ], "text/latex": [ "'/home/jupyter/cloudml-samples/notebooks/R'" ], "text/markdown": [ "'/home/jupyter/cloudml-samples/notebooks/R'" ], "text/plain": [ "[1] \"/home/jupyter/cloudml-samples/notebooks/R\"" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "serving_image_url <- paste0(\"gcr.io/\", PROJECT_ID, \"/\", model_name, \"_serving\")\n", "print(serving_image_url)\n", "\n", "setwd(\"src/caret/serving\")\n", "getwd()\n", "\n", "print(\"Building the Docker container image...\")\n", "command <- paste0(\"docker build -f Dockerfile --tag \", serving_image_url, \" ./\")\n", "print(command)\n", "system(command, intern = TRUE)\n", "\n", "print(\"Pushing the Docker container image...\")\n", "command <- paste0(\"gcloud docker -- push \", serving_image_url)\n", "print(command)\n", "system(command, intern = TRUE)\n", "\n", "setwd(\"../../..\")\n", "getwd()" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/html": [ "<ol class=list-inline>\n", "\t<li>'NAME'</li>\n", "\t<li>'gcr.io/r-on-gcp/caret_babyweight_estimator_serving'</li>\n", "\t<li>'gcr.io/r-on-gcp/caret_babyweight_estimator_training'</li>\n", "\t<li>'gcr.io/r-on-gcp/caret_base'</li>\n", "</ol>\n" ], "text/latex": [ "\\begin{enumerate*}\n", "\\item 'NAME'\n", "\\item 'gcr.io/r-on-gcp/caret\\_babyweight\\_estimator\\_serving'\n", "\\item 'gcr.io/r-on-gcp/caret\\_babyweight\\_estimator\\_training'\n", "\\item 'gcr.io/r-on-gcp/caret\\_base'\n", "\\end{enumerate*}\n" ], "text/markdown": [ "1. 'NAME'\n", "2. 'gcr.io/r-on-gcp/caret_babyweight_estimator_serving'\n", "3. 'gcr.io/r-on-gcp/caret_babyweight_estimator_training'\n", "4. 'gcr.io/r-on-gcp/caret_base'\n", "\n", "\n" ], "text/plain": [ "[1] \"NAME\" \n", "[2] \"gcr.io/r-on-gcp/caret_babyweight_estimator_serving\" \n", "[3] \"gcr.io/r-on-gcp/caret_babyweight_estimator_training\"\n", "[4] \"gcr.io/r-on-gcp/caret_base\" " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "command <- paste0(\"gcloud container images list --repository=gcr.io/\", PROJECT_ID)\n", "system(command, intern = TRUE)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.2. Deploy prediction container to Cloud Run" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "service_name <- \"caret-babyweight-estimator\"\n", "command <- paste(\n", " \"gcloud beta run deploy\", service_name,\n", " \"--image\", serving_image_url,\n", " \"--platform managed\",\n", " \"--allow-unauthenticated\",\n", " \"--region\", REGION\n", ")\n", "\n", "print(command)\n", "system(command, intern = TRUE)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 5. Invoke the Model API for Predictions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When the **caret-babyweight-estimator** service is deployed to Cloud Run:\n", "1. Go to Cloud Run in the [Cloud Console](https://console.cloud.google.com/run/).\n", "2. Select the **caret-babyweight-estimator** service.\n", "3. Copy the service URL, and use it to update the **url** variable in the following cell." ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "# Update to the deployed service URL\n", "url <- \"https://caret-babyweight-estimator-lbcii4x34q-uc.a.run.app/\"\n", "endpoint <- \"estimate\"" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [], "source": [ "instances_json <- '\n", "[\n", " {\n", " \"is_male\": \"TRUE\",\n", " \"mother_age\": 28,\n", " \"mother_race\": 8,\n", " \"plurality\": 1,\n", " \"gestation_weeks\": 28,\n", " \"mother_married\": \"TRUE\",\n", " \"cigarette_use\": \"FALSE\",\n", " \"alcohol_use\": \"FALSE\"\n", " },\n", " {\n", " \"is_male\": \"FALSE\",\n", " \"mother_age\": 38,\n", " \"mother_race\": 18,\n", " \"plurality\": 1,\n", " \"gestation_weeks\": 28,\n", " \"mother_married\": \"TRUE\",\n", " \"cigarette_use\": \"TRUE\",\n", " \"alcohol_use\": \"TRUE\"\n", " }\n", "]\n", "'" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "\n", "Attaching package: ‘httr’\n", "\n", "The following object is masked from ‘package:caret’:\n", "\n", " progress\n", "\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[1] \"Estimated weight(s): 4.5\" \"Estimated weight(s): 2.57\"\n" ] } ], "source": [ "library(\"httr\")\n", "full_url <- paste0(url, endpoint)\n", "response <- POST(full_url, body = instances_json)\n", "estimates <- content(response)\n", "print(paste(\"Estimated weight(s):\", estimate))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# License" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Authors: Daniel Sparing & Khalid Salama\n", "\n", "---\n", "**Disclaimer**: This is not an official Google product. The sample code provided for an educational purpose.\n", "\n", "---\n", "\n", "Copyright 2019 Google LLC\n", "\n", "Licensed under the Apache License, Version 2.0 (the \"License\");\n", "you may not use this file except in compliance with the License.\n", "You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.\n", "\n", "Unless required by applicable law or agreed to in writing, software\n", "distributed under the License is distributed on an \"AS IS\" BASIS,\n", "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", "See the License for the specific language governing permissions and\n", "limitations under the License." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "R", "language": "R", "name": "ir" }, "language_info": { "codemirror_mode": "r", "file_extension": ".r", "mimetype": "text/x-r-source", "name": "R", "pygments_lexer": "r", "version": "3.5.1" } }, "nbformat": 4, "nbformat_minor": 2 }