"
+ ],
+ "text/plain": [
+ " longitude latitude housing_median_age total_rooms total_bedrooms \\\n",
+ "count 17000.0 17000.0 17000.0 17000.0 17000.0 \n",
+ "mean -119.6 35.6 28.6 2643.7 539.4 \n",
+ "std 2.0 2.1 12.6 2179.9 421.5 \n",
+ "min -124.3 32.5 1.0 2.0 1.0 \n",
+ "25% -121.8 33.9 18.0 1462.0 297.0 \n",
+ "50% -118.5 34.2 29.0 2127.0 434.0 \n",
+ "75% -118.0 37.7 37.0 3151.2 648.2 \n",
+ "max -114.3 42.0 52.0 37937.0 6445.0 \n",
+ "\n",
+ " population households median_income median_house_value \n",
+ "count 17000.0 17000.0 17000.0 17000.0 \n",
+ "mean 1429.6 501.2 3.9 207.3 \n",
+ "std 1147.9 384.5 1.9 116.0 \n",
+ "min 3.0 1.0 0.5 15.0 \n",
+ "25% 790.0 282.0 2.6 119.4 \n",
+ "50% 1167.0 409.0 3.5 180.4 \n",
+ "75% 1721.0 605.2 4.8 265.0 \n",
+ "max 35682.0 6082.0 15.0 500.0 "
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 5
+ }
+ ]
+ },
+ {
+ "metadata": {
+ "id": "Lr6wYl2bt2Ep",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## Build the First Model\n",
+ "\n",
+ "In this exercise, we'll try to predict `median_house_value`, which will be our label (sometimes also called a target). We'll use `total_rooms` as our input feature.\n",
+ "\n",
+ "**NOTE:** Our data is at the city block level, so this feature represents the total number of rooms in that block.\n",
+ "\n",
+ "To train our model, we'll use the [LinearRegressor](https://www.tensorflow.org/api_docs/python/tf/estimator/LinearRegressor) interface provided by the TensorFlow [Estimator](https://www.tensorflow.org/get_started/estimator) API. This API takes care of a lot of the low-level model plumbing, and exposes convenient methods for performing model training, evaluation, and inference."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "0cpcsieFhsNI",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "### Step 1: Define Features and Configure Feature Columns"
+ ]
+ },
+ {
+ "metadata": {
+ "id": "EL8-9d4ZJNR7",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "In order to import our training data into TensorFlow, we need to specify what type of data each feature contains. There are two main types of data we'll use in this and future exercises:\n",
+ "\n",
+ "* **Categorical Data**: Data that is textual. In this exercise, our housing data set does not contain any categorical features, but examples you might see would be the home style, the words in a real-estate ad.\n",
+ "\n",
+ "* **Numerical Data**: Data that is a number (integer or float) and that you want to treat as a number. As we will discuss more later sometimes you might want to treat numerical data (e.g., a postal code) as if it were categorical.\n",
+ "\n",
+ "In TensorFlow, we indicate a feature's data type using a construct called a **feature column**. Feature columns store only a description of the feature data; they do not contain the feature data itself.\n",
+ "\n",
+ "To start, we're going to use just one numeric input feature, `total_rooms`. The following code pulls the `total_rooms` data from our `california_housing_dataframe` and defines the feature column using `numeric_column`, which specifies its data is numeric:"
+ ]
+ },
+ {
+ "metadata": {
+ "id": "rhEbFCZ86cDZ",
+ "colab_type": "code",
+ "outputId": "254ca935-1bec-4451-ef0d-9039c2628847",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ }
+ },
+ "cell_type": "code",
+ "source": [
+ "# Define the input feature: total_rooms.\n",
+ "my_feature = california_housing_dataframe[[\"total_rooms\"]]\n",
+ "\n",
+ "# Configure a numeric feature column for total_rooms.\n",
+ "feature_columns = [tf.feature_column.numeric_column(\"total_rooms\")]\n",
+ "\n",
+ "{key:np.array(value) for key,value in dict(my_feature).items()}\n"
+ ],
+ "execution_count": 0,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "{'total_rooms': array([3135., 3713., 1066., ..., 8489., 1734., 5151.])}"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 26
+ }
+ ]
+ },
+ {
+ "metadata": {
+ "id": "K_3S8teX7Rd2",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "**NOTE:** The shape of our `total_rooms` data is a one-dimensional array (a list of the total number of rooms for each block). This is the default shape for `numeric_column`, so we don't have to pass it as an argument."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "UMl3qrU5MGV6",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "### Step 2: Define the Target"
+ ]
+ },
+ {
+ "metadata": {
+ "id": "cw4nrfcB7kyk",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "Next, we'll define our target, which is `median_house_value`. Again, we can pull it from our `california_housing_dataframe`:"
+ ]
+ },
+ {
+ "metadata": {
+ "id": "l1NvvNkH8Kbt",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "# Define the label.\n",
+ "targets = california_housing_dataframe[\"median_house_value\"]\n"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "4M-rTFHL2UkA",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "### Step 3: Configure the LinearRegressor"
+ ]
+ },
+ {
+ "metadata": {
+ "id": "fUfGQUNp7jdL",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "Next, we'll configure a linear regression model using LinearRegressor. We'll train this model using the `GradientDescentOptimizer`, which implements Mini-Batch Stochastic Gradient Descent (SGD). The `learning_rate` argument controls the size of the gradient step.\n",
+ "\n",
+ "**NOTE:** To be safe, we also apply [gradient clipping](https://developers.google.com/machine-learning/glossary/#gradient_clipping) to our optimizer via `clip_gradients_by_norm`. Gradient clipping ensures the magnitude of the gradients do not become too large during training, which can cause gradient descent to fail. "
+ ]
+ },
+ {
+ "metadata": {
+ "id": "ubhtW-NGU802",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "# Use gradient descent as the optimizer for training the model.\n",
+ "my_optimizer=tf.train.GradientDescentOptimizer(learning_rate=0.0000001)\n",
+ "my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0)\n",
+ "\n",
+ "# Configure the linear regression model with our feature columns and optimizer.\n",
+ "# Set a learning rate of 0.0000001 for Gradient Descent.\n",
+ "linear_regressor = tf.estimator.LinearRegressor(\n",
+ " feature_columns=feature_columns,\n",
+ " optimizer=my_optimizer\n",
+ ")"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "-0IztwdK2f3F",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "### Step 4: Define the Input Function"
+ ]
+ },
+ {
+ "metadata": {
+ "id": "S5M5j6xSCHxx",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "To import our California housing data into our `LinearRegressor`, we need to define an input function, which instructs TensorFlow how to preprocess\n",
+ "the data, as well as how to batch, shuffle, and repeat it during model training.\n",
+ "\n",
+ "First, we'll convert our *pandas* feature data into a dict of NumPy arrays. We can then use the TensorFlow [Dataset API](https://www.tensorflow.org/programmers_guide/datasets) to construct a dataset object from our data, and then break\n",
+ "our data into batches of `batch_size`, to be repeated for the specified number of epochs (num_epochs). \n",
+ "\n",
+ "**NOTE:** When the default value of `num_epochs=None` is passed to `repeat()`, the input data will be repeated indefinitely.\n",
+ "\n",
+ "Next, if `shuffle` is set to `True`, we'll shuffle the data so that it's passed to the model randomly during training. The `buffer_size` argument specifies\n",
+ "the size of the dataset from which `shuffle` will randomly sample.\n",
+ "\n",
+ "Finally, our input function constructs an iterator for the dataset and returns the next batch of data to the LinearRegressor."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "RKZ9zNcHJtwc",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def my_input_fn(features, targets, batch_size=1, shuffle=True, num_epochs=None):\n",
+ " \"\"\"Trains a linear regression model of one feature.\n",
+ " \n",
+ " Args:\n",
+ " features: pandas DataFrame of features\n",
+ " targets: pandas DataFrame of targets\n",
+ " batch_size: Size of batches to be passed to the model\n",
+ " shuffle: True or False. Whether to shuffle the data.\n",
+ " num_epochs: Number of epochs for which data should be repeated. None = repeat indefinitely\n",
+ " Returns:\n",
+ " Tuple of (features, labels) for next data batch\n",
+ " \"\"\"\n",
+ " \n",
+ " # Convert pandas data into a dict of np arrays.\n",
+ " features = {key:np.array(value) for key,value in dict(features).items()} \n",
+ " \n",
+ " # Construct a dataset, and configure batching/repeating.\n",
+ " ds = Dataset.from_tensor_slices((features,targets)) # warning: 2GB limit\n",
+ " ds = ds.batch(batch_size).repeat(num_epochs)\n",
+ " \n",
+ " # Shuffle the data, if specified.\n",
+ " if shuffle:\n",
+ " ds = ds.shuffle(buffer_size=10000)\n",
+ " \n",
+ " # Return the next batch of data.\n",
+ " features, labels = ds.make_one_shot_iterator().get_next()\n",
+ " return features, labels"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "wwa6UeA1V5F_",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "**NOTE:** We'll continue to use this same input function in later exercises. For more\n",
+ "detailed documentation of input functions and the `Dataset` API, see the [TensorFlow Programmer's Guide](https://www.tensorflow.org/programmers_guide/datasets)."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "4YS50CQb2ooO",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "### Step 5: Train the Model"
+ ]
+ },
+ {
+ "metadata": {
+ "id": "yP92XkzhU803",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "We can now call `train()` on our `linear_regressor` to train the model. We'll wrap `my_input_fn` in a `lambda`\n",
+ "so we can pass in `my_feature` and `target` as arguments (see this [TensorFlow input function tutorial](https://www.tensorflow.org/get_started/input_fn#passing_input_fn_data_to_your_model) for more details), and to start, we'll\n",
+ "train for 100 steps."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "5M-Kt6w8U803",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "_ = linear_regressor.train(\n",
+ " input_fn = lambda:my_input_fn(my_feature, targets),\n",
+ " steps=100\n",
+ ")"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "7Nwxqxlx2sOv",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "### Step 6: Evaluate the Model"
+ ]
+ },
+ {
+ "metadata": {
+ "id": "KoDaF2dlJQG5",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "Let's make predictions on that training data, to see how well our model fit it during training.\n",
+ "\n",
+ "**NOTE:** Training error measures how well your model fits the training data, but it **_does not_** measure how well your model **_generalizes to new data_**. In later exercises, you'll explore how to split your data to evaluate your model's ability to generalize.\n"
+ ]
+ },
+ {
+ "metadata": {
+ "id": "pDIxp6vcU809",
+ "colab_type": "code",
+ "outputId": "5ea6fda6-8ca1-4e09-d8ca-0ad37d2e90bb",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 90
+ }
+ },
+ "cell_type": "code",
+ "source": [
+ "# Create an input function for predictions.\n",
+ "# Note: Since we're making just one prediction for each example, we don't \n",
+ "# need to repeat or shuffle the data here.\n",
+ "prediction_input_fn =lambda: my_input_fn(my_feature, targets, num_epochs=1, shuffle=False)\n",
+ "\n",
+ "# Call predict() on the linear_regressor to make predictions.\n",
+ "predictions = linear_regressor.predict(input_fn=prediction_input_fn)\n",
+ "\n",
+ "# Format predictions as a NumPy array, so we can calculate error metrics.\n",
+ "predictions = np.array([item['predictions'][0] for item in predictions])\n",
+ "\n",
+ "# Print Mean Squared Error and Root Mean Squared Error.\n",
+ "mean_squared_error = metrics.mean_squared_error(predictions, targets)\n",
+ "root_mean_squared_error = math.sqrt(mean_squared_error)\n",
+ "print(\"Mean Squared Error (on training data): %0.3f\" % mean_squared_error)\n",
+ "print(\"Root Mean Squared Error (on training data): %0.3f\" % root_mean_squared_error)\n",
+ "predictions"
+ ],
+ "execution_count": 0,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Mean Squared Error (on training data): 56367.025\n",
+ "Root Mean Squared Error (on training data): 237.417\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "array([0.15674996, 0.18564996, 0.05330002, ..., 0.42444986, 0.0867 ,\n",
+ " 0.25754994], dtype=float32)"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 34
+ }
+ ]
+ },
+ {
+ "metadata": {
+ "id": "AKWstXXPzOVz",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "Is this a good model? How would you judge how large this error is?\n",
+ "\n",
+ "Mean Squared Error (MSE) can be hard to interpret, so we often look at Root Mean Squared Error (RMSE)\n",
+ "instead. A nice property of RMSE is that it can be interpreted on the same scale as the original targets.\n",
+ "\n",
+ "Let's compare the RMSE to the difference of the min and max of our targets:"
+ ]
+ },
+ {
+ "metadata": {
+ "id": "7UwqGbbxP53O",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "min_house_value = california_housing_dataframe[\"median_house_value\"].min()\n",
+ "max_house_value = california_housing_dataframe[\"median_house_value\"].max()\n",
+ "min_max_difference = max_house_value - min_house_value\n",
+ "\n",
+ "print(\"Min. Median House Value: %0.3f\" % min_house_value)\n",
+ "print(\"Max. Median House Value: %0.3f\" % max_house_value)\n",
+ "print(\"Difference between Min. and Max.: %0.3f\" % min_max_difference)\n",
+ "print(\"Root Mean Squared Error: %0.3f\" % root_mean_squared_error)"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "JigJr0C7Pzit",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "Our error spans nearly half the range of the target values. Can we do better?\n",
+ "\n",
+ "This is the question that nags at every model developer. Let's develop some basic strategies to reduce model error.\n",
+ "\n",
+ "The first thing we can do is take a look at how well our predictions match our targets, in terms of overall summary statistics."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "941nclxbzqGH",
+ "colab_type": "code",
+ "cellView": "both",
+ "outputId": "381526f4-b195-405d-f1b7-7b48d1dec42e",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 300
+ }
+ },
+ "cell_type": "code",
+ "source": [
+ "calibration_data = pd.DataFrame()\n",
+ "calibration_data[\"predictions\"] = pd.Series(predictions)\n",
+ "calibration_data[\"targets\"] = pd.Series(targets)\n",
+ "calibration_data.describe()"
+ ],
+ "execution_count": 0,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/html": [
+ "
\n",
+ "\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
predictions
\n",
+ "
targets
\n",
+ "
\n",
+ " \n",
+ " \n",
+ "
\n",
+ "
count
\n",
+ "
17000.0
\n",
+ "
17000.0
\n",
+ "
\n",
+ "
\n",
+ "
mean
\n",
+ "
0.1
\n",
+ "
207.3
\n",
+ "
\n",
+ "
\n",
+ "
std
\n",
+ "
0.1
\n",
+ "
116.0
\n",
+ "
\n",
+ "
\n",
+ "
min
\n",
+ "
0.0
\n",
+ "
15.0
\n",
+ "
\n",
+ "
\n",
+ "
25%
\n",
+ "
0.1
\n",
+ "
119.4
\n",
+ "
\n",
+ "
\n",
+ "
50%
\n",
+ "
0.1
\n",
+ "
180.4
\n",
+ "
\n",
+ "
\n",
+ "
75%
\n",
+ "
0.2
\n",
+ "
265.0
\n",
+ "
\n",
+ "
\n",
+ "
max
\n",
+ "
1.9
\n",
+ "
500.0
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " predictions targets\n",
+ "count 17000.0 17000.0\n",
+ "mean 0.1 207.3\n",
+ "std 0.1 116.0\n",
+ "min 0.0 15.0\n",
+ "25% 0.1 119.4\n",
+ "50% 0.1 180.4\n",
+ "75% 0.2 265.0\n",
+ "max 1.9 500.0"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 35
+ }
+ ]
+ },
+ {
+ "metadata": {
+ "id": "E2-bf8Hq36y8",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "Okay, maybe this information is helpful. How does the mean value compare to the model's RMSE? How about the various quantiles?\n",
+ "\n",
+ "We can also visualize the data and the line we've learned. Recall that linear regression on a single feature can be drawn as a line mapping input *x* to output *y*.\n",
+ "\n",
+ "First, we'll get a uniform random sample of the data so we can make a readable scatter plot."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "SGRIi3mAU81H",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "sample = california_housing_dataframe.sample(n=300)"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "N-JwuJBKU81J",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "Next, we'll plot the line we've learned, drawing from the model's bias term and feature weight, together with the scatter plot. The line will show up red."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "7G12E76-339G",
+ "colab_type": "code",
+ "cellView": "both",
+ "outputId": "260cea61-17ee-476f-ab63-424a335fe38f",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 361
+ }
+ },
+ "cell_type": "code",
+ "source": [
+ "# Get the min and max total_rooms values.\n",
+ "x_0 = sample[\"total_rooms\"].min()\n",
+ "x_1 = sample[\"total_rooms\"].max()\n",
+ "\n",
+ "# Retrieve the final weight and bias generated during training.\n",
+ "weight = linear_regressor.get_variable_value('linear/linear_model/total_rooms/weights')[0]\n",
+ "bias = linear_regressor.get_variable_value('linear/linear_model/bias_weights')\n",
+ "\n",
+ "# Get the predicted median_house_values for the min and max total_rooms values.\n",
+ "y_0 = weight * x_0 + bias \n",
+ "y_1 = weight * x_1 + bias\n",
+ "\n",
+ "# Plot our regression line from (x_0, y_0) to (x_1, y_1).\n",
+ "plt.plot([x_0, x_1], [y_0, y_1], c='r')\n",
+ "\n",
+ "# Label the graph axes.\n",
+ "plt.ylabel(\"median_house_value\")\n",
+ "plt.xlabel(\"total_rooms\")\n",
+ "\n",
+ "# Plot a scatter plot from our data sample.\n",
+ "plt.scatter(sample[\"total_rooms\"], sample[\"median_house_value\"])\n",
+ "\n",
+ "# Display graph.\n",
+ "plt.show()"
+ ],
+ "execution_count": 0,
+ "outputs": [
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "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\nQgjhwf4F80/9fTlIK+0AAAAASUVORK5CYII=\n",
+ "text/plain": [
+ "
"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ }
+ }
+ ]
+ },
+ {
+ "metadata": {
+ "id": "t0lRt4USU81L",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "This initial line looks way off. See if you can look back at the summary stats and see the same information encoded there.\n",
+ "\n",
+ "Together, these initial sanity checks suggest we may be able to find a much better line."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "AZWF67uv0HTG",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## Tweak the Model Hyperparameters\n",
+ "For this exercise, we've put all the above code in a single function for convenience. You can call the function with different parameters to see the effect.\n",
+ "\n",
+ "In this function, we'll proceed in 10 evenly divided periods so that we can observe the model improvement at each period.\n",
+ "\n",
+ "For each period, we'll compute and graph training loss. This may help you judge when a model is converged, or if it needs more iterations.\n",
+ "\n",
+ "We'll also plot the feature weight and bias term values learned by the model over time. This is another way to see how things converge."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "wgSMeD5UU81N",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def train_model(learning_rate, steps, batch_size, input_feature=\"total_rooms\"):\n",
+ " \"\"\"Trains a linear regression model of one feature.\n",
+ " \n",
+ " Args:\n",
+ " learning_rate: A `float`, the learning rate.\n",
+ " steps: A non-zero `int`, the total number of training steps. A training step\n",
+ " consists of a forward and backward pass using a single batch.\n",
+ " batch_size: A non-zero `int`, the batch size.\n",
+ " input_feature: A `string` specifying a column from `california_housing_dataframe`\n",
+ " to use as input feature.\n",
+ " \"\"\"\n",
+ " \n",
+ " periods = 10\n",
+ " steps_per_period = steps / periods\n",
+ "\n",
+ " my_feature = input_feature\n",
+ " my_feature_data = california_housing_dataframe[[my_feature]]\n",
+ " my_label = \"median_house_value\"\n",
+ " targets = california_housing_dataframe[my_label]\n",
+ "\n",
+ " # Create feature columns.\n",
+ " feature_columns = [tf.feature_column.numeric_column(my_feature)]\n",
+ " \n",
+ " # Create input functions.\n",
+ " training_input_fn = lambda:my_input_fn(my_feature_data, targets, batch_size=batch_size)\n",
+ " prediction_input_fn = lambda: my_input_fn(my_feature_data, targets, num_epochs=1, shuffle=False)\n",
+ " \n",
+ " # Create a linear regressor object.\n",
+ " my_optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)\n",
+ " my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0)\n",
+ " linear_regressor = tf.estimator.LinearRegressor(\n",
+ " feature_columns=feature_columns,\n",
+ " optimizer=my_optimizer\n",
+ " )\n",
+ "\n",
+ " # Set up to plot the state of our model's line each period.\n",
+ " plt.figure(figsize=(15, 6))\n",
+ " plt.subplot(1, 2, 1)\n",
+ " plt.title(\"Learned Line by Period\")\n",
+ " plt.ylabel(my_label)\n",
+ " plt.xlabel(my_feature)\n",
+ " sample = california_housing_dataframe.sample(n=300)\n",
+ " plt.scatter(sample[my_feature], sample[my_label])\n",
+ " colors = [cm.coolwarm(x) for x in np.linspace(-1, 1, periods)]\n",
+ "\n",
+ " # Train the model, but do so inside a loop so that we can periodically assess\n",
+ " # loss metrics.\n",
+ " print(\"Training model...\")\n",
+ " print(\"RMSE (on training data):\")\n",
+ " root_mean_squared_errors = []\n",
+ " for period in range (0, periods):\n",
+ " # Train the model, starting from the prior state.\n",
+ " linear_regressor.train(\n",
+ " input_fn=training_input_fn,\n",
+ " steps=steps_per_period\n",
+ " )\n",
+ " # Take a break and compute predictions.\n",
+ " predictions = linear_regressor.predict(input_fn=prediction_input_fn)\n",
+ " predictions = np.array([item['predictions'][0] for item in predictions])\n",
+ " \n",
+ " # Compute loss.\n",
+ " root_mean_squared_error = math.sqrt(\n",
+ " metrics.mean_squared_error(predictions, targets))\n",
+ " # Occasionally print the current loss.\n",
+ " print(\" period %02d : %0.2f\" % (period, root_mean_squared_error))\n",
+ " # Add the loss metrics from this period to our list.\n",
+ " root_mean_squared_errors.append(root_mean_squared_error)\n",
+ " # Finally, track the weights and biases over time.\n",
+ " # Apply some math to ensure that the data and line are plotted neatly.\n",
+ " y_extents = np.array([0, sample[my_label].max()])\n",
+ " \n",
+ " weight = linear_regressor.get_variable_value('linear/linear_model/%s/weights' % input_feature)[0]\n",
+ " bias = linear_regressor.get_variable_value('linear/linear_model/bias_weights')\n",
+ "\n",
+ " x_extents = (y_extents - bias) / weight\n",
+ " x_extents = np.maximum(np.minimum(x_extents,\n",
+ " sample[my_feature].max()),\n",
+ " sample[my_feature].min())\n",
+ " y_extents = weight * x_extents + bias\n",
+ " plt.plot(x_extents, y_extents, color=colors[period]) \n",
+ " print(\"Model training finished.\")\n",
+ "\n",
+ " # Output a graph of loss metrics over periods.\n",
+ " plt.subplot(1, 2, 2)\n",
+ " plt.ylabel('RMSE')\n",
+ " plt.xlabel('Periods')\n",
+ " plt.title(\"Root Mean Squared Error vs. Periods\")\n",
+ " plt.tight_layout()\n",
+ " plt.plot(root_mean_squared_errors)\n",
+ "\n",
+ " # Output a table with calibration data.\n",
+ " calibration_data = pd.DataFrame()\n",
+ " calibration_data[\"predictions\"] = pd.Series(predictions)\n",
+ " calibration_data[\"targets\"] = pd.Series(targets)\n",
+ " display.display(calibration_data.describe())\n",
+ "\n",
+ " print(\"Final RMSE (on training data): %0.2f\" % root_mean_squared_error)"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "kg8A4ArBU81Q",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## Task 1: Achieve an RMSE of 180 or Below\n",
+ "\n",
+ "Tweak the model hyperparameters to improve loss and better match the target distribution.\n",
+ "If, after 5 minutes or so, you're having trouble beating a RMSE of 180, check the solution for a possible combination."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "UzoZUSdLIolF",
+ "colab_type": "code",
+ "cellView": "both",
+ "outputId": "ac6e3e85-1e9d-46a9-b41e-92ccd3ab8675",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 977
+ }
+ },
+ "cell_type": "code",
+ "source": [
+ "train_model(\n",
+ " learning_rate=0.0001,\n",
+ " steps=300,\n",
+ " batch_size=1000\n",
+ ")"
+ ],
+ "execution_count": 0,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Training model...\n",
+ "RMSE (on training data):\n",
+ " period 00 : 204.04\n",
+ " period 01 : 179.23\n",
+ " period 02 : 167.79\n",
+ " period 03 : 166.39\n",
+ " period 04 : 166.53\n",
+ " period 05 : 166.32\n",
+ " period 06 : 166.39\n",
+ " period 07 : 166.32\n",
+ " period 08 : 166.53\n",
+ " period 09 : 166.53\n",
+ "Model training finished.\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "text/plain": [
+ " predictions targets\n",
+ "count 17000.0 17000.0\n",
+ "mean 137.5 207.3\n",
+ "std 113.4 116.0\n",
+ "min 0.1 15.0\n",
+ "25% 76.0 119.4\n",
+ "50% 110.6 180.4\n",
+ "75% 163.9 265.0\n",
+ "max 1973.1 500.0"
+ ],
+ "text/html": [
+ "
"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ }
+ }
+ ]
+ },
+ {
+ "metadata": {
+ "id": "ajVM7rkoYXeL",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "### Solution\n",
+ "\n",
+ "Click below for one possible solution."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "T3zmldDwYy5c",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "train_model(\n",
+ " learning_rate=0.00002,\n",
+ " steps=500,\n",
+ " batch_size=5\n",
+ ")"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "M8H0_D4vYa49",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "This is just one possible configuration; there may be other combinations of settings that also give good results. Note that in general, this exercise isn't about finding the *one best* setting, but to help build your intutions about how tweaking the model configuration affects prediction quality."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "QU5sLyYTqzqL",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "### Is There a Standard Heuristic for Model Tuning?\n",
+ "\n",
+ "This is a commonly asked question. The short answer is that the effects of different hyperparameters are data dependent. So there are no hard-and-fast rules; you'll need to test on your data.\n",
+ "\n",
+ "That said, here are a few rules of thumb that may help guide you:\n",
+ "\n",
+ " * Training error should steadily decrease, steeply at first, and should eventually plateau as training converges.\n",
+ " * If the training has not converged, try running it for longer.\n",
+ " * If the training error decreases too slowly, increasing the learning rate may help it decrease faster.\n",
+ " * But sometimes the exact opposite may happen if the learning rate is too high.\n",
+ " * If the training error varies wildly, try decreasing the learning rate.\n",
+ " * Lower learning rate plus larger number of steps or larger batch size is often a good combination.\n",
+ " * Very small batch sizes can also cause instability. First try larger values like 100 or 1000, and decrease until you see degradation.\n",
+ "\n",
+ "Again, never go strictly by these rules of thumb, because the effects are data dependent. Always experiment and verify."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "GpV-uF_cBCBU",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## Task 2: Try a Different Feature\n",
+ "\n",
+ "See if you can do any better by replacing the `total_rooms` feature with the `population` feature.\n",
+ "\n",
+ "Don't take more than 5 minutes on this portion."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "YMyOxzb0ZlAH",
+ "colab_type": "code",
+ "outputId": "c8091026-424f-4fbd-a8bd-44d0287dfbc9",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 977
+ }
+ },
+ "cell_type": "code",
+ "source": [
+ "train_model(\n",
+ " learning_rate=0.0001,\n",
+ " steps=500,\n",
+ " batch_size=1000,\n",
+ " input_feature=\"population\"\n",
+ ")"
+ ],
+ "execution_count": 0,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Training model...\n",
+ "RMSE (on training data):\n",
+ " period 00 : 209.51\n",
+ " period 01 : 188.58\n",
+ " period 02 : 177.30\n",
+ " period 03 : 175.95\n",
+ " period 04 : 175.92\n",
+ " period 05 : 175.95\n",
+ " period 06 : 175.92\n",
+ " period 07 : 176.06\n",
+ " period 08 : 175.99\n",
+ " period 09 : 175.92\n",
+ "Model training finished.\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "text/plain": [
+ " predictions targets\n",
+ "count 17000.0 17000.0\n",
+ "mean 122.9 207.3\n",
+ "std 98.7 116.0\n",
+ "min 0.3 15.0\n",
+ "25% 67.9 119.4\n",
+ "50% 100.3 180.4\n",
+ "75% 148.0 265.0\n",
+ "max 3068.1 500.0"
+ ],
+ "text/html": [
+ "
"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ }
+ }
+ ]
+ },
+ {
+ "metadata": {
+ "id": "oJlrB4rJ_2Ma",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def construct_feature_columns(input_features):\n",
+ " \"\"\"Construct the TensorFlow Feature Columns.\n",
+ "\n",
+ " Args:\n",
+ " input_features: The names of the numerical input features to use.\n",
+ " Returns:\n",
+ " A set of feature columns\n",
+ " \"\"\"\n",
+ " return set([tf.feature_column.numeric_column(my_feature)\n",
+ " for my_feature in input_features])"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "NBxoAfp2AcB6",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def my_input_fn(features, targets, batch_size=1, shuffle=True, num_epochs=None):\n",
+ " \"\"\"Trains a linear regression model.\n",
+ " \n",
+ " Args:\n",
+ " features: pandas DataFrame of features\n",
+ " targets: pandas DataFrame of targets\n",
+ " batch_size: Size of batches to be passed to the model\n",
+ " shuffle: True or False. Whether to shuffle the data.\n",
+ " num_epochs: Number of epochs for which data should be repeated. None = repeat indefinitely\n",
+ " Returns:\n",
+ " Tuple of (features, labels) for next data batch\n",
+ " \"\"\"\n",
+ " \n",
+ " # Convert pandas data into a dict of np arrays.\n",
+ " features = {key:np.array(value) for key,value in dict(features).items()} \n",
+ " \n",
+ " # Construct a dataset, and configure batching/repeating.\n",
+ " ds = Dataset.from_tensor_slices((features,targets)) # warning: 2GB limit\n",
+ " ds = ds.batch(batch_size).repeat(num_epochs)\n",
+ " \n",
+ " # Shuffle the data, if specified.\n",
+ " if shuffle:\n",
+ " ds = ds.shuffle(10000)\n",
+ " \n",
+ " # Return the next batch of data.\n",
+ " features, labels = ds.make_one_shot_iterator().get_next()\n",
+ " return features, labels"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "hweDyy31LBsV",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## FTRL Optimization Algorithm\n",
+ "\n",
+ "High dimensional linear models benefit from using a variant of gradient-based optimization called FTRL. This algorithm has the benefit of scaling the learning rate differently for different coefficients, which can be useful if some features rarely take non-zero values (it also is well suited to support L1 regularization). We can apply FTRL using the [FtrlOptimizer](https://www.tensorflow.org/api_docs/python/tf/train/FtrlOptimizer)."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "S0SBf1X1IK_O",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def train_model(\n",
+ " learning_rate,\n",
+ " steps,\n",
+ " batch_size,\n",
+ " feature_columns,\n",
+ " training_examples,\n",
+ " training_targets,\n",
+ " validation_examples,\n",
+ " validation_targets):\n",
+ " \"\"\"Trains a linear regression model.\n",
+ " \n",
+ " In addition to training, this function also prints training progress information,\n",
+ " as well as a plot of the training and validation loss over time.\n",
+ " \n",
+ " Args:\n",
+ " learning_rate: A `float`, the learning rate.\n",
+ " steps: A non-zero `int`, the total number of training steps. A training step\n",
+ " consists of a forward and backward pass using a single batch.\n",
+ " feature_columns: A `set` specifying the input feature columns to use.\n",
+ " training_examples: A `DataFrame` containing one or more columns from\n",
+ " `california_housing_dataframe` to use as input features for training.\n",
+ " training_targets: A `DataFrame` containing exactly one column from\n",
+ " `california_housing_dataframe` to use as target for training.\n",
+ " validation_examples: A `DataFrame` containing one or more columns from\n",
+ " `california_housing_dataframe` to use as input features for validation.\n",
+ " validation_targets: A `DataFrame` containing exactly one column from\n",
+ " `california_housing_dataframe` to use as target for validation.\n",
+ " \n",
+ " Returns:\n",
+ " A `LinearRegressor` object trained on the training data.\n",
+ " \"\"\"\n",
+ "\n",
+ " periods = 10\n",
+ " steps_per_period = steps / periods\n",
+ "\n",
+ " # Create a linear regressor object.\n",
+ " my_optimizer = tf.train.FtrlOptimizer(learning_rate=learning_rate)\n",
+ " my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0)\n",
+ " linear_regressor = tf.estimator.LinearRegressor(\n",
+ " feature_columns=feature_columns,\n",
+ " optimizer=my_optimizer\n",
+ " )\n",
+ " \n",
+ " training_input_fn = lambda: my_input_fn(training_examples, \n",
+ " training_targets[\"median_house_value\"], \n",
+ " batch_size=batch_size)\n",
+ " predict_training_input_fn = lambda: my_input_fn(training_examples, \n",
+ " training_targets[\"median_house_value\"], \n",
+ " num_epochs=1, \n",
+ " shuffle=False)\n",
+ " predict_validation_input_fn = lambda: my_input_fn(validation_examples, \n",
+ " validation_targets[\"median_house_value\"], \n",
+ " num_epochs=1, \n",
+ " shuffle=False)\n",
+ "\n",
+ " # Train the model, but do so inside a loop so that we can periodically assess\n",
+ " # loss metrics.\n",
+ " print(\"Training model...\")\n",
+ " print(\"RMSE (on training data):\")\n",
+ " training_rmse = []\n",
+ " validation_rmse = []\n",
+ " for period in range (0, periods):\n",
+ " # Train the model, starting from the prior state.\n",
+ " linear_regressor.train(\n",
+ " input_fn=training_input_fn,\n",
+ " steps=steps_per_period\n",
+ " )\n",
+ " # Take a break and compute predictions.\n",
+ " training_predictions = linear_regressor.predict(input_fn=predict_training_input_fn)\n",
+ " training_predictions = np.array([item['predictions'][0] for item in training_predictions])\n",
+ " validation_predictions = linear_regressor.predict(input_fn=predict_validation_input_fn)\n",
+ " validation_predictions = np.array([item['predictions'][0] for item in validation_predictions])\n",
+ " \n",
+ " # Compute training and validation loss.\n",
+ " training_root_mean_squared_error = math.sqrt(\n",
+ " metrics.mean_squared_error(training_predictions, training_targets))\n",
+ " validation_root_mean_squared_error = math.sqrt(\n",
+ " metrics.mean_squared_error(validation_predictions, validation_targets))\n",
+ " # Occasionally print the current loss.\n",
+ " print(\" period %02d : %0.2f\" % (period, training_root_mean_squared_error))\n",
+ " # Add the loss metrics from this period to our list.\n",
+ " training_rmse.append(training_root_mean_squared_error)\n",
+ " validation_rmse.append(validation_root_mean_squared_error)\n",
+ " print(\"Model training finished.\")\n",
+ "\n",
+ " \n",
+ " # Output a graph of loss metrics over periods.\n",
+ " plt.ylabel(\"RMSE\")\n",
+ " plt.xlabel(\"Periods\")\n",
+ " plt.title(\"Root Mean Squared Error vs. Periods\")\n",
+ " plt.tight_layout()\n",
+ " plt.plot(training_rmse, label=\"training\")\n",
+ " plt.plot(validation_rmse, label=\"validation\")\n",
+ " plt.legend()\n",
+ "\n",
+ " return linear_regressor"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "1Cdr02tLIK_Q",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 640
+ },
+ "outputId": "30383cf6-9021-4af9-f19b-df584d9f6f7d"
+ },
+ "cell_type": "code",
+ "source": [
+ "_ = train_model(\n",
+ " learning_rate=1.0,\n",
+ " steps=500,\n",
+ " batch_size=100,\n",
+ " feature_columns=construct_feature_columns(training_examples),\n",
+ " training_examples=training_examples,\n",
+ " training_targets=training_targets,\n",
+ " validation_examples=validation_examples,\n",
+ " validation_targets=validation_targets)"
+ ],
+ "execution_count": 28,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Training model...\n",
+ "RMSE (on training data):\n",
+ " period 00 : 145.53\n",
+ " period 01 : 159.50\n",
+ " period 02 : 116.73\n",
+ " period 03 : 313.37\n",
+ " period 04 : 353.00\n",
+ " period 05 : 316.81\n",
+ " period 06 : 311.05\n",
+ " period 07 : 283.78\n",
+ " period 08 : 265.21\n",
+ " period 09 : 224.52\n",
+ "Model training finished.\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjAAAAGACAYAAACz01iHAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzs3Xd4FNX6wPHvbnovm2wqIfQA6RCQ\nTgAhFEUBEQRExYZiw4aK93e9Kuq1o4JiF0UBRRSR3osCKYQAgQBJSEJ67213fn9EckE2oZhsEvJ+\nnoeH7M6ZmXf27G7enDlFpSiKghBCCCFEG6Ju6QCEEEIIIa6WJDBCCCGEaHMkgRFCCCFEmyMJjBBC\nCCHaHElghBBCCNHmSAIjhBBCiDbHtKUDEKI169GjBz4+PpiYmACg0+kICwtj4cKFWFtbX/NxV61a\nxdSpUy95fs2aNTz33HN8/PHHhIeH1z9fWVnJwIEDGT16NK+//vo1n/dKpaSksGjRIpKSkgCwsrJi\n3rx5jBo1qtnPfTWWLFlCSkrKJa/JgQMHmDNnDt7e3pfss3HjRmOF94+kpaUxcuRIOnXqBICiKLi4\nuPDCCy/Qq1evqzrW22+/jaenJ9OnT7/ifX755Rd+/PFHli9fflXnEsJYJIER4jKWL1+Ou7s7ANXV\n1TzxxBN88sknPPHEE9d0vJycHD777DODCQyAh4cHv/3220UJzI4dO7C3t7+m812Lp556iokTJ/Lx\nxx8DEBsby+zZs9mwYQMeHh5Gi+Of8PDwaDPJSkNMTEwuuobff/+dhx9+mE2bNmFubn7Fx3nyySeb\nIzwhWpTcQhLiKpibmzNkyBDi4+MBqKqq4l//+hdjxoxh7NixvP766+h0OgBOnDjBtGnTiIiIYOLE\niezZsweAadOmkZ6eTkREBNXV1ZecIzQ0lAMHDlBRUVH/3O+//86gQYPqH1dXV/PKK68wZswYRowY\nUZ9oAMTExDBp0iQiIiIYN24c+/fvB+r+oh88eDDffPMNN910E0OGDOH33383eJ0JCQkEBQXVPw4K\nCmLTpk31idyHH37IsGHDuOWWW1i2bBkjRowAYMGCBSxZsqR+vwsfXy6uRYsWMXPmTACioqKYPHky\nN954I1OnTiU1NRWoa4l6/PHHCQ8PZ+bMmWRmZl6mxgxbs2YN8+bNY/bs2fz3v//lwIEDTJs2jcce\ne6z+l/2GDRuYMGECERER3HnnnaSkpADwwQcfsHDhQqZMmcJXX3110XEfe+wxvvjii/rH8fHxDB48\nGL1ez7vvvsuYMWMYM2YMd955J1lZWVcd97hx46isrCQxMRGAlStXEhERwYgRI5g/fz6VlZVA3ev+\n2muvcdNNN7Fhw4aL6qGh96Ver+c///kPw4cPZ8qUKZw4caL+vAcPHuTWW29l3LhxjB07lg0bNlx1\n7EI0OUUI0aDu3bsrGRkZ9Y8LCwuVGTNmKEuWLFEURVE++eQT5b777lNqamqUiooKZfLkycratWsV\nnU6njB07Vlm3bp2iKIpy5MgRJSwsTCkpKVH+/PNPZdSoUQbP99NPPynPPvus8tRTT9XvW1JSoowc\nOVJZvXq18uyzzyqKoigffvihMnv2bKWqqkopKytTbrnlFmX79u2KoijKhAkTlN9++01RFEX5+eef\n68+Vmpqq9OrVS1m+fLmiKIry+++/KzfeeKPBOB555BElPDxc+frrr5XTp09ftO3kyZNK3759lezs\nbKWmpkaZO3euEh4eriiKojz77LPKRx99VF/2wseNxdW7d29lzZo19dcbFham7N27V1EURVm3bp1y\n6623KoqiKN9++60yY8YMpaamRsnPz1fCw8PrX5MLNfYan3+dg4ODlaSkpPryAQEByv79+xVFUZRz\n584pffr0UZKTkxVFUZTPP/9cmT17tqIoirJ48WJl8ODBSl5e3iXHXb9+vTJjxoz6x++//77y8ssv\nKwkJCcro0aOV6upqRVEU5ZtvvlF+/vnnBuM7/7r07NnzkufDwsKUM2fOKIcOHVIGDBigZGZmKoqi\nKC+++KLy+uuvK4pS97rfdNNNSmVlZf3jjz76qNH35c6dO5XRo0crpaWlSkVFhTJlyhRl5syZiqIo\nyqRJk5QDBw4oiqIoSUlJyvz58xuNXQhjkBYYIS5j1qxZREREMHLkSEaOHMkNN9zAfffdB8DOnTuZ\nOnUqpqamWFpactNNN7Fv3z7S0tLIzc1l/PjxAAQEBODp6UlcXNwVnXP8+PH89ttvAGzdupXw8HDU\n6v99XHfs2MEdd9yBubk51tbWTJw4kc2bNwOwdu1axo4dC0CfPn3qWy8AamtrmTRpEgC9e/cmPT3d\n4PnffPNNZsyYwbp165gwYQIjRozg+++/B+paR8LCwnB1dcXU1JQJEyZc0TU1FldNTQ033nhj/fHd\n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\n",
+ "text/plain": [
+ "
"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ }
+ }
+ ]
+ },
+ {
+ "metadata": {
+ "id": "i4lGvqajDWlw",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## One-Hot Encoding for Discrete Features\n",
+ "\n",
+ "Discrete (i.e. strings, enumerations, integers) features are usually converted into families of binary features before training a logistic regression model.\n",
+ "\n",
+ "For example, suppose we created a synthetic feature that can take any of the values `0`, `1` or `2`, and that we have a few training points:\n",
+ "\n",
+ "| # | feature_value |\n",
+ "|---|---------------|\n",
+ "| 0 | 2 |\n",
+ "| 1 | 0 |\n",
+ "| 2 | 1 |\n",
+ "\n",
+ "For each possible categorical value, we make a new **binary** feature of **real values** that can take one of just two possible values: 1.0 if the example has that value, and 0.0 if not. In the example above, the categorical feature would be converted into three features, and the training points now look like:\n",
+ "\n",
+ "| # | feature_value_0 | feature_value_1 | feature_value_2 |\n",
+ "|---|-----------------|-----------------|-----------------|\n",
+ "| 0 | 0.0 | 0.0 | 1.0 |\n",
+ "| 1 | 1.0 | 0.0 | 0.0 |\n",
+ "| 2 | 0.0 | 1.0 | 0.0 |"
+ ]
+ },
+ {
+ "metadata": {
+ "id": "KnssXowblKm7",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## Bucketized (Binned) Features\n",
+ "\n",
+ "Bucketization is also known as binning.\n",
+ "\n",
+ "We can bucketize `population` into the following 3 buckets (for instance):\n",
+ "- `bucket_0` (`< 5000`): corresponding to less populated blocks\n",
+ "- `bucket_1` (`5000 - 25000`): corresponding to mid populated blocks\n",
+ "- `bucket_2` (`> 25000`): corresponding to highly populated blocks\n",
+ "\n",
+ "Given the preceding bucket definitions, the following `population` vector:\n",
+ "\n",
+ " [[10001], [42004], [2500], [18000]]\n",
+ "\n",
+ "becomes the following bucketized feature vector:\n",
+ "\n",
+ " [[1], [2], [0], [1]]\n",
+ "\n",
+ "The feature values are now the bucket indices. Note that these indices are considered to be discrete features. Typically, these will be further converted in one-hot representations as above, but this is done transparently.\n",
+ "\n",
+ "To define feature columns for bucketized features, instead of using `numeric_column`, we can use [`bucketized_column`](https://www.tensorflow.org/api_docs/python/tf/feature_column/bucketized_column), which takes a numeric column as input and transforms it to a bucketized feature using the bucket boundaries specified in the `boundaries` argument. The following code defines bucketized feature columns for `households` and `longitude`; the `get_quantile_based_boundaries` function calculates boundaries based on quantiles, so that each bucket contains an equal number of elements."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "cc9qZrtRy-ED",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def get_quantile_based_boundaries(feature_values, num_buckets):\n",
+ " boundaries = np.arange(1.0, num_buckets) / num_buckets\n",
+ " quantiles = feature_values.quantile(boundaries)\n",
+ " return [quantiles[q] for q in quantiles.keys()]\n",
+ "\n",
+ "# Divide households into 7 buckets.\n",
+ "households = tf.feature_column.numeric_column(\"households\")\n",
+ "bucketized_households = tf.feature_column.bucketized_column(\n",
+ " households, boundaries=get_quantile_based_boundaries(\n",
+ " california_housing_dataframe[\"households\"], 7))\n",
+ "\n",
+ "# Divide longitude into 10 buckets.\n",
+ "longitude = tf.feature_column.numeric_column(\"longitude\")\n",
+ "bucketized_longitude = tf.feature_column.bucketized_column(\n",
+ " longitude, boundaries=get_quantile_based_boundaries(\n",
+ " california_housing_dataframe[\"longitude\"], 10))"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "U-pQDAa0MeN3",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## Task 1: Train the Model on Bucketized Feature Columns\n",
+ "**Bucketize all the real valued features in our example, train the model and see if the results improve.**\n",
+ "\n",
+ "In the preceding code block, two real valued columns (namely `households` and `longitude`) have been transformed into bucketized feature columns. Your task is to bucketize the rest of the columns, then run the code to train the model. There are various heuristics to find the range of the buckets. This exercise uses a quantile-based technique, which chooses the bucket boundaries in such a way that each bucket has the same number of examples."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "YFXV9lyMLedy",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def construct_feature_columns():\n",
+ " \"\"\"Construct the TensorFlow Feature Columns.\n",
+ "\n",
+ " Returns:\n",
+ " A set of feature columns\n",
+ " \"\"\" \n",
+ " households = tf.feature_column.numeric_column(\"households\")\n",
+ " longitude = tf.feature_column.numeric_column(\"longitude\")\n",
+ " latitude = tf.feature_column.numeric_column(\"latitude\")\n",
+ " housing_median_age = tf.feature_column.numeric_column(\"housing_median_age\")\n",
+ " median_income = tf.feature_column.numeric_column(\"median_income\")\n",
+ " rooms_per_person = tf.feature_column.numeric_column(\"rooms_per_person\")\n",
+ " \n",
+ " # Divide households into 7 buckets.\n",
+ " bucketized_households = tf.feature_column.bucketized_column(\n",
+ " households, boundaries=get_quantile_based_boundaries(\n",
+ " training_examples[\"households\"], 7))\n",
+ "\n",
+ " # Divide longitude into 10 buckets.\n",
+ " bucketized_longitude = tf.feature_column.bucketized_column(\n",
+ " longitude, boundaries=get_quantile_based_boundaries(\n",
+ " training_examples[\"longitude\"], 10))\n",
+ "\n",
+ " #\n",
+ " # YOUR CODE HERE: bucketize the following columns, following the example above:\n",
+ " #\n",
+ " bucketized_latitude = tf.feature_column.bucketized_column(latitude, boundaries=get_quantile_based_boundaries(training_examples[\"latitude\"], 10))\n",
+ " bucketized_housing_median_age = tf.feature_column.bucketized_column(housing_median_age,boundaries=get_quantile_based_boundaries(training_examples[\"housing_median_age\"], 10))\n",
+ " bucketized_median_income = tf.feature_column.bucketized_column(median_income, boundaries=get_quantile_based_boundaries(training_examples[\"median_income\"], 10))\n",
+ " bucketized_rooms_per_person =tf.feature_column.bucketized_column(rooms_per_person, boundaries=get_quantile_based_boundaries(training_examples[\"rooms_per_person\"], 10))\n",
+ " \n",
+ " \n",
+ " feature_columns = set([\n",
+ " bucketized_longitude,\n",
+ " bucketized_latitude,\n",
+ " bucketized_housing_median_age,\n",
+ " bucketized_households,\n",
+ " bucketized_median_income,\n",
+ " bucketized_rooms_per_person])\n",
+ " \n",
+ " return feature_columns\n"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "0FfUytOTNJhL",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 640
+ },
+ "outputId": "4ebc66b2-8688-4901-b601-d3e3dc857220"
+ },
+ "cell_type": "code",
+ "source": [
+ "_ = train_model(\n",
+ " learning_rate=1.0,\n",
+ " steps=500,\n",
+ " batch_size=100,\n",
+ " feature_columns=construct_feature_columns(),\n",
+ " training_examples=training_examples,\n",
+ " training_targets=training_targets,\n",
+ " validation_examples=validation_examples,\n",
+ " validation_targets=validation_targets)"
+ ],
+ "execution_count": 31,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Training model...\n",
+ "RMSE (on training data):\n",
+ " period 00 : 170.32\n",
+ " period 01 : 143.98\n",
+ " period 02 : 127.43\n",
+ " period 03 : 116.14\n",
+ " period 04 : 108.01\n",
+ " period 05 : 101.93\n",
+ " period 06 : 97.29\n",
+ " period 07 : 93.64\n",
+ " period 08 : 90.67\n",
+ " period 09 : 88.19\n",
+ "Model training finished.\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjAAAAGACAYAAACz01iHAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzs3Xd4lfX9//HnOTmZZJAJCWEjO4QV\nIOxNWAVk1AHiqG1VqlVarb+qraVVqauK4KqKggsoMlwoS8ABhEDYhB0yyCQJZOec+/cHmq+sGCDJ\nfZK8HtfldXn26+SdAy8+933u22IYhoGIiIhILWI1O4CIiIjI1VKBERERkVpHBUZERERqHRUYERER\nqXVUYERERKTWUYERERGRWsdmdgARZ9auXTuaNWuGi4sLAHa7naioKB577DG8vLyu+XmXLFnCtGnT\nLrl++fLlPProo7z22msMGTKk/PqioiL69u3LyJEjeeaZZ675dSsrMTGRp556iuPHjwPg6enJrFmz\nGD58eLW/9tVYsGABiYmJl/xMtm7dyl133UV4ePglj/nyyy9rKt51SUpKYtiwYbRs2RIAwzAICgri\nr3/9Kx07dryq53r++ecJCwvj5ptvrvRjVq5cybJly1i0aNFVvZZITVGBEfkFixYtonHjxgCUlJTw\n4IMP8vrrr/Pggw9e0/NlZGTw3//+97IFBiA0NJRPP/30ggKzYcMGfH19r+n1rsWf/vQnJkyYwGuv\nvQZAfHw8M2fO5IsvviA0NLTGclyP0NDQWlNWrsTFxeWC9/D5559z3333sWbNGtzc3Cr9PLNnz66O\neCKm0iYkkavg5ubGgAEDOHDgAADFxcU88cQTjBo1itGjR/PMM89gt9sBOHjwIDfddBMxMTFMmDCB\nzZs3A3DTTTeRkpJCTEwMJSUll7xG9+7d2bp1K4WFheXXff755/Tr16/8cklJCf/85z8ZNWoUQ4cO\nLS8aADt37uTGG28kJiaGMWPG8N133wHn/0Xfv39/3nvvPcaPH8+AAQP4/PPPL/s+ExISiIyMLL8c\nGRnJmjVryovcK6+8wqBBg5g4cSJvvPEGQ4cOBeAvf/kLCxYsKH/czy//Uq6nnnqK6dOnA7Bjxw4m\nT57MiBEjmDZtGqdOnQLOr0T98Y9/ZMiQIUyfPp3Tp0//wsQub/ny5cyaNYuZM2fy73//m61bt3LT\nTTfxwAMPlP9l/8UXXzBu3DhiYmK47bbbSExMBGDevHk89thjTJkyhYULF17wvA888ABvv/12+eUD\nBw7Qv39/HA4HL774IqNGjWLUqFHcdtttpKWlXXXuMWPGUFRUxLFjxwD4+OOPiYmJYejQoTz00EMU\nFRUB53/uTz/9NOPHj+eLL764YA5X+r10OBz84x//YPDgwUyZMoWDBw+Wv+62bduYNGkSY8aMYfTo\n0XzxxRdXnV2kyhkickVt27Y1UlNTyy/n5OQYt956q7FgwQLDMAzj9ddfN+6++26jtLTUKCwsNCZP\nnmysWLHCsNvtxujRo43Vq1cbhmEYu3fvNqKiooyzZ88aP/zwgzF8+PDLvt7//vc/45FHHjH+9Kc/\nlT/27NmzxrBhw4ylS5cajzzyiGEYhvHKK68YM2fONIqLi438/Hxj4sSJxvr16w3DMIxx48YZn376\nqWEYhvHJJ5+Uv9apU6eMjh07GosWLTIMwzA+//xzY8SIEZfN8Yc//MEYMmSI8e677xpHjhy54LZD\nhw4ZPXv2NNLT043S0lLjnnvuMYYMGWIYhmE88sgjxvz588vv+/PLFeXq1KmTsXz58vL3GxUVZWzZ\nssUwDMNYvXq1MWnSJMMwDGPx4sXGrbfeapSWlhrZ2dnGkCFDyn8mP1fRz/inn3PXrl2N48ePl98/\nIiLC+O677wzDMIzk5GSjR48exokTJwzDMIy33nrLmDlzpmEYhvHyyy8b/fv3N7Kysi553s8++8y4\n9dZbyy+/9NJLxpw5c4yEhARj5MiRRklJiWEYhvHee+8Zn3zyyRXz/fRz6dChwyXXR0VFGUePHjW2\nb99uREdHG6dPnzYMwzAef/xx45lnnjEM4/zPffz48UZRUVH55fnz51f4e7lx40Zj5MiRxrlz54zC\nwkJjypQpxvTp0w3DMIwbb7zR2Lp1q2EYhnH8+HHjoYceqjC7SE3QCozIL5gxYwYxMTEMGzaMYcOG\n0adPH+6++24ANm7cyLRp07DZbHh4eDB+/Hi+/fZbkpKSyMzMZOzYsQBEREQQFhbGnj17KvWaY8eO\n5dNPPwVg7dq1DBkyBKv1/z6uGzZs4JZbbsHNzQ0vLy8mTJjAV199BcCKFSsYPXo0AD169ChfvQAo\nKyvjxhtvBKBTp06kpKRc9vWfffZZbr31VlavXs24ceMYOnQoH374IXB+dSQqKorg4GBsNhvjxo2r\n1HuqKFdpaSkjRowof/5GjRqVrziNGzeOxMREUlJSiI2NZcSIEdhsNvz9/S/YzHax1NRUYmJiLvjv\n5/vKtGjRghYtWpRf9vDwIDo6GoBvv/2W3r1707x5cwCmTp3K1q1bKSsrA86vSAUEBFzymoMHD2b/\n/v3k5OQA8PXXXxMTE4Ovry/Z2dmsXr2a3NxcZsyYwcSJEyv1c/uJYRh8/PHHNGrUiBYtWrB+/XrG\njBlDo0aNALj55pvLfwcAoqOjcXd3v+A5Kvq93L59O4MGDaJBgwZ4eHiUzwogMDCQFStWcPToUVq0\naMHzzz9/VdlFqoP2gRH5BT/tA5OdnV2++cNmO//Ryc7Oxs/Pr/y+fn5+ZGVlkZ2djY+PDxaLpfy2\nn/4SCwoK+sXX7NevH4899hg5OTl89tln3HvvveU71AKcPXuWp59+mhdeeAE4v0mpS5cuAKxevZr3\n3nuP/Px8HA4Hxs9Od+bi4lK+87HVasXhcFz29d3d3bnrrru46667yMvL48svv+Spp54iPDyc3Nzc\nC/bHCQwM/MX3U5lc3t7eAOTl5XHq1CliYmLKb3dzcyM7O5vc3Fx8fHzKr/f19SU/P/+yr/dL+8D8\nfG4XXz5z5swF79HHxwfDMDhz5sxlH/sTLy8v+vbty8aNG+nRowd5eXn06NEDi8XCvHnzePvtt5kz\nZw5RUVE8+eSTv7g/kd1uL/85GIZBmzZtWLBgAVarlbNnz/L111+zZcuW8ttLS0uv+P6ACn8vc3Nz\nCQkJueD6nzz11FO8+uqr3HHHHXh4ePDQQw9dMB8RM6jAiFRSQEAAM2bM4Nlnn+XVV18FICgoqPxf\n2wA5OTkEBQURGBhIbm4uhmGU/2WRk5NT6b/sXV1dGTJkCCtWrODkyZN069btggITEhLCnXfeeckK\nRFpaGo899hhLly6lQ4cOnDhxglGjRl3V+8zOzubAgQPlKyC+vr5MmzaNzZs3k5CQgI+PD2fPnr3g\n/j+5uBTl5uZeda6QkBBatWrF8uXLL7nN19f3iq9dlQIDA9m5c2f55dzcXKxWK/7+/r/42FGjRvH1\n119z5swZRo0aVT7/Pn360KdPHwoKCpg7dy7PPffcL65kXLwT78+FhIQwadIkHnnkkat6X1f6vazo\nZxsUFMTjjz/O448/zpYtW/jDH/7AgAEDaNCgQaVfW6SqaROSyFW444472LlzJ9u2bQPObzJYtmwZ\ndrudgoICVq5cyaBBgwgPD6dx48blO8nGxcWRmZlJly5dsNlsFBQUlG+OuJKxY8fy5ptvXvary8OG\nDWPp0qXY7XYMw2DBggVs2rSJ7OxsvLy8aNWqFWVlZXz88ccAV1yluJyioiLuv//+8p07AU6ePEl8\nfDw9e/akW7duxMbGkp2dTVlZGStWrCi/X3BwcPnOn6dOnSIuLg7gqnJFRkaSkZFBfHx8+fP8+c9/\nxjAMunbtyvr167Hb7WRnZ7Np06ZKv6+r0a9fP2JjY8s3c3300Uf069evfOWtIkOGDGHnzp2sXbu2\nfDPMli1bePLJJ3E4HHh5edG+ffsLVkGuxdChQ/nqq6/Ki8batWt54403KnxMRb+X3bp1Y8uWLRQW\nFlJYWFhenEpLS5kxYwbp6enA+U2PNpvtgk2aImbQCozIVfD29ua3v/0tc+fOZdmyZcyYMYNTp04x\nduxYLBYLMTExjB49GovFwgsvvMDf/vY3XnnlFTw9PXnppZfw8vKiXbt2+Pn50a9fPz755BPCwsIu\n+1q9evXCYrEwZsyYS2675ZZbSEpKYuzYsRiGQefOnZk5cyZeXl4MHDiQUaNGERgYyF/+8hfi4uKY\nMWMGL7/8cqXeY1hYGK+++iovv/wy//znPzEMA29vbx599NHybyb9+te/ZtKkSfj7+zNy5EgOHz4M\nwLRp05g1axYjR46kY8eO5ass7du3r3QuDw8PXn75ZebMmUN+fj6urq488MADWCwWpk2bRmxsLMOH\nDycsLIzhw4dfsGrwcz/tA3Oxf//737/4M2jcuDH//Oc/uffeeyktLSU8PJw5c+ZU6ufn7e1Np06d\nOHToEF27dgUgKiqKzz77jFGjRuHm5kZAQABPPfUUAA8//HD5N4muRqdOnfj973/PjBkzcDgcBAYG\n8uSTT1b4mIp+L4cMGcLGjRuJiYkhKCiIQYMGERsbi6urK1OmTOH2228Hzq+yPfbYY3h6el5VXpGq\nZjF+viFaROQqxcbG8vDDD7N+/Xqzo4hIPaI1QBEREal1VGBERESk1tEmJBEREal1tAIjIiIitY4K\njIiIiNQ6tfJr1BkZl//aZFXw9/fizJmCant+uXaajXPSXJyXZuO8NJvKCQ72ueJtWoG5iM3mYnYE\nuQLNxjlpLs5Ls3Fems31U4ERERGRWkcFRkRERGodFRgRERGpdVRgREREpNZRgREREZFaRwVGRERE\nah0VGBEREal1VGBERETqmI0b11Xqfi+99DwpKclXvP0vf3moqiJVORUYERGROiQ1NYW1a9dU6r4P\nPDCbsLAmV7z9mWdeqKpYVa5WnkpARERELu+FF+Zy4MA+BgyIYuTI0aSmpvCf/yzg6af/QUZGOoWF\nhdx552/p128As2b9loceepgNG9aRn3+OxMSTJCcncf/9s4mO7sfYscP47LN1zJr1W6KiehMXF0tO\nTg5z575IUFAQ//jH45w+nUpERBfWr1/LJ598XmPvUwVGRESkmixZf4TtB9Mvud7FxYLdblzTc0a1\nD2Ha0DZXvP3mm2ewfPkSWrZsTWLiCRYs+C9nzmTTq1cfRo8eR3JyEo8//hf69RtwwePS09N47rmX\n+eGH71i58n9ER/e74PYGDRrw0kuv8uqr89i0aT1hYeGUlBTzxhsL+fbbzSxZ8uE1vZ9rpQLzM2n5\nmZwsOkVzj6ZmRxEREbluHTp0AsDHx5cDB/axatVyLBYreXm5l9y3S5euAISEhHDu3LlLbo+M7FZ+\ne25uLidPHiciIhKA6Oh+uLjU7PmdVGB+5rXvV5BuTeCejr+nc+NWZscREZFabtrQNpddLQkO9iEj\n42y1v76rqysAX3/9JXl5ecyf/1/y8vL4zW9mXHLfnxcQw7h0deji2w3DwGo9f53FYsFisVR1/App\nJ96f6dgwAoDFe1dedngiIiLOzmq1YrfbL7guJyeH0NAwrFYr33yzntLS0ut+nSZNwjl0aD8A27b9\ncMlrVjcVmJ+5sXsUrgWNOWtNZfPxeLPjiIiIXLXmzVty6NBB8vP/bzPQ4MFD+e67zTzwwD14enoS\nEhLCO++8eV2v07fvAPLz87nnnruIj9+Jr6/f9Ua/KhajFi41VOey27aTx1h45DU8HA15bvhfsFrU\n8ZxFTS25ytXRXJyXZuO86sJs8vJyiYuLZfDgYWRkpPPAA/fwwQf/q9LXCA72ueJt2gfmImN6dGHp\n7pYUNDjOqv2bmdhpkNmRREREnI6XVwPWr1/LBx8swjAc/OEPNXvQOxWYi1gsFm6JGMebh+ezLmU9\no9v1wd3mbnYsERERp2Kz2fjHP5427fW1feQyurVoSnBpRxwuhby/6yuz44iIiMhFVGCu4PaeYzFK\nXdmR8z05RXlmxxEREZGfUYG5gpYhgbSw9gBrGe/s+NTsOCIiIvIzKjAVuKv3KIxiL44UxZOUm2Z2\nHBEREfmRCkwFAn0bEOnVDywG7+xcYXYcERGRKjNlyngKCgpYtGghe/fuvuC2goICpkwZX+HjN25c\nB8Dnn6/mm282VFvOK1GB+QUzeg/GUtCQ046j7E07anYcERGRKjVjxu107tzlqh6TmprC2rVrABgz\nZjyDBg2pjmgV0teof4GXhysDQoax6dz/WLx3JU+HPFjj53sQERGprDvvvJWnnnqexo0bc/p0Ko8+\nOpvg4BAKCwspKiriwQf/TMeOncvv/69//Z3Bg4fRtWs3/vrXhykpKSk/sSPAV199wbJlH+PiYqVF\ni9Y88shfeeGFuRw4sI933nkTh8NBw4YNmTz51yxY8BJ79sRTVmZn8uRpxMSMZdas3xIV1Zu4uFhy\ncnKYO/dFGjdufN3vUwWmEib3iOK7z77lrPdpNp/YxcCW3cyOJCIitcDyI5+yM33PJde7WC3YHdd2\nIPxuIRHc2GbcFW8fOHAI3367icmTp7F58zcMHDiE1q1vYODAwezYsZ3333+Xf/3r2Uset2bNF7Rq\n1Zr775/NunVfla+wFBYW8vzz8/Dx8eG+++7m6NEj3HzzDJYvX8Idd9zNW2+9DsCuXXEcO3aUV199\nm8LCQmbOvImBAwcD0KBBA1566VVefXUemzatZ9q0W67pvf+cNiFVgs3FyviWozEMWHHkc+yOmj1h\nlYiISGWdLzCbAdiy5Rv69x/EN9+s45577uLVV+eRm5t72cedOHGMzp0jAejWrUf59b6+vjz66Gxm\nzfotJ08eJzc357KPP3hwP127dgfA09OTFi1acerUKQAiI8//wz8kJIRz585d9vFXSyswlTSsc3vW\nrG5FgfcxVh3czKSOg82OJCIiTu7GNuMuu1pSnedCatWqNVlZGaSlnebs2bNs3ryRoKAQHn98DgcP\n7ueVV/5z2ccZBlit53eRcPy4OlRaWsoLL/ybhQs/IDAwiIcf/uMVX9disfDzsyuWlZWWP5+Li8vP\nXqdqTsGoFZhKslgs3Nx5LIbdhfXJ6ykqLTI7koiIyGVFR/fnjTcWMGDAIHJzc2jSJByAb77ZQFlZ\n2WUf06xZcw4ePABAXFwsAAUF+bi4uBAYGERa2mkOHjxAWVkZVqsVu/3CrRHt23di584dPz6ugOTk\nJMLDm1XXW1SBuRrdWzUlsLgjDpciPti9xuw4IiIilzVo0BDWrl3D4MHDiIkZy8cfv8+DD95Hp06d\nycrK4rPPVl3ymJiYsezbt4cHHriHU6dOYrFY8PNrSFRUb37zm9t45503ueWWGbz88gs0b96SQ4cO\n8vLLz5c/PjKyK+3atee+++7mwQfv4/e/n4Wnp2e1vUeLUVVrOTWoOk9B/kvLesdOZ/Fc/ItYXOz8\nq/+jNPTwrbYscqG6cPr5ukhzcV6ajfPSbConONjnirdpBeYqtWocSHN6gNXOOzsubbAiIiJS/VRg\nrsFdfUZhFDXgSNEeTuWeNjuOiIhIvaMCcw2C/LzoUn6KgU/MjiMiIlLvqMBcoxm9B0G+P2mO4+xJ\nO2x2HBERkXpFBeYaNfB0ZUDwMADe37uyyr7XLiIiIr9MBeY6TO7ZE5ezoZy1pLPpRJzZcUREROoN\nFZjr4GqzMq5FDIZhYcXRL3SKARERkRqiAnOdhndpj9e5VpRY81h9cJPZcUREROoFFZjrZLVYuKnT\nGAy7C+tS1lNUplMMiIiIVDcVmCrQs01TAoo64rAW88HuL82OIyIiUuepwFSR23uOwShxZ0f2Vs4U\nXf5U5SIiIlI1VGCqSJvQQJoZ508xsDBupdlxRERE6jQVmCp0R/RwjMIGHCncy6ncFLPjiIiI1Fkq\nMFWoUUNvOnv2Awu8s2uF2XFERETqLBWYKjajz0A4F0Ca/QS70xLMjiMiIlInVWuBSUhIYPjw4Sxe\nvBiA0tJSZs+ezZQpU5g5cya5ued3dl21ahWTJ09m6tSpLF26tDojVTsfLzf6BQ0F4IN9OsWAiIhI\ndai2AlNQUMCcOXOIjo4uv27JkiX4+/uzbNkyxowZQ2xsLAUFBcyfP5+FCxeyaNEi3n33XXJycqor\nVo2Y2qsHLnlhnCWDTSd3mB1HRESkzqm2AuPm5sabb75JSEhI+XUbNmzgV7/6FQC//vWvGTZsGPHx\n8URERODj44OHhwfdu3cnLq52n1fI1ebCmBajMBwWVhz5gjJHmdmRRERE6pRqKzA2mw0PD48LrktO\nTmbTpk3MmDGDBx98kJycHDIzMwkICCi/T0BAABkZGdUVq8aM7NIez7OtKbGeZfWhb8yOIyIiUqfY\navLFDMOgZcuWzJo1iwULFvD666/TsWPHS+7zS/z9vbDZXKorJsHBPlXyPL+JnsS83S+yIXkj0/uM\nwsvNs0qetz6rqtlI1dJcnJdm47w0m+tTowUmKCiIqKgoAPr378+8efMYPHgwmZmZ5fdJT0+na9eu\nFT7PmTMF1ZYxONiHjIyzVfJc7RsF4V/YkRyf3czbsJQ7u0+qkuetr6pyNlJ1NBfnpdk4L82mcioq\neTX6NeqBAweyefNmAPbt20fLli2JjIxkz5495OXlkZ+fT1xcHD179qzJWNXGYrEws+doHMUe7Mje\nSlbhGbMjiYiI1AnVtgKzd+9e5s6dS3JyMjabjTVr1vDcc8/xr3/9i2XLluHl5cXcuXPx8PBg9uzZ\n3HXXXVgsFu677z58fOrOslrbJoE029WdJOt3vLdrFQ9GzzQ7koiISK1nMWrhgUqqc9mtOpb1Tp/J\n58lvX8DqeZZHev6RZn5hVfr89YWWXJ2T5uK8NBvnpdlUjtNsQqqvGvs3oLN7X7DAwvhPzI4jIiJS\n66nA1JDpfftjnA0krewku9MOmh1HRESkVlOBqSF+DdzpG/jTKQZW4TAcJicSERGpvVRgatDUXt2x\n5jThLJlsOhlrdhwREZFaSwWmBrm7uTC6+UgMh4WVR7+kVKcYEBERuSYqMDVsVLd2eOS1ocRyjk8P\nbTQ7joiISK2kAlPDXKxWpnYchVFmY33yRgpKq++owiIiInWVCowJ+rRrSsP8TjisJXy090uz44iI\niNQ6KjAmsFgs3NYz5sdTDGwjqzDb7EgiIiK1igqMSdo3DSS8rAdYHLy7a5XZcURERGoVFRgT3RE9\nDEe+D0cL9nMi55TZcURERGoNFRgThQV509G9H1jg3d0rzY4jIiJSa6jAmOy2vv0w8oJJL0skPu2A\n2XFERERqBRUYk/l5uxMdMAjDgA/36xQDIiIilaEC4wSm9O6ONSecs0YWm05uNzuOiIiI01OBcQKe\n7jZimo/AcFhZefRLSuylZkcSERFxaiowTiKmWzvcc1pTYsnn04QNZscRERFxaiowTsLmYmVKx1EY\nZa5sSPmGc6X5ZkcSERFxWiowTqRvh6b4neuEw1LKx3u/MDuOiIiI01KBcSIWi4XpPUbgKPIkLjuW\njIJMsyOJiIg4JRUYJ9OpeTBhpd3B4mDRbp1iQERE5HJUYJzQHdFDceT7crTgIMdzEs2OIyIi4nRU\nYJxQeIgP7V37AvDu7k8wDMPkRCIiIs5FBcZJ3davH0ZuMBllyexK3292HBEREaeiAuOk/H3c6e0/\nGMOAj/avwu6wmx1JRETEaajAOLGpfbphPdOMc8YZvkncanYcERERp6EC48S8PGyMaDoMw25l9dGv\nKLaXmB1JRETEKajAOLkxPdrhltOGEksBnyasNzuOiIiIU1CBcXKuNis3th+BUerGxpTNnC05Z3Yk\nERER06nA1AL9OzfDJ+/8KQaW7NMpBkRERFRgagGrxcL0nsNxFHkRlx1LWn6G2ZFERERMpQJTS0S0\nDCa0uDtYDBbv0SkGRESkflOBqUVmRg/Gcc6PYwWHOJpzwuw4IiIiplGBqUWaN/alrcv5Uwws2rNC\npxgQEZF6SwWmlpnRvw+OM43IKE1hZ9pes+OIiIiYQgWmlgny86SX/0AMw8JHB1brFAMiIlIvqcDU\nQlOju2LJaka+kcPGxB/MjiMiIlLjVGBqIW9PV4Y3HYJhd2H1sa8oKis2O5KIiEiNUoGppcZFtcM1\nuw2lFPLpYZ1iQERE6hcVmFrK1ebCpA7DMUrc+CZlM7nFZ82OJCIiUmNUYGqxgZ2b4Z3XCYeljKUH\nPjc7joiISI1RganFrFYLt3QfjqOwATuz4jidn252JBERkRqhAlPLRbYOolFRN7AYvL9XpxgQEZH6\nQQWmlrNYLNwWPQj7WX+O5Sdw+MwxsyOJiIhUOxWYOqBVmB9trX0AWLx3pU4xICIidZ4KTB0xfUAf\nHNmNySxNZUfabrPjiIiIVCsVmDoipKEnPf0GYDgsLDn4qU4xICIidZoKTB0ytV8kZDUj35HLhsTv\nzI4jIiJSbVRg6hBfLzeGhp8/xcCnx76msKzI7EgiIiLVQgWmjhkf1Q5b1g2UUsSnh9eZHUdERKRa\nqMDUMe5uLkxoNxSjxJ1NKVs4U5RjdiQREZEqpwJTBw2ObIZXTiccFjvz4t7W2apFRKTOUYGpg1ys\nVmb0HEZZejhpRad5I36RvpUkIiJ1igpMHRXZJpgxTcdizwniUG4CHx1coQPciYhInaECU4f9qm8r\nenjE4Mj34bvTW/n65EazI4mIiFQJFZg6zGKxcMeozjQvHIqj2IOVx75gR9ous2OJiIhcNxWYOs7m\nYuX+X/WmYXp/jDIbC/d9xJGc42bHEhERuS4qMPWAl4eN2RMH4JoUhd1hsGDnO6Tlp5sdS0RE5Jqp\nwNQTQX6ePDhmGMapCIqNIl6K+y9nS86ZHUtEROSaqMDUIy0a+/K7/jGUJbcmtzSHeXFvUWIvMTuW\niIjIVVOBqWe63hDElPajKcsII7kgmf/ueR+H4TA7loiIyFVRgamHRkQ1Y2BgDPbcAPZlH2Bpwiqz\nI4mIiFwVFZh66uah7WjvGI6jwJtNyd+xPnGT2ZFEREQqrVoLTEJCAsOHD2fx4sUXXL9582batWtX\nfnnVqlVMnjyZqVOnsnTp0uqMJD+yWi3cM74bjXIGYZS4878jn7IzfY/ZsURERCql2gpMQUEBc+bM\nITo6+oLri4uLeeONNwgODi5f63c1AAAgAElEQVS/3/z581m4cCGLFi3i3XffJSdHZ1CuCe5uLjw4\nKRrP5GgMuwvv7P2AY7knzY4lIiLyi6qtwLi5ufHmm28SEhJywfWvvfYat9xyC25ubgDEx8cTERGB\nj48PHh4edO/enbi4uOqKJRfxa+DGQxMGYTnZgzLDwfydb5NekGl2LBERkQrZqu2JbTZstguf/vjx\n4xw8eJAHHniAZ599FoDMzEwCAgLK7xMQEEBGRkaFz+3v74XN5lL1oX8UHOxTbc/tjIKDffirbRxP\nLi+gqMVe5se/xTOj/oKvu7fZ0S5R32ZTW2guzkuzcV6azfWptgJzOU8//TSPPfZYhfepzBmTz5wp\nqKpIlwgO9iEj42y1Pb+zCmvowW1RI3g3voDMsGPMWTuPP/b4HW4urmZHK1dfZ+PsNBfnpdk4L82m\ncioqeTX2LaS0tDSOHTvGn/70J6ZNm0Z6ejrTp08nJCSEzMz/22SRnp5+yWYnqRn9IkIZ3WwEZVmh\nnDyXyMJ9H+kYMSIi4pRqrMA0atSItWvXsmTJEpYsWUJISAiLFy8mMjKSPXv2kJeXR35+PnFxcfTs\n2bOmYslFJg5oRXeP4djz/InP3MOKI5+bHUlEROQS1bYJae/evcydO5fk5GRsNhtr1qxh3rx5NGzY\n8IL7eXh4MHv2bO666y4sFgv33XcfPj7aLmgWi8XCnaM78dySfBJd17Du1CYCPQMYFN7X7GgiIiLl\nLEZldjpxMtW53VDbJc/LLyplzoebyAvbgMW1lN93mUlEUEdTM2k2zklzcV6ajfPSbCrHKfaBkdql\ngYcrD03qi+1kbwy7lf/ueZ+TeafMjiUiIgKowEgFQhp68sC4gThOdKXUUcorO98mszDb7FgiIiIq\nMFKx1mF+3D1wCGUnO1Bgz2fezv9SUFp9X2MXERGpDBUY+UU92oUwufMwSlNbkFmUyavx71LqKDM7\nloiI1GMqMFIpI6Oa0j94KPbsRhzLO857+z/WMWJERMQ0KjBSKRaLhVuHt6WtMQT72YbEpcez+uga\ns2OJiEg9pQIjleZitXLvhC6E5AzAUeTFV4kb2JL8g9mxRESkHlKBkavi4WbjwRt74ZEUjVHqykeH\nPmFf1kGzY4mISD2jAiNXzd/HndkT+8HxKBwOC2/uXsSps8lmxxIRkXpEBUauSXiIN/eOGkDZscgf\njxHzFtlFZ8yOJSIi9YQKjFyzzi0Dmd57ECWJ7TlXdo5Xdr5FQWmh2bFERKQeUIGR6zIwMoxRLQdS\ndro5aYXpvLHnPcp0jBgREalmKjBy3W4c1JquDQZgzw7hcM5R3j+4jFp4jlAREalFVGDkulktFn4z\nthPhxQNwnPNj2+k4Pj/+tdmxRESkDlOBkSrhanPhgUnd8Envh6PIk89PrOX71FizY4mISB2lAiNV\nxsfLjdk39sJ2sg9GmSsfHFjGwezDZscSEZE6SAVGqlSjAC/uHx+N/WgP7A54Y/d7JJ9LNTuWiIjU\nMSowUuVuCG/IXYP7UXosgmJHMa/sfIuc4lyzY4mISB2iAiPVoleHRkyM6EdpYlvySvOYv+ttCsuK\nzI4lIiJ1xDUXmBMnTlRhDKmLxvRpTnSjfpSlNSUlP5X/7lmM3WE3O5aIiNQBFRaYO+6444LLCxYs\nKP//J554onoSSZ1hsViYMbIdN1j7Yc8J5uCZBD46tFzHiBERketWYYEpK7vwiKo//PBD+f/rLyGp\nDJuLlfsmdiE4py+OfF++S93OmpMbzI4lIiK1XIUFxmKxXHD556Xl4ttErsTT3caDU3rgkdwHo9iD\n1ce+ZNvpOLNjiYhILXZV+8CotMi1CvD14I8Te2Mc64VRZmPR/iUknDlqdiwREamlbBXdmJuby/ff\nf19+OS8vjx9++AHDMMjLy6v2cFK3NG/swz0xfZi3phBL21he3/0uf+p5H6ENGpkdTUREapkKC4yv\nr+8FO+76+Pgwf/788v8XuVpdWgdxc59oPtxRDK13M3/XW/y55x/wc9fvk4iIVF6FBWbRokU1lUPq\nkaHdw8nI6c26pELOhB/m1fi3+WP33+Nhczc7moiI1BIV7gNz7tw5Fi5cWH75o48+YsKECdx///1k\nZmZWdzapw6YOaUMXn96UpYdz6lwy7+z7QMeIERGRSquwwDzxxBNkZWUBcPz4cV544QUeeeQR+vbt\ny7/+9a8aCSh1k9Vi4bfjOhFe0gd7biB7sw6w9PAqfT1fREQqpcICc+rUKWbPng3AmjVriImJoW/f\nvtx0001agZHr5ubqwgOTu+KT3gdHgQ+bk79nbeI3ZscSEZFaoMIC4+XlVf7/27Zto0+fPuWX9ZVq\nqQq+Ddx4aEpPXE72wihxZ8XRz9mRFm92LBERcXIVFhi73U5WVhaJiYns3LmTfv36AZCfn09hYWGN\nBJS6LzSwAX8Y34uywz3BbuPd/R9xJOe42bFERMSJVVhg7r77bsaMGcP48eO599578fPzo6ioiFtu\nuYWJEyfWVEapB9o18+eOIb0pPtwVu8PBa/ELSctPNzuWiIg4KYvxC3tNlpaWUlxcjLe3d/l1W7Zs\noX///tUe7koyMs5W23MHB/tU6/NLxVZ9e5zVBzbj1movgR4B/LnnLHzczv/uaTbOSXNxXpqN89Js\nKic4+MrHCKtwBSYlJYWMjAzy8vJISUkp/69Vq1akpKRUeVCR8X1b0Ce0J6XJrckqyua1+HcosZeY\nHUtERJxMhQeyGzp0KC1btiQ4OBi49GSO7733XvWmk3rHYrEwM6Y9WUuKOJpZyAlOsXDfh/wmYobZ\n0URExIlUWGDmzp3LypUryc/PZ+zYsYwbN46AgICayib1lM3FyqxJEfxrcTFZrt8Qzz6WH/6Ue0Ju\nNTuaiIg4iV/cBwYgNTWVTz75hNWrV9OkSRMmTJjAiBEj8PDwqImMl9A+MPVDZk4hc97/gZLmm7F6\nnWNa5/EMDO6vr/A7GX1mnJdm47w0m8qpaB+YShWYn1u6dCnPPfccdrud2NjY6w53LVRg6o/jqXnM\nXfIt1nbfY3EromtwBDM6TMXDZk55lkvpM+O8NBvnpdlUTkUFpsJNSD/Jy8tj1apVLF++HLvdzu9+\n9zvGjRtXZQFFrqRlqC+/G92TV1aD+w3x7GIPqflp/DZiBo0bNDI7noiImKTCFZgtW7bwv//9j717\n9zJy5EgmTJhA27ZtazLfZWkFpv6JS8jgrc/2URqyH9fQE7i7uDGjw6/pFhJhdrR6T58Z56XZOC/N\npnKueRNS+/btadGiBZGRkVitl37j+umnn66ahFdJBaZ+KnLAnLd+IN04inurfRjWMoY3G8SvWsXg\nYnUxO169pc+M89JsnJdmUznXvAnpp69JnzlzBn9//wtuS0pKqoJoIpXXtJEPj93Wk7c/a0DcPm88\n2+5ibeI3JOYlcWfnW8sPeCciInVfhQeys1qtzJ49m8cff5wnnniCRo0a0atXLxISEvjPf/5TUxlF\nynm627h3Umcm9+5K4b4+OM40IiHnKM9sf4njuYlmxxMRkRpS4QrMiy++yMKFC2ndujXr1q3jiSee\nwOFw4Ofnx9KlS2sqo8gFLBYLY/o0p3ljH15b6UnxuQRywg/zYtyrTG07gf5hvfVVaxGROu4XV2Ba\nt24NwLBhw0hOTua2227jlVdeoVEjfQNEzNWpRQB/uz2KJkYkxYd64Chz4aNDy1l8YCkl9lKz44mI\nSDWqsMBc/K/Y0NBQRowYUa2BRK5GkJ8n/296d/o2j6BwTzQU+PHD6Vhe2DGfzMJss+OJiEg1qbDA\nXEzL8uKMXG0u3DGmPTOGdKXkQG/KMsI5dS6FudtfZn/WIbPjiYhINahwH5idO3cyePDg8stZWVkM\nHjwYwzCwWCxs3LixmuOJVI7FYmFwtyY0DfFmwQpP8s75YWlxgAXxbzO25UhGtRiC1XJVfV1ERJxY\nhQXmyy+/rKkcIlWidRM/nrg9itdWeJKw3xfPtrv49PgaTp5N5LYON+Hl6ml2RBERqQIVFpgmTZrU\nVA6RKuPXwI3ZN3Vl2UYfvtrpiccNu9nDAf4d+zJ3R9xGE+9QsyOKiMh10pq61Ek2Fys3DbuB343p\nhuNIFKUprcgozOLZ2FfYfnqn2fFEROQ6qcBInda7YyMemxFFQH4kxQndKCuDhfs/ZGnCSuwOu9nx\nRETkGqnASJ0XHuLNEzN7EhHYkcK9fbAU+7Ax6Vv+s/N1covzzI4nIiLXQAVG6gUvD1f+MKULE3p2\npnBPbxzZoRzLPcEz21/iSM5xs+OJiMhVUoGResNqsfCr/i15YHJ3rKe6U3KyPXnF53hp5+tsOLWF\nCk7MLiIiTkYFRuqdLq2D+NvtUYQ6OlF8MArK3Fh2eBUL939Isb3E7HgiIlIJKjBSL4X4e/HXGT3p\n1bQD+bv7YCnwJzZtF8/FvkJ6QYbZ8URE5BeowEi95e7mwt3jO3LzwAiK9vfCntaclPzTzN3+Mnsy\n95sdT0REKqACI/WaxWJhRFRT/nxTdzwyIyk52oXisjJe272Q1cfW4DAcZkcUEZHLUIERAdo18+dv\nt0fRwr09hXt7Yy1twJcn1rEg/m3OleabHU9ERC6iAiPyI38fdx65tTuDO5zfL4a8EA5kJzB3+8sk\n5iWZHU9ERH5GBUbkZ2wuVmaMbMedo7pQergHpUltyC46w/NxC/guZbvZ8URE5EfVWmASEhIYPnw4\nixcvBiA1NZXbb7+d6dOnc/vtt5ORcf7bHqtWrWLy5MlMnTqVpUuXVmckkUrp3yWUv87oid+5zhQf\n6oGjzMr7B5fywcH/UeooMzueiEi9V20FpqCggDlz5hAdHV1+3X/+8x+mTZvG4sWLGTFiBO+88w4F\nBQXMnz+fhQsXsmjRIt59911ycnKqK5ZIpTVv7MPf7oiig39bCvb0wVrkx7cpW3lxx6ucKdLvqIiI\nmaqtwLi5ufHmm28SEhJSft3f/vY3Ro0aBYC/vz85OTnEx8cTERGBj48PHh4edO/enbi4uOqKJXJV\nvD1deXBaV8Z070D+3l44sppw8uwpntn+Eoeyj5gdT0Sk3rJV2xPbbNhsFz69l5cXAHa7nQ8++ID7\n7ruPzMxMAgICyu8TEBBQvmnpSvz9vbDZXKo+9I+Cg32q7bnl+pg1m99P6UpkuxBe/NCNkrN+5Lc4\nyLxdb3JLl4n8qv0ILBaLKbmchT4zzkuzcV6azfWptgJzJXa7nYcffpg+ffoQHR3N6tWrL7i9Muej\nOXOmoLriERzsQ0bG2Wp7frl2Zs+mTWMfHrutJ68sdydtvw9e7Xbz/u5P2Jd6mOkdpuFp8zAtm5nM\nnotcmWbjvDSbyqmo5NX4t5AeffRRmjdvzqxZswAICQkhMzOz/Pb09PQLNjuJOJPQwAY8dltPujVp\ny7n4PljyA9mVsZdnY+dxOj/N7HgiIvVGjRaYVatW4erqyv33319+XWRkJHv27CEvL4/8/Hzi4uLo\n2bNnTcYSuSqe7jbundiZqf07Uri/B/bTLUkryODfsfOIS99tdjwRkXqh2jYh7d27l7lz55KcnIzN\nZmPNmjVkZWXh7u7OjBkzAGjdujV///vfmT17NnfddRcWi4X77rsPHx9tFxTnZrFYGN2nOc0a+/D6\nSncKzvphbbOXt/Yu5kSzgUxoNRoXa/XtpyUiUt9ZjMrsdOJkqnO7obZLOi9nnU1mbiHzP9lLYk4q\nDTrswu56jhsatuKuztPxcfM2O161c9a5iGbjzDSbynGqfWBE6pogP0/+3/Tu9LvhBs7F94HcxhzO\nOcYz21/ieO5Js+OJiNRJKjAiVcDV5sIdY9pz24hOlBzuSumptuQU5/Fi3GtsSvq+Ut+uExGRylOB\nEakiFouFwd2a8Jdbe+BzrgPFB3uC3cbHCZ+w6MASSuylZkcUEakzVGBEqljrJn48cXsUN/i1Jn93\n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\n",
+ "text/plain": [
+ "
"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ }
+ }
+ ]
+ },
+ {
+ "metadata": {
+ "id": "ZTDHHM61NPTw",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "### Solution\n",
+ "\n",
+ "Click below for a solution."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "JQHnUhL_NRwA",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "You may be wondering how to determine how many buckets to use. That is of course data-dependent. Here, we just selected arbitrary values so as to obtain a not-too-large model."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "Ro5civQ3Ngh_",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def construct_feature_columns():\n",
+ " \"\"\"Construct the TensorFlow Feature Columns.\n",
+ "\n",
+ " Returns:\n",
+ " A set of feature columns\n",
+ " \"\"\" \n",
+ " households = tf.feature_column.numeric_column(\"households\")\n",
+ " longitude = tf.feature_column.numeric_column(\"longitude\")\n",
+ " latitude = tf.feature_column.numeric_column(\"latitude\")\n",
+ " housing_median_age = tf.feature_column.numeric_column(\"housing_median_age\")\n",
+ " median_income = tf.feature_column.numeric_column(\"median_income\")\n",
+ " rooms_per_person = tf.feature_column.numeric_column(\"rooms_per_person\")\n",
+ " \n",
+ " # Divide households into 7 buckets.\n",
+ " bucketized_households = tf.feature_column.bucketized_column(\n",
+ " households, boundaries=get_quantile_based_boundaries(\n",
+ " training_examples[\"households\"], 7))\n",
+ "\n",
+ " # Divide longitude into 10 buckets.\n",
+ " bucketized_longitude = tf.feature_column.bucketized_column(\n",
+ " longitude, boundaries=get_quantile_based_boundaries(\n",
+ " training_examples[\"longitude\"], 10))\n",
+ " \n",
+ " # Divide latitude into 10 buckets.\n",
+ " bucketized_latitude = tf.feature_column.bucketized_column(\n",
+ " latitude, boundaries=get_quantile_based_boundaries(\n",
+ " training_examples[\"latitude\"], 10))\n",
+ "\n",
+ " # Divide housing_median_age into 7 buckets.\n",
+ " bucketized_housing_median_age = tf.feature_column.bucketized_column(\n",
+ " housing_median_age, boundaries=get_quantile_based_boundaries(\n",
+ " training_examples[\"housing_median_age\"], 7))\n",
+ " \n",
+ " # Divide median_income into 7 buckets.\n",
+ " bucketized_median_income = tf.feature_column.bucketized_column(\n",
+ " median_income, boundaries=get_quantile_based_boundaries(\n",
+ " training_examples[\"median_income\"], 7))\n",
+ " \n",
+ " # Divide rooms_per_person into 7 buckets.\n",
+ " bucketized_rooms_per_person = tf.feature_column.bucketized_column(\n",
+ " rooms_per_person, boundaries=get_quantile_based_boundaries(\n",
+ " training_examples[\"rooms_per_person\"], 7))\n",
+ " \n",
+ " feature_columns = set([\n",
+ " bucketized_longitude,\n",
+ " bucketized_latitude,\n",
+ " bucketized_housing_median_age,\n",
+ " bucketized_households,\n",
+ " bucketized_median_income,\n",
+ " bucketized_rooms_per_person])\n",
+ " \n",
+ " return feature_columns"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "RNgfYk6OO8Sy",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "_ = train_model(\n",
+ " learning_rate=1.0,\n",
+ " steps=500,\n",
+ " batch_size=100,\n",
+ " feature_columns=construct_feature_columns(),\n",
+ " training_examples=training_examples,\n",
+ " training_targets=training_targets,\n",
+ " validation_examples=validation_examples,\n",
+ " validation_targets=validation_targets)"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "AFJ1qoZPlQcs",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## Feature Crosses\n",
+ "\n",
+ "Crossing two (or more) features is a clever way to learn non-linear relations using a linear model. In our problem, if we just use the feature `latitude` for learning, the model might learn that city blocks at a particular latitude (or within a particular range of latitudes since we have bucketized it) are more likely to be expensive than others. Similarly for the feature `longitude`. However, if we cross `longitude` by `latitude`, the crossed feature represents a well defined city block. If the model learns that certain city blocks (within range of latitudes and longitudes) are more likely to be more expensive than others, it is a stronger signal than two features considered individually.\n",
+ "\n",
+ "Currently, the feature columns API only supports discrete features for crosses. To cross two continuous values, like `latitude` or `longitude`, we can bucketize them.\n",
+ "\n",
+ "If we cross the `latitude` and `longitude` features (supposing, for example, that `longitude` was bucketized into `2` buckets, while `latitude` has `3` buckets), we actually get six crossed binary features. Each of these features will get its own separate weight when we train the model."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "-Rk0c1oTYaVH",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## Task 2: Train the Model Using Feature Crosses\n",
+ "\n",
+ "**Add a feature cross of `longitude` and `latitude` to your model, train it, and determine whether the results improve.**\n",
+ "\n",
+ "Refer to the TensorFlow API docs for [`crossed_column()`](https://www.tensorflow.org/api_docs/python/tf/feature_column/crossed_column) to build the feature column for your cross. Use a `hash_bucket_size` of `1000`."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "-eYiVEGeYhUi",
+ "colab_type": "code",
+ "cellView": "both",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def construct_feature_columns():\n",
+ " \"\"\"Construct the TensorFlow Feature Columns.\n",
+ "\n",
+ " Returns:\n",
+ " A set of feature columns\n",
+ " \"\"\" \n",
+ " households = tf.feature_column.numeric_column(\"households\")\n",
+ " longitude = tf.feature_column.numeric_column(\"longitude\")\n",
+ " latitude = tf.feature_column.numeric_column(\"latitude\")\n",
+ " housing_median_age = tf.feature_column.numeric_column(\"housing_median_age\")\n",
+ " median_income = tf.feature_column.numeric_column(\"median_income\")\n",
+ " rooms_per_person = tf.feature_column.numeric_column(\"rooms_per_person\")\n",
+ " \n",
+ " # Divide households into 7 buckets.\n",
+ " bucketized_households = tf.feature_column.bucketized_column(\n",
+ " households, boundaries=get_quantile_based_boundaries(\n",
+ " training_examples[\"households\"], 7))\n",
+ "\n",
+ " # Divide longitude into 10 buckets.\n",
+ " bucketized_longitude = tf.feature_column.bucketized_column(\n",
+ " longitude, boundaries=get_quantile_based_boundaries(\n",
+ " training_examples[\"longitude\"], 10))\n",
+ " \n",
+ " # Divide latitude into 10 buckets.\n",
+ " bucketized_latitude = tf.feature_column.bucketized_column(\n",
+ " latitude, boundaries=get_quantile_based_boundaries(\n",
+ " training_examples[\"latitude\"], 10))\n",
+ "\n",
+ " # Divide housing_median_age into 7 buckets.\n",
+ " bucketized_housing_median_age = tf.feature_column.bucketized_column(\n",
+ " housing_median_age, boundaries=get_quantile_based_boundaries(\n",
+ " training_examples[\"housing_median_age\"], 7))\n",
+ " \n",
+ " # Divide median_income into 7 buckets.\n",
+ " bucketized_median_income = tf.feature_column.bucketized_column(\n",
+ " median_income, boundaries=get_quantile_based_boundaries(\n",
+ " training_examples[\"median_income\"], 7))\n",
+ " \n",
+ " # Divide rooms_per_person into 7 buckets.\n",
+ " bucketized_rooms_per_person = tf.feature_column.bucketized_column(\n",
+ " rooms_per_person, boundaries=get_quantile_based_boundaries(\n",
+ " training_examples[\"rooms_per_person\"], 7))\n",
+ " \n",
+ " # YOUR CODE HERE: Make a feature column for the long_x_lat feature cross\n",
+ " long_x_lat = tf.feature_column.crossed_column([bucketized_longitude, bucketized_latitude], 1000)\n",
+ " \n",
+ " feature_columns = set([\n",
+ " bucketized_longitude,\n",
+ " bucketized_latitude,\n",
+ " bucketized_housing_median_age,\n",
+ " bucketized_households,\n",
+ " bucketized_median_income,\n",
+ " bucketized_rooms_per_person,\n",
+ " long_x_lat])\n",
+ " \n",
+ " return feature_columns"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "xZuZMp3EShkM",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 640
+ },
+ "outputId": "b4f97380-8835-4641-bcb8-b6abc11c76b6"
+ },
+ "cell_type": "code",
+ "source": [
+ "_ = train_model(\n",
+ " learning_rate=1.0,\n",
+ " steps=500,\n",
+ " batch_size=100,\n",
+ " feature_columns=construct_feature_columns(),\n",
+ " training_examples=training_examples,\n",
+ " training_targets=training_targets,\n",
+ " validation_examples=validation_examples,\n",
+ " validation_targets=validation_targets)"
+ ],
+ "execution_count": 33,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Training model...\n",
+ "RMSE (on training data):\n",
+ " period 00 : 163.60\n",
+ " period 01 : 135.47\n",
+ " period 02 : 118.48\n",
+ " period 03 : 107.22\n",
+ " period 04 : 99.25\n",
+ " period 05 : 93.33\n",
+ " period 06 : 88.78\n",
+ " period 07 : 85.17\n",
+ " period 08 : 82.21\n",
+ " period 09 : 79.75\n",
+ "Model training finished.\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "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\nvn37NnJIIiIikoM29AjM/v37OXToEPfeey/RaJTHHnsMj8fDI488QjweZ+fOnezZs2cjhyQiIiI5\naEMLjM1m43vf+947Hn/uuec2chgiIiKS44x1XWARERGRdVCBERERkZyjAiMiIiI5RwVGREREco4K\njIiIiOQcFRgRERHJOSowIiIiknNUYERERCTnqMCIiIhIzlGBERERkZxjSiQSiWwPQkRERCQTOgIj\nIiIiOUcFRkRERHKOCoyIiIjkHBUYERERyTkqMCIiIpJzVGBEREQk56jArPLtb3+b/fv3c/fdd9PZ\n2Znt4cgqTzzxBPv37+euu+7itddey/ZwZJWFhQVuvfVWXnrppWwPRVb51a9+xcc//nHuvPNOjh07\nlu3hCBCJRPjiF7/IgQMHuPvuu3njjTeyPaScZs32AIzib3/7GwMDAxw9epTz589z6NAhjh49mu1h\nCfDmm2/S09PD0aNHCQQCfOITn+AjH/lItoclKU8//TSlpaXZHoasEggEeOqpp3jxxReZm5vjBz/4\nAR/60IeyPayr3ssvv0xTUxMHDx5kfHyc++67j1dffTXbw8pZKjApx48f59ZbbwWgpaWFYDDI7Ows\ndrs9yyOT66+/no6ODgBKSkqYn58nFothsViyPDI5f/48vb29+uVoMMePH+eGG27Abrdjt9v55je/\nme0hCeByueju7gYgFArhcrmyPKLcpiWkFL/fv2YylZWVMTk5mcURyUUWi4Xi4mIAXnjhBW666SaV\nF4M4fPgwDz30ULaHIZcYGhpiYWGBL3zhC9xzzz0cP34820MS4Pbbb2dkZITbbruNe++9lwcffDDb\nQ8ppOgLzLnSHBeP54x//yAsvvMBPf/rTbA9FgF/+8pfs2rWL+vr6bA9F/oWZmRmefPJJRkZG+Nzn\nPsef//xnTCZTtod1VXvllVeoqanhmWee4ezZsxw6dEh7x94HFZiUiooK/H5/+t8nJibweDxZHJGs\n9sYbb/DDH/6Qn/zkJzgcjmwPR4Bjx44xODjIsWPHGBsbIz8/n6qqKvbs2ZPtoV31ysvL2b17N1ar\nFa/Xi81mY3p6mvLy8mwP7ap24sQJ9u7dC8CWLVuYmJjQcvj7oCWklBtvvJHf//73AHR1dVFRUaH9\nLwYRDod54okn+NGPfoTT6cz2cCTlu9/9Li+++CI///nP+dSnPsX999+v8mIQe/fu5c033yQejxMI\nBJibm9N+CwNoaGjg1KlTAAwPD2Oz2VRe3gcdgUm55ppr2LZtG3fffTcmk4lHH30020OSlN/+9rcE\nAgG+9KUvpR87fPgwNTU1WRyViHFVVlby0Y9+lE9/+tMAfP3rX8ds1v+vZtv+/fs5dOgQ9957L9Fo\nlMceeyzbQ8pppoQ2e4iIiEiOUSUXERGRnKMCIyIiIjlHBUZERERyjgqMiIiI5BwVGBEREck5KjAi\nclkNDQ2xfft2Dhw4kL4L78GDBwmFQut+jQMHDhCLxdb9/M985jP89a9//U+GKyI5QgVGRC67srIy\njhw5wpEjR3j++eepqKjg6aefXvfPHzlyRBf8EpE1dCE7Edlw119/PUePHuXs2bMcPnyYaDTK8vIy\njzzyCO3t7Rw4cIAtW7Zw5swZnn32Wdrb2+nq6mJpaYmHH36YsbExotEod9xxB/fccw/z8/N8+ctf\nJhAI0NDQwOLiIgDj4+N85StfAWBhYYH9+/fzyU9+MptvXUQ+ICowIrKhYrEYf/jDH7j22mv56le/\nylNPPYXX633Hze2Ki4v52c9+tuZnjxw5QklJCd/5zndYWFjgYx/7GPv27eMvf/kLhYWFHD16lImJ\nCW655RYAfve739Hc3Mzjjz/O4uIiv/jFLzb8/YrI5aECIyKX3fT0NAcOHAAgHo9z3XXXcdddd/H9\n73+fr33ta+nnzc7OEo/HgeTtPS516tQp7rzzTgAKCwvZvn07XV1dnDt3jmuvvRZI3pi1ubkZgH37\n9vHcc8/x0EMPcfPNN7N///7L+j5FZOOowIjIZXdxD8xq4XCYvLy8dzx+UV5e3jseM5lMa/49kUhg\nMplIJBJr7vVzsQS1tLTwm9/8hr///e+8+uqrPPvsszz//PPv9+2IiAFoE6+IZIXD4aCuro7XX38d\ngP7+fp588sn3/JmdO3fyxhtvADA3N0dXVxfbtm2jpaWFkydPAjA6Okp/fz8Av/71r3n77bfZs2cP\njz76KKOjo0Sj0cv4rkRko+gIjIhkzeHDh/nWt77Fj3/8Y6LRKA899NB7Pv/AgQM8/PDDfPazn2Vp\naYn777+furo67rjjDv70pz9xzz33UFdXx44dOwBobW3l0UcfJT8/n0Qiwec//3msVv21J3Il0N2o\nRUREJOdoCUlERERyjgqMiIiI5BwVGBEREck5KjAiIiKSc1RgREREJOeowIiIiEjOUYERERGRnKMC\nIyIiIjnn/wOrfpbT0cmDEwAAAABJRU5ErkJggg==\n",
+ "text/plain": [
+ "
"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ }
+ }
+ ]
+ },
+ {
+ "metadata": {
+ "id": "0i7vGo9PTaZl",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "### Solution\n",
+ "\n",
+ "Click below for the solution."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "3tAWu8qSTe2v",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def construct_feature_columns():\n",
+ " \"\"\"Construct the TensorFlow Feature Columns.\n",
+ "\n",
+ " Returns:\n",
+ " A set of feature columns\n",
+ " \"\"\" \n",
+ " households = tf.feature_column.numeric_column(\"households\")\n",
+ " longitude = tf.feature_column.numeric_column(\"longitude\")\n",
+ " latitude = tf.feature_column.numeric_column(\"latitude\")\n",
+ " housing_median_age = tf.feature_column.numeric_column(\"housing_median_age\")\n",
+ " median_income = tf.feature_column.numeric_column(\"median_income\")\n",
+ " rooms_per_person = tf.feature_column.numeric_column(\"rooms_per_person\")\n",
+ " \n",
+ " # Divide households into 7 buckets.\n",
+ " bucketized_households = tf.feature_column.bucketized_column(\n",
+ " households, boundaries=get_quantile_based_boundaries(\n",
+ " training_examples[\"households\"], 7))\n",
+ "\n",
+ " # Divide longitude into 10 buckets.\n",
+ " bucketized_longitude = tf.feature_column.bucketized_column(\n",
+ " longitude, boundaries=get_quantile_based_boundaries(\n",
+ " training_examples[\"longitude\"], 10))\n",
+ " \n",
+ " # Divide latitude into 10 buckets.\n",
+ " bucketized_latitude = tf.feature_column.bucketized_column(\n",
+ " latitude, boundaries=get_quantile_based_boundaries(\n",
+ " training_examples[\"latitude\"], 10))\n",
+ "\n",
+ " # Divide housing_median_age into 7 buckets.\n",
+ " bucketized_housing_median_age = tf.feature_column.bucketized_column(\n",
+ " housing_median_age, boundaries=get_quantile_based_boundaries(\n",
+ " training_examples[\"housing_median_age\"], 7))\n",
+ " \n",
+ " # Divide median_income into 7 buckets.\n",
+ " bucketized_median_income = tf.feature_column.bucketized_column(\n",
+ " median_income, boundaries=get_quantile_based_boundaries(\n",
+ " training_examples[\"median_income\"], 7))\n",
+ " \n",
+ " # Divide rooms_per_person into 7 buckets.\n",
+ " bucketized_rooms_per_person = tf.feature_column.bucketized_column(\n",
+ " rooms_per_person, boundaries=get_quantile_based_boundaries(\n",
+ " training_examples[\"rooms_per_person\"], 7))\n",
+ " \n",
+ " # YOUR CODE HERE: Make a feature column for the long_x_lat feature cross\n",
+ " long_x_lat = tf.feature_column.crossed_column(\n",
+ " set([bucketized_longitude, bucketized_latitude]), hash_bucket_size=1000) \n",
+ " \n",
+ " feature_columns = set([\n",
+ " bucketized_longitude,\n",
+ " bucketized_latitude,\n",
+ " bucketized_housing_median_age,\n",
+ " bucketized_households,\n",
+ " bucketized_median_income,\n",
+ " bucketized_rooms_per_person,\n",
+ " long_x_lat])\n",
+ " \n",
+ " return feature_columns"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "-_vvNYIyTtPC",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "_ = train_model(\n",
+ " learning_rate=1.0,\n",
+ " steps=500,\n",
+ " batch_size=100,\n",
+ " feature_columns=construct_feature_columns(),\n",
+ " training_examples=training_examples,\n",
+ " training_targets=training_targets,\n",
+ " validation_examples=validation_examples,\n",
+ " validation_targets=validation_targets)"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "ymlHJ-vrhLZw",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## Optional Challenge: Try Out More Synthetic Features\n",
+ "\n",
+ "So far, we've tried simple bucketized columns and feature crosses, but there are many more combinations that could potentially improve the results. For example, you could cross multiple columns. What happens if you vary the number of buckets? What other synthetic features can you think of? Do they improve the model?"
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/feature_sets.ipynb b/feature_sets.ipynb
new file mode 100644
index 0000000..9fcae40
--- /dev/null
+++ b/feature_sets.ipynb
@@ -0,0 +1,1564 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "name": "feature_sets.ipynb",
+ "version": "0.3.2",
+ "provenance": [],
+ "collapsed_sections": [
+ "JndnmDMp66FL",
+ "IGINhMIJ5Wyt",
+ "pZa8miwu6_tQ"
+ ],
+ "include_colab_link": true
+ },
+ "kernelspec": {
+ "name": "python2",
+ "display_name": "Python 2"
+ }
+ },
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "view-in-github",
+ "colab_type": "text"
+ },
+ "source": [
+ ""
+ ]
+ },
+ {
+ "metadata": {
+ "id": "JndnmDMp66FL",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "#### Copyright 2017 Google LLC."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "hMqWDc_m6rUC",
+ "colab_type": "code",
+ "cellView": "both",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "# 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\n",
+ "#\n",
+ "# https://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."
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "zbIgBK-oXHO7",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "# Feature Sets"
+ ]
+ },
+ {
+ "metadata": {
+ "id": "bL04rAQwH3pH",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "**Learning Objective:** Create a minimal set of features that performs just as well as a more complex feature set"
+ ]
+ },
+ {
+ "metadata": {
+ "id": "F8Hci6tAH3pH",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "So far, we've thrown all of our features into the model. Models with fewer features use fewer resources and are easier to maintain. Let's see if we can build a model on a minimal set of housing features that will perform equally as well as one that uses all the features in the data set."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "F5ZjVwK_qOyR",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## Setup\n",
+ "\n",
+ "As before, let's load and prepare the California housing data."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "SrOYRILAH3pJ",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "from __future__ import print_function\n",
+ "\n",
+ "import math\n",
+ "\n",
+ "from IPython import display\n",
+ "from matplotlib import cm\n",
+ "from matplotlib import gridspec\n",
+ "from matplotlib import pyplot as plt\n",
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "from sklearn import metrics\n",
+ "import tensorflow as tf\n",
+ "from tensorflow.python.data import Dataset\n",
+ "\n",
+ "tf.logging.set_verbosity(tf.logging.ERROR)\n",
+ "pd.options.display.max_rows = 10\n",
+ "pd.options.display.float_format = '{:.1f}'.format\n",
+ "\n",
+ "california_housing_dataframe = pd.read_csv(\"https://download.mlcc.google.com/mledu-datasets/california_housing_train.csv\", sep=\",\")\n",
+ "\n",
+ "california_housing_dataframe = california_housing_dataframe.reindex(\n",
+ " np.random.permutation(california_housing_dataframe.index))"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "dGnXo7flH3pM",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def preprocess_features(california_housing_dataframe):\n",
+ " \"\"\"Prepares input features from California housing data set.\n",
+ "\n",
+ " Args:\n",
+ " california_housing_dataframe: A Pandas DataFrame expected to contain data\n",
+ " from the California housing data set.\n",
+ " Returns:\n",
+ " A DataFrame that contains the features to be used for the model, including\n",
+ " synthetic features.\n",
+ " \"\"\"\n",
+ " selected_features = california_housing_dataframe[\n",
+ " [\"latitude\",\n",
+ " \"longitude\",\n",
+ " \"housing_median_age\",\n",
+ " \"total_rooms\",\n",
+ " \"total_bedrooms\",\n",
+ " \"population\",\n",
+ " \"households\",\n",
+ " \"median_income\"]]\n",
+ " processed_features = selected_features.copy()\n",
+ " # Create a synthetic feature.\n",
+ " processed_features[\"rooms_per_person\"] = (\n",
+ " california_housing_dataframe[\"total_rooms\"] /\n",
+ " california_housing_dataframe[\"population\"])\n",
+ " return processed_features\n",
+ "\n",
+ "def preprocess_targets(california_housing_dataframe):\n",
+ " \"\"\"Prepares target features (i.e., labels) from California housing data set.\n",
+ "\n",
+ " Args:\n",
+ " california_housing_dataframe: A Pandas DataFrame expected to contain data\n",
+ " from the California housing data set.\n",
+ " Returns:\n",
+ " A DataFrame that contains the target feature.\n",
+ " \"\"\"\n",
+ " output_targets = pd.DataFrame()\n",
+ " # Scale the target to be in units of thousands of dollars.\n",
+ " output_targets[\"median_house_value\"] = (\n",
+ " california_housing_dataframe[\"median_house_value\"] / 1000.0)\n",
+ " return output_targets"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "jLXC8y4AqsIy",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 1224
+ },
+ "outputId": "4a00a62d-0a2c-4189-f724-4213165122e8"
+ },
+ "cell_type": "code",
+ "source": [
+ "# Choose the first 12000 (out of 17000) examples for training.\n",
+ "training_examples = preprocess_features(california_housing_dataframe.head(12000))\n",
+ "training_targets = preprocess_targets(california_housing_dataframe.head(12000))\n",
+ "\n",
+ "# Choose the last 5000 (out of 17000) examples for validation.\n",
+ "validation_examples = preprocess_features(california_housing_dataframe.tail(5000))\n",
+ "validation_targets = preprocess_targets(california_housing_dataframe.tail(5000))\n",
+ "\n",
+ "# Double-check that we've done the right thing.\n",
+ "print(\"Training examples summary:\")\n",
+ "display.display(training_examples.describe())\n",
+ "print(\"Validation examples summary:\")\n",
+ "display.display(validation_examples.describe())\n",
+ "\n",
+ "print(\"Training targets summary:\")\n",
+ "display.display(training_targets.describe())\n",
+ "print(\"Validation targets summary:\")\n",
+ "display.display(validation_targets.describe())"
+ ],
+ "execution_count": 3,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Training examples summary:\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "text/plain": [
+ " latitude longitude housing_median_age total_rooms total_bedrooms \\\n",
+ "count 12000.0 12000.0 12000.0 12000.0 12000.0 \n",
+ "mean 35.6 -119.6 28.5 2637.3 539.1 \n",
+ "std 2.1 2.0 12.6 2139.4 417.0 \n",
+ "min 32.5 -124.3 2.0 2.0 1.0 \n",
+ "25% 33.9 -121.8 18.0 1456.8 295.0 \n",
+ "50% 34.2 -118.5 29.0 2127.0 433.0 \n",
+ "75% 37.7 -118.0 37.0 3147.2 649.2 \n",
+ "max 42.0 -114.3 52.0 30401.0 4957.0 \n",
+ "\n",
+ " population households median_income rooms_per_person \n",
+ "count 12000.0 12000.0 12000.0 12000.0 \n",
+ "mean 1426.9 500.9 3.9 2.0 \n",
+ "std 1133.9 379.3 1.9 1.1 \n",
+ "min 3.0 1.0 0.5 0.0 \n",
+ "25% 792.0 281.0 2.6 1.5 \n",
+ "50% 1166.0 408.0 3.5 1.9 \n",
+ "75% 1718.2 607.0 4.8 2.3 \n",
+ "max 35682.0 4769.0 15.0 55.2 "
+ ],
+ "text/html": [
+ "
"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ }
+ }
+ ]
+ },
+ {
+ "metadata": {
+ "id": "6N0p91k2iFCP",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "**Try creating some synthetic features that do a better job with latitude.**\n",
+ "\n",
+ "For example, you could have a feature that maps `latitude` to a value of `|latitude - 38|`, and call this `distance_from_san_francisco`.\n",
+ "\n",
+ "Or you could break the space into 10 different buckets. `latitude_32_to_33`, `latitude_33_to_34`, etc., each showing a value of `1.0` if `latitude` is within that bucket range and a value of `0.0` otherwise.\n",
+ "\n",
+ "Use the correlation matrix to help guide development, and then add them to your model if you find something that looks good.\n",
+ "\n",
+ "What's the best validation performance you can get?"
+ ]
+ },
+ {
+ "metadata": {
+ "id": "wduJ2B28yMFl",
+ "colab_type": "code",
+ "cellView": "form",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 640
+ },
+ "outputId": "26cef08b-62bb-4a51-e818-64a10fe4dbed"
+ },
+ "cell_type": "code",
+ "source": [
+ "#\n",
+ "# YOUR CODE HERE: Train on a new data set that includes synthetic features based on latitude.\n",
+ "#First create a seperate feature function which will add a feature for each set of latitudes (Binning) and add 1 if the house exists for the latitude and 0 if the house doesn't exists in the given latitude and longitude\n",
+ "def new_features_for_training(prev_df):\n",
+ " new_df = pd.DataFrame()\n",
+ " new_df[\"median_income\"]=prev_df[\"median_income\"]\n",
+ " latitude_sets = zip(range(32,44),range(33,45))\n",
+ " for i in latitude_sets:\n",
+ " new_df[\"latitude_%d_to_%d\" %i] = prev_df[\"latitude\"].apply(lambda l: 1.0 if l>= i[0] and l < i[1] else 0.0) \n",
+ " return new_df\n",
+ "\n",
+ "new_df_training = new_features_for_training(training_examples)\n",
+ "new_df_validation = new_features_for_training(validation_examples)\n",
+ "\n",
+ "train = train_model(learning_rate = 0.01,\n",
+ " steps = 500,\n",
+ " batch_size=500,\n",
+ " training_examples=new_df_training,\n",
+ " training_targets=training_targets,\n",
+ " validation_examples=new_df_validation,\n",
+ " validation_targets=validation_targets)\n",
+ "\n"
+ ],
+ "execution_count": 23,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Training model...\n",
+ "RMSE (on training data):\n",
+ " period 00 : 226.33\n",
+ " period 01 : 216.09\n",
+ " period 02 : 205.94\n",
+ " period 03 : 195.90\n",
+ " period 04 : 185.97\n",
+ " period 05 : 176.17\n",
+ " period 06 : 166.54\n",
+ " period 07 : 157.10\n",
+ " period 08 : 147.88\n",
+ " period 09 : 138.93\n",
+ "Model training finished.\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ "
"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ }
+ }
+ ]
+ },
+ {
+ "metadata": {
+ "id": "pZa8miwu6_tQ",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "### Solution\n",
+ "\n",
+ "Click below for a solution."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "PzABdyjq7IZU",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "Aside from `latitude`, we'll also keep `median_income`, to compare with the previous results.\n",
+ "\n",
+ "We decided to bucketize the latitude. This is fairly straightforward in Pandas using `Series.apply`."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "xdVF8siZ7Lup",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def select_and_transform_features(source_df):\n",
+ " LATITUDE_RANGES = zip(range(32, 44), range(33, 45))\n",
+ " selected_examples = pd.DataFrame()\n",
+ " selected_examples[\"median_income\"] = source_df[\"median_income\"]\n",
+ " for r in LATITUDE_RANGES:\n",
+ " selected_examples[\"latitude_%d_to_%d\" % r] = source_df[\"latitude\"].apply(\n",
+ " lambda l: 1.0 if l >= r[0] and l < r[1] else 0.0)\n",
+ " return selected_examples\n",
+ "\n",
+ "selected_training_examples = select_and_transform_features(training_examples)\n",
+ "selected_validation_examples = select_and_transform_features(validation_examples)"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "U4iAdY6t7Pkh",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 2268
+ },
+ "outputId": "f225d61c-0e4a-44f6-e505-2ca13d766e35"
+ },
+ "cell_type": "code",
+ "source": [
+ "_ = train_model(\n",
+ " learning_rate=0.01,\n",
+ " steps=500,\n",
+ " batch_size=5,\n",
+ " training_examples=selected_training_examples,\n",
+ " training_targets=training_targets,\n",
+ " validation_examples=selected_validation_examples,\n",
+ " validation_targets=validation_targets)"
+ ],
+ "execution_count": 20,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Training model...\n",
+ "RMSE (on training data):\n",
+ " period 00 : 226.40\n",
+ " period 01 : 216.24\n",
+ " period 02 : 206.18\n",
+ " period 03 : 196.19\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "error",
+ "ename": "KeyboardInterrupt",
+ "evalue": "ignored",
+ "traceback": [
+ "\u001b[0;31m\u001b[0m",
+ "\u001b[0;31mKeyboardInterrupt\u001b[0mTraceback (most recent call last)",
+ "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0mtraining_targets\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtraining_targets\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0mvalidation_examples\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mselected_validation_examples\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m validation_targets=validation_targets)\n\u001b[0m",
+ "\u001b[0;32m\u001b[0m in \u001b[0;36mtrain_model\u001b[0;34m(learning_rate, steps, batch_size, training_examples, training_targets, validation_examples, validation_targets)\u001b[0m\n\u001b[1;32m 64\u001b[0m linear_regressor.train(\n\u001b[1;32m 65\u001b[0m \u001b[0minput_fn\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtraining_input_fn\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 66\u001b[0;31m \u001b[0msteps\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msteps_per_period\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 67\u001b[0m )\n\u001b[1;32m 68\u001b[0m \u001b[0;31m# Take a break and compute predictions.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/usr/local/lib/python2.7/dist-packages/tensorflow_estimator/python/estimator/estimator.pyc\u001b[0m in \u001b[0;36mtrain\u001b[0;34m(self, input_fn, hooks, steps, max_steps, saving_listeners)\u001b[0m\n\u001b[1;32m 352\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 353\u001b[0m \u001b[0msaving_listeners\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_check_listeners_type\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msaving_listeners\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 354\u001b[0;31m \u001b[0mloss\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_train_model\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minput_fn\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mhooks\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msaving_listeners\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 355\u001b[0m \u001b[0mlogging\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minfo\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Loss for final step: %s.'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mloss\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 356\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/usr/local/lib/python2.7/dist-packages/tensorflow_estimator/python/estimator/estimator.pyc\u001b[0m in \u001b[0;36m_train_model\u001b[0;34m(self, input_fn, hooks, saving_listeners)\u001b[0m\n\u001b[1;32m 1181\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_train_model_distributed\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minput_fn\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mhooks\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msaving_listeners\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1182\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1183\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_train_model_default\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minput_fn\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mhooks\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msaving_listeners\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1184\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1185\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_train_model_default\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0minput_fn\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mhooks\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msaving_listeners\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/usr/local/lib/python2.7/dist-packages/tensorflow_estimator/python/estimator/estimator.pyc\u001b[0m in \u001b[0;36m_train_model_default\u001b[0;34m(self, input_fn, hooks, saving_listeners)\u001b[0m\n\u001b[1;32m 1215\u001b[0m return self._train_with_estimator_spec(estimator_spec, worker_hooks,\n\u001b[1;32m 1216\u001b[0m \u001b[0mhooks\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mglobal_step_tensor\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1217\u001b[0;31m saving_listeners)\n\u001b[0m\u001b[1;32m 1218\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1219\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_train_model_distributed\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0minput_fn\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mhooks\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msaving_listeners\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/usr/local/lib/python2.7/dist-packages/tensorflow_estimator/python/estimator/estimator.pyc\u001b[0m in \u001b[0;36m_train_with_estimator_spec\u001b[0;34m(self, estimator_spec, worker_hooks, hooks, global_step_tensor, saving_listeners)\u001b[0m\n\u001b[1;32m 1406\u001b[0m \u001b[0msave_summaries_steps\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_config\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msave_summary_steps\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1407\u001b[0m \u001b[0mconfig\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_session_config\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1408\u001b[0;31m log_step_count_steps=self._config.log_step_count_steps) as mon_sess:\n\u001b[0m\u001b[1;32m 1409\u001b[0m \u001b[0mloss\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1410\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mmon_sess\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshould_stop\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/usr/local/lib/python2.7/dist-packages/tensorflow/python/training/monitored_session.pyc\u001b[0m in \u001b[0;36mMonitoredTrainingSession\u001b[0;34m(master, is_chief, checkpoint_dir, scaffold, hooks, chief_only_hooks, save_checkpoint_secs, save_summaries_steps, save_summaries_secs, config, stop_grace_period_secs, log_step_count_steps, max_wait_secs, save_checkpoint_steps, summary_dir)\u001b[0m\n\u001b[1;32m 506\u001b[0m \u001b[0msession_creator\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msession_creator\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 507\u001b[0m \u001b[0mhooks\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mall_hooks\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 508\u001b[0;31m stop_grace_period_secs=stop_grace_period_secs)\n\u001b[0m\u001b[1;32m 509\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 510\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/usr/local/lib/python2.7/dist-packages/tensorflow/python/training/monitored_session.pyc\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, session_creator, hooks, stop_grace_period_secs)\u001b[0m\n\u001b[1;32m 932\u001b[0m super(MonitoredSession, self).__init__(\n\u001b[1;32m 933\u001b[0m \u001b[0msession_creator\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mhooks\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mshould_recover\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mTrue\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 934\u001b[0;31m stop_grace_period_secs=stop_grace_period_secs)\n\u001b[0m\u001b[1;32m 935\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 936\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/usr/local/lib/python2.7/dist-packages/tensorflow/python/training/monitored_session.pyc\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, session_creator, hooks, should_recover, stop_grace_period_secs)\u001b[0m\n\u001b[1;32m 646\u001b[0m stop_grace_period_secs=stop_grace_period_secs)\n\u001b[1;32m 647\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mshould_recover\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 648\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_sess\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_RecoverableSession\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_coordinated_creator\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 649\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 650\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_sess\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_coordinated_creator\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcreate_session\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/usr/local/lib/python2.7/dist-packages/tensorflow/python/training/monitored_session.pyc\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, sess_creator)\u001b[0m\n\u001b[1;32m 1120\u001b[0m \"\"\"\n\u001b[1;32m 1121\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_sess_creator\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msess_creator\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1122\u001b[0;31m \u001b[0m_WrappedSession\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__init__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_create_session\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1123\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1124\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_create_session\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/usr/local/lib/python2.7/dist-packages/tensorflow/python/training/monitored_session.pyc\u001b[0m in \u001b[0;36m_create_session\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 1125\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0mTrue\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1126\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1127\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_sess_creator\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcreate_session\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1128\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0m_PREEMPTION_ERRORS\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1129\u001b[0m logging.info('An error was raised while a session was being created. '\n",
+ "\u001b[0;32m/usr/local/lib/python2.7/dist-packages/tensorflow/python/training/monitored_session.pyc\u001b[0m in \u001b[0;36mcreate_session\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 810\u001b[0m \u001b[0;31m# Inform the hooks that a new session has been created.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 811\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mhook\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_hooks\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 812\u001b[0;31m \u001b[0mhook\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mafter_create_session\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtf_sess\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcoord\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 813\u001b[0m return _CoordinatedSession(\n\u001b[1;32m 814\u001b[0m \u001b[0m_HookedSession\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtf_sess\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_hooks\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcoord\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/usr/local/lib/python2.7/dist-packages/tensorflow/python/training/basic_session_run_hooks.pyc\u001b[0m in \u001b[0;36mafter_create_session\u001b[0;34m(self, session, coord)\u001b[0m\n\u001b[1;32m 563\u001b[0m \u001b[0mgraph_def\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mgraph\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mas_graph_def\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0madd_shapes\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 564\u001b[0m saver_def=saver_def)\n\u001b[0;32m--> 565\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_summary_writer\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_graph\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgraph\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 566\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_summary_writer\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_meta_graph\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmeta_graph_def\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 567\u001b[0m \u001b[0;31m# The checkpoint saved here is the state at step \"global_step\".\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/usr/local/lib/python2.7/dist-packages/tensorflow/python/summary/writer/writer.pyc\u001b[0m in \u001b[0;36madd_graph\u001b[0;34m(self, graph, global_step, graph_def)\u001b[0m\n\u001b[1;32m 192\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 193\u001b[0m \u001b[0;31m# Serialize the graph with additional info.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 194\u001b[0;31m \u001b[0mtrue_graph_def\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mgraph\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mas_graph_def\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0madd_shapes\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 195\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_write_plugin_assets\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgraph\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 196\u001b[0m elif (isinstance(graph, graph_pb2.GraphDef) or\n",
+ "\u001b[0;32m/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.pyc\u001b[0m in \u001b[0;36mas_graph_def\u001b[0;34m(self, from_version, add_shapes)\u001b[0m\n\u001b[1;32m 3148\u001b[0m \"\"\"\n\u001b[1;32m 3149\u001b[0m \u001b[0;31m# pylint: enable=line-too-long\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3150\u001b[0;31m \u001b[0mresult\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_as_graph_def\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfrom_version\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0madd_shapes\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3151\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3152\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32m/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.pyc\u001b[0m in \u001b[0;36m_as_graph_def\u001b[0;34m(self, from_version, add_shapes)\u001b[0m\n\u001b[1;32m 3118\u001b[0m \u001b[0mop\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_nodes_by_name\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mnode\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3119\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mop\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moutputs\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3120\u001b[0;31m node.attr[\"_output_shapes\"].list.shape.extend(\n\u001b[0m\u001b[1;32m 3121\u001b[0m [output.get_shape().as_proto() for output in op.outputs])\n\u001b[1;32m 3122\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mgraph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_version\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/improving_neural_net_performance.ipynb b/improving_neural_net_performance.ipynb
new file mode 100644
index 0000000..8c09a3a
--- /dev/null
+++ b/improving_neural_net_performance.ipynb
@@ -0,0 +1,1780 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "name": "improving_neural_net_performance.ipynb",
+ "version": "0.3.2",
+ "provenance": [],
+ "collapsed_sections": [
+ "JndnmDMp66FL",
+ "jFfc3saSxg6t",
+ "FSPZIiYgyh93",
+ "GhFtWjQRzD2l",
+ "P8BLQ7T71JWd"
+ ],
+ "include_colab_link": true
+ },
+ "kernelspec": {
+ "name": "python2",
+ "display_name": "Python 2"
+ }
+ },
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "view-in-github",
+ "colab_type": "text"
+ },
+ "source": [
+ ""
+ ]
+ },
+ {
+ "metadata": {
+ "colab_type": "text",
+ "id": "JndnmDMp66FL"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "#### Copyright 2017 Google LLC."
+ ]
+ },
+ {
+ "metadata": {
+ "cellView": "both",
+ "colab_type": "code",
+ "id": "hMqWDc_m6rUC",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "# 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\n",
+ "#\n",
+ "# https://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."
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "colab_type": "text",
+ "id": "eV16J6oUY-HN"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "# Improving Neural Net Performance"
+ ]
+ },
+ {
+ "metadata": {
+ "colab_type": "text",
+ "id": "0Rwl1iXIKxkm"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "**Learning Objective:** Improve the performance of a neural network by normalizing features and applying various optimization algorithms\n",
+ "\n",
+ "**NOTE:** The optimization methods described in this exercise are not specific to neural networks; they are effective means to improve most types of models."
+ ]
+ },
+ {
+ "metadata": {
+ "colab_type": "text",
+ "id": "lBPTONWzKxkn"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## Setup\n",
+ "\n",
+ "First, we'll load the data."
+ ]
+ },
+ {
+ "metadata": {
+ "colab_type": "code",
+ "id": "VtYVuONUKxko",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "from __future__ import print_function\n",
+ "\n",
+ "import math\n",
+ "\n",
+ "from IPython import display\n",
+ "from matplotlib import cm\n",
+ "from matplotlib import gridspec\n",
+ "from matplotlib import pyplot as plt\n",
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "from sklearn import metrics\n",
+ "import tensorflow as tf\n",
+ "from tensorflow.python.data import Dataset\n",
+ "\n",
+ "tf.logging.set_verbosity(tf.logging.ERROR)\n",
+ "pd.options.display.max_rows = 10\n",
+ "pd.options.display.float_format = '{:.1f}'.format\n",
+ "\n",
+ "california_housing_dataframe = pd.read_csv(\"https://download.mlcc.google.com/mledu-datasets/california_housing_train.csv\", sep=\",\")\n",
+ "\n",
+ "california_housing_dataframe = california_housing_dataframe.reindex(\n",
+ " np.random.permutation(california_housing_dataframe.index))"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "colab_type": "code",
+ "id": "B8qC-jTIKxkr",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def preprocess_features(california_housing_dataframe):\n",
+ " \"\"\"Prepares input features from California housing data set.\n",
+ "\n",
+ " Args:\n",
+ " california_housing_dataframe: A Pandas DataFrame expected to contain data\n",
+ " from the California housing data set.\n",
+ " Returns:\n",
+ " A DataFrame that contains the features to be used for the model, including\n",
+ " synthetic features.\n",
+ " \"\"\"\n",
+ " selected_features = california_housing_dataframe[\n",
+ " [\"latitude\",\n",
+ " \"longitude\",\n",
+ " \"housing_median_age\",\n",
+ " \"total_rooms\",\n",
+ " \"total_bedrooms\",\n",
+ " \"population\",\n",
+ " \"households\",\n",
+ " \"median_income\"]]\n",
+ " processed_features = selected_features.copy()\n",
+ " # Create a synthetic feature.\n",
+ " processed_features[\"rooms_per_person\"] = (\n",
+ " california_housing_dataframe[\"total_rooms\"] /\n",
+ " california_housing_dataframe[\"population\"])\n",
+ " return processed_features\n",
+ "\n",
+ "def preprocess_targets(california_housing_dataframe):\n",
+ " \"\"\"Prepares target features (i.e., labels) from California housing data set.\n",
+ "\n",
+ " Args:\n",
+ " california_housing_dataframe: A Pandas DataFrame expected to contain data\n",
+ " from the California housing data set.\n",
+ " Returns:\n",
+ " A DataFrame that contains the target feature.\n",
+ " \"\"\"\n",
+ " output_targets = pd.DataFrame()\n",
+ " # Scale the target to be in units of thousands of dollars.\n",
+ " output_targets[\"median_house_value\"] = (\n",
+ " california_housing_dataframe[\"median_house_value\"] / 1000.0)\n",
+ " return output_targets"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "colab_type": "code",
+ "id": "Ah6LjMIJ2spZ",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 1224
+ },
+ "outputId": "b19a9b97-9ca6-4c34-8675-50d27b6e37d2"
+ },
+ "cell_type": "code",
+ "source": [
+ "# Choose the first 12000 (out of 17000) examples for training.\n",
+ "training_examples = preprocess_features(california_housing_dataframe.head(12000))\n",
+ "training_targets = preprocess_targets(california_housing_dataframe.head(12000))\n",
+ "\n",
+ "# Choose the last 5000 (out of 17000) examples for validation.\n",
+ "validation_examples = preprocess_features(california_housing_dataframe.tail(5000))\n",
+ "validation_targets = preprocess_targets(california_housing_dataframe.tail(5000))\n",
+ "\n",
+ "# Double-check that we've done the right thing.\n",
+ "print(\"Training examples summary:\")\n",
+ "display.display(training_examples.describe())\n",
+ "print(\"Validation examples summary:\")\n",
+ "display.display(validation_examples.describe())\n",
+ "\n",
+ "print(\"Training targets summary:\")\n",
+ "display.display(training_targets.describe())\n",
+ "print(\"Validation targets summary:\")\n",
+ "display.display(validation_targets.describe())"
+ ],
+ "execution_count": 3,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Training examples summary:\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "text/plain": [
+ " latitude longitude housing_median_age total_rooms total_bedrooms \\\n",
+ "count 12000.0 12000.0 12000.0 12000.0 12000.0 \n",
+ "mean 35.6 -119.6 28.6 2634.2 537.6 \n",
+ "std 2.1 2.0 12.6 2176.3 418.5 \n",
+ "min 32.5 -124.3 1.0 2.0 1.0 \n",
+ "25% 33.9 -121.8 18.0 1452.0 295.0 \n",
+ "50% 34.2 -118.5 29.0 2121.0 434.0 \n",
+ "75% 37.7 -118.0 37.0 3146.0 647.2 \n",
+ "max 42.0 -114.5 52.0 37937.0 5471.0 \n",
+ "\n",
+ " population households median_income rooms_per_person \n",
+ "count 12000.0 12000.0 12000.0 12000.0 \n",
+ "mean 1426.9 499.5 3.9 2.0 \n",
+ "std 1142.5 381.4 1.9 1.2 \n",
+ "min 3.0 1.0 0.5 0.1 \n",
+ "25% 786.0 280.0 2.6 1.5 \n",
+ "50% 1168.0 410.0 3.5 1.9 \n",
+ "75% 1721.0 603.0 4.7 2.3 \n",
+ "max 35682.0 5189.0 15.0 55.2 "
+ ],
+ "text/html": [
+ "
"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ }
+ }
+ ]
+ },
+ {
+ "metadata": {
+ "colab_type": "text",
+ "id": "NqIbXxx222ea"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## Train the Neural Network\n",
+ "\n",
+ "Next, we'll train the neural network."
+ ]
+ },
+ {
+ "metadata": {
+ "colab_type": "code",
+ "id": "6k3xYlSg27VB",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def construct_feature_columns(input_features):\n",
+ " \"\"\"Construct the TensorFlow Feature Columns.\n",
+ "\n",
+ " Args:\n",
+ " input_features: The names of the numerical input features to use.\n",
+ " Returns:\n",
+ " A set of feature columns\n",
+ " \"\"\" \n",
+ " return set([tf.feature_column.numeric_column(my_feature)\n",
+ " for my_feature in input_features])"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "colab_type": "code",
+ "id": "De9jwyy4wTUT",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def my_input_fn(features, targets, batch_size=1, shuffle=True, num_epochs=None):\n",
+ " \"\"\"Trains a neural network model.\n",
+ " \n",
+ " Args:\n",
+ " features: pandas DataFrame of features\n",
+ " targets: pandas DataFrame of targets\n",
+ " batch_size: Size of batches to be passed to the model\n",
+ " shuffle: True or False. Whether to shuffle the data.\n",
+ " num_epochs: Number of epochs for which data should be repeated. None = repeat indefinitely\n",
+ " Returns:\n",
+ " Tuple of (features, labels) for next data batch\n",
+ " \"\"\"\n",
+ " \n",
+ " # Convert pandas data into a dict of np arrays.\n",
+ " features = {key:np.array(value) for key,value in dict(features).items()} \n",
+ " \n",
+ " # Construct a dataset, and configure batching/repeating.\n",
+ " ds = Dataset.from_tensor_slices((features,targets)) # warning: 2GB limit\n",
+ " ds = ds.batch(batch_size).repeat(num_epochs)\n",
+ " \n",
+ " # Shuffle the data, if specified.\n",
+ " if shuffle:\n",
+ " ds = ds.shuffle(10000)\n",
+ " \n",
+ " # Return the next batch of data.\n",
+ " features, labels = ds.make_one_shot_iterator().get_next()\n",
+ " return features, labels"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "colab_type": "code",
+ "id": "W-51R3yIKxk4",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def train_nn_regression_model(\n",
+ " my_optimizer,\n",
+ " steps,\n",
+ " batch_size,\n",
+ " hidden_units,\n",
+ " training_examples,\n",
+ " training_targets,\n",
+ " validation_examples,\n",
+ " validation_targets):\n",
+ " \"\"\"Trains a neural network regression model.\n",
+ " \n",
+ " In addition to training, this function also prints training progress information,\n",
+ " as well as a plot of the training and validation loss over time.\n",
+ " \n",
+ " Args:\n",
+ " my_optimizer: An instance of `tf.train.Optimizer`, the optimizer to use.\n",
+ " steps: A non-zero `int`, the total number of training steps. A training step\n",
+ " consists of a forward and backward pass using a single batch.\n",
+ " batch_size: A non-zero `int`, the batch size.\n",
+ " hidden_units: A `list` of int values, specifying the number of neurons in each layer.\n",
+ " training_examples: A `DataFrame` containing one or more columns from\n",
+ " `california_housing_dataframe` to use as input features for training.\n",
+ " training_targets: A `DataFrame` containing exactly one column from\n",
+ " `california_housing_dataframe` to use as target for training.\n",
+ " validation_examples: A `DataFrame` containing one or more columns from\n",
+ " `california_housing_dataframe` to use as input features for validation.\n",
+ " validation_targets: A `DataFrame` containing exactly one column from\n",
+ " `california_housing_dataframe` to use as target for validation.\n",
+ " \n",
+ " Returns:\n",
+ " A tuple `(estimator, training_losses, validation_losses)`:\n",
+ " estimator: the trained `DNNRegressor` object.\n",
+ " training_losses: a `list` containing the training loss values taken during training.\n",
+ " validation_losses: a `list` containing the validation loss values taken during training.\n",
+ " \"\"\"\n",
+ "\n",
+ " periods = 10\n",
+ " steps_per_period = steps / periods\n",
+ " \n",
+ " # Create a DNNRegressor object.\n",
+ " my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0)\n",
+ " dnn_regressor = tf.estimator.DNNRegressor(\n",
+ " feature_columns=construct_feature_columns(training_examples),\n",
+ " hidden_units=hidden_units,\n",
+ " optimizer=my_optimizer\n",
+ " )\n",
+ " \n",
+ " # Create input functions.\n",
+ " training_input_fn = lambda: my_input_fn(training_examples, \n",
+ " training_targets[\"median_house_value\"], \n",
+ " batch_size=batch_size)\n",
+ " predict_training_input_fn = lambda: my_input_fn(training_examples, \n",
+ " training_targets[\"median_house_value\"], \n",
+ " num_epochs=1, \n",
+ " shuffle=False)\n",
+ " predict_validation_input_fn = lambda: my_input_fn(validation_examples, \n",
+ " validation_targets[\"median_house_value\"], \n",
+ " num_epochs=1, \n",
+ " shuffle=False)\n",
+ "\n",
+ " # Train the model, but do so inside a loop so that we can periodically assess\n",
+ " # loss metrics.\n",
+ " print(\"Training model...\")\n",
+ " print(\"RMSE (on training data):\")\n",
+ " training_rmse = []\n",
+ " validation_rmse = []\n",
+ " for period in range (0, periods):\n",
+ " # Train the model, starting from the prior state.\n",
+ " dnn_regressor.train(\n",
+ " input_fn=training_input_fn,\n",
+ " steps=steps_per_period\n",
+ " )\n",
+ " # Take a break and compute predictions.\n",
+ " training_predictions = dnn_regressor.predict(input_fn=predict_training_input_fn)\n",
+ " training_predictions = np.array([item['predictions'][0] for item in training_predictions])\n",
+ " \n",
+ " validation_predictions = dnn_regressor.predict(input_fn=predict_validation_input_fn)\n",
+ " validation_predictions = np.array([item['predictions'][0] for item in validation_predictions])\n",
+ " \n",
+ " # Compute training and validation loss.\n",
+ " training_root_mean_squared_error = math.sqrt(\n",
+ " metrics.mean_squared_error(training_predictions, training_targets))\n",
+ " validation_root_mean_squared_error = math.sqrt(\n",
+ " metrics.mean_squared_error(validation_predictions, validation_targets))\n",
+ " # Occasionally print the current loss.\n",
+ " print(\" period %02d : %0.2f\" % (period, training_root_mean_squared_error))\n",
+ " # Add the loss metrics from this period to our list.\n",
+ " training_rmse.append(training_root_mean_squared_error)\n",
+ " validation_rmse.append(validation_root_mean_squared_error)\n",
+ " print(\"Model training finished.\")\n",
+ "\n",
+ " # Output a graph of loss metrics over periods.\n",
+ " plt.ylabel(\"RMSE\")\n",
+ " plt.xlabel(\"Periods\")\n",
+ " plt.title(\"Root Mean Squared Error vs. Periods\")\n",
+ " plt.tight_layout()\n",
+ " plt.plot(training_rmse, label=\"training\")\n",
+ " plt.plot(validation_rmse, label=\"validation\")\n",
+ " plt.legend()\n",
+ "\n",
+ " print(\"Final RMSE (on training data): %0.2f\" % training_root_mean_squared_error)\n",
+ " print(\"Final RMSE (on validation data): %0.2f\" % validation_root_mean_squared_error)\n",
+ "\n",
+ " return dnn_regressor, training_rmse, validation_rmse"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "colab_type": "code",
+ "id": "KueReMZ9Kxk7",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 805
+ },
+ "outputId": "dd7f43d6-ad8f-4b8b-ed89-c8fd1a9b81b5"
+ },
+ "cell_type": "code",
+ "source": [
+ "_ = train_nn_regression_model(\n",
+ " my_optimizer=tf.train.GradientDescentOptimizer(learning_rate=0.0007),\n",
+ " steps=5000,\n",
+ " batch_size=70,\n",
+ " hidden_units=[10, 10],\n",
+ " training_examples=training_examples,\n",
+ " training_targets=training_targets,\n",
+ " validation_examples=validation_examples,\n",
+ " validation_targets=validation_targets)"
+ ],
+ "execution_count": 7,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "WARNING: The TensorFlow contrib module will not be included in TensorFlow 2.0.\n",
+ "For more information, please see:\n",
+ " * https://github.com/tensorflow/community/blob/master/rfcs/20180907-contrib-sunset.md\n",
+ " * https://github.com/tensorflow/addons\n",
+ "If you depend on functionality not listed there, please file an issue.\n",
+ "\n",
+ "Training model...\n",
+ "RMSE (on training data):\n",
+ " period 00 : 150.63\n",
+ " period 01 : 135.21\n",
+ " period 02 : 123.19\n",
+ " period 03 : 115.75\n",
+ " period 04 : 109.58\n",
+ " period 05 : 108.87\n",
+ " period 06 : 108.01\n",
+ " period 07 : 110.06\n",
+ " period 08 : 107.97\n",
+ " period 09 : 109.78\n",
+ "Model training finished.\n",
+ "Final RMSE (on training data): 109.78\n",
+ "Final RMSE (on validation data): 109.73\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "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\niIiISNr5/xwdX7ddwEqgAAAAAElFTkSuQmCC\n",
+ "text/plain": [
+ "
"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ }
+ }
+ ]
+ },
+ {
+ "metadata": {
+ "colab_type": "text",
+ "id": "flxmFt0KKxk9"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## Linear Scaling\n",
+ "It can be a good standard practice to normalize the inputs to fall within the range -1, 1. This helps SGD not get stuck taking steps that are too large in one dimension, or too small in another. Fans of numerical optimization may note that there's a connection to the idea of using a preconditioner here."
+ ]
+ },
+ {
+ "metadata": {
+ "colab_type": "code",
+ "id": "Dws5rIQjKxk-",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def linear_scale(series):\n",
+ " min_val = series.min()\n",
+ " max_val = series.max()\n",
+ " scale = (max_val - min_val) / 2.0\n",
+ " return series.apply(lambda x:((x - min_val) / scale) - 1.0)"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "colab_type": "text",
+ "id": "MVmuHI76N2Sz"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## Task 1: Normalize the Features Using Linear Scaling\n",
+ "\n",
+ "**Normalize the inputs to the scale -1, 1.**\n",
+ "\n",
+ "**Spend about 5 minutes training and evaluating on the newly normalized data. How well can you do?**\n",
+ "\n",
+ "As a rule of thumb, NN's train best when the input features are roughly on the same scale.\n",
+ "\n",
+ "Sanity check your normalized data. (What would happen if you forgot to normalize one feature?)\n"
+ ]
+ },
+ {
+ "metadata": {
+ "colab_type": "code",
+ "id": "yD948ZgAM6Cx",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 677
+ },
+ "outputId": "e3e4e31f-4fee-4080-ee1f-9db0bd51091a"
+ },
+ "cell_type": "code",
+ "source": [
+ "def normalize_linear_scale(examples_dataframe):\n",
+ " \"\"\"Returns a version of the input `DataFrame` that has all its features normalized linearly.\"\"\"\n",
+ " #\n",
+ " processed_features = pd.DataFrame()\n",
+ " processed_features[\"latitude\"] = linear_scale(examples_dataframe[\"latitude\"])\n",
+ " processed_features[\"longitude\"] = linear_scale(examples_dataframe[\"longitude\"])\n",
+ " processed_features[\"housing_median_age\"] = linear_scale(examples_dataframe[\"housing_median_age\"])\n",
+ " processed_features[\"total_rooms\"] = linear_scale(examples_dataframe[\"total_rooms\"])\n",
+ " processed_features[\"total_bedrooms\"] = linear_scale(examples_dataframe[\"total_bedrooms\"])\n",
+ " processed_features[\"population\"] = linear_scale(examples_dataframe[\"population\"])\n",
+ " processed_features[\"households\"] = linear_scale(examples_dataframe[\"households\"])\n",
+ " processed_features[\"median_income\"] = linear_scale(examples_dataframe[\"median_income\"])\n",
+ " processed_features[\"rooms_per_person\"] = linear_scale(examples_dataframe[\"rooms_per_person\"])\n",
+ " return processed_features\n",
+ " #\n",
+ " pass\n",
+ "\n",
+ "normalized_dataframe = normalize_linear_scale(preprocess_features(california_housing_dataframe))\n",
+ "normalized_training_examples = normalized_dataframe.head(12000)\n",
+ "normalized_validation_examples = normalized_dataframe.tail(5000)\n",
+ "\n",
+ "_ = train_nn_regression_model(\n",
+ " my_optimizer=tf.train.GradientDescentOptimizer(learning_rate=0.0007),\n",
+ " steps=5000,\n",
+ " batch_size=70,\n",
+ " hidden_units=[10, 10],\n",
+ " training_examples=normalized_training_examples,\n",
+ " training_targets=training_targets,\n",
+ " validation_examples=normalized_validation_examples,\n",
+ " validation_targets=validation_targets)"
+ ],
+ "execution_count": 9,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Training model...\n",
+ "RMSE (on training data):\n",
+ " period 00 : 230.10\n",
+ " period 01 : 206.71\n",
+ " period 02 : 159.93\n",
+ " period 03 : 118.77\n",
+ " period 04 : 115.06\n",
+ " period 05 : 111.25\n",
+ " period 06 : 106.80\n",
+ " period 07 : 101.55\n",
+ " period 08 : 95.33\n",
+ " period 09 : 88.40\n",
+ "Model training finished.\n",
+ "Final RMSE (on training data): 88.40\n",
+ "Final RMSE (on validation data): 88.26\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "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\nHJn14x//mOeee45f//rX3HXXXdx7770KLxli8+bNvP766ySTScLhMPF4XPUWGWDZsmXU19cD0N3d\njdvtVni5BBqBmXXdddexevVq7rnnHgzD4MEHH0x3k2TWn//8Z8LhMF/+8pfnju3Zs4fS0tI0tkok\ncxUXF/PRj36Uu+++G4D7778fi0X/Xk23bdu2sXv3bnbs2MH09DTf/va3092krGaYKvYQERGRLKNI\nLiIiIllHAUZERESyjgKMiIiIZB0FGBEREck6CjAiIiKSdRRgRGRRdXV1sWbNGnbu3Dm3C+99991H\nNBq96Gvs3LmTmZmZiz7/05/+NG+88ca7aa6IZAkFGBFZdIFAgL1797J3716effZZioqKeOKJJy76\n83v37tWCXyKygBayE5HL7sYbb2Tfvn00NjayZ88epqenmZqa4lvf+harVq1i586d1NXVceLECZ55\n5hlWrVpFQ0MDk5OTPPDAA/T19TE9Pc3WrVvZvn07iUSCr3zlK4TDYZYtW8bExAQA/f39fPWrXwVg\nfHycbdu2ceedd6bz1kXkv0QBRkQuq5mZGV5++WWuv/56vva1r/H4449TUVFx3uZ2LpeLX/7ylws+\nu3fvXnw+Hz/84Q8ZHx/n4x//OFu2bOG1117D6XSyb98+QqEQH/7whwH4y1/+wvLly3nooYeYmJjg\nN7/5zWW/XxFZHAowIrLohoeH2blzJwDJZJIbbriBO+64g0cffZRvfvObc+eNjY2RTCaB1PYe56qv\nr+f2228HwOl0smbNGhoaGjh16hTXX389kNqYdfny5QBs2bKFX/3qV+zatYubbrqJbdu2Lep9isjl\nowAjIovuTA3MfKOjo9jt9vOOn2G32887ZhjGgt+bpolhGJimuWCvnzMhqLq6mj/96U+8+eabvPDC\nCzzzzDM8++yzl3o7IpIBVMQrImnh9XopLy/nH//4BwCtra089thjF/zMunXrOHDgAADxeJyGhgZW\nr15NdXU1hw8fBqC3t5fW1lYA/vjHP3L06FE2bdrEgw8+SG9vL9PT04t4VyJyuWgERkTSZs+ePXzn\nO9/h5z//OdPT0+zateuC5+/cuZMHHniAz3zmM0xOTnLvvfdSXl7O1q1b+dvf/sb27dspLy9n7dq1\nANTU1PDggw/icDgwTZMvfOEL2Gz6a0/kSqDdqEVERCTraApJREREso4CjIiIiGQdBRgRERHJOgow\nIiIiknUUYERERCTrKMCIiIhI1lGAERERkayjACMiIiJZ5/8BSNlY9Jj8Kp4AAAAASUVORK5CYII=\n",
+ "text/plain": [
+ "
"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ }
+ }
+ ]
+ },
+ {
+ "metadata": {
+ "colab_type": "text",
+ "id": "jFfc3saSxg6t"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "### Solution\n",
+ "\n",
+ "Click below for one possible solution."
+ ]
+ },
+ {
+ "metadata": {
+ "colab_type": "text",
+ "id": "Ax_IIQVRx4gr"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "Since normalization uses min and max, we have to ensure it's done on the entire dataset at once. \n",
+ "\n",
+ "We can do that here because all our data is in a single DataFrame. If we had multiple data sets, a good practice would be to derive the normalization parameters from the training set and apply those identically to the test set."
+ ]
+ },
+ {
+ "metadata": {
+ "colab_type": "code",
+ "id": "D-bJBXrJx-U_",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def normalize_linear_scale(examples_dataframe):\n",
+ " \"\"\"Returns a version of the input `DataFrame` that has all its features normalized linearly.\"\"\"\n",
+ " processed_features = pd.DataFrame()\n",
+ " processed_features[\"latitude\"] = linear_scale(examples_dataframe[\"latitude\"])\n",
+ " processed_features[\"longitude\"] = linear_scale(examples_dataframe[\"longitude\"])\n",
+ " processed_features[\"housing_median_age\"] = linear_scale(examples_dataframe[\"housing_median_age\"])\n",
+ " processed_features[\"total_rooms\"] = linear_scale(examples_dataframe[\"total_rooms\"])\n",
+ " processed_features[\"total_bedrooms\"] = linear_scale(examples_dataframe[\"total_bedrooms\"])\n",
+ " processed_features[\"population\"] = linear_scale(examples_dataframe[\"population\"])\n",
+ " processed_features[\"households\"] = linear_scale(examples_dataframe[\"households\"])\n",
+ " processed_features[\"median_income\"] = linear_scale(examples_dataframe[\"median_income\"])\n",
+ " processed_features[\"rooms_per_person\"] = linear_scale(examples_dataframe[\"rooms_per_person\"])\n",
+ " return processed_features\n",
+ "\n",
+ "normalized_dataframe = normalize_linear_scale(preprocess_features(california_housing_dataframe))\n",
+ "normalized_training_examples = normalized_dataframe.head(12000)\n",
+ "normalized_validation_examples = normalized_dataframe.tail(5000)\n",
+ "\n",
+ "_ = train_nn_regression_model(\n",
+ " my_optimizer=tf.train.GradientDescentOptimizer(learning_rate=0.005),\n",
+ " steps=2000,\n",
+ " batch_size=50,\n",
+ " hidden_units=[10, 10],\n",
+ " training_examples=normalized_training_examples,\n",
+ " training_targets=training_targets,\n",
+ " validation_examples=normalized_validation_examples,\n",
+ " validation_targets=validation_targets)"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "colab_type": "text",
+ "id": "MrwtdStNJ6ZQ"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## Task 2: Try a Different Optimizer\n",
+ "\n",
+ "** Use the Adagrad and Adam optimizers and compare performance.**\n",
+ "\n",
+ "The Adagrad optimizer is one alternative. The key insight of Adagrad is that it modifies the learning rate adaptively for each coefficient in a model, monotonically lowering the effective learning rate. This works great for convex problems, but isn't always ideal for the non-convex problem Neural Net training. You can use Adagrad by specifying `AdagradOptimizer` instead of `GradientDescentOptimizer`. Note that you may need to use a larger learning rate with Adagrad.\n",
+ "\n",
+ "For non-convex optimization problems, Adam is sometimes more efficient than Adagrad. To use Adam, invoke the `tf.train.AdamOptimizer` method. This method takes several optional hyperparameters as arguments, but our solution only specifies one of these (`learning_rate`). In a production setting, you should specify and tune the optional hyperparameters carefully."
+ ]
+ },
+ {
+ "metadata": {
+ "colab_type": "code",
+ "id": "61GSlDvF7-7q",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 677
+ },
+ "outputId": "aefe89df-c727-45e8-e0b6-b243b7886201"
+ },
+ "cell_type": "code",
+ "source": [
+ "#\n",
+ "# YOUR CODE HERE: Retrain the network using Adagrad and then Adam.\n",
+ "#\n",
+ "_, adagrad_training_losses, adagrad_validation_losses = train_nn_regression_model(\n",
+ " my_optimizer=tf.train.AdagradOptimizer(learning_rate=0.5),\n",
+ " steps=500,\n",
+ " batch_size=100,\n",
+ " hidden_units=[10, 10],\n",
+ " training_examples=normalized_training_examples,\n",
+ " training_targets=training_targets,\n",
+ " validation_examples=normalized_validation_examples,\n",
+ " validation_targets=validation_targets)"
+ ],
+ "execution_count": 10,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Training model...\n",
+ "RMSE (on training data):\n",
+ " period 00 : 93.44\n",
+ " period 01 : 75.53\n",
+ " period 02 : 75.13\n",
+ " period 03 : 73.52\n",
+ " period 04 : 71.01\n",
+ " period 05 : 71.45\n",
+ " period 06 : 70.28\n",
+ " period 07 : 71.60\n",
+ " period 08 : 69.35\n",
+ " period 09 : 68.68\n",
+ "Model training finished.\n",
+ "Final RMSE (on training data): 68.68\n",
+ "Final RMSE (on validation data): 67.68\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAioAAAGACAYAAACDX0mmAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzs3Xl8VPW9//HXbFkm62RPCEkgCQk7\nLiirbCII+HO9uCBFa9vftWq96q1Uq1Zr69LF/qSKt/a2tdpaV9SquLMoLiCCqEDCnp3s+z4z5/dH\nwggSQoBMZpK8n48HDzLLmfOd+Zwhb77nc84xGYZhICIiIuKHzL4egIiIiMixKKiIiIiI31JQERER\nEb+loCIiIiJ+S0FFRERE/JaCioiIiPgtq68HIOIPsrKySElJwWKxAOByuZg4cSJ33XUXdrv9pF/3\nhRdeYPHixUfdv2rVKu644w7+53/+h1mzZnnub2lpYcqUKZx33nk89NBDJ73ensrPz+eBBx5g//79\nAAQHB3PjjTdy7rnnen3dJ2LlypXk5+cf9Zls3LiR6667juTk5KOWefvtt/tqeKeksLCQOXPmMGzY\nMAAMwyAmJoaf//znjBo16oRe6/e//z1JSUlceeWVPV7mtdde46WXXuKZZ545oXWJ9BUFFZFOzzzz\nDAkJCQC0tbVxyy238Kc//YlbbrnlpF6vvLyc//3f/+0yqAAkJibyxhtvHBFU1q5dS3h4+Emt72T8\n93//NxdeeCH/8z//A8C2bdtYtmwZb731FomJiX02jlORmJjYb0LJsVgsliPew+rVq7nhhht45513\nCAgI6PHr3Hbbbd4YnohPadePSBcCAgKYPn06O3fuBKC1tZV77rmHefPmcf755/PQQw/hcrkAyMnJ\n4YorrmD+/PlceOGFfPTRRwBcccUVFBcXM3/+fNra2o5ax+mnn87GjRtpbm723Ld69WqmTp3qud3W\n1savfvUr5s2bx+zZsz2BAmDr1q1ccsklzJ8/nwULFvDJJ58AHf9DnzZtGk8//TQXXHAB06dPZ/Xq\n1V2+z127djF+/HjP7fHjx/POO+94Attjjz3GjBkzuOiii3jyySeZPXs2AD/72c9YuXKlZ7nDbx9v\nXA888ABXX301AF988QWXXnopc+fOZfHixRQUFAAdM0v/9V//xaxZs7j66qs5ePDgcSrWtVWrVnHj\njTeybNkyfvOb37Bx40auuOIKbr75Zs8v9bfeeotFixYxf/58vve975Gfnw/AH//4R+666y4uu+wy\nnnrqqSNe9+abb+avf/2r5/bOnTuZNm0abrebP/zhD8ybN4958+bxve99j9LS0hMe94IFC2hpaWHf\nvn0APP/888yfP5/Zs2dz66230tLSAnR87g8++CAXXHABb7311hF1ONZ26Xa7+eUvf8nMmTO57LLL\nyMnJ8ax306ZNXHzxxSxYsIDzzz+ft95664THLtLrDBExRowYYZSUlHhu19TUGEuWLDFWrlxpGIZh\n/OlPfzJ++MMfGu3t7UZzc7Nx6aWXGq+++qrhcrmM888/33j99dcNwzCMr776ypg4caJRX19vfPbZ\nZ8a5557b5fpefvllY/ny5cZ///d/e5atr6835syZY7z44ovG8uXLDcMwjMcee8xYtmyZ0draajQ2\nNhoXXXSRsWbNGsMwDGPRokXGG2+8YRiGYbzyyiuedRUUFBijRo0ynnnmGcMwDGP16tXG3LlzuxzH\nTTfdZMyaNcv4+9//buzZs+eIx3Jzc40zzzzTKCsrM9rb243rr7/emDVrlmEYhrF8+XLj8ccf9zz3\n8NvdjWv06NHGqlWrPO934sSJxoYNGwzDMIzXX3/duPjiiw3DMIx//OMfxpIlS4z29najqqrKmDVr\nluczOVx3n/Ghz3nChAnG/v37Pc8fO3as8cknnxiGYRhFRUXGGWecYRw4cMAwDMP4y1/+Yixbtsww\nDMNYsWKFMW3aNKOysvKo133zzTeNJUuWeG4/+uijxv3332/s2rXLOO+884y2tjbDMAzj6aefNl55\n5ZVjju/Q5zJy5Mij7p84caKxd+9e4/PPPzcmT55sHDx40DAMw7j77ruNhx56yDCMjs/9ggsuMFpa\nWjy3H3/88W63y3Xr1hnnnXee0dDQYDQ3NxuXXXaZcfXVVxuGYRiXXHKJsXHjRsMwDGP//v3Grbfe\n2u3YRfqCZlREOi1dupT58+czZ84c5syZw6RJk/jhD38IwLp161i8eDFWq5WgoCAuuOACPv74YwoL\nC6moqGDhwoUAjB07lqSkJL7++userXPhwoW88cYbALz//vvMmjULs/nbr+XatWu56qqrCAgIwG63\nc+GFF/Luu+8C8Oqrr3L++ecDcMYZZ3hmIwCcTieXXHIJAKNHj6a4uLjL9f/2t79lyZIlvP766yxa\n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\nQmCC\n",
+ "text/plain": [
+ "
"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ }
+ }
+ ]
+ },
+ {
+ "metadata": {
+ "id": "RWq0xecNKNeG",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## Building a Neural Network\n",
+ "\n",
+ "The NN is defined by the [DNNRegressor](https://www.tensorflow.org/api_docs/python/tf/estimator/DNNRegressor) class.\n",
+ "\n",
+ "Use **`hidden_units`** to define the structure of the NN. The `hidden_units` argument provides a list of ints, where each int corresponds to a hidden layer and indicates the number of nodes in it. For example, consider the following assignment:\n",
+ "\n",
+ "`hidden_units=[3,10]`\n",
+ "\n",
+ "The preceding assignment specifies a neural net with two hidden layers:\n",
+ "\n",
+ "* The first hidden layer contains 3 nodes.\n",
+ "* The second hidden layer contains 10 nodes.\n",
+ "\n",
+ "If we wanted to add more layers, we'd add more ints to the list. For example, `hidden_units=[10,20,30,40]` would create four layers with ten, twenty, thirty, and forty units, respectively.\n",
+ "\n",
+ "By default, all hidden layers will use ReLu activation and will be fully connected."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "ni0S6zHcTb04",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def construct_feature_columns(input_features):\n",
+ " \"\"\"Construct the TensorFlow Feature Columns.\n",
+ "\n",
+ " Args:\n",
+ " input_features: The names of the numerical input features to use.\n",
+ " Returns:\n",
+ " A set of feature columns\n",
+ " \"\"\" \n",
+ " return set([tf.feature_column.numeric_column(my_feature)\n",
+ " for my_feature in input_features])"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "zvCqgNdzpaFg",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def my_input_fn(features, targets, batch_size=1, shuffle=True, num_epochs=None):\n",
+ " \"\"\"Trains a neural net regression model.\n",
+ " \n",
+ " Args:\n",
+ " features: pandas DataFrame of features\n",
+ " targets: pandas DataFrame of targets\n",
+ " batch_size: Size of batches to be passed to the model\n",
+ " shuffle: True or False. Whether to shuffle the data.\n",
+ " num_epochs: Number of epochs for which data should be repeated. None = repeat indefinitely\n",
+ " Returns:\n",
+ " Tuple of (features, labels) for next data batch\n",
+ " \"\"\"\n",
+ " \n",
+ " # Convert pandas data into a dict of np arrays.\n",
+ " features = {key:np.array(value) for key,value in dict(features).items()} \n",
+ " \n",
+ " # Construct a dataset, and configure batching/repeating.\n",
+ " ds = Dataset.from_tensor_slices((features,targets)) # warning: 2GB limit\n",
+ " ds = ds.batch(batch_size).repeat(num_epochs)\n",
+ " \n",
+ " # Shuffle the data, if specified.\n",
+ " if shuffle:\n",
+ " ds = ds.shuffle(10000)\n",
+ " \n",
+ " # Return the next batch of data.\n",
+ " features, labels = ds.make_one_shot_iterator().get_next()\n",
+ " return features, labels"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "U52Ychv9KNeH",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def train_nn_regression_model(\n",
+ " learning_rate,\n",
+ " steps,\n",
+ " batch_size,\n",
+ " hidden_units,\n",
+ " training_examples,\n",
+ " training_targets,\n",
+ " validation_examples,\n",
+ " validation_targets):\n",
+ " \"\"\"Trains a neural network regression model.\n",
+ " \n",
+ " In addition to training, this function also prints training progress information,\n",
+ " as well as a plot of the training and validation loss over time.\n",
+ " \n",
+ " Args:\n",
+ " learning_rate: A `float`, the learning rate.\n",
+ " steps: A non-zero `int`, the total number of training steps. A training step\n",
+ " consists of a forward and backward pass using a single batch.\n",
+ " batch_size: A non-zero `int`, the batch size.\n",
+ " hidden_units: A `list` of int values, specifying the number of neurons in each layer.\n",
+ " training_examples: A `DataFrame` containing one or more columns from\n",
+ " `california_housing_dataframe` to use as input features for training.\n",
+ " training_targets: A `DataFrame` containing exactly one column from\n",
+ " `california_housing_dataframe` to use as target for training.\n",
+ " validation_examples: A `DataFrame` containing one or more columns from\n",
+ " `california_housing_dataframe` to use as input features for validation.\n",
+ " validation_targets: A `DataFrame` containing exactly one column from\n",
+ " `california_housing_dataframe` to use as target for validation.\n",
+ " \n",
+ " Returns:\n",
+ " A `DNNRegressor` object trained on the training data.\n",
+ " \"\"\"\n",
+ "\n",
+ " periods = 10\n",
+ " steps_per_period = steps / periods\n",
+ " \n",
+ " # Create a DNNRegressor object.\n",
+ " my_optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)\n",
+ " my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0)\n",
+ " dnn_regressor = tf.estimator.DNNRegressor(\n",
+ " feature_columns=construct_feature_columns(training_examples),\n",
+ " hidden_units=hidden_units,\n",
+ " optimizer=my_optimizer,\n",
+ " )\n",
+ " \n",
+ " # Create input functions.\n",
+ " training_input_fn = lambda: my_input_fn(training_examples, \n",
+ " training_targets[\"median_house_value\"], \n",
+ " batch_size=batch_size)\n",
+ " predict_training_input_fn = lambda: my_input_fn(training_examples, \n",
+ " training_targets[\"median_house_value\"], \n",
+ " num_epochs=1, \n",
+ " shuffle=False)\n",
+ " predict_validation_input_fn = lambda: my_input_fn(validation_examples, \n",
+ " validation_targets[\"median_house_value\"], \n",
+ " num_epochs=1, \n",
+ " shuffle=False)\n",
+ "\n",
+ " # Train the model, but do so inside a loop so that we can periodically assess\n",
+ " # loss metrics.\n",
+ " print(\"Training model...\")\n",
+ " print(\"RMSE (on training data):\")\n",
+ " training_rmse = []\n",
+ " validation_rmse = []\n",
+ " for period in range (0, periods):\n",
+ " # Train the model, starting from the prior state.\n",
+ " dnn_regressor.train(\n",
+ " input_fn=training_input_fn,\n",
+ " steps=steps_per_period\n",
+ " )\n",
+ " # Take a break and compute predictions.\n",
+ " training_predictions = dnn_regressor.predict(input_fn=predict_training_input_fn)\n",
+ " training_predictions = np.array([item['predictions'][0] for item in training_predictions])\n",
+ " \n",
+ " validation_predictions = dnn_regressor.predict(input_fn=predict_validation_input_fn)\n",
+ " validation_predictions = np.array([item['predictions'][0] for item in validation_predictions])\n",
+ " \n",
+ " # Compute training and validation loss.\n",
+ " training_root_mean_squared_error = math.sqrt(\n",
+ " metrics.mean_squared_error(training_predictions, training_targets))\n",
+ " validation_root_mean_squared_error = math.sqrt(\n",
+ " metrics.mean_squared_error(validation_predictions, validation_targets))\n",
+ " # Occasionally print the current loss.\n",
+ " print(\" period %02d : %0.2f\" % (period, training_root_mean_squared_error))\n",
+ " # Add the loss metrics from this period to our list.\n",
+ " training_rmse.append(training_root_mean_squared_error)\n",
+ " validation_rmse.append(validation_root_mean_squared_error)\n",
+ " print(\"Model training finished.\")\n",
+ "\n",
+ " # Output a graph of loss metrics over periods.\n",
+ " plt.ylabel(\"RMSE\")\n",
+ " plt.xlabel(\"Periods\")\n",
+ " plt.title(\"Root Mean Squared Error vs. Periods\")\n",
+ " plt.tight_layout()\n",
+ " plt.plot(training_rmse, label=\"training\")\n",
+ " plt.plot(validation_rmse, label=\"validation\")\n",
+ " plt.legend()\n",
+ "\n",
+ " print(\"Final RMSE (on training data): %0.2f\" % training_root_mean_squared_error)\n",
+ " print(\"Final RMSE (on validation data): %0.2f\" % validation_root_mean_squared_error)\n",
+ "\n",
+ " return dnn_regressor"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "2QhdcCy-Y8QR",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## Task 1: Train a NN Model\n",
+ "\n",
+ "**Adjust hyperparameters, aiming to drop RMSE below 110.**\n",
+ "\n",
+ "Run the following block to train a NN model. \n",
+ "\n",
+ "Recall that in the linear regression exercise with many features, an RMSE of 110 or so was pretty good. We'll aim to beat that.\n",
+ "\n",
+ "Your task here is to modify various learning settings to improve accuracy on validation data.\n",
+ "\n",
+ "Overfitting is a real potential hazard for NNs. You can look at the gap between loss on training data and loss on validation data to help judge if your model is starting to overfit. If the gap starts to grow, that is usually a sure sign of overfitting.\n",
+ "\n",
+ "Because of the number of different possible settings, it's strongly recommended that you take notes on each trial to help guide your development process.\n",
+ "\n",
+ "Also, when you get a good setting, try running it multiple times and see how repeatable your result is. NN weights are typically initialized to small random values, so you should see differences from run to run.\n"
+ ]
+ },
+ {
+ "metadata": {
+ "id": "rXmtSW1yKNeK",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 677
+ },
+ "outputId": "9456e61e-73a5-4871-b48d-cc8338607171"
+ },
+ "cell_type": "code",
+ "source": [
+ "dnn_regressor = train_nn_regression_model(\n",
+ " learning_rate=0.001,\n",
+ " steps=5000,\n",
+ " batch_size=10,\n",
+ " hidden_units=[10, 10],\n",
+ " training_examples=training_examples,\n",
+ " training_targets=training_targets,\n",
+ " validation_examples=validation_examples,\n",
+ " validation_targets=validation_targets)"
+ ],
+ "execution_count": 8,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Training model...\n",
+ "RMSE (on training data):\n",
+ " period 00 : 189.98\n",
+ " period 01 : 162.18\n",
+ " period 02 : 158.25\n",
+ " period 03 : 146.24\n",
+ " period 04 : 151.64\n",
+ " period 05 : 134.54\n",
+ " period 06 : 127.59\n",
+ " period 07 : 124.71\n",
+ " period 08 : 121.16\n",
+ " period 09 : 106.83\n",
+ "Model training finished.\n",
+ "Final RMSE (on training data): 106.83\n",
+ "Final RMSE (on validation data): 103.87\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjAAAAGACAYAAACz01iHAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzs3Xd4VNX28PHvmZn03iskIfTQQ4TQ\nO6EoIEUFEcv1/ixc+2u76FW5gly7KBbs2EEUUBBFOtKDlCT0hISE9N6TyXn/CIxEICQhyZlJ1ud5\neB5mTlsza85kzT777K2oqqoihBBCCGFBdFoHIIQQQghRX1LACCGEEMLiSAEjhBBCCIsjBYwQQggh\nLI4UMEIIIYSwOFLACCGEEMLiGLQOQAhz1qlTJ9q2bYterwfAaDQSERHBvHnzsLe3b/B+v/vuO2bM\nmHHJ8ytXruSpp57ivffeY/jw4abnS0tLGTBgAGPGjOGll15q8HHrKjExkQULFhAfHw+AnZ0dc+fO\nZdSoUU1+7PpYsmQJiYmJl7wnu3fv5q677iIwMPCSbX755ZfmCu+anD17lpEjRxISEgKAqqp4enry\n73//m65du9ZrX6+++ir+/v7ccsstdd5m1apVrFixgmXLltXrWEI0FylghLiKZcuW4evrC0B5eTkP\nP/ww77//Pg8//HCD9peRkcGHH3542QIGwM/Pj59++qlGAbNp0yacnZ0bdLyGeOyxx5g0aRLvvfce\nAAcPHmTOnDmsW7cOPz+/ZovjWvj5+VlMsXIler2+xmtYu3Yt999/P+vXr8fa2rrO+3n00UebIjwh\nNCWXkISoB2trawYPHkxcXBwAZWVlPPvss4wdO5Zx48bx0ksvYTQaATh69Cg333wzUVFRTJo0iW3b\ntgFw8803k5KSQlRUFOXl5Zcco0+fPuzevZuSkhLTc2vXrmXgwIGmx+Xl5fz3v/9l7NixjBgxwlRo\nABw4cIAbb7yRqKgoxo8fzx9//AFU/6IfNGgQn3/+Oddffz2DBw9m7dq1l32dx48fp2fPnqbHPXv2\nZP369aZC7u2332bo0KFMnjyZDz74gBEjRgDw5JNPsmTJEtN2Fz++WlwLFizg1ltvBWD//v1MnTqV\n0aNHM2PGDJKSkoDqlqiHHnqI4cOHc+utt5KamnqVjF3eypUrmTt3LnPmzOF///sfu3fv5uabb+bB\nBx80/bFft24dEydOJCoqittuu43ExEQAFi9ezLx585g2bRqffvppjf0++OCDfPzxx6bHcXFxDBo0\niKqqKl5//XXGjh3L2LFjue2220hLS6t33OPHj6e0tJTTp08D8O233xIVFcWIESN45JFHKC0tBarf\n94ULF3L99dezbt26Gnm40ueyqqqKF154gWHDhjFt2jSOHj1qOu6ePXuYMmUK48ePZ9y4caxbt67e\nsQvR6FQhxBV17NhRPXfunOlxbm6uOmvWLHXJkiWqqqrq+++/r959991qRUWFWlJSok6dOlX98ccf\nVaPRqI4bN05ds2aNqqqqeujQITUiIkItKChQd+3apY4aNeqyx/v+++/VJ554Qn3sscdM2xYUFKgj\nR45Uly9frj7xxBOqqqrq22+/rc6ZM0ctKytTi4qK1MmTJ6sbN25UVVVVJ06cqP7000+qqqrqDz/8\nYDpWUlKS2rVrV3XZsmWqqqrq2rVr1dGjR182jn/961/q8OHD1c8++0w9efJkjWXHjh1T+/btq6an\np6sVFRXqvffeqw4fPlxVVVV94okn1Hfeece07sWPa4srLCxMXblypen1RkREqNu3b1dVVVXXrFmj\nTpkyRVVVVf3iiy/UWbNmqRUVFWp2drY6fPhw03tysdre4wvvc69evdT4+HjT+t27d1f/+OMPVVVV\nNTk5WQ0PD1cTEhJUVVXVjz76SJ0zZ46qqqr61ltvqYMGDVKzsrIu2e/PP/+szpo1y/T4zTffVOfP\nn68eP35cHTNmjFpeXq6qqqp+/vnn6g8//HDF+C68L126dLnk+YiICPXUqVPq3r171cjISDU1NVVV\nVVV95pln1JdeeklV1er3/frrr1dLS0tNj995551aP5ebN29Wx4wZoxYWFqolJSXqtGnT1FtvvVVV\nVVW98cYb1d27d6uqqqrx8fHqI488UmvsQjQHaYER4ipmz55NVFQUI0eOZOTIkfTv35+7774bgM2b\nNzNjxgwMBgO2trZcf/317Nixg7Nnz5KZmcmECRMA6N69O/7+/hw+fLhOx5wwYQI//fQTABs2bGD4\n8OHodH+drps2bWLmzJlYW1tjb2/PpEmT+PXXXwH48ccfGTduHADh4eGm1guAyspKbrzxRgDCwsJI\nSUm57PFffvllZs2axZo1a5g4cSIjRozg66+/BqpbRyIiIvDy8sJgMDBx4sQ6vaba4qqoqGD06NGm\n/fv4+JhanCZOnEhiYiIpKSns27eP0aNHYzAYcHNzq3GZ7e/OnTtHVFRUjX8X95UJDg4mODjY9NjW\n1pbIyEgAduzYQb9+/QgKCgJg+vTp7N69m8rKSqC6Rcrd3f2SYw4bNozY2Fhyc3MB+O2334iKisLZ\n2Zns7GzWrFlDXl4es2fPZvLkyXV63y5QVZVvv/0WHx8fgoOD2bhxI+PHj8fHxweAW265xfQZAIiM\njMTGxqbGPmr7XO7du5ehQ4fi4OCAra2tKVcAHh4e/Pjjj5w6dYrg4GBeffXVesUuRFOQPjBCXMWF\nPjDZ2dmmyx8GQ/Wpk52djYuLi2ldFxcXsrKyyM7OxsnJCUVRTMsu/BHz9PS86jEHDhzIvHnzyM3N\n5eeff+a+++4zdagFKCgoYOHChbz22mtA9SWlHj16ALBmzRo+//xzioqKqKqqQr1oujO9Xm/qfKzT\n6aiqqrrs8W1sbLjrrru46667yM/P55dffmHBggUEBgaSl5dXoz+Oh4fHVV9PXeJydHQEID8/n6Sk\nJKKiokzLra2tyc7OJi8vDycnJ9Pzzs7OFBUVXfZ4V+sDc3He/v44Jyenxmt0cnJCVVVycnIuu+0F\n9vb2DBgwgM2bNxMeHk5+fj7h4eEoisLixYv5+OOPmT9/PhERETz//PNX7U9kNBpN74OqqrRv354l\nS5ag0+koKCjgt99+Y/v27ablFRUVV3x9QK2fy7y8PLy9vWs8f8GCBQt49913ueOOO7C1teWRRx6p\nkR8htCAFjBB15O7uzuzZs3n55Zd59913AfD09DT92gbIzc3F09MTDw8P8vLyUFXV9MciNze3zn/s\nraysGD58OD/++CNnzpyhd+/eNQoYb29v7rzzzktaINLS0pg3bx7Lly+nS5cuJCQkMHbs2Hq9zuzs\nbOLi4kwtIM7OzsyYMYNt27Zx/PhxnJycKCgoqLH+BX8vivLy8uodl7e3N+3atWPlypWXLHN2dr7i\nsRuTh4cHBw4cMD3Oy8tDp9Ph5uZ21W3Hjh3Lb7/9Rk5ODmPHjjXlv3///vTv35/i4mIWLVrEK6+8\nctWWjL934r2Yt7c3U6ZM4YknnqjX67rS57K299bT05NnnnmGZ555hu3bt/Ovf/2LwYMH4+DgUOdj\nC9HY5BKSEPVwxx13cODAAfbs2QNUXzJYsWIFRqOR4uJiVq1axdChQwkMDMTX19fUSTY6OprMzEx6\n9OiBwWCguLjYdDniSiZMmMDSpUsve+vyyJEjWb58OUajEVVVWbJkCVu3biU7Oxt7e3vatWtHZWUl\n3377LcAVWykup7S0lAceeMDUuRPgzJkzHDx4kL59+9K7d2/27dtHdnY2lZWV/Pjjj6b1vLy8TJ0/\nk5KSiI6OBqhXXD179iQjI4ODBw+a9vP//t//Q1VVevXqxcaNGzEajWRnZ7N169Y6v676GDhwIPv2\n7TNd5vrmm28YOHCgqeWtNsOHD+fAgQNs2LDBdBlm+/btPP/881RVVWFvb0/nzp1rtII0xIgRI/j1\n119NhcaGDRv44IMPat2mts9l79692b59OyUlJZSUlJgKp4qKCmbPnk16ejpQfenRYDDUuKQphBak\nBUaIenB0dOSf//wnixYtYsWKFcyePZukpCQmTJiAoihERUUxbtw4FEXhtdde4z//+Q9vv/02dnZ2\nvPnmm9jb29OpUydcXFwYOHAgP/zwA/7+/pc91nXXXYeiKIwfP/6SZTNnzuTs2bNMmDABVVXp1q0b\nc+bMwd7eniFDhjB27Fg8PDx48skniY6OZvbs2bz11lt1eo3+/v68++67vPXWW/z3v/9FVVUcHR15\n6qmnTHcm3XTTTUyZMgU3NzfGjBnDiRMnAJgxYwZz585lzJgxdO3a1dTK0rlz5zrHZWtry1tvvcX8\n+fMpKirCysqKBx98EEVRmDFjBvv27WPUqFH4+/szatSoGq0GF7vQB+bv/ve//131PfD19eW///0v\n9913HxUVFQQGBjJ//vw6vX+Ojo6EhYVx7NgxevXqBUBERAQ///wzY8eOxdraGnd3dxYsWADA448/\nbrqTqD7CwsK45557mD17NlVVVXh4ePD888/Xuk1tn8vhw4ezefNmoqKi8PT0ZOjQoezbtw8rKyum\nTZvG7bffDlS3ss2bNw87O7t6xStEY1PUiy9ECyFEPe3bt4/HH3+cjRs3ah2KEKIVkTZAIYQQQlgc\nKWCEEEIIYXHkEpIQQgghLI60wAghhBDC4kgBI4QQQgiLY5G3UWdkXP62ycbg5mZPTk5xk+1fNJzk\nxjxJXsyX5MZ8SW7qxsvL6YrLpAXmbwwGvdYhiCuQ3JgnyYv5ktyYL8nNtZMCRgghhBAWRwoYIYQQ\nQlgcKWCEEEIIYXGkgBFCCCGExZECRgghhBAWRwoYIYQQQlgcKWCEEEIIYXGkgBFCCCFamM2bf6/T\nem+++SopKclXXP7kk480VkiNTgoYIYQQogU5dy6FDRvW12ndBx98FH//gCsuf+ml1xorrEZnkVMJ\nCCGEEOLyXnttEXFxMQweHMGYMeM4dy6FN95YwsKFL5CRkU5JSQl33vlPBg4czNy5/+SRRx5n06bf\nKSoqJDHxDMnJZ3nggUeJjBzIhAkj+fnn35k7959ERPQjOnofubm5LFr0Op6enrzwwjOkpp6je/ce\nbNy4gR9+WNtsr1MKGCGEEKKJfLfxJHuPpl/yvF6vYDSqDdpnRGdvZoxof8Xlt9wym5UrvyMkJJTE\nxASWLPmQnJxsrruuP+PGTSQ5+SzPPPMkAwcOrrFdenoar7zyFrt2/cGqVd8TGTmwxnIHBwfefPNd\n3n13MVu3bsTfP5Dy8jI++OBTduzYxnfffd2g19NQUsBcJDO3hNS8MnxdbLQORQghhLhmXbqEAeDk\n5ExcXAyrV69EUXTk5+ddsm6PHr0A8Pb2prCw8JLlPXv2Ni3Py8vjzJl4unfvCUBk5ED0+uad30kK\nmIus3pHA9sPnePb2vgT7OmsdjhBCCAs3Y0T7y7aWeHk5kZFR0OTHt7KyAuC3334hPz+fd975kPz8\nfP7xj9mXrHtxAaKql7YO/X25qqrodNXPKYqCoiiNHX6tpBPvRfqH+QCwYvMpjSMRQgghGkan02E0\nGms8l5ubi5+fPzqdji1bNlJRUXHNxwkICOTYsVgA9uzZdckxm5oUMBfpGuxO745exCbkEBOfrXU4\nQgghRL0FBYVw7NhRior+ugw0bNgI/vhjGw8+eC92dnZ4e3vzySdLr+k4AwYMpqioiHvvvYuDBw/g\n7OxyraHXi6Jerp3IzDVls1t+mZGHXt9CWx9Hnr09Al0zN4mJK2uuJldRP5IX8yW5MV8tITf5+XlE\nR+9j2LCRZGSk8+CD9/LVV9836jG8vJyuuEz6wPxNaKAr/bv6sCs2jT1xafTv6qt1SEIIIYTZsbd3\nYOPGDXz11TJUtYp//at5B72TAuYypgxpx96j6azccpq+nbwx6OVKmxBCCHExg8HACy8s1Oz48pf5\nMrxc7RjeJ4DMvFI2HbjyEMtCCCGE0IYUMFcwcUAwttZ61uxIoKSsUutwhBBCCHERKWCuwNnemnH9\n2lJYUsEvuxO1DkcIIYQQF5ECphZjItri7GDN+r2J5BWWaR2OEEIIIc6TAqYWNtZ6Jg0KobyiitU7\nErQORwghhGg006ZdT3FxMcuWfcqRI4dqLCsuLmbatOtr3X7z5t8BWLt2DVu2bGqyOK9ECpirGNzD\nDx83O7b8mUJqdrHW4QghhBCNavbs2+nWrUe9tjl3LoUNG9YDMH789QwdOrwpQquV3EZ9FQa9jqlD\nQ1ny4xFWbj3NfZO7aR2SEEIIcUV33jmLBQtexdfXl9TUczz11KN4eXlTUlJCaWkpDz/8/+ja9a+/\nZS+++BzDho2kV6/e/Pvfj1NeXm6a2BHg11/XsWLFt+j1OoKDQ3niiX/z2muLiIuL4ZNPllJVVYWr\nqytTp97EkiVvcvjwQSorjUydOoOoqAnMnftPIiL6ER29j9zcXBYteh1f32sfY00KmDoI7+RFiJ8z\n+46mczoln3b+MtGjEEKIq1t58icOpB++5Hm9TsFY1bCB8Ht7d+fG9hOvuHzIkOHs2LGVqVNnsG3b\nFoYMGU5oaAeGDBnG/v17+fLLz3jxxZcv2W79+nW0axfKAw88yu+//2pqYSkpKeHVVxfj5OTE/fff\nzalTJ7nlltmsXPkdd9xxNx999D4Af/4ZzenTp3j33Y8pKSlhzpybGTJkGAAODg68+ea7vPvuYrZu\n3ciMGTMb9NovJpeQ6kBRFGYMDwVg+aaTl52lUwghhDAH1QXMNgC2b9/CoEFD2bLld+699y7efXcx\neXl5l90uIeE03br1BKB373DT887Ozjz11KPMnftPzpyJJy8v97LbHz0aS69efQCws7MjOLgdSUlJ\nAPTs2RsAb29vCgsLL7t9fUkLTB11autGj1APDp3K4vDpbHqEemgdkhBCCDN3Y/uJl20tacq5kNq1\nCyUrK4O0tFQKCgrYtm0znp7ePPPMfI4ejeXtt9+47HaqCjpd9fx/VedbhyoqKnjttf/x6adf4eHh\nyeOPP3TF4yqKwsW/7ysrK0z70+v1Fx2ncRoBpAWmHqYODUUBVmw+aUquEEIIYW4iIwfxwQdLGDx4\nKHl5uQQEBAKwZcsmKisvPzhr27ZBHD0aB0B09D4AiouL0Ov1eHh4kpaWytGjcVRWVqLT6TAajTW2\n79w5jAMH9p/frpjk5LMEBrZtqpcoBUx9tPF2JLKbL2czitgVm6p1OEIIIcRlDR06nA0b1jNs2Eii\noibw7bdf8vDD9xMW1o2srCx+/nn1JdtERU0gJuYwDz54L0lJZ1AUBRcXVyIi+vGPf9zGJ58sZebM\n2bz11msEBYVw7NhR3nrrVdP2PXv2olOnztx//908/PD93HPPXOzs7JrsNSqqBXboaMopyK/WrJeZ\nV8LTH+zCxcGaBf/sj5VBf8V1ReNqCdPPt0SSF/MluTFfkpu68fJyuuIyaYGpJ08XO0b0CSQrv4xN\n0TLRoxBCCKEFKWAaYOKAYOxsDKz5I4Hi0gqtwxFCCCFaHSlgGsDRzorx/dtSVFrJOpnoUQghhGh2\nUsA00Ki+bXB1tOa3vUnkFMhEj0IIIURzkgKmgWys9Ewe3I7yyipWbY/XOhwhhBCiVZEC5hoM7O6L\nn4c92w6lcC6rSOtwhBBCiFZDCphroNdVT/SoqvD9ltNahyOEEEK0GlLAXKPeHTxpH+BC9PEMTiZf\nfn4JIYQQQjQuKWCukaIoTBsmEz0KIYQQzUkKmEbQsY0rvdp7cuJsHgdPZmkdjhBCCNHiSQHTSKYO\nbYeiwIotp2SiRyGEEKKJSQHTSAK8HBnY3Y+UzCJ2HDmndThCCCFEi9akBczx48cZNWoUX3zxBQB7\n9+7llltuYfbs2fzf//0feXnVnV4//PBDpk2bxvTp09myZUtThtSkJg8Kwcqg48dt8ZRXGK++gRBC\nCCEapMkKmOLiYubPn09kZKTpuYULF/Liiy+ybNkyevfuzbfffktSUhJr167lq6++4v3332fhwoUY\njZb5x9/d2ZZR4YHkFJTxe/RZrcMRQgghWqwmK2Csra1ZunQp3t7epufc3NzIzc0FIC8vDzc3N3bv\n3s3gwYOxtrbG3d2dgIAATp482VRhNbnxkUE42Br4+Y8zFMlEj0IIIUSTaLICxmAwYGtrW+O5p59+\nmvvvv5+xY8eyf/9+pkyZQmZmJu7u7qZ13N3dycjIaKqwmpyDrRUTIoMpLqvk551ntA5HCCGEaJEM\nzXmw+fPn8/bbbxMeHs6iRYv46quvLlmnLuOouLnZYzDomyJEALy8nK5p+5vGdmbjgWR+33+WGaM7\n4+Vm10iRiWvNjWgakhfzJbkxX5Kba9OsBcyxY8cIDw8HYMCAAaxZs4b+/fsTH//XZIhpaWk1Ljtd\nTk5OcZPF6OXlREZGwTXv54YBwXy8No6PVx3mzgldGiEy0Vi5EY1L8mK+JDfmS3JTN7UVec16G7Wn\np6epf8vhw4cJCgqif//+bN68mfLyctLS0khPT6d9+/bNGVaTGNDNlwBPB3YcOcfZjEKtwxFCCCFa\nlCZrgTly5AiLFi0iOTkZg8HA+vXref7555k3bx5WVla4uLiwYMECnJ2dmTFjBrfeeiuKovDcc8+h\n01n+8DQ6ncLUYaG8teIQK7ec5oFpPbQOSQghhGgxFNUCJ+9pyma3xmzWU1WVRV9Gc/xsHk/O6kPH\nNq6Nst/WSppczZPkxXxJbsyX5KZuzOYSUmujKArTh1dfDlu+WSZ6FEIIIRqLFDBNLDTAhfCOXpxK\nzif6eKbW4QghhBAtghQwzeDGoe3QKQrfbzmFsapK63CEEEIIiycFTDPw83BgcE8/UrOL2X5IJnoU\nQgghrpUUMM3khoEhWBt0/Lg9njKZ6FEIIYS4JlLANBM3JxtGR7Qhr7CcDfuStA5HCCGEsGhSwDSj\ncf2CcLSzYu2uMxSWyESPQgghRENJAdOM7G0NTBwQTEmZkZ/+SNA6HCGEEMJiSQHTzIb3DsDD2ZaN\n0WfJzC3ROhwhhBDCIkkB08ysDDpuHNKOSqPKD9vir76BEEIIIS4hBYwG+oX50MbbkV0xqSSmyVDS\nQgghRH1JAaMBnaIwbVgoKvD9ltNahyOEEEJYHClgNNItxJ3ObV05fDqLuDM5WocjhBBCWBQpYDRy\n8USPK2SiRyGEEKJepIDRUIifMxGdvYk/V8D+YxlahyOEEEJYDClgNHbjkHboddUTPVYaZaJHIYQQ\noi6kgNGYj7s9Q3r5k5ZTwraDKVqHI4QQQlgEKWDMwA0DgrGx0rNqRwKl5ZVahyOEEEKYPSlgzICL\now1jr2tDflE5v+6ViR6FEEKIq5ECxkyMva4tTvZWrNudSH5xudbhCCGEEGZNChgzYWdj4PoBwZSV\nG/lpR4LW4QghhBBmTQoYMzKsdwBerrZsOpBMukz0KIQQQlyRFDBmxKDXceOQUIxVKj9ulSkGhBBC\niCuRAsbMRHTxJsjHiV2xaZxJlYkehRBCiMuRAsbM6BSFacNDgeopBoQQQghxKSlgzFBYsDthwW7E\nJOQQE5+tdThCCCGE2ZECxkxNG3ZhosdTVMlEj0IIIUQNUsCYqSBfJ/p19eFMWgF749K1DkcIIYQw\nK1LAmLEp5yd6XLlVJnoUQgghLiYFzEV2n9vPW7s+ocJYoXUoAHi72jG8dwAZuaVs+VMmehRCCCEu\nkALmIunFGWw/s4eVJ3/SOhSTiQODsbXWs3pHPCVlMtGjEEIIAVLA1DA2eARtnP3YmryTA+mHtQ4H\nAGd7a6L6taWguIL1exK1DkcIIYQwC1LAXMRab83DA+7GSmfFl0eXk1ViHrcwj4log7ODNev3JJFX\nWKZ1OEIIIYTmpID5m0AXP2Z0nERJZSmfxHyFscqodUjYWhuYNDCYsgojq/9I0DocIYQQQnNSwFxG\npF8EfX16EZ+fyJrT67UOB4DBPf3xcbNj658ppGUXax2OEEIIoSkpYC5DURRu7nQjnnYe/Ja4mZis\nY1qHhEGvY+rQ6okeV8pEj0IIIVo5KWCuwM5gy11hs9Arej6P/YbcsjytQyK8kxchfs7sPZpO/Ll8\nrcMRQgghNCMFTC3aOgcypf0ECiuK+CzmG6pUbQeTUxSF6cOqJ3pcvukkqkwxIIQQopWSAuYqhgUO\npLtnV47nnmJ9wkatw6FzkBvd23lwNDGXIzLRoxBCiFZKCpirUBSFW7tMx9XGhZ/jf+NEjvb9T6YO\nbYcCLN8kEz0KIYRonaSAqQNHKwfuCJuJoih8Gvs1hRVFmsbT1seJ/mG+nM0oZHdMmqaxCCGEEFqQ\nAqaO2ruGMCFkNLlleSyL/U7z/idThoRg0Cus3HqaikqZ6FEIIUTrIgVMPYwJGk4nt/YcyYpj09nt\nmsbi6WLHiD6BZOWXsulAsqaxCCGEEM1NCph60Ck65nS9BScrR348uZYz+UmaxjNxQDB2Nnp++iOB\n4lKZ6FEIIUTrIQVMPbnYODGn680YVSMfx3xFSWWpZrE42lkxvn8QhSUVrNt9RrM4hBBCiOYmBUwD\ndPHoyJig4WSWZPH10e817Q8zqm8bXByt+W1vEjkFMtGjEEKI1kEKmAaaGDKGEOcg9qcf5I9zezSL\nw8ZKz+RBIZRXVrF6R7xmcQghhBDNSQqYBtLr9NwRNhM7gx3Lj68mpTBVs1gG9fDDz8OebQfPcS5L\n21u8hRBCiOYgBcw18LBzY3aX6VRUVfBRzJeUG8s1iUOvq57osUpVWblF+4H2hBBCiKYmBcw16unV\njaGBA0gtSmP58dWaxdG7gyehAc7sP57BqWTtJ54UQgghmpIUMI1gSugEAh39+ePcHval/alJDNUT\nPbYHZKJHIYQQLZ8UMI3ASm/Fnd1mYa235uuj35NenKlJHB3buNKrvSfHz+Zx8FSWJjEIIYQQzUEK\nmEbiY+/FLZ1upNRYxicxX1JRpc3AcjcObYeiwPebT1FVJa0wQgghWiYpYBrRdb596O/bl8SCZFad\nWqtJDIFejgzs5kdyZhF/HNHuzighhBCiKUkB08hmdJqMj703m5K2czgzVpMYJg8Owcqg44dtp8kr\nlMHthBBCtDxSwDQyG701d3WbhUFnYFnsd+SU5jZ7DO7OtowKDySnoIyH397BMx/t5qsNx/nzZCYl\nZTJnkhBCCMtn0DqAlijA0Y80RMjUAAAgAElEQVRpHa7nm2M/8EnMVzzY+//Q6/TNGsPkwe1wsrfm\nSHwWJ87mkZxRxIZ9Z9EpCiH+TnQJcqdrkBuhAS5YGaSOFUIIYVmkgGkig/z7cyz7JAcyDrM2YQPX\ntxvbrMe3MuiI6teWqH5tqag0cjI5n7gz2cQl5BCfUsCp5Hx++iMBa4OODoEudAl2p0uQG0E+Tuh0\nSrPGKoQQQtSXFDBNRFEUZnaeRmLBWdYnbKSDazs6u3fQJBYrg54uQW50CXKDIVBcWsmxpBziEnKI\nO5NDTEL1PwAHWwOd27rRJbh6fV93exRFChohhBDmRVEtcMSzjIyCJtu3l5dTo+4/IT+RV/cvwdHK\ngaeuewhna6dG23djySssI+5MDrFnqouarPxS0zI3JxtT8dM12B03JxvN4mzs3IjGIXkxX5Ib8yW5\nqRsvryv/zdQ/99xzzzXVgY8fP85NN92ETqejR48eVFRU8Pjjj7N06VJ+/vlnRowYga2tLatXr+bp\np59mxYoVKIpCWFhYrfstLm66OYccHGwadf+uNi5Y6604mHGElMJU+vr0MrsWDVtrA4HejvTu4MXo\nvoEM6OaLv5cDVgY96TklnErJ58CJTH7dm8SeuDTOZRVRUani4miNtaH5+vY0dm5E45C8mC/JjfmS\n3NSNg8OVfzQ32SWk4uJi5s+fT2RkpOm57777Djc3N1599VW+/fZb9u3bR2RkJO+88w4rVqzAysqK\nadOmMXr0aFxdXZsqtGY3os1gjuWcJDbrGBsStzAmaLjWIV2Roih4u9nj7WbPsF4BVKkqZ9MLiT1/\nuel4Ui4bo5PZGJ2MokCQjxNdgt3oGuROh0AXrK2at7OyEEKI1qnJChhra2uWLl3K0qVLTc9t2rSJ\nBx54AICbbroJgJ07d9K9e3ecnKqbifr06UN0dDQjRoxoqtCanU7RcVuXm1i45w3WnF5Pe9d2tHMJ\n0jqsOtEpCm19nGjr40RUv7ZUGqs4nZJffckpIZvTKfkkpBawblciBr2O9gHOdAmuvsMp2M8JvU7u\ncBJCCNH4mqyAMRgMGAw1d5+cnMzWrVt5+eWX8fT05D//+Q+ZmZm4u7ub1nF3dycjI6PWfbu52WNo\nwksXtV1za/A+ceKhgXfxwuY3+Czua/439mkcrR0a/TjNwc/XhYF92gBQUlZJzOksDp7I4NCJTI4m\n5nI0MZcfAHtbA93aedKzgyc9O3jR1tfpmi+fNUVuxLWTvJgvyY35ktxcm2a9C0lVVUJCQpg7dy5L\nlizh/fffp2vXrpesczU5OcVNFWKTdqzyVvwYFzSStQkbeHP7p9zdbbbZ9YdpiCBPe4I8g7ghMoiC\n4nKOJuYSm1B9y/ae2FT2xFZPaeDsYE3X8x2CuwS74eliV6/jSKc38yR5MV+SG/Mluamb2oq8Zi1g\nPD09iYiIAGDQoEEsXryYYcOGkZn51+zN6enp9OrVqznDalbjQkZxIvc0BzOOsDV5J0MDB2gdUqNy\nsrcmorM3EZ29AcjMKzHdrh17JoddsWnsik0DwNvVznS7dpcgN5zsrbUMXQghhAVp1gJmyJAhbNu2\njalTpxITE0NISAg9e/Zk3rx55Ofno9friY6O5umnn27OsJqVTtFxe9gtLNjzOitPrKGdSzBtnPy1\nDqvJeLrYMbinHYN7+qOqKimZRabbtY8l5bDlzxS2/JkCQBtvR7oGu9ElyJ2ObVywtZZhioQQQlxe\nk40Dc+TIERYtWkRycjIGgwEfHx9eeeUVXnzxRTIyMrC3t2fRokV4enryyy+/8NFHH6EoCrfeeis3\n3HBDrfu2pHFgruRIZhzvHvoEb3tPnuj7ILYG7cZX0YqxqoqEcwXnC5psTibnUWms/jjqdQrt/J1N\n48+083fGz9dFmlzNkDSFmy/JjfmS3NRNbZeQZCC7v2nOD9X3J9awMWkb1/n2YU7Xm5vlmOasvMLI\nieQ8U/+ZM6kFXPhw2ljpmTAwhHHXBcqdTWZGvojNl+TGfElu6sZs+sCImiaFjuNUbgJ7UqPp7NaB\nfn7hWoekKWsrPWHB7oQFV9+VVlRawdEzucSdyebPk5ms3HyS2NOZ3DO5G87SX0YIIVo1+SmrIYPO\nwJ3dZmKrt+Wb4z+QVpSudUhmxcHWivBOXtw6phPz7+pHvzBfjibmMv/TvZxJlV8uQgjRmkkBozFP\nOw9mdp5KubGcj2K+pMJYoXVIZsnOxsDTt1/H5EEhZOWXseCL/eyMSdU6LCGEEBqRAsYMhPv0ZKB/\nP5ILz7Hy5E9ah2O2dDqFGwaF8MC0Hhj0CkvXxPLN7ycwVlVpHZoQQohmJgWMmZjW4Qb8HXzZmryT\nA+mHtQ7HrPVq78m82/ri52HPr3uTePWbP8mXSdGEEKJVkQLGTFjrrbiz2yysdFZ8eXQ5WSXZWodk\n1vw8HJh3W196d/CUfjFCCNEKSQFjRvwcfJjRcTIllaV8EvMVxiqj1iGZNTsbA/ff2N3UL2bhF/vZ\nJf1ihBCiVZACxsxE+vWlr08v4vMTWXN6vdbhmD2d8le/GL1e4QPpFyOEEK2CFDBmRlEUbul0I152\nHvyWuJmYrGNah2QR/t4v5rVvD1Ig/WKEEKLFkgLGDNkabLmz2ywMip7PY78htyxP65AswoV+Mb3a\nexJ3JocXPt0n/WKEEKKFkgLGTLV1CmRy+wkUVhTxWcw3VKlySaQu7GwMzJ16oV9MqfSLEUKIFkoK\nGDM2LHAgPTzDOJ57ivUJG7UOx2KY+sVMlX4xQgjRUkkBY8YUReHWLtNxs3Hl5/jfOJFzWuuQLEqv\nDtIvRgghWiopYMycg5U9d4TNRFEUPo39msLyIq1DsijSL0YIIVomKWAsQKhrMBNCxpBblseyuO9Q\nVVXrkCyK9IsRQoiWRwoYCzEmaBid3TpwJCuOTUnbtA7H4ki/GCGEaFmkgLEQOkXHbV1vxsnKkR9P\nreNMfpLWIVkk6RcjhBAtgxQwFsTFxok5YTdTpVbx8ZEvKaks0Toki3S5fjGJadIvRgghLIkUMBam\ni3tHRgcNI7M0m6+PrpT+MA10oV/MpPP9YhYsk34xQghhSaSAsUATQ8bQziWI/ekH+SNlj9bhWCyd\nojBpUAj/mtodnU76xQghhCWRAsYC6XV67gibib3BjuUnVpFSKC0H16J3By+emdMXX3fpFyOEEJZC\nChgL5W7rxq1dplNRVclHMV9SbpQ/uNdC+sU0TKWxisTUfLmUKYRodvrnnnvuOa2DqK/iJvx17OBg\n06T7b0y+Dt4UVRQTkxVHQXkBPbzCtA6pSTV1bqwMOiK6eKMoCgdOZPLHkVQ8XW0J9HJssmNaIlVV\nOZmcx887z/Dxz3H8uPU0iqLQua2b1qGJv7Gk77PWRnJTNw4ONldcZmjGOEQTmNJ+Aqdz4/nj3F46\nubWnr29vrUOyaBf6xbT1cWTpmlg+WB3LmdQCpg0LRa9r3Q2W57KK2BmTxq6YVDLzSgFwcbDG3dmW\nVdvjcXe2YXAPf42jFEK0FopqgW2/GRlN17Tv5eXUpPtvCunFGby0900Anox4CG97T40jahrNnZtz\nWUUs/v4wqdnFdAly497J3XC0s2q245uDvKJy9sSmsTMmlYTzUzDYWOkJ7+RFZJgvXYLcqFAUHntz\nK6XlRh6c3oNuIR4aRy0usMTvs9ZCclM3Xl5OV1zW4AImISGB4ODghsZ0TaSAudSe1Gg+i/2GNk4B\nPBp+P1a6lte4pkVuiksr+fCnWP48mYmniy1zb+xOW58rn1AtQVm5kegTGeyMSSU2PocqVUWnKHRr\n507/MB96t/fCxlpvWt/Ly4kd0Um88s2fGPQKT87q0+LfI0thqd9nrYHkpm5qK2BqbRO/4447ajxe\nsmSJ6f/PPvvsNYYlGtN1vn3o79eXpIJkVp1cq3U4LYa97V/jxWTmnR8vJrbl3fVlrKriyOkslq6J\n4aHF21m6JpYjp7MJ8nVi5qgOvDZ3IA9N70n/rr41ipcLOrZx5e7ru1JWbuSN5QfJzi/V4FUIIVqT\nWn+mV1ZW1ni8a9cu7rvvPgC568AMzeg4mYS8RDad3U5Ht9AW36m3ubTUfjGqqnImrYCdR9LYHZdG\nflF1h0IvV1siw9rQP8wXX3f7Ou8vorM32SPa8+3Gk7y+/CBPzeqDvW3ruuQmhGg+tRYwiqLUeHxx\n0fL3ZUJ7Nnpr7uw2i5f3LeaLuOU85RSAm62r1mG1GBfGi1n8/WHW70kiMa3QIvvFZOaWsDO2ujPu\nuaxiABztrBjeJ4DIMF9C/Z0bfH6PiWhDZl4pv+8/y9srD/PITb0w6C23yBNCmK96dZSQosX8BTj6\nMbXDDXxzbCWfxHzFPT3uwN7KTuuwWowL48Vc6Bfzwqd7LaJfTGFJBfuOprMzJpUTZ/MAMOh1RHT2\nJjLMl27t3Bul0FAUhVtGdiA7v5QDJzL5ZG0c/5jYVb47hBCNrtYCJi8vj507d5oe5+fns2vXLlRV\nJT8/v8mDEw0zyL8fx3JOciD9EI9ve462zoF0cetAZ/cOhLgEYWiBHXyb04V+Mau3x7N6RwILlu3n\njvFd6NfVR+vQaqioNHLwZBY7Y1I5dCoLY5WKAnQJcqN/mA/hHb2xt238z4JOp/DPG8J45esD7IxJ\nw8PFlhuHhDb6cYQQrVutdyHNnj271o2XLVvW6AHVhdyFdHVlxnI2JW0jNusY8fmJVKnV8/tY66xo\n79aOLm4d6OTeAX8HX4v5dWyOuTlwPIOlP8VSWm4k6rq2TB3WTtN+MVWqyomkXHbGpLL3aAYlZdX9\n2AK9HIjs5ku/Lj64O9s26jGvlJf84nIWLNtPek4Jc6I6MbRXQKMeV1ydOZ4zoprkpm6a5DZqLUkB\nUz+llaWcyD3N0ewTHM05SWpRmmmZs7UTndw60Nm9PZ3dO+Bq46JhpLUz19xcPF5M12A37pnU/P1i\nkjMKqweZi00lO78MADcnG/p39aF/mC9tvJtuNOHa8pKWU8yLn++nuLSSB6b1oEeojBHTnMz1nBGS\nm7pqcAFTWFjIihUruP322wH45ptv+PrrrwkKCuLZZ5/F01ObAdOkgLk2uWV51cVM9kmO5Zwgv/yv\n1+vr4ENnt+pipoNrO2wNjftr/VqYc260GC8mp6CMPXFp7DySSmJ6IQB2NnrCO1X3a+nUxhWdrulb\n166Wl1PJefzv6wPoFIUnZvUm2Ne5yWMS1cz5nGntJDd10+AC5pFHHiEgIIBHH32U+Ph4brrpJt54\n4w0SExPZvXs3r7/+epMEfDVSwDQeVVVJKUrlWPYJ4nJOcDLnNOVVFQDoFB0hzm3p7N6Bzu4dCXIK\nRK+7dAyQ5mLuualSVVO/GGuDrkn6xZSUVRJ9vHqQubgzOagq6HUK3dt5ENnNl56hHlhbNW+O6pKX\n/ccyWPLDYZwdrPn37HA8XaVjeXMw93OmNZPc1E2DC5jp06ezfPlyAN577z1SUlJ44YUXgOr+MdIH\npuWprKokPu8MR88XNIn5Z1Gp/ojY6m3p6BZKJ/f2dHHrgLe9V7P2n7GU3DR2v5hKYxUx8dnsjEnl\nzxOZlFdW92cKDXAmMsyXiM7eONlbN1b49VbXvPy2L4mvN5zAz8Oep2eH4yBjxDQ5SzlnWiPJTd3U\nVsDUeguCvf1fg1jt2bOHadOmmR5bSsdPUT8GnYEObqF0cAvleqIorijmeM4pjuac5Gj2cQ5lxnAo\nMwYANxtXUzHTyb0DTtYyazNA745/jRfzy55EEtML6t0vRlVV4s8VsDMmlT1xaRQUV7eK+bjZERnm\nS/8wH7zd6j7InDkY3bcNWXml/Lo3icXfH+bRm3phZZAxYoQQDVNrAWM0GsnKyqKoqIgDBw6YLhkV\nFRVRUlLSLAEKbdlb2dPLuzu9vLsDkFWSzdGcExzNPsGxnJPsOrePXef2AdVj0HR270AXt46EugZj\nrdeuVUBrDR0vJj2nmF0x1ZMnpuVUn2NO9laMDA8kMsyXED8ni/7xMGNEe7LzS9l3LIOPfo7lnzeE\nobPg1yOE0E6tBczdd9/N+PHjKS0tZe7cubi4uFBaWsrMmTOZMWNGc8UozIiHnTsD7fox0L8fVWoV\nZwtTzncIPsGpvASSC8/xe+JWDDoD7VyCz7fOtKeNUwA6pXX92q7reDEFxeXsPT/I3Knk6vGVrA06\n+nX1ITLMh67BjTPInDnQKQp3X9+V3KI/2ROXjoezLdOHt9c6LCGEBbrqbdQVFRWUlZXh6PjX5YHt\n27czaNCgJg/uSqQPjHkqN1ZwKi++unUm+wRJhSmmZQ4Gezq6tz9/h1NHPO3c671/S85NjX4x/dpy\nw8BgDp3KYldMGodPnx9kToGuQW70D/OlT0cv7GwsY8DBhuSlsKSCF5ftJy27mFvHdGREn8Amiq51\ns+RzpqWT3NRNgzvxpqSkXGkRAP7+/g2P6hpIAWMZCsoLOZZzsvoOp+wT5JTlmpZ52rqb7m7q6BaK\ng9XV+3NYem5SMotYvPIwadnF6BSFqvOnXlsfRyLDfLmuiw9uTjYaR1l/Dc1Lem4JCz7fR0FJBXNv\n7E7vDl5NEF3rZunnTEsmuambBhcwnTt3JiQkBC+v6i+Wv0/m+PnnnzdimHUnBYzlUVWV9JJMjmVf\n6D9zilJjKQAKCm2dAs8XNO0JcQnG6jLTHbSE3BSXVvLJujiS0gqJ6OJN/64+BHhZdufna8lL/Ll8\nFn0ZDcATs/oQ4idjxDSmlnDOtFSSm7ppcAGzatUqVq1aRVFRERMmTGDixIm4u9e/6b+xSQFj+YxV\nRhILzlbfrp19gvj8MzWnO3BtV32Hk3tH03QHkhvzdK15+fNEJotXHsLJzoqnb+uLt4wR02jknDFf\nkpu6ueapBM6dO8cPP/zAmjVrCAgIYNKkSYwePRpbW21GaZUCpuUprSzjZO5p0x1O5y6a7sDJ2pFO\nbu0Z02kw/vpAi74LpyVqjHNmU/RZlv16HB93e/49O7zZp2JoqeT7zHxJbuqmUedCWr58Oa+88gpG\no5F9+/Zdc3ANIQVMy5dblsex7JOmgubCdAftXUOYFDqOdi7B2gYoTBrrnFm++STrdiXSPtCFx27q\n1ewjCrdE8n1mviQ3dXPNBUx+fj6rV69m5cqVGI1GJk2axMSJE/H29m7UQOtKCpjWRVVVEgvOsiFl\nM9EphwHo5tGFG0KjCHD00zY40WjnTJWq8sHqGPbEpdO3kxf3TO4mY8RcI/k+M1+Sm7ppcAGzfft2\nvv/+e44cOcKYMWOYNGkSHTt2bJIg60MKmNbJy8uJXScOs/r0Ok7mxqOgEO7Tk4khY/Gyl1mOtdKY\n50xFZRWvffsnx5JyGRPRhptHdmiU/bZW8n1mviQ3dXNNdyEFBwfTs2dPdJeZy2XhwoWNE2E9SQHT\nOl3IjaqqxGYfZ82pdSQVpqBTdAzwv45xwSNxtXHROsxWp7HPmaLSChYs28+5rGJuGdWB0X3bNNq+\nWxv5PjNfkpu6afBcSBduk87JycHNza3GsrNnzzZCaELUn6IohHl0oot7Bw6kH+an+PVsT97F7nP7\nGRY4kNFBw+o0rowwTw62Vjw8oycvfr6fbzacwN3JlvBOMkaMEKKmWscn1+l0PProozzzzDM8++yz\n+Pj4cN1113H8+HHeeOON5opRiMvSKTrCfXoy77pHmdl5Kg5W9vyWuJn/7HyJXxJ+p7SyTOsQRQN5\nutjx0PSeWFvp+WBNDCeT87QOSQhhZmq9hDRr1ixeeOEFQkND+f333/n888+pqqrCxcWFZ555Bh8f\nnytt2qTkElLrdLXcVBgr2Jq8k/VnNlJUUYyTlSNRwSMZGNDvsgPjicbRlOfMoVNZvLXiEPa2Bv49\nOxwfd2lZqw/5PjNfkpu6qe0S0lVbYEJDQwEYOXIkycnJ3Hbbbbz99tuaFS9CXImV3oqRbYfwfOST\njA8eRXlVOctPrOKFXS+z69w+00B5wnL0CPVg9tiOFJZU8Pp3B8kvLtc6JCGEmai1gPn7gGF+fn6M\nHj26SQMS4lrZGWyZ0G4Mz0c+yYg2g8kvL2BZ3He8uPs1/kw/TD2HPhIaG9orgIkDgkjPLeGtFYco\nqzBqHZIQwgzUWsD8nYyAKiyJk7UjUztcz3P9H2eA33Wkl2Sy9MgyXt73NkezT2gdnqiHKYPbERnm\ny+mUfD5YHUNVlRShQrR2tfaB6d69Ox4ef42vkZWVhYeHB6qqoigKmzdvbo4YLyF9YFqna81NWlE6\nP8X/SnT6IQA6ubXnhtAogp3bNlaIrVJznTOVxipe/+4gcWdyGBkeyMxRHeRH1VXI95n5ktzUTYPH\ngUlOTq51xwEBAQ2P6hpIAdM6NVZuEgvOsubUemKzjwHQ0zOMie3G4u/oe837bo2a85wpLq1k4Zf7\nSc4oYsbw9kT1k+KzNvJ9Zr4kN3XTqHMhmQMpYFqnxs7NiZzTrD69jtN5Z1BQuM63DxNCRuNhp/2M\n65akuc+Z7PxS/vv5PnILy7l3cjciOmszpYklkO8z8yW5qZsG34UkREvWwa0dj/S5j3t63I6/oy+7\nU/fz/K6X+e74j6bJI4X5cXe25aHpPbG11rN0TSzHk3K1DkkIoQEpYESrpigK3T278mTEg9ze9Rbc\nbF3ZcvYP/vPHS6w+9QvFFSVahyguo62PE/dN6Yaqqiz+/hDnsoq0DkkI0cyatIA5fvw4o0aN4osv\nvqjx/LZt2+jUqZPp8erVq5k6dSrTp09n+fLlTRmSEJelU3RE+Pbm2X6PcXOnKdgZbFl/ZiP/2fkS\nv57ZRLlRxh8xN91CPJgT1Zmi0kpe/+4geUWSIyFakyYrYIqLi5k/fz6RkZE1ni8rK+ODDz7Ay8vL\ntN4777zDp59+yrJly/jss8/IzZUmYaENvU7P4IBInot8gsmh4wFYdWodz+1cxNazO6msqtQ4QnGx\nQT38mDQohMy8Ut5cfpCychkjRojWoskKGGtra5YuXYq3d80Odu+99x4zZ87E2toagIMHD9K9e3ec\nnJywtbWlT58+REdHN1VYQtSJtd6a0UHDeD7ySaKCRlBiLOPb4z8wf9cr7EmNllF9zcgNA4MZ1N2P\nhNQC3lt1BGOV5EaI1qDJJogxGAwYDDV3Hx8fz9GjR3nwwQd5+eWXAcjMzMTd/a+7Ptzd3cnIyKh1\n325u9hgM+sYP+rzaej0LbTV/bpy40386N5aOZWXsOn47tY3PYr9hU/I2bu5+A+H+3WUsErQ/Zx6d\n3ZeiD3dx4HgGK7clcO/UHpKX87TOjbgyyc21adYZ7hYuXMi8efNqXacud3Xn5BQ3VkiXkFvbzJe2\nuVG4vs14Bnj25+f439iTGs3/tr9LiHMQN4RG0dEtVKO4tGcu58w/JnThpdwS1u1MwMFGz/j+QVqH\npDlzyY24lOSmbsziNuq0tDROnz7NY489xowZM0hPT+fWW2/F29ubzMxM03rp6emXXHYSwlx42Llz\nW9eb+He/R+jl1Y34/DO8eeB93v7zQxLzz2odXqtmZ2Pgoek9cXOyYcXmU+yKSdU6JCFEE2q2Fhgf\nHx82bNhgejxixAi++OILSktLmTdvHvn5+ej1eqKjo3n66aebKywhGsTPwYe7u9/GmfwkVp/6hbjs\n48RlH6e3V3cmthuLr4MU4Vpwc7Lh4Rk9WfjFfj5eG4ebkw2d2rppHZYQogk0WQFz5MgRFi1aRHJy\nMgaDgfXr17N48WJcXV1rrGdra8ujjz7KXXfdhaIo3H///Tg5yXVBYRmCnNvwr953cyz7JKtOr+NA\nxmH+zDhCf7++jA8Zhbut/PFsboFejsyd0p3XvjvI4u8P89TscAI8HbQOSwjRyGQqgb+R65Lmy9xz\no6oqhzJjWH16PalFaRgUPYMDIxkbNAIna0etw2sy5pqXnUdSWfpTLB7ONjw9uy9uTjZah9TszDU3\nQnJTV7X1gdE/99xzzzVfKI2juLjpBqxycLBp0v2LhjP33CiKgq+DN4MD+uNl50FiwVlis4+zLXkn\nFVWVtHEKwErXrP3mm4W55qWNtyM6nUL08UyOJubQr6sPVobWNfi4ueZGSG7qysHhyj88pAXmb6Qq\nNl+WlpuKqkp2pOzml4TfKSgvxMHKnjFBwxkSMABrvVWjHENVVSpVI5VVFVRWGamoqqCyqvKi/xup\nrKqs/r964f+V59ep+a+iqpJKtfJv69TcZ2VVBRXn93Phn42VNZPbTaCPd49GeU2NSVVVPvvlGFsP\nptCtnTsPTO2BQd96ihhLO2daE8lN3chs1PUgHyrzZam5KTOWsylpOxsSN1NSWYqrjQv9fcNBUWoU\nGZcUE+cLiorLPX++mKhUm2/kWZ2iw6AzYKUzYFAMGHTV/3LKcqgwVjK5/XhGthliduOvGKuqWPz9\nYQ6dymJITz/mRHU2uxibiqWeM62B5KZupICpB/lQmS9Lz01RRTG/ndnM5rM7qKiqqNM2pqLhooLB\nVEToDBh0eqx0Vhh0+vNFhRVWOn2NdWusr1xp+4v+r1zYvua+dMrlWy4KDbks2LyYvPIChgYOYFqH\nG664rlZKyytZ9OUBzqQVMGVwCNcPDNE6pGZh6edMSya5qRspYOpBPlTmq6XkJr+8gJTC1GsqGsyJ\nl5cTx5ISeffgJ6QUpdLdsyt3hM3ERm+tdWg15BWW8d/P95OVX8pdE7owsLuf1iE1uZZyzrREkpu6\nMYuB7IQQ1Zytnejs3oH2riEEO7clwNEPHwdvPOzccbFxwt7KHmu9tUUULxe427rxSPi9dHJrz+HM\nWN6Ifo/8cvP6cnZxrB4jxt7GwKfrjhKbkK11SEKIa2A535BCCLNmZ7Djvp530s83nMSCs7yy721S\ni9K0DqsGf08H/jW1O4oC7/xwmLPphVqHJIRoIClghBCNxqAzMLvLDMaHjCarNIdX9i/hRM4prcOq\noVNbN+6a0JWSMiOvLz9Idn6p1iEJIRpAChghRKNSFIUJIaOZ3WUGZcYy3v7zQ/amHtA6rBr6dfVh\n+rBQcgrKeGP5IUrKKkTdEIAAACAASURBVLUOSQhRT1LACCGaRH+/vtzf8y4MOis+jf2a9Qkb6zTb\nfHOJ6teW4X0COJtRyDs/HKbSWKV1SEKIepACRgjRZDq7d+CR8Htxs3Fl9elf+PrY9xirmm/smtoo\nisLMUR3o1d6T2IQcPlt31KwKLCFE7aSAEUI0qQBHPx7rez+Bjv7sSNnDe4c+pbTSPPqd6HU6/u+G\nMEL8nNhxJJVV2+O1DkkIUUdSwAghmpyrjQsP97mHru6diM0+xuvR75Fblqd1WADYWOt5YFpPPF1s\nWb0jgRWbT1FYUreBBoUQ2pECRgjRLGwNttzT43YG+vfjbGEKL+97m+TCc1qHBYCLgzWP3NQLZwdr\n1u46w2NLdvDVb8fJzCvROjQhxBXIbNR/IzOEmi/JjXmqT150io5uHl2w0llxMPMIe1P/JMg5EE87\njyaO8uoc7awY2ssfZ3srEtMLiU3I4ff9yaTmFOPlaoeL45VnxTVXcs6YL8lN3dQ2G7UUMH8jHyrz\nJbkxT/XNi6IohLqG4G3nyZ8Zh9mTFo27rSuBTv5NGGXdWBl0hAa4MDI8EG83O9Kyi4k7k8PmP1M4\nlZKHq6MNni62FjMZpJwz5ktyUze1FTCGZoxDCCFMInx742rjwgeHP2NZ3HdklWQzPmS0WRQHBr2O\ngd39GNDNl0Onsli3O5Ejp7M5cjqbED8nxvULok9HL3Q67WMVorWSyRz/RibYMl+SG/N0rXlJLUpn\nycGPyCrNoZ9vODM7T8WgM7/fVqeS81i3O5EDxzNQAW83O6Kua8vA7r5YGfRah3dZcs6YL8lN3chs\n1PUgHyrzJbkxT42Rl/zyAt49+AmJBWfp5Naeu7vPxs5g10gRNq5zWUWs35PIH0dSqTSqODtYMyo8\nkOF9AnCwtdI6vBrknDFfkpu6kQKmHuRDZb4kN+apsfJSZiznk5ivOJwZ+//bu/f4qOoD7+OfSSa3\nyeQ2SSYXckECARIu4SIIaL3bR7eLrYooQt3aduuiz7Zd24puu3Zf7rNd7HYf18pqq6gURVG0lj5W\nqq7iIiIogRACJOFiyP1+TyaXmXn+SIhgISSQyTmTfN+vl6++zAyTX/yeE74953d+P5LCE1g9+x4c\noTEjMELfaGzt4r29pWzfV05nl5uQ4ECunJ3MDZem4ogMNXp4gM4ZM1M2QzNYgdEk3i/RxCrzUjbm\nNFK5WAMCmeucRUdvBwfrj5BbnUdmzGSiQiJHYJQjLyzESvZEB1fPSSE8zEpJdWv/k0tl1DZ2kuCw\nEWkLNnSMOmfMS9kMjZ5CGgYdVOalbMxpJHOxWCxkOaYSag0lr7aAT6tzSYlIxmmLG5HP94UgawBT\nUqK5dm4K8VGhVDZ0cKikkQ9yy/m8sgVHZCixUcZckdE5Y17KZmhUYIZBB5V5KRtzGulcLBYLk6LS\nSQpPZH9tPp9W7yMy2E5aZMqIfQ9fCAywkJ4YwdVzJ5CeEEF9i4vDJU18lF9JwYkG7GFBJDhso/qU\nlc4Z81I2Q6PHqEXE78xxziQqJJKnDzzPy4VvUO9q5K8nfZUAi7kXEA+wWJiTGc+czHiKSpvYtvsk\n+4/W8es38kmKtfG/FqRxWXYiQVZz/xwiZqcrMF+iVmxeysacfJlLTGg0s+OzOVRfSH7dIWo765gR\nN51Ak5eYU2KjQlmYlcD8qfF097opPNlEbnEdHx2owOP1khJv92mR0TljXspmaAa7AqOnkL5EM8PN\nS9mY02jk0tbdztMHXuBESwmToy/hb2feTXiQzaff0xcaWly8+1kp2/dX0NXtJiwkkKvmTOD6+alE\n+2CrAp0z5qVshkaPUQ+DDirzUjbmNFq5dLt72HDoFfbX5pNgi2f17G8TF+bw+ff1hXZXDx/klvPe\nZ6W0dPRgDbSweEYiX12QRlJs+Ih9H50z5qVshkaPUQ+DLuuZl7Ixp9HKJTAgkDnOmXS7u8mvP8ze\n6v1MiZlEdEiUz7/3SAu2BpKZGs2181JwRIRSXtfOoc/7nlwqrWkjNioUR8TFP7mkc8a8lM3Q6Cmk\nYdBBZV7KxpxGMxeLxcL02EzsQeF9G0FW5ZIUnkhiuHNUvv9ICwwIYGJSJNfMTSEl3k5tUyeHSxrZ\nkVfJkZJGIsODcMaEXfCTSzpnzEvZDI2eQhKRMeXKlMU4QqN57uBLPJP/O27LXMpVKUuMHtYFCwiw\nMH+ak3lT4zlysom3d5dw8HgDhaVNTIgP58aFaSyYnoA10D8mL4uMBl2B+RK1YvNSNuZkVC4Jtnim\nOzI5UFvAvtp8XL0upjmmmGI36wtlsViIjw5jUXYic6bE4epxU1jSxN6iWnYerAQsTIgPH3KR0Tlj\nXspmaHQLaRh0UJmXsjEnI3OJDokixzmTww1FHKw/TGV7NTPjsggMMOfu0MMRZQ9h3lQni2ck4vVC\ncXkzeUfr2b6vHFe3mwlx4YQED/5z6pwxL2UzNHqMehg0M9y8lI05mSGXjp4Ofpv/O4qbjnNJZDrf\nm3U3EcF2Q8c00to6e3h/bxnv7S2jrbOHIGsAl89M4qsLUnHGnP2RcjNkI2enbIZGj1EPgw4q81I2\n5mSWXHo8vbx4+FU+q95PfFgsq2ffg9MWb/SwRlxXj5uPDlTy5z0nqWt2YbHA/KlObrwsjYmJZ258\naZZs5C8pm6HRY9TDoMt65qVszMksuQRaApgdn43H6+FA3SE+q95PRvREYkKjjR7aiLIGBjApOZJr\n5k0gOTacmsa+J5c+3F9BUWkT0fYQ4qNDsVgspslG/pKyGRrNgRkGHVTmpWzMyUy5WCwWpjomEx0c\nyf7ag+ypyiXBFk9SeILRQxtxARYLKfF2rsxJZkpKNE1tXRwuaWRXQRX7j9YRFmIlIzWazs4eo4cq\nZ2Gm88bMNAdmGHRZz7yUjTmZNZeC+kLWH9xIt7uHr0++iWtTv+LXTygNxedVLbz9yUk+K6zB64UI\nWzBpznDSEiL6/7GT4LARMMb/O/gDs543ZqM5MMOgg8q8lI05mTmX0tYKnsp7jubuFq5MWcxtU5aa\nfjfrkVDT2MGfPy3l0OeNVDd0nPFaSHAgqU476c6+QpOWEDGsR7NlZJj5vDETFZhh0EFlXsrGnMye\nS6Orif/Ke46K9ipmxmXxrewVhAQGGz2sUREfH0FJaQMnq9s4Wd1KSXUrJ6vbqKhv5/Tf/IEBfevL\npCVEkN5/pSbVaSc0WGud+orZzxuzUIEZBh1U5qVszMkfcuns7eTZ/Bc50lhMWkQK9876FlEh5/7F\nOFacK5vuHjdlte2nlZpWymrb6en1DLzHAiQ4bKQl2PtLTV+xibCNj/Lna/5w3piBCsww6KAyL2Vj\nTv6SS6+nl5ePvMEnVZ8RGxrD6tn3kDgGJ/eebjjZuD0eKus7ONl/laakqpWTNW10dvWe8T5HZAhp\n/befThUbR2TImJ9fNNL85bwxmgrMMOigMi9lY07+lIvX6+Xtz9/jrRPvEmYN43szv8mUmAyjh+Uz\nF5uN1+ulttnFyapWTta0UlLVdyuquf3Mp2fsYUED82lOFZuEGBsBASo15+JP542RVGCGQQeVeSkb\nc/LHXD6p/IyXjmwhAAsrp9/OpYlzjB6ST/gqm+a2Lkr659Wcug1V2+Q64z0hQX2ThU8Vm/SECJLj\nwgmyarIw+Od5Y4TBCoxmaInIuHNZ0nyiQ6J4Jn8jLxx6mQZXIzekX63bIEMUZQ9hlj2EWRmxA1/r\ncPVSWtN6RrE5XtHC0fLmgfcEBliYEBc+cKUmLSGCVKedsBD9VSTDp6NGRMalaY4pPDBvNf+V9xxb\nj2+j3tXA8sxvjImNII1gC7UyNS2GqWkxA1/r7nFTXtc+8PTTyepWSmvaOFnTBvl977EAToeN9NNu\nQaUlRBCpycJyHrqF9CW6rGdeysac/D2Xpq5mns57ntK2CrIcU7lnxgrCrGFGD2tEmDEbt8dDVX1H\n30Th/is1J6vb6PjSZOGYiJCBR7pP3YIaS5OFzZiNGWkOzDDooDIvZWNOYyEXV6+L9QUvcai+kNDA\nUOYn5rAkeQFpESlGD+2i+Es2Xq+XumZX/3yaL25BNbWdOVk4JiKEKSlRZKZGMyUlmgnx4X67qrC/\nZGM0FZhh0EFlXsrGnMZKLm6Pm3dPfsiO8l00dfXN20iLmMDi5IXMT8ghzBpq8AiHz9+zaW7vHigz\nJypbKS5rorXji72dbCFWJqdEDZSaiYmRfjNJ2N+zGS0qMMOgg8q8lI05jbVcPF4Ph+oL+ahiNwX1\nR/B4PQQHBjPfOZvFyQuZGJnqN7cxxlo2Xq+X6sZOikqbKC5rori0mZqmzoHXrYEBTEqKYEr/FZrJ\nE6KwhZpzqudYy8ZXVGCGQQeVeSkbcxrLuTR1NfNJ5Wd8XLGHelcjABPsSSxOXsCChLnYgsw9V2Ys\nZ3NKU1sXxWXNA6WmtKZtYJsEC5DitJOZEs2U1CimpEQTE3Hu3Y1H03jIZiSowAyDDirzUjbmNB5y\n8Xg9FDYcZWfFbvLqCvB4PQQFWJnrnM3i5AVkRE005VWZ8ZDNl3W4ejle0UxRWRNFpc0cr2ih1/3F\nFglxUaFkpkb3z6OJItFhMyS78ZjNhVCBGQYdVOalbMxpvOXS0t3K7sq97KzYTW1nPQCJNieLkxew\nMHEe9uBwg0f4hfGWzdn09HooqeqbP1NU2sTR8mbaXV888RRhC2JKSvTAPJpUp31UduZWNkOjAjMM\nOqjMS9mY03jNxev1Utx0jJ0Ve9hfk0+v143VEsjs+BksSV7IlJhJBFiMnVA6XrMZjMfrpaKuneLS\npr5bT2VNNLR0DbweEhTIpOTIgUKTkRxFSPDIrw2kbIZGBWYYdFCZl7IxJ+UCbd3t7Knay86KPVR1\n1AAQHxbL4uQFXJY0n8hgY3a+VjZDU9/soqisaaDUlNe1D7wWYLGQnmjvv0rTN5dmJBbZUzZDowIz\nDDqozEvZmJNy+YLX6+V4cwk7K3aTW5NHj6eXAEsAs+KyWZK8gGmOKaN6VUbZXJi2zh6O9l+dKS5t\n4vOqVtyeL/6qTHTYyOyfFDwlNZr4qNBhz6NRNkOjAjMMOqjMS9mYk3I5u46eTj6t3sfOit2Ut1UC\n4AiNYXHSAhYl9+3F5GvKZmR09bg5UdHSN4+mrJmj5c10dbsHXo+2BzMl5YuJwSnx9vPuxK1shkYF\nZhh0UJmXsjEn5TI4r9dLSWspO8v38FnNfrrd3ViwMCNuGkuSF5LlmOqz/ZeUjW+4PR7KatoHHt0u\nKmumpf2LVYPDQgKZPOGLicGXJEUQZD0zY2UzNCoww6CDyryUjTkpl6Fz9br4rHo/Oyv2cLK1DIDo\nkCgWJc1nUdICYsNizvMJw6NsRofX66WmqX+BvdJmisuaqG48fYE9CxOT+icGp0QzOSWKiakOZTME\nKjDDoBPevJSNOSmXC1PaWs7Oij18WrUPl9uFBQvTHZksSV7AzLisEbkqo2yM03xqgb2yvonBJ6tb\nz1hg76+/Momli9L9di+n0WJYgSkqKmL16tX8zd/8DStXrqSyspKHHnqI3t5erFYrv/zlL4mPj2fr\n1q1s2LCBgIAAbr/9dpYtWzbo56rAjE/KxpyUy8XpcneTW3OAneW7OdFSAkBEsJ1FSZeyOGkB8bbY\nC/5sZWMenV29HKtopri0mT2Hq6lu7GTJzES+deP0886XGc8GKzA+2ySio6ODRx99lEWLFg187fHH\nH+f222/npptu4qWXXuL555/n/vvvZ926dWzZsoWgoCBuu+02rr/+eqKjo301NBER0wgJDO6/hTSf\nirYqPq7Yw+6qvbxT8gHvlHzA1JjJLElewKz4GQQFmHNfHzm/4CALoTEtWD1FOMKOEVjqZGc+dPd4\n+O5fZ43K4nljjc/OhuDgYJ555hmeeeaZga898sgjhIT07UMRExNDQUEBeXl5zJw5k4iIvpY1d+5c\ncnNzueaaa3w1NBERU0q2J3Jb5lKWZtzI/tp8dlbsprDxKIWNR7EHhbMgcS5LkheSGO40eqgyBI2u\nJg43FFFQX0hhYzGdva6B1yzRJ5kw+TI+PdK3WvDffT37Lyb6yuB8VmCsVitW65kfb7PZAHC73Wza\ntIn77ruPuro6HA7HwHscDge1tbW+GpaIiOkFBwaxIHEuCxLnUt1ew87KPeyu3Mv7pTt4v3QHGVGX\nsCR5AXOcswgODDJ6uNKvx9PL8abPOdRQyKH6QiraqwZeiw2NYX7CHLIcmYQHhfPUgedojt3DJMuV\n7C+u4z+3HOB/3zLLJ6v+jlWjfj3S7Xbzk5/8hMsuu4xFixbxxz/+8YzXhzIlJybGhtWHTXWwe25i\nLGVjTsrFd+LjI5gxMYN73LfxafkB/vv4R+RXH+FY8wleP7qVKyYu5LpJl5MWPeGcf158p6atjv1V\nBeyrLOBgTRFdvX3bEgQFBpGTmEVOUjY5Sdkk2Z1nLHZnj/we/+d/nqQp/mNmhd7AgfxGnngjn0e+\ncxnhYSqlQzHqBeahhx4iPT2d+++/HwCn00ldXd3A6zU1NeTk5Az6GY2NHT4bnya9mZeyMSflMnqm\nhGUyJTuT2kvq+bhyD59Ufsa24u1sK97OJZFpLE5eyLyE2YQE9i11r2xGXre7h+Km4xyuL6Sg4Qg1\nHV/8/ZVgiycrcSpZsVOZHD3pi6tjLqhztZ3xOTMSpnH39OU8X/Ay1VEfkJN1PfsPNbDmyR38w/Ic\n7CoxgEGTeM9m69atBAUF8fd///cDX5s9ezY//elPaWlpITAwkNzcXB5++OHRHJaIiF+Jt8Vyc8aN\nfO2SG8ivP8zOit0cri/iRMtJXi/eyvzEOSxJXkB8/HSjh+r3vF4vNR21HGoo4lB9IcVNx+jx9O1m\nHRwYzMy4LLIcfaUlLsxxnk8707yEHFq629hSvJXQ+P9h4czr2Z3fyNpNufxoeQ5R9hBf/Ehjhs8e\noz548CBr166lvLwcq9VKQkIC9fX1hISEYLfbAcjIyODnP/8527ZtY/369VgsFlauXMnSpUsH/Ww9\nRj0+KRtzUi7m0OBqZFfFp3xc+SlNXc0AJNmdJIQlkBSeQFK4k6TwRJy2OKx6mmlQrt4uihqPDpSW\nelfDwGvJ4YlkxU4lO3Yqk6ImXvB/y9PPmzeP/ol3T24nPSKVxMZr2J5bTYLDxo/vyMERGToiP5O/\n0kJ2w6BfxualbMxJuZiLx+vhUH0hOyv2UNx8jM4e1xmvB1gCcIbFkRh+qtj0/TOei43X66WivYpD\n9YUcaijiWNMJ3N6+vY7CrKFMi5lCVmzfVZaR2sPq9PPG6/Wy8fCr7K7aS7ZjGrGNl/Pn3WXERoby\n4ztzcMbYRuR7+iMVmGHQL2PzUjbmpFzMKy7OztHycirbqqnsqO773/a+f1zu8V1sOno6OdJYzOH+\n0nLqqhVAWsSE/ttC05gYmeqTvaq+fN64PW6ePvAChxoKWZg4j+iGS3nzo8+JtgfzozvmkBwXPuJj\n8AcqMMOgX8bmpWzMSbmY17my8Xq9NHe3jKti4/F6KGutGHjE+UTLSTxeDwDhQTamOzIH5rJEBNt9\nPp6zZePq7eKJfb+lpLWUG9KvJqw+m1feP0qELYgHlueQljD+nihTgRkG/TI2L2VjTsrFvIabzVgr\nNm3d7RxuKOJQQyGH64to7el7EsiChYmRaWTFZpIVO5W0iBQCLKO7Eu65smntbuM/9v4XNZ11LJty\nM9RPZOO2QsJCrPxw+WwykkfmFpa/UIEZBv0yNi9lY07KxbxGKht/KTYer4eSllIK6gs51FDIyZYy\nvPT9FRcZHNF/hSWTaY5MwoOMnVcyWDZ1nQ38au86Wrvb+Fb2CrprE3j2rUMEBwXyg9tmMTVtZHct\nNzMVmGHQL2PzUjbmpFzMy9fZXEixSQpPOKPcXGyxae5q5XD/baHDDUV09HYOfL+MqIkDt4Um2JPO\nWEjOaOfLprS1nMdzn6bX08t9Od+mpTqS32wtICDAwv23zGTmpAvf5NOfqMAMg34Zm5eyMSflYl5G\nZXNGsWmvorK9ZsSKjdvj5nhzycBclrK2ioHXYkKiB54WmhozmTCreR9BHko2hQ1HWZe3nqCAIH44\n914aaoJZ9/uDeDxe7r15BvOmxo/SaI2jAjMM+mVsXsrGnJSLeZktm4spNvagcIqajlHYUIzL3bdc\nv9USyOToSQPrsiTYnKa6yjKYoWazt3o/zxVsIjI4gh/Nu4+aGgtPbDlAT6+H73xtOpdlJ47CaI2j\nAjMMZjvh5QvKxpyUi3n5SzbDKTbxYbF9V1kcU5kSkzGwbYK/GU42H5R+xJbirThtcfzD3NVU17r5\nv6/m4erq5e4bp/GV2ck+Hq1xTLOVgIiIyJdZLBaiQ6KIDoliemzmwNdPLzYt3a1cEpWO0xZn4EiN\ncXXq5TR3tfDuye08deB5vj/ne/zkzjn8avN+Xnj7CF09bq6fn2r0MEfd6D43JiIiMkSnis302EwW\nJs0bl+XllJszbmRh4jxKWkpZf/BFUpw2HrxrLlH2YF5+r5i3dn1u9BBHnQqMiIiIyVksFu6adhtZ\njqkU1B/hpSNbSI61seauucRGhvD6h8d5/cNj+OGskAumAiMiIuIHAgMC+faMlaRHpLK7ai9bj28j\nIcbGmrvm4YwJ461dJbz838XjpsSowIiIiPiJUGsIfzf7WzjD4nin5AO2l+4kNiqUNXfNJTkunPc+\nK2PDtiN4PGO/xKjAiIiI+JGIYDv35XyHyOAIthRvZW91HtH2EB5cMYe0BDv/k1fJs//vEG6Px+ih\n+pQKjIiIiJ+JC3OwevY9hAQG87tDr1DUeJQIWzA/uXMOGRMi+eRQNU+9WUBP79gtMSowIiIifig1\nYgJ/O/NuvMBvDvyOstYKbKF9O1dPS4smt6iWX79xgK4et9FD9QkVGBERET811TGZu7OW43K7WJe3\nnvrOBkKDrfxg2WxmZcRy8HgDj7+aR2dXr9FDHXEqMCIiIn5sXkIOt01ZSkt3K0/mPUtrdxvBQYHc\nf8tM5k2Np7C0iV9t3k+7q8fooY4oFRgRERE/d3Xq5VyfdhU1HXU8deB5utzdWAMDuPfmbBZlJ3K8\nooXHNu2jpb3b6KGOGBUYERGRMeDLq/W6PW4CAwL49temc9WcCZTWtLF2Uy6NrV1GD3VEqMCIiIiM\nAWdbrdfr9RJgsbDqhkxuuDSVyvoO/u2lvdQ1dRo93IumAiMiIjJGnG21XugrN8uvmczSJROpbXLx\ni5dyqWroMHi0F0cFRkREZAw522q90Fdivn7FJJZdlUFjaxf/9lIuZTVtBo/2wqnAiIiIjDFnW633\nlBsvS+eu6zNpae9m7aZcTlS2GDjSC6cCIyIiMgadbbXeU66dl8I9N02no6uXX768j6LSJgNHemFU\nYERERMaos63We8rls5L43tJseno9/Mer+yn4vMG4gV4AFRgREZEx7Gyr9Z6yYHoC931jJh6Pl/98\n7QD7j9YZONLhUYEREREZ4862Wu8pOVPi+P6y2QQEwLo38vn0SI2BIx06FRgREZFx4Gyr9Z6SPdHB\nP9yeQ5A1gKf/cJCd+ZUGjnRoVGBERETGibOt1ntKZmo0P75zDrYQK+vfOsz7uWUGjvT8VGBERETG\niXOt1nvKJUmRPLhiLpG2IF58p4htu08aONrBqcCIiIiMI+darfeUFKedNSvnERMRwqsfHOXNHcfP\nKDlmoQIjIiIyzpxrtd5TEh02HrprLvHRoWzd+TmvfXDMdCVGBUZERGQcGmy1XoC46DDW3DWPpFgb\n2/ac5MV3ivCYqMSowIiIiIxTg63WCxATEcKDK+aS6rTzwb5ynnvrMG6Px6DRnkkFRkREZBwbbLVe\ngMjwYH6yYg6TkiP5+GAVv9l6iF638SVGBUZERGScG2y1XoDw0CAeWJ5DZmo0nx2p4ck38unpdZ/j\n00aHCoyIiIgMulovQFiIlR/ePpsZlzg4cKyex187gKu716DRqsCIiIhIv8FW6wUICQrkf986izlT\n4jhc0sh/bM6jw2VMiVGBERERkQGDrdYLEGQN4O++PoPLshI4Wt7MU384aMg4rYZ8VxERETGlU6v1\ntna3DazWu2r67VgsloH3WAMD+M7XsoiNCjXs0WpdgREREZEznG+1XoCAAAu3XpnBsqsmGzBCFRgR\nERE5i/Ot1ms0FRgRERE5q/Ot1mskFRgRERE5p/Ot1msUFRgREREZ1PlW6zWCCoyIiIic1/lW6x1t\nKjAiIiIyJOdbrXc0qcCIiIjIkJ1vtd7RogIjIiIiw3L6ar0vHX7NkDFoJV4REREZllOr9bq9brwG\nrcSrAiMiIiLDFhgQyLeyVxj2/XULSURERPyOCoyIiIj4HRUYERER8TsqMCIiIuJ3VGBERETE76jA\niIiIiN9RgRERERG/owIjIiIifsenBaaoqIjrrruOF198EYDKykpWrVrFihUr+P73v093d9/+CVu3\nbuXWW29l2bJlvPaaMUsSi4iIiP/wWYHp6Ojg0UcfZdGiRQNfe+KJJ1ixYgWbNm0iPT2dLVu20NHR\nwbp163jhhRfYuHEjGzZsoKmpyVfDEhERkTHAZwUmODiYZ555BqfTOfC13bt3c+211wJw9dVXs2vX\nLvLy8pg5cyYRERGEhoYyd+5ccnNzfTUsERERGQN8theS1WrFaj3z4zs7OwkODgYgNjaW2tpa6urq\ncDgcA+9xOBzU1tYO+tkxMTas1sCRH3S/+PgIn322XBxlY07KxbyUjXkpm4tj2GaO59q9cii7WjY2\ndoz0cAbEx0dQW9vqs8+XC6dszEm5mJeyMS9lMzSDlbxRLTA2mw2Xy0VoaCjV1dU4nU6cTid1dXUD\n76mpqSEnJ2fQz/F1a1UrNi9lY07KxbyUjXkpm4szqo9RL168mD//+c8AvPPOO1xxxRXMnj2b/Px8\nWlpaaG9vJzc3l/nz54/msERERMTPWLxDuWdzAQ4ePMjatWspLy/HarWSkJDAv//7v7NmzRq6urpI\nTk7mF7/4BUFBGPbxpgAABnZJREFUQWzbto3169djsVhYuXIlS5cu9cWQREREZIzwWYERERER8RWt\nxCsiIiJ+RwVGRERE/I4KjIiIiPgdFZjT/Ou//ivLly/njjvu4MCBA0YPR07z2GOPsXz5cm699Vbe\neecdo4cjp3G5XFx33XW88cYbRg9FTrN161aWLl3KLbfcwvbt240ejgDt7e3cf//9rFq1ijvuuIMd\nO3YYPSS/ZthCdmazZ88eSkpK2Lx5M8eOHePhhx9m8+bNRg9LgE8++YTi4mI2b95MY2Mj3/jGN7jh\nhhuMHpb0e+qpp4iKijJ6GHKaxsZG1q1bx+uvv05HRwe//vWvueqqq4we1rj3+9//nksuuYQHHniA\n6upq7r77brZt22b0sPyWCky/Xbt2cd111wGQkZFBc3MzbW1t2O12g0cml156KbNmzQIgMjKSzs5O\n3G43gYG+205ChubYsWMcPXpUfzmazK5du1i0aBF2ux273c6jjz5q9JAEiImJobCwEICWlhZiYmIM\nHpF/0y2kfnV1dWccTEPZk0lGR2BgIDabDYAtW7bwla98ReXFJNauXcuaNWuMHoZ8SVlZGS6Xi3vv\nvZcVK1awa9cuo4ckwF/91V9RUVHB9ddfz8qVK3nwwQeNHpJf0xWYc9DyOObz3nvvsWXLFp577jmj\nhyLAm2++SU5ODqmpqUYPRc6iqamJJ598koqKCr75zW/ywQcfYLFYjB7WuPaHP/yB5ORk1q9fz5Ej\nR3j44Yc1d+wiqMD0O9ueTPHx8QaOSE63Y8cOnn76aZ599lkiIrR/iBls376d0tJStm/fTlVVFcHB\nwSQmJrJ48WKjhzbuxcbGMmfOHKxWK2lpaYSHh9PQ0EBsbKzRQxvXcnNzufzyywGYNm0aNTU1uh1+\nEXQLqd+SJUsG9mkqKCjA6XRq/otJtLa28thjj/Gb3/yG6Ohoo4cj/R5//HFef/11Xn31VZYtW8bq\n1atVXkzi8ssv55NPPsHj8dDY2EhHR4fmW5hAeno6eXl5AJSXlxMeHq7ychF0Babf3Llzyc7O5o47\n7sBisfDII48YPSTp96c//YnGxkZ+8IMfDHxt7dq1JCcnGzgqEfNKSEjgq1/9KrfffjsAP/3pTwkI\n0P9fNdry5ct5+OGHWblyJb29vfz85z83ekh+TXshiYiIiN9RJRcRERG/owIjIiIifkcFRkRERPyO\nCoyIiIj4HRUYERER8TsqMCLiU2VlZcyYMYNVq1YN7ML7wAMP0NLSMuTPWLVqFW63e8jvv/POO9m9\ne/eFDFdE/IQKjIj4nMPhYOPGjWzcuJFXXnkFp9PJU089NeQ/v3HjRi34JSJn0EJ2IjLqLr30UjZv\n3syRI0dYu3Ytvb299PT08E//9E9kZWWxatUqpk2bxuHDh9mwYQNZWVkUFBTQ3d3Nz372M6qqqujt\n7eXmm29mxYoVdHZ28sMf/pDGxkbS09Pp6uoCoLq6mh/96EcAuFwuli9fzm233Wbkjy4iI0QFRkRG\nldvt5t1332XevHn8+Mc/Zt26daSlpf3F5nY2m40XX3zxjD+7ceNGIiMj+dWvfoXL5eKmm27iiiuu\n4OOPPyY0NJTNmzdTU1PDtddeC8Dbb7/NpEmT+Od//me6urp47bXXRv3nFRHfUIEREZ9raGhg1apV\nAHg8HubPn8+tt97KE088wT/+4z8OvK+trQ2PxwP0be/xZXl5edxyyy0AhIaGMmPGDAoKCigqKmLe\nvHlA38askyZNAuCKK65g06ZNrFmzhiuvvJLly5f79OcUkdGjAiMiPndqDszpWltbCQoK+ouvnxIU\nFPQXX7NYLGf8u9frxWKx4PV6z9jr51QJysjI4K233uLTTz9l27ZtbNiwgVdeeeVifxwRMQFN4hUR\nQ0RERJCSksKHH34IwIkTJ3jyyScH/TOzZ89mx44dAHR0dFBQUEB2djYZGRns27cPgMrKSk6cOAHA\nH//4R/Lz81m8eDGPPPIIlZWV9Pb2+vCnEpHRoiswImKYtWvX8i//8i/89re/pbe3lzVr1gz6/lWr\nVvGzn/2Mu+66i+7ublavXk1KSgo333wz77//PitWrCAlJYWZM2cCMHnyZB555BGCg4Pxer1897vf\nxWrVrz2RsUC7UYuIiIjf0S0kERER8TsqMCIiIuJ3VGBERETE76jAiIiIiN9RgRERERG/owIjIiIi\nfkcFRkRERPyOCoyIiIj4nf8PhRCKpGZkt3wAAAAASUVORK5CYII=\n",
+ "text/plain": [
+ "
"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ }
+ }
+ ]
+ },
+ {
+ "metadata": {
+ "id": "O2q5RRCKqYaU",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "### Solution\n",
+ "\n",
+ "Click below to see a possible solution"
+ ]
+ },
+ {
+ "metadata": {
+ "id": "j2Yd5VfrqcC3",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "**NOTE:** This selection of parameters is somewhat arbitrary. Here we've tried combinations that are increasingly complex, combined with training for longer, until the error falls below our objective (training is nondeterministic, so results may fluctuate a bit each time you run the solution). This may not be the best combination; others may attain an even lower RMSE. If your aim is to find the model that can attain the best error, then you'll want to use a more rigorous process, like a parameter search."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "IjkpSqmxqnSM",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "dnn_regressor = train_nn_regression_model(\n",
+ " learning_rate=0.001,\n",
+ " steps=2000,\n",
+ " batch_size=100,\n",
+ " hidden_units=[10, 10],\n",
+ " training_examples=training_examples,\n",
+ " training_targets=training_targets,\n",
+ " validation_examples=validation_examples,\n",
+ " validation_targets=validation_targets)"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "c6diezCSeH4Y",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## Task 2: Evaluate on Test Data\n",
+ "\n",
+ "**Confirm that your validation performance results hold up on test data.**\n",
+ "\n",
+ "Once you have a model you're happy with, evaluate it on test data to compare that to validation performance.\n",
+ "\n",
+ "Reminder, the test data set is located [here](https://download.mlcc.google.com/mledu-datasets/california_housing_test.csv)."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "icEJIl5Vp51r",
+ "colab_type": "code",
+ "cellView": "both",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ },
+ "outputId": "bedbaf6c-3cc0-4748-ea0b-2b0704339c86"
+ },
+ "cell_type": "code",
+ "source": [
+ "california_housing_test_data = pd.read_csv(\"https://download.mlcc.google.com/mledu-datasets/california_housing_test.csv\", sep=\",\")\n",
+ "\n",
+ "# YOUR CODE HERE\n",
+ "test_examples = preprocess_features(california_housing_test_data)\n",
+ "test_targets = preprocess_targets(california_housing_test_data)\n",
+ "input_function = lambda: my_input_fn(test_examples, \n",
+ " test_targets[\"median_house_value\"], \n",
+ " num_epochs=1, \n",
+ " shuffle=False)\n",
+ "predictions = dnn_regressor.predict(input_fn=input_function)\n",
+ "predictions = np.array([item['predictions'][0] for item in predictions])\n",
+ "root_mean_squared_error = math.sqrt(\n",
+ " metrics.mean_squared_error(predictions, targets))\n",
+ "\n",
+ "print(\"Final RMSE: %0.2f\" % root_mean_squared_error)"
+ ],
+ "execution_count": 13,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Final RMSE: 107.04\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "metadata": {
+ "id": "vvT2jDWjrKew",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "### Solution\n",
+ "\n",
+ "Click below to see a possible solution."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "FyDh7Qy6rQb0",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "Similar to what the code at the top does, we just need to load the appropriate data file, preprocess it and call predict and mean_squared_error.\n",
+ "\n",
+ "Note that we don't have to randomize the test data, since we will use all records."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "vhb0CtdvrWZx",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "california_housing_test_data = pd.read_csv(\"https://download.mlcc.google.com/mledu-datasets/california_housing_test.csv\", sep=\",\")\n",
+ "\n",
+ "test_examples = preprocess_features(california_housing_test_data)\n",
+ "test_targets = preprocess_targets(california_housing_test_data)\n",
+ "\n",
+ "predict_testing_input_fn = lambda: my_input_fn(test_examples, \n",
+ " test_targets[\"median_house_value\"], \n",
+ " num_epochs=1, \n",
+ " shuffle=False)\n",
+ "\n",
+ "test_predictions = dnn_regressor.predict(input_fn=predict_testing_input_fn)\n",
+ "test_predictions = np.array([item['predictions'][0] for item in test_predictions])\n",
+ "\n",
+ "root_mean_squared_error = math.sqrt(\n",
+ " metrics.mean_squared_error(test_predictions, test_targets))\n",
+ "\n",
+ "print(\"Final RMSE (on test data): %0.2f\" % root_mean_squared_error)"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ }
+ ]
+}
\ No newline at end of file
diff --git a/logistic_regression.ipynb b/logistic_regression.ipynb
new file mode 100644
index 0000000..ea99620
--- /dev/null
+++ b/logistic_regression.ipynb
@@ -0,0 +1,1607 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "name": "logistic_regression.ipynb",
+ "version": "0.3.2",
+ "provenance": [],
+ "collapsed_sections": [
+ "JndnmDMp66FL",
+ "dPpJUV862FYI",
+ "i2e3TlyL57Qs",
+ "wCugvl0JdWYL"
+ ],
+ "include_colab_link": true
+ },
+ "kernelspec": {
+ "name": "python2",
+ "display_name": "Python 2"
+ }
+ },
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "view-in-github",
+ "colab_type": "text"
+ },
+ "source": [
+ ""
+ ]
+ },
+ {
+ "metadata": {
+ "id": "JndnmDMp66FL",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "#### Copyright 2017 Google LLC."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "hMqWDc_m6rUC",
+ "colab_type": "code",
+ "cellView": "both",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "# 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\n",
+ "#\n",
+ "# https://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."
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "g4T-_IsVbweU",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "# Logistic Regression"
+ ]
+ },
+ {
+ "metadata": {
+ "id": "LEAHZv4rIYHX",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "**Learning Objectives:**\n",
+ " * Reframe the median house value predictor (from the preceding exercises) as a binary classification model\n",
+ " * Compare the effectiveness of logisitic regression vs linear regression for a binary classification problem"
+ ]
+ },
+ {
+ "metadata": {
+ "id": "CnkCZqdIIYHY",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "As in the prior exercises, we're working with the [California housing data set](https://developers.google.com/machine-learning/crash-course/california-housing-data-description), but this time we will turn it into a binary classification problem by predicting whether a city block is a high-cost city block. We'll also revert to the default features, for now."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "9pltCyy2K3dd",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## Frame the Problem as Binary Classification\n",
+ "\n",
+ "The target of our dataset is `median_house_value` which is a numeric (continuous-valued) feature. We can create a boolean label by applying a threshold to this continuous value.\n",
+ "\n",
+ "Given features describing a city block, we wish to predict if it is a high-cost city block. To prepare the targets for train and eval data, we define a classification threshold of the 75%-ile for median house value (a value of approximately 265000). All house values above the threshold are labeled `1`, and all others are labeled `0`."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "67IJwZX1Vvjt",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## Setup\n",
+ "\n",
+ "Run the cells below to load the data and prepare the input features and targets."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "fOlbcJ4EIYHd",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "from __future__ import print_function\n",
+ "\n",
+ "import math\n",
+ "\n",
+ "from IPython import display\n",
+ "from matplotlib import cm\n",
+ "from matplotlib import gridspec\n",
+ "from matplotlib import pyplot as plt\n",
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "from sklearn import metrics\n",
+ "import tensorflow as tf\n",
+ "from tensorflow.python.data import Dataset\n",
+ "\n",
+ "tf.logging.set_verbosity(tf.logging.ERROR)\n",
+ "pd.options.display.max_rows = 10\n",
+ "pd.options.display.float_format = '{:.1f}'.format\n",
+ "\n",
+ "california_housing_dataframe = pd.read_csv(\"https://download.mlcc.google.com/mledu-datasets/california_housing_train.csv\", sep=\",\")\n",
+ "\n",
+ "california_housing_dataframe = california_housing_dataframe.reindex(\n",
+ " np.random.permutation(california_housing_dataframe.index))"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "lTB73MNeIYHf",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "Note how the code below is slightly different from the previous exercises. Instead of using `median_house_value` as target, we create a new binary target, `median_house_value_is_high`."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "kPSqspaqIYHg",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def preprocess_features(california_housing_dataframe):\n",
+ " \"\"\"Prepares input features from California housing data set.\n",
+ "\n",
+ " Args:\n",
+ " california_housing_dataframe: A Pandas DataFrame expected to contain data\n",
+ " from the California housing data set.\n",
+ " Returns:\n",
+ " A DataFrame that contains the features to be used for the model, including\n",
+ " synthetic features.\n",
+ " \"\"\"\n",
+ " selected_features = california_housing_dataframe[\n",
+ " [\"latitude\",\n",
+ " \"longitude\",\n",
+ " \"housing_median_age\",\n",
+ " \"total_rooms\",\n",
+ " \"total_bedrooms\",\n",
+ " \"population\",\n",
+ " \"households\",\n",
+ " \"median_income\"]]\n",
+ " processed_features = selected_features.copy()\n",
+ " # Create a synthetic feature.\n",
+ " processed_features[\"rooms_per_person\"] = (\n",
+ " california_housing_dataframe[\"total_rooms\"] /\n",
+ " california_housing_dataframe[\"population\"])\n",
+ " return processed_features\n",
+ "\n",
+ "def preprocess_targets(california_housing_dataframe):\n",
+ " \"\"\"Prepares target features (i.e., labels) from California housing data set.\n",
+ "\n",
+ " Args:\n",
+ " california_housing_dataframe: A Pandas DataFrame expected to contain data\n",
+ " from the California housing data set.\n",
+ " Returns:\n",
+ " A DataFrame that contains the target feature.\n",
+ " \"\"\"\n",
+ " output_targets = pd.DataFrame()\n",
+ " # Create a boolean categorical feature representing whether the\n",
+ " # median_house_value is above a set threshold.\n",
+ " output_targets[\"median_house_value_is_high\"] = (\n",
+ " california_housing_dataframe[\"median_house_value\"] > 265000).astype(float)\n",
+ " return output_targets"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "FwOYWmXqWA6D",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 1224
+ },
+ "outputId": "f24b25b6-61da-4833-e0cc-013dcba900c8"
+ },
+ "cell_type": "code",
+ "source": [
+ "# Choose the first 12000 (out of 17000) examples for training.\n",
+ "training_examples = preprocess_features(california_housing_dataframe.head(12000))\n",
+ "training_targets = preprocess_targets(california_housing_dataframe.head(12000))\n",
+ "\n",
+ "# Choose the last 5000 (out of 17000) examples for validation.\n",
+ "validation_examples = preprocess_features(california_housing_dataframe.tail(5000))\n",
+ "validation_targets = preprocess_targets(california_housing_dataframe.tail(5000))\n",
+ "\n",
+ "# Double-check that we've done the right thing.\n",
+ "print(\"Training examples summary:\")\n",
+ "display.display(training_examples.describe())\n",
+ "print(\"Validation examples summary:\")\n",
+ "display.display(validation_examples.describe())\n",
+ "\n",
+ "print(\"Training targets summary:\")\n",
+ "display.display(training_targets.describe())\n",
+ "print(\"Validation targets summary:\")\n",
+ "display.display(validation_targets.describe())"
+ ],
+ "execution_count": 3,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Training examples summary:\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "text/plain": [
+ " latitude longitude housing_median_age total_rooms total_bedrooms \\\n",
+ "count 12000.0 12000.0 12000.0 12000.0 12000.0 \n",
+ "mean 35.6 -119.6 28.6 2645.6 539.5 \n",
+ "std 2.1 2.0 12.6 2204.2 425.1 \n",
+ "min 32.5 -124.3 2.0 8.0 1.0 \n",
+ "25% 33.9 -121.8 18.0 1459.0 296.0 \n",
+ "50% 34.2 -118.5 29.0 2127.0 433.0 \n",
+ "75% 37.7 -118.0 37.0 3143.2 648.0 \n",
+ "max 42.0 -114.3 52.0 37937.0 5471.0 \n",
+ "\n",
+ " population households median_income rooms_per_person \n",
+ "count 12000.0 12000.0 12000.0 12000.0 \n",
+ "mean 1432.2 501.2 3.9 2.0 \n",
+ "std 1156.5 388.7 1.9 1.2 \n",
+ "min 3.0 1.0 0.5 0.0 \n",
+ "25% 790.0 281.8 2.6 1.5 \n",
+ "50% 1166.0 409.0 3.5 1.9 \n",
+ "75% 1720.0 603.0 4.8 2.3 \n",
+ "max 35682.0 5189.0 15.0 55.2 "
+ ],
+ "text/html": [
+ "
"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ }
+ }
+ ]
+ },
+ {
+ "metadata": {
+ "id": "uon1LB3A31VN",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## How Would Linear Regression Fare?\n",
+ "To see why logistic regression is effective, let us first train a naive model that uses linear regression. This model will use labels with values in the set `{0, 1}` and will try to predict a continuous value that is as close as possible to `0` or `1`. Furthermore, we wish to interpret the output as a probability, so it would be ideal if the output will be within the range `(0, 1)`. We would then apply a threshold of `0.5` to determine the label.\n",
+ "\n",
+ "Run the cells below to train the linear regression model using [LinearRegressor](https://www.tensorflow.org/api_docs/python/tf/estimator/LinearRegressor)."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "smmUYRDtWOV_",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def construct_feature_columns(input_features):\n",
+ " \"\"\"Construct the TensorFlow Feature Columns.\n",
+ "\n",
+ " Args:\n",
+ " input_features: The names of the numerical input features to use.\n",
+ " Returns:\n",
+ " A set of feature columns\n",
+ " \"\"\"\n",
+ " return set([tf.feature_column.numeric_column(my_feature)\n",
+ " for my_feature in input_features])"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "B5OwSrr1yIKD",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def my_input_fn(features, targets, batch_size=1, shuffle=True, num_epochs=None):\n",
+ " \"\"\"Trains a linear regression model.\n",
+ " \n",
+ " Args:\n",
+ " features: pandas DataFrame of features\n",
+ " targets: pandas DataFrame of targets\n",
+ " batch_size: Size of batches to be passed to the model\n",
+ " shuffle: True or False. Whether to shuffle the data.\n",
+ " num_epochs: Number of epochs for which data should be repeated. None = repeat indefinitely\n",
+ " Returns:\n",
+ " Tuple of (features, labels) for next data batch\n",
+ " \"\"\"\n",
+ " \n",
+ " # Convert pandas data into a dict of np arrays.\n",
+ " features = {key:np.array(value) for key,value in dict(features).items()} \n",
+ " \n",
+ " # Construct a dataset, and configure batching/repeating.\n",
+ " ds = Dataset.from_tensor_slices((features,targets)) # warning: 2GB limit\n",
+ " ds = ds.batch(batch_size).repeat(num_epochs)\n",
+ " \n",
+ " # Shuffle the data, if specified.\n",
+ " if shuffle:\n",
+ " ds = ds.shuffle(10000)\n",
+ " \n",
+ " # Return the next batch of data.\n",
+ " features, labels = ds.make_one_shot_iterator().get_next()\n",
+ " return features, labels"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "SE2-hq8PIYHz",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def train_linear_regressor_model(\n",
+ " learning_rate,\n",
+ " steps,\n",
+ " batch_size,\n",
+ " training_examples,\n",
+ " training_targets,\n",
+ " validation_examples,\n",
+ " validation_targets):\n",
+ " \"\"\"Trains a linear regression model.\n",
+ " \n",
+ " In addition to training, this function also prints training progress information,\n",
+ " as well as a plot of the training and validation loss over time.\n",
+ " \n",
+ " Args:\n",
+ " learning_rate: A `float`, the learning rate.\n",
+ " steps: A non-zero `int`, the total number of training steps. A training step\n",
+ " consists of a forward and backward pass using a single batch.\n",
+ " batch_size: A non-zero `int`, the batch size.\n",
+ " training_examples: A `DataFrame` containing one or more columns from\n",
+ " `california_housing_dataframe` to use as input features for training.\n",
+ " training_targets: A `DataFrame` containing exactly one column from\n",
+ " `california_housing_dataframe` to use as target for training.\n",
+ " validation_examples: A `DataFrame` containing one or more columns from\n",
+ " `california_housing_dataframe` to use as input features for validation.\n",
+ " validation_targets: A `DataFrame` containing exactly one column from\n",
+ " `california_housing_dataframe` to use as target for validation.\n",
+ " \n",
+ " Returns:\n",
+ " A `LinearRegressor` object trained on the training data.\n",
+ " \"\"\"\n",
+ "\n",
+ " periods = 10\n",
+ " steps_per_period = steps / periods\n",
+ "\n",
+ " # Create a linear regressor object.\n",
+ " my_optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)\n",
+ " my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0)\n",
+ " linear_regressor = tf.estimator.LinearRegressor(\n",
+ " feature_columns=construct_feature_columns(training_examples),\n",
+ " optimizer=my_optimizer\n",
+ " )\n",
+ " \n",
+ " # Create input functions.\n",
+ " training_input_fn = lambda: my_input_fn(training_examples, \n",
+ " training_targets[\"median_house_value_is_high\"], \n",
+ " batch_size=batch_size)\n",
+ " predict_training_input_fn = lambda: my_input_fn(training_examples, \n",
+ " training_targets[\"median_house_value_is_high\"], \n",
+ " num_epochs=1, \n",
+ " shuffle=False)\n",
+ " predict_validation_input_fn = lambda: my_input_fn(validation_examples, \n",
+ " validation_targets[\"median_house_value_is_high\"], \n",
+ " num_epochs=1, \n",
+ " shuffle=False)\n",
+ "\n",
+ " # Train the model, but do so inside a loop so that we can periodically assess\n",
+ " # loss metrics.\n",
+ " print(\"Training model...\")\n",
+ " print(\"RMSE (on training data):\")\n",
+ " training_rmse = []\n",
+ " validation_rmse = []\n",
+ " for period in range (0, periods):\n",
+ " # Train the model, starting from the prior state.\n",
+ " linear_regressor.train(\n",
+ " input_fn=training_input_fn,\n",
+ " steps=steps_per_period\n",
+ " )\n",
+ " \n",
+ " # Take a break and compute predictions.\n",
+ " training_predictions = linear_regressor.predict(input_fn=predict_training_input_fn)\n",
+ " training_predictions = np.array([item['predictions'][0] for item in training_predictions])\n",
+ " \n",
+ " validation_predictions = linear_regressor.predict(input_fn=predict_validation_input_fn)\n",
+ " validation_predictions = np.array([item['predictions'][0] for item in validation_predictions])\n",
+ " \n",
+ " # Compute training and validation loss.\n",
+ " training_root_mean_squared_error = math.sqrt(\n",
+ " metrics.mean_squared_error(training_predictions, training_targets))\n",
+ " validation_root_mean_squared_error = math.sqrt(\n",
+ " metrics.mean_squared_error(validation_predictions, validation_targets))\n",
+ " # Occasionally print the current loss.\n",
+ " print(\" period %02d : %0.2f\" % (period, training_root_mean_squared_error))\n",
+ " # Add the loss metrics from this period to our list.\n",
+ " training_rmse.append(training_root_mean_squared_error)\n",
+ " validation_rmse.append(validation_root_mean_squared_error)\n",
+ " print(\"Model training finished.\")\n",
+ " \n",
+ " # Output a graph of loss metrics over periods.\n",
+ " plt.ylabel(\"RMSE\")\n",
+ " plt.xlabel(\"Periods\")\n",
+ " plt.title(\"Root Mean Squared Error vs. Periods\")\n",
+ " plt.tight_layout()\n",
+ " plt.plot(training_rmse, label=\"training\")\n",
+ " plt.plot(validation_rmse, label=\"validation\")\n",
+ " plt.legend()\n",
+ "\n",
+ " return linear_regressor"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "TDBD8xeeIYH2",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 640
+ },
+ "outputId": "0460c7f6-1552-4dce-f4c9-7e1a88553d6b"
+ },
+ "cell_type": "code",
+ "source": [
+ "linear_regressor = train_linear_regressor_model(\n",
+ " learning_rate=0.000001,\n",
+ " steps=200,\n",
+ " batch_size=20,\n",
+ " training_examples=training_examples,\n",
+ " training_targets=training_targets,\n",
+ " validation_examples=validation_examples,\n",
+ " validation_targets=validation_targets)"
+ ],
+ "execution_count": 10,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Training model...\n",
+ "RMSE (on training data):\n",
+ " period 00 : 0.45\n",
+ " period 01 : 0.45\n",
+ " period 02 : 0.45\n",
+ " period 03 : 0.44\n",
+ " period 04 : 0.44\n",
+ " period 05 : 0.44\n",
+ " period 06 : 0.44\n",
+ " period 07 : 0.44\n",
+ " period 08 : 0.45\n",
+ " period 09 : 0.44\n",
+ "Model training finished.\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAj4AAAGACAYAAACtGmg0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzs3Xd4VFX6wPHvTHqvMymUhISeRm8R\n6RKKiwoigthYd12NspZV4Serroq6u7oKCKuui8qqi7IBUVGQpqD0QBoESIEkkDLJpPfM3N8fkREE\nQsjMpL6f5+F5MjP3nvveOZnMyznnvVelKIqCEEIIIUQXoG7rAIQQQgghWoskPkIIIYToMiTxEUII\nIUSXIYmPEEIIIboMSXyEEEII0WVI4iOEEEKILsO2rQMQojPq168fPXv2xMbGBgCDwcDw4cN59tln\ncXZ2bnG7n332GXPnzr3s+bi4OJYsWcI///lPJkyYYHq+pqaGMWPGcNNNN/Hqq6+2+LjNlZWVxfLl\ny8nMzATAycmJ2NhYJk+ebPVjX4/Vq1eTlZV12Xty4MABFi1aRPfu3S/b59tvv22t8MySk5PDpEmT\n6NWrFwCKouDr68v//d//MXDgwOtq6/XXXycwMJA777yz2ft88cUXbNiwgXXr1l3XsYRoLZL4CGEl\n69atw9/fH4C6ujoee+wx3nnnHR577LEWtafT6fjXv/51xcQHICAggK+++uqSxGfXrl24u7u36Hgt\n8eSTTzJr1iz++c9/ApCQkMA999zDN998Q0BAQKvFYY6AgIAOk+RcjY2NzSXnsGXLFh5++GG2bt2K\nvb19s9t54oknrBGeEG1KprqEaAX29vaMHTuWEydOAFBbW8uf//xnpk6dyrRp03j11VcxGAwApKam\nMm/ePGJiYpg1axZ79uwBYN68eZw/f56YmBjq6uouO8aQIUM4cOAA1dXVpue2bNlCdHS06XFdXR0v\nvfQSU6dOZeLEiaYEBeDo0aPcdtttxMTEMH36dH766SegcQThhhtu4KOPPuLmm29m7NixbNmy5Yrn\neerUKaKiokyPo6Ki2Lp1qykBXLVqFePGjeOWW27h3XffZeLEiQA888wzrF692rTfxY+vFdfy5cu5\n6667ADhy5AizZ89mypQpzJ07l+zsbKBx5OuPf/wjEyZM4K677iIvL+8aPXZlcXFxxMbGcs899/DX\nv/6VAwcOMG/ePBYvXmxKEr755htmzpxJTEwMd999N1lZWQCsXLmSZ599ljlz5vDBBx9c0u7ixYv5\n97//bXp84sQJbrjhBoxGI//4xz+YOnUqU6dO5e677yY/P/+6454+fTo1NTVkZGQAsH79emJiYpg4\ncSKPP/44NTU1QOP7/sorr3DzzTfzzTffXNIPV/u9NBqN/OUvf2H8+PHMmTOH1NRU03EPHjzIrbfe\nyvTp05k2bRrffPPNdccuhMUpQgiL69u3r5Kbm2t6XFJSoixYsEBZvXq1oiiK8s477ygPPPCAUl9f\nr1RXVyuzZ89WNm3apBgMBmXatGnKl19+qSiKoiQmJirDhw9XysvLlf379yuTJ0++4vH+97//KU8/\n/bTy5JNPmvYtLy9XJk2apHz++efK008/rSiKoqxatUq55557lNraWqWyslK55ZZblJ07dyqKoigz\nZ85UvvrqK0VRFGXjxo2mY2VnZysDBw5U1q1bpyiKomzZskWZMmXKFeN45JFHlAkTJigffvihkpaW\ndslrJ0+eVIYNG6YUFBQo9fX1yh/+8AdlwoQJiqIoytNPP628/fbbpm0vftxUXGFhYUpcXJzpfIcP\nH67s3btXURRF+fLLL5Vbb71VURRF+c9//qMsWLBAqa+vV/R6vTJhwgTTe3Kxpt7jC+/zoEGDlMzM\nTNP2ERERyk8//aQoiqKcO3dOGTp0qHLmzBlFURTl/fffV+655x5FURRlxYoVyg033KAUFRVd1u7X\nX3+tLFiwwPT4rbfeUl588UXl1KlTyk033aTU1dUpiqIoH330kbJx48arxnfhfRkwYMBlzw8fPlxJ\nT09XDh06pIwePVrJy8tTFEVRli1bprz66quKojS+7zfffLNSU1Njevz22283+Xu5e/du5aabblIq\nKiqU6upqZc6cOcpdd92lKIqi3HbbbcqBAwcURVGUzMxM5fHHH28ydiFag4z4CGElCxcuJCYmhkmT\nJjFp0iRGjRrFAw88AMDu3buZO3cutra2ODo6cvPNN/Pjjz+Sk5NDYWEhM2bMACAiIoLAwECSkpKa\ndcwZM2bw1VdfAbB9+3YmTJiAWv3Lx3zXrl3Mnz8fe3t7nJ2dmTVrFtu2bQNg06ZNTJs2DYChQ4ea\nRksAGhoauO222wAICwvj/PnzVzz+3/72NxYsWMCXX37JzJkzmThxIp9++inQOBozfPhwNBoNtra2\n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\n",
+ "text/plain": [
+ "
"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ }
+ }
+ ]
+ },
+ {
+ "metadata": {
+ "id": "JjBZ_q7aD9gh",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## Task 1: Can We Calculate LogLoss for These Predictions?\n",
+ "\n",
+ "**Examine the predictions and decide whether or not we can use them to calculate LogLoss.**\n",
+ "\n",
+ "`LinearRegressor` uses the L2 loss, which doesn't do a great job at penalizing misclassifications when the output is interpreted as a probability. For example, there should be a huge difference whether a negative example is classified as positive with a probability of 0.9 vs 0.9999, but L2 loss doesn't strongly differentiate these cases.\n",
+ "\n",
+ "In contrast, `LogLoss` penalizes these \"confidence errors\" much more heavily. Remember, `LogLoss` is defined as:\n",
+ "\n",
+ "$$Log Loss = \\sum_{(x,y)\\in D} -y \\cdot log(y_{pred}) - (1 - y) \\cdot log(1 - y_{pred})$$\n",
+ "\n",
+ "\n",
+ "But first, we'll need to obtain the prediction values. We could use `LinearRegressor.predict` to obtain these.\n",
+ "\n",
+ "Given the predictions and the targets, can we calculate `LogLoss`?"
+ ]
+ },
+ {
+ "metadata": {
+ "id": "dPpJUV862FYI",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "### Solution\n",
+ "\n",
+ "Click below to display the solution."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "yiVTBuHIcIXx",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 347
+ },
+ "outputId": "ea6b2617-6ea4-41b8-961f-9a2c0028e70c"
+ },
+ "cell_type": "code",
+ "source": [
+ "predict_validation = lambda: my_input_fn(validation_examples, \n",
+ " validation_targets[\"median_house_value_is_high\"], \n",
+ " num_epochs=1, \n",
+ " shuffle=False)\n",
+ "\n",
+ "validation_predictions = linear_regressor.predict(input_fn=predict_validation)\n",
+ "validation_predictions = np.array([item['predictions'][0] for item in validation_predictions])\n",
+ "\n",
+ "_ = plt.hist(validation_predictions)"
+ ],
+ "execution_count": 13,
+ "outputs": [
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "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\ntzt37tTcuXNna6lT7ujRo9q0aZN+9atfaePGjWPui/V9H2/2WN/37du367333tO5c+d0zz33aPXq\n1ZH7Ynnfx5s7lvd8YGBAVVVVOn36tL744gtt2rRJeXl5kfsves+tS8xf/vIXa9u2bZZlWdahQ4es\nBx544Lxzrrvuuple1rRpb2+3fv3rX1uWZVkfffSRtX79+jH3r1271jpx4oQ1MjJilZaWWh9++OFs\nLHNaRJs9Ly/P+vzzz2djadOur6/P2rhxo/X4449b+/btO+/+WN73aLPH8r4HAgHrrrvusizLss6c\nOWPdcMMNY+6P1X2PNncs7/nf/vY3a8+ePZZlWdbHH39srV69esz9F7vnl9zl8UAgoIKCAklSTk6O\ngsHgLK9oen3Tx7xK0rFjx3TllVdq3rx5stvtuuGGGxQIBGZzuVNqvNljncvl0t69e+Xz+c67L9b3\nfbzZY92yZcv03HPPSZKSkpI0MDCgkZERSbG97+PNHeuKiop09913S5JOnjw55grCZPb8krs8Hg6H\n5fV6JUl2u102m01DQ0NyuVyRc4aGhlRZWanjx49rzZo1uuOOO2Zrud/aeB/zGgqFIv8uvrrv2LFj\ns7HMaTGRj7h96qmndPz4cf3sZz9TZWWlbDbbbCx1yjmdTjmdF/7PL9b3fbzZvxKr++5wOJSYmChJ\n8vv9WrlyZeSScCzv+3hzfyVW9/wrGzZs0CeffKLdu3dHjk1mz2c12gcOHNCBAwfGHOvo6Bhz27rA\nT6Rt2bJFv/jFL2Sz2bRx40ZlZWUpPT19Wtc6Uy40b7z4+uy//e1vtWLFCl155ZWqqKhQS0uLCgsL\nZ2l1mCnxsO9vvfWW/H6/6uvrZ3spM+qb5o6HPX/99df1wQcf6JFHHlFTU9Ok/1Iyq5fHS0pK9Kc/\n/WnMPzfffLNCoZCkL78pzbKsMa+yJam0tFSXX365EhMTdf311+vo0aOzsfwpMd7HvH79vlOnTsXU\nJcVoH3FbXFyslJQUOZ1OrVy50uh9vhixvu/RxPq+Hzp0SLt379bevXvl8fz/z52O9X3/prml2N7z\nrq4unTx5UpKUlpamkZERnTlzRtLk9vySe087NzdXzc3NkqTW1lZlZ2ePuf8///mPKisrZVmWzp07\np2AwqIULF87GUqfEeB/zetVVV+nzzz/Xxx9/rHPnzqm1tVW5ubmzudwpNd7sZ8+eVXl5uYaGhiRJ\n7777rtH7fDFifd/HE+v7fvbsWW3fvl0vvviikpOTx9wXy/s+3tyxvudHjhyJXFkIh8Pq7+/XnDlz\nJE1uzy+5T0QbGRnR448/rv/+979yuVyqqanRvHnztGfPHi1btkxLly7Vjh079M4778hutys/P1+/\n+c1vZnvZ38rOnTt15MiRyMe8/utf/5LH41FBQYHeffdd7dy5U5K0evVqlZeXz/Jqp9Z4szc0NOiv\nf/2rvvOd7+gnP/mJnnjiiZh5n6urq0vPPPOMjh8/LqfTqblz5yo/P19XXXVVzO97tNljed8bGxv1\nhz/8QT/84Q8jx7Kzs/XjH/84pvc92tyxvOeDg4N67LHHdPLkSQ0ODuq+++7Tp59+Ouk/4y+5aAMA\ngAu75C6PAwCACyPaAAAYgmgDAGAIog0AgCGINgAAhiDaAAAYgmgDAGAIog0AgCH+H2BD3QnIuESO\nAAAAAElFTkSuQmCC\n",
+ "text/plain": [
+ "
"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ }
+ }
+ ]
+ },
+ {
+ "metadata": {
+ "id": "kXFQ5uig2RoP",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "predict_validation_input_fn = lambda: my_input_fn(validation_examples, \n",
+ " validation_targets[\"median_house_value_is_high\"], \n",
+ " num_epochs=1, \n",
+ " shuffle=False)\n",
+ "\n",
+ "validation_predictions = linear_regressor.predict(input_fn=predict_validation_input_fn)\n",
+ "validation_predictions = np.array([item['predictions'][0] for item in validation_predictions])\n",
+ "\n",
+ "_ = plt.hist(validation_predictions)"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "rYpy336F9wBg",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## Task 2: Train a Logistic Regression Model and Calculate LogLoss on the Validation Set\n",
+ "\n",
+ "To use logistic regression, simply use [LinearClassifier](https://www.tensorflow.org/api_docs/python/tf/estimator/LinearClassifier) instead of `LinearRegressor`. Complete the code below.\n",
+ "\n",
+ "**NOTE**: When running `train()` and `predict()` on a `LinearClassifier` model, you can access the real-valued predicted probabilities via the `\"probabilities\"` key in the returned dict—e.g., `predictions[\"probabilities\"]`. Sklearn's [log_loss](http://scikit-learn.org/stable/modules/generated/sklearn.metrics.log_loss.html) function is handy for calculating LogLoss using these probabilities.\n"
+ ]
+ },
+ {
+ "metadata": {
+ "id": "JElcb--E9wBm",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def train_linear_classifier_model(\n",
+ " learning_rate,\n",
+ " steps,\n",
+ " batch_size,\n",
+ " training_examples,\n",
+ " training_targets,\n",
+ " validation_examples,\n",
+ " validation_targets):\n",
+ " \"\"\"Trains a linear classification model.\n",
+ " \n",
+ " In addition to training, this function also prints training progress information,\n",
+ " as well as a plot of the training and validation loss over time.\n",
+ " \n",
+ " Args:\n",
+ " learning_rate: A `float`, the learning rate.\n",
+ " steps: A non-zero `int`, the total number of training steps. A training step\n",
+ " consists of a forward and backward pass using a single batch.\n",
+ " batch_size: A non-zero `int`, the batch size.\n",
+ " training_examples: A `DataFrame` containing one or more columns from\n",
+ " `california_housing_dataframe` to use as input features for training.\n",
+ " training_targets: A `DataFrame` containing exactly one column from\n",
+ " `california_housing_dataframe` to use as target for training.\n",
+ " validation_examples: A `DataFrame` containing one or more columns from\n",
+ " `california_housing_dataframe` to use as input features for validation.\n",
+ " validation_targets: A `DataFrame` containing exactly one column from\n",
+ " `california_housing_dataframe` to use as target for validation.\n",
+ " \n",
+ " Returns:\n",
+ " A `LinearClassifier` object trained on the training data.\n",
+ " \"\"\"\n",
+ "\n",
+ " periods = 10\n",
+ " steps_per_period = steps / periods\n",
+ " \n",
+ " # Create a linear classifier object.\n",
+ " my_optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)\n",
+ " my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0)\n",
+ " linear_classifier = tf.estimator.LinearClassifier(\n",
+ " feature_columns=construct_feature_columns(training_examples),\n",
+ " optimizer=my_optimizer\n",
+ " )\n",
+ " \n",
+ " # Create input functions.\n",
+ " training_input_fn = lambda: my_input_fn(training_examples, \n",
+ " training_targets[\"median_house_value_is_high\"], \n",
+ " batch_size=batch_size)\n",
+ " predict_training_input_fn = lambda: my_input_fn(training_examples, \n",
+ " training_targets[\"median_house_value_is_high\"], \n",
+ " num_epochs=1, \n",
+ " shuffle=False)\n",
+ " predict_validation_input_fn = lambda: my_input_fn(validation_examples, \n",
+ " validation_targets[\"median_house_value_is_high\"], \n",
+ " num_epochs=1, \n",
+ " shuffle=False)\n",
+ " \n",
+ " # Train the model, but do so inside a loop so that we can periodically assess\n",
+ " # loss metrics.\n",
+ " print(\"Training model...\")\n",
+ " print(\"LogLoss (on training data):\")\n",
+ " training_log_losses = []\n",
+ " validation_log_losses = []\n",
+ " for period in range (0, periods):\n",
+ " # Train the model, starting from the prior state.\n",
+ " linear_classifier.train(\n",
+ " input_fn=training_input_fn,\n",
+ " steps=steps_per_period\n",
+ " )\n",
+ " # Take a break and compute predictions. \n",
+ " training_probabilities = linear_classifier.predict(input_fn=predict_training_input_fn)\n",
+ " training_probabilities = np.array([item['probabilities'] for item in training_probabilities])\n",
+ " \n",
+ " validation_probabilities = linear_classifier.predict(input_fn=predict_validation_input_fn)\n",
+ " validation_probabilities = np.array([item['probabilities'] for item in validation_probabilities])\n",
+ " \n",
+ " training_log_loss = metrics.log_loss(training_targets, training_probabilities)\n",
+ " validation_log_loss = metrics.log_loss(validation_targets, validation_probabilities)\n",
+ " # Occasionally print the current loss.\n",
+ " print(\" period %02d : %0.2f\" % (period, training_log_loss))\n",
+ " # Add the loss metrics from this period to our list.\n",
+ " training_log_losses.append(training_log_loss)\n",
+ " validation_log_losses.append(validation_log_loss)\n",
+ " print(\"Model training finished.\")\n",
+ " \n",
+ " # Output a graph of loss metrics over periods.\n",
+ " plt.ylabel(\"LogLoss\")\n",
+ " plt.xlabel(\"Periods\")\n",
+ " plt.title(\"LogLoss vs. Periods\")\n",
+ " plt.tight_layout()\n",
+ " plt.plot(training_log_losses, label=\"training\")\n",
+ " plt.plot(validation_log_losses, label=\"validation\")\n",
+ " plt.legend()\n",
+ "\n",
+ " return linear_classifier"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "VM0wmnFUIYH9",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 640
+ },
+ "outputId": "3905c6bb-1b9d-42b7-fbb7-2586e2de6f15"
+ },
+ "cell_type": "code",
+ "source": [
+ "linear_classifier = train_linear_classifier_model(\n",
+ " learning_rate=0.000005,\n",
+ " steps=500,\n",
+ " batch_size=20,\n",
+ " training_examples=training_examples,\n",
+ " training_targets=training_targets,\n",
+ " validation_examples=validation_examples,\n",
+ " validation_targets=validation_targets)"
+ ],
+ "execution_count": 15,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Training model...\n",
+ "LogLoss (on training data):\n",
+ " period 00 : 0.60\n",
+ " period 01 : 0.58\n",
+ " period 02 : 0.57\n",
+ " period 03 : 0.55\n",
+ " period 04 : 0.55\n",
+ " period 05 : 0.54\n",
+ " period 06 : 0.54\n",
+ " period 07 : 0.53\n",
+ " period 08 : 0.54\n",
+ " period 09 : 0.53\n",
+ "Model training finished.\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ "
"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ }
+ }
+ ]
+ },
+ {
+ "metadata": {
+ "id": "i2e3TlyL57Qs",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "### Solution\n",
+ "\n",
+ "Click below to see the solution.\n",
+ "\n"
+ ]
+ },
+ {
+ "metadata": {
+ "id": "5YxXd2hn6MuF",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def train_linear_classifier_model(\n",
+ " learning_rate,\n",
+ " steps,\n",
+ " batch_size,\n",
+ " training_examples,\n",
+ " training_targets,\n",
+ " validation_examples,\n",
+ " validation_targets):\n",
+ " \"\"\"Trains a linear classification model.\n",
+ " \n",
+ " In addition to training, this function also prints training progress information,\n",
+ " as well as a plot of the training and validation loss over time.\n",
+ " \n",
+ " Args:\n",
+ " learning_rate: A `float`, the learning rate.\n",
+ " steps: A non-zero `int`, the total number of training steps. A training step\n",
+ " consists of a forward and backward pass using a single batch.\n",
+ " batch_size: A non-zero `int`, the batch size.\n",
+ " training_examples: A `DataFrame` containing one or more columns from\n",
+ " `california_housing_dataframe` to use as input features for training.\n",
+ " training_targets: A `DataFrame` containing exactly one column from\n",
+ " `california_housing_dataframe` to use as target for training.\n",
+ " validation_examples: A `DataFrame` containing one or more columns from\n",
+ " `california_housing_dataframe` to use as input features for validation.\n",
+ " validation_targets: A `DataFrame` containing exactly one column from\n",
+ " `california_housing_dataframe` to use as target for validation.\n",
+ " \n",
+ " Returns:\n",
+ " A `LinearClassifier` object trained on the training data.\n",
+ " \"\"\"\n",
+ "\n",
+ " periods = 10\n",
+ " steps_per_period = steps / periods\n",
+ " \n",
+ " # Create a linear classifier object.\n",
+ " my_optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)\n",
+ " my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0) \n",
+ " linear_classifier = tf.estimator.LinearClassifier(\n",
+ " feature_columns=construct_feature_columns(training_examples),\n",
+ " optimizer=my_optimizer\n",
+ " )\n",
+ " \n",
+ " # Create input functions.\n",
+ " training_input_fn = lambda: my_input_fn(training_examples, \n",
+ " training_targets[\"median_house_value_is_high\"], \n",
+ " batch_size=batch_size)\n",
+ " predict_training_input_fn = lambda: my_input_fn(training_examples, \n",
+ " training_targets[\"median_house_value_is_high\"], \n",
+ " num_epochs=1, \n",
+ " shuffle=False)\n",
+ " predict_validation_input_fn = lambda: my_input_fn(validation_examples, \n",
+ " validation_targets[\"median_house_value_is_high\"], \n",
+ " num_epochs=1, \n",
+ " shuffle=False)\n",
+ " \n",
+ " # Train the model, but do so inside a loop so that we can periodically assess\n",
+ " # loss metrics.\n",
+ " print(\"Training model...\")\n",
+ " print(\"LogLoss (on training data):\")\n",
+ " training_log_losses = []\n",
+ " validation_log_losses = []\n",
+ " for period in range (0, periods):\n",
+ " # Train the model, starting from the prior state.\n",
+ " linear_classifier.train(\n",
+ " input_fn=training_input_fn,\n",
+ " steps=steps_per_period\n",
+ " )\n",
+ " # Take a break and compute predictions. \n",
+ " training_probabilities = linear_classifier.predict(input_fn=predict_training_input_fn)\n",
+ " training_probabilities = np.array([item['probabilities'] for item in training_probabilities])\n",
+ " \n",
+ " validation_probabilities = linear_classifier.predict(input_fn=predict_validation_input_fn)\n",
+ " validation_probabilities = np.array([item['probabilities'] for item in validation_probabilities])\n",
+ " \n",
+ " training_log_loss = metrics.log_loss(training_targets, training_probabilities)\n",
+ " validation_log_loss = metrics.log_loss(validation_targets, validation_probabilities)\n",
+ " # Occasionally print the current loss.\n",
+ " print(\" period %02d : %0.2f\" % (period, training_log_loss))\n",
+ " # Add the loss metrics from this period to our list.\n",
+ " training_log_losses.append(training_log_loss)\n",
+ " validation_log_losses.append(validation_log_loss)\n",
+ " print(\"Model training finished.\")\n",
+ " \n",
+ " # Output a graph of loss metrics over periods.\n",
+ " plt.ylabel(\"LogLoss\")\n",
+ " plt.xlabel(\"Periods\")\n",
+ " plt.title(\"LogLoss vs. Periods\")\n",
+ " plt.tight_layout()\n",
+ " plt.plot(training_log_losses, label=\"training\")\n",
+ " plt.plot(validation_log_losses, label=\"validation\")\n",
+ " plt.legend()\n",
+ "\n",
+ " return linear_classifier"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "UPM_T1FXsTaL",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "linear_classifier = train_linear_classifier_model(\n",
+ " learning_rate=0.000005,\n",
+ " steps=500,\n",
+ " batch_size=20,\n",
+ " training_examples=training_examples,\n",
+ " training_targets=training_targets,\n",
+ " validation_examples=validation_examples,\n",
+ " validation_targets=validation_targets)"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "i-Xo83_aR6s_",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## Task 3: Calculate Accuracy and plot a ROC Curve for the Validation Set\n",
+ "\n",
+ "A few of the metrics useful for classification are the model [accuracy](https://en.wikipedia.org/wiki/Accuracy_and_precision#In_binary_classification), the [ROC curve](https://en.wikipedia.org/wiki/Receiver_operating_characteristic) and the area under the ROC curve (AUC). We'll examine these metrics.\n",
+ "\n",
+ "`LinearClassifier.evaluate` calculates useful metrics like accuracy and AUC."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "DKSQ87VVIYIA",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "evaluation_metrics = linear_classifier.evaluate(input_fn=predict_validation_input_fn)\n",
+ "\n",
+ "print(\"AUC on the validation set: %0.2f\" % evaluation_metrics['auc'])\n",
+ "print(\"Accuracy on the validation set: %0.2f\" % evaluation_metrics['accuracy'])"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "47xGS2uNIYIE",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "You may use class probabilities, such as those calculated by `LinearClassifier.predict`,\n",
+ "and Sklearn's [roc_curve](http://scikit-learn.org/stable/modules/model_evaluation.html#roc-metrics) to\n",
+ "obtain the true positive and false positive rates needed to plot a ROC curve."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "xaU7ttj8IYIF",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "validation_probabilities = linear_classifier.predict(input_fn=predict_validation_input_fn)\n",
+ "# Get just the probabilities for the positive class.\n",
+ "validation_probabilities = np.array([item['probabilities'][1] for item in validation_probabilities])\n",
+ "\n",
+ "false_positive_rate, true_positive_rate, thresholds = metrics.roc_curve(\n",
+ " validation_targets, validation_probabilities)\n",
+ "plt.plot(false_positive_rate, true_positive_rate, label=\"our model\")\n",
+ "plt.plot([0, 1], [0, 1], label=\"random classifier\")\n",
+ "_ = plt.legend(loc=2)"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "PIdhwfgzIYII",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "**See if you can tune the learning settings of the model trained at Task 2 to improve AUC.**\n",
+ "\n",
+ "Often times, certain metrics improve at the detriment of others, and you'll need to find the settings that achieve a good compromise.\n",
+ "\n",
+ "**Verify if all metrics improve at the same time.**"
+ ]
+ },
+ {
+ "metadata": {
+ "id": "XKIqjsqcCaxO",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 677
+ },
+ "outputId": "2d1e1c73-75e8-4e4d-8448-49dfd03f6506"
+ },
+ "cell_type": "code",
+ "source": [
+ "# TUNE THE SETTINGS BELOW TO IMPROVE AUC\n",
+ "linear_classifier = train_linear_classifier_model(\n",
+ " learning_rate=0.000003,\n",
+ " steps=50000,\n",
+ " batch_size=50,\n",
+ " training_examples=training_examples,\n",
+ " training_targets=training_targets,\n",
+ " validation_examples=validation_examples,\n",
+ " validation_targets=validation_targets)\n",
+ "\n",
+ "#I hope that it doesn't overfit\n",
+ "\n",
+ "evaluation_metrics = linear_classifier.evaluate(input_fn=predict_validation)\n",
+ "\n",
+ "print(\"AUC on the validation set: %0.2f\" % evaluation_metrics['auc'])\n",
+ "print(\"Accuracy on the validation set: %0.2f\" % evaluation_metrics['accuracy'])"
+ ],
+ "execution_count": 19,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Training model...\n",
+ "LogLoss (on training data):\n",
+ " period 00 : 0.50\n",
+ " period 01 : 0.49\n",
+ " period 02 : 0.48\n",
+ " period 03 : 0.48\n",
+ " period 04 : 0.47\n",
+ " period 05 : 0.47\n",
+ " period 06 : 0.47\n",
+ " period 07 : 0.47\n",
+ " period 08 : 0.46\n",
+ " period 09 : 0.46\n",
+ "Model training finished.\n",
+ "AUC on the validation set: 0.80\n",
+ "Accuracy on the validation set: 0.78\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "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\n3AAAAABJRU5ErkJggg==\n",
+ "text/plain": [
+ "
"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ }
+ }
+ ]
+ },
+ {
+ "metadata": {
+ "id": "wCugvl0JdWYL",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "### Solution\n",
+ "\n",
+ "Click below for a possible solution."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "VHosS1g2aetf",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "One possible solution that works is to just train for longer, as long as we don't overfit. \n",
+ "\n",
+ "We can do this by increasing the number the steps, the batch size, or both.\n",
+ "\n",
+ "All metrics improve at the same time, so our loss metric is a good proxy\n",
+ "for both AUC and accuracy.\n",
+ "\n",
+ "Notice how it takes many, many more iterations just to squeeze a few more \n",
+ "units of AUC. This commonly happens. But often even this small gain is worth \n",
+ "the costs."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "dWgTEYMddaA-",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "linear_classifier = train_linear_classifier_model(\n",
+ " learning_rate=0.000003,\n",
+ " steps=20000,\n",
+ " batch_size=500,\n",
+ " training_examples=training_examples,\n",
+ " training_targets=training_targets,\n",
+ " validation_examples=validation_examples,\n",
+ " validation_targets=validation_targets)\n",
+ "\n",
+ "evaluation_metrics = linear_classifier.evaluate(input_fn=predict_validation_input_fn)\n",
+ "\n",
+ "print(\"AUC on the validation set: %0.2f\" % evaluation_metrics['auc'])\n",
+ "print(\"Accuracy on the validation set: %0.2f\" % evaluation_metrics['accuracy'])"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ }
+ ]
+}
\ No newline at end of file
diff --git a/multi_class_classification_of_handwritten_digits.ipynb b/multi_class_classification_of_handwritten_digits.ipynb
new file mode 100644
index 0000000..6a9b5fc
--- /dev/null
+++ b/multi_class_classification_of_handwritten_digits.ipynb
@@ -0,0 +1,2094 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "name": "multi-class_classification_of_handwritten_digits.ipynb",
+ "version": "0.3.2",
+ "provenance": [],
+ "collapsed_sections": [
+ "JndnmDMp66FL",
+ "266KQvZoMxMv",
+ "6sfw3LH0Oycm"
+ ],
+ "include_colab_link": true
+ },
+ "kernelspec": {
+ "name": "python2",
+ "display_name": "Python 2"
+ }
+ },
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "view-in-github",
+ "colab_type": "text"
+ },
+ "source": [
+ ""
+ ]
+ },
+ {
+ "metadata": {
+ "id": "JndnmDMp66FL",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "#### Copyright 2017 Google LLC."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "hMqWDc_m6rUC",
+ "colab_type": "code",
+ "cellView": "both",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "# 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\n",
+ "#\n",
+ "# https://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."
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "mPa95uXvcpcn",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "# Classifying Handwritten Digits with Neural Networks"
+ ]
+ },
+ {
+ "metadata": {
+ "id": "Fdpn8b90u8Tp",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ ""
+ ]
+ },
+ {
+ "metadata": {
+ "id": "c7HLCm66Cs2p",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "**Learning Objectives:**\n",
+ " * Train both a linear model and a neural network to classify handwritten digits from the classic [MNIST](http://yann.lecun.com/exdb/mnist/) data set\n",
+ " * Compare the performance of the linear and neural network classification models\n",
+ " * Visualize the weights of a neural-network hidden layer"
+ ]
+ },
+ {
+ "metadata": {
+ "id": "HSEh-gNdu8T0",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "Our goal is to map each input image to the correct numeric digit. We will create a NN with a few hidden layers and a Softmax layer at the top to select the winning class."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "2NMdE1b-7UIH",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "## Setup\n",
+ "\n",
+ "First, let's download the data set, import TensorFlow and other utilities, and load the data into a *pandas* `DataFrame`. Note that this data is a sample of the original MNIST training data; we've taken 20000 rows at random."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "4LJ4SD8BWHeh",
+ "colab_type": "code",
+ "cellView": "both",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 236
+ },
+ "outputId": "7959881e-725e-402c-b364-0931bc22b187"
+ },
+ "cell_type": "code",
+ "source": [
+ "from __future__ import print_function\n",
+ "\n",
+ "import glob\n",
+ "import math\n",
+ "import os\n",
+ "\n",
+ "from IPython import display\n",
+ "from matplotlib import cm\n",
+ "from matplotlib import gridspec\n",
+ "from matplotlib import pyplot as plt\n",
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "import seaborn as sns\n",
+ "from sklearn import metrics\n",
+ "import tensorflow as tf\n",
+ "from tensorflow.python.data import Dataset\n",
+ "\n",
+ "tf.logging.set_verbosity(tf.logging.ERROR)\n",
+ "pd.options.display.max_rows = 10\n",
+ "pd.options.display.float_format = '{:.1f}'.format\n",
+ "\n",
+ "mnist_dataframe = pd.read_csv(\n",
+ " \"https://download.mlcc.google.com/mledu-datasets/mnist_train_small.csv\",\n",
+ " sep=\",\",\n",
+ " header=None)\n",
+ "\n",
+ "# Use just the first 10,000 records for training/validation.\n",
+ "mnist_dataframe = mnist_dataframe.head(10000)\n",
+ "\n",
+ "mnist_dataframe = mnist_dataframe.reindex(np.random.permutation(mnist_dataframe.index))\n",
+ "mnist_dataframe.head()"
+ ],
+ "execution_count": 3,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/html": [
+ "
\n",
+ "\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
0
\n",
+ "
1
\n",
+ "
2
\n",
+ "
3
\n",
+ "
4
\n",
+ "
5
\n",
+ "
6
\n",
+ "
7
\n",
+ "
8
\n",
+ "
9
\n",
+ "
...
\n",
+ "
775
\n",
+ "
776
\n",
+ "
777
\n",
+ "
778
\n",
+ "
779
\n",
+ "
780
\n",
+ "
781
\n",
+ "
782
\n",
+ "
783
\n",
+ "
784
\n",
+ "
\n",
+ " \n",
+ " \n",
+ "
\n",
+ "
6849
\n",
+ "
3
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
...
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
\n",
+ "
\n",
+ "
562
\n",
+ "
6
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
...
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
\n",
+ "
\n",
+ "
3824
\n",
+ "
9
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
...
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
\n",
+ "
\n",
+ "
1958
\n",
+ "
1
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
...
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
\n",
+ "
\n",
+ "
4523
\n",
+ "
3
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
...
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
0
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
5 rows × 785 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " 0 1 2 3 4 5 6 7 8 9 ... 775 776 777 \\\n",
+ "6849 3 0 0 0 0 0 0 0 0 0 ... 0 0 0 \n",
+ "562 6 0 0 0 0 0 0 0 0 0 ... 0 0 0 \n",
+ "3824 9 0 0 0 0 0 0 0 0 0 ... 0 0 0 \n",
+ "1958 1 0 0 0 0 0 0 0 0 0 ... 0 0 0 \n",
+ "4523 3 0 0 0 0 0 0 0 0 0 ... 0 0 0 \n",
+ "\n",
+ " 778 779 780 781 782 783 784 \n",
+ "6849 0 0 0 0 0 0 0 \n",
+ "562 0 0 0 0 0 0 0 \n",
+ "3824 0 0 0 0 0 0 0 \n",
+ "1958 0 0 0 0 0 0 0 \n",
+ "4523 0 0 0 0 0 0 0 \n",
+ "\n",
+ "[5 rows x 785 columns]"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 3
+ }
+ ]
+ },
+ {
+ "metadata": {
+ "id": "kg0-25p2mOi0",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "Each row represents one labeled example. Column 0 represents the label that a human rater has assigned for one handwritten digit. For example, if Column 0 contains '6', then a human rater interpreted the handwritten character as the digit '6'. The ten digits 0-9 are each represented, with a unique class label for each possible digit. Thus, this is a multi-class classification problem with 10 classes."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "PQ7vuOwRCsZ1",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ ""
+ ]
+ },
+ {
+ "metadata": {
+ "id": "dghlqJPIu8UM",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "Columns 1 through 784 contain the feature values, one per pixel for the 28×28=784 pixel values. The pixel values are on a gray scale in which 0 represents white, 255 represents black, and values between 0 and 255 represent shades of gray. Most of the pixel values are 0; you may want to take a minute to confirm that they aren't all 0. For example, adjust the following text block to print out the values in column 72."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "2ZkrL5MCqiJI",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 424
+ },
+ "outputId": "e2788e98-fe58-44e8-e6ed-609fb99b6014"
+ },
+ "cell_type": "code",
+ "source": [
+ "mnist_dataframe.loc[:, 72:72]"
+ ],
+ "execution_count": 4,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/html": [
+ "
\n",
+ "\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
72
\n",
+ "
\n",
+ " \n",
+ " \n",
+ "
\n",
+ "
6849
\n",
+ "
0
\n",
+ "
\n",
+ "
\n",
+ "
562
\n",
+ "
0
\n",
+ "
\n",
+ "
\n",
+ "
3824
\n",
+ "
0
\n",
+ "
\n",
+ "
\n",
+ "
1958
\n",
+ "
0
\n",
+ "
\n",
+ "
\n",
+ "
4523
\n",
+ "
0
\n",
+ "
\n",
+ "
\n",
+ "
...
\n",
+ "
...
\n",
+ "
\n",
+ "
\n",
+ "
4517
\n",
+ "
0
\n",
+ "
\n",
+ "
\n",
+ "
2893
\n",
+ "
0
\n",
+ "
\n",
+ "
\n",
+ "
3727
\n",
+ "
0
\n",
+ "
\n",
+ "
\n",
+ "
1209
\n",
+ "
0
\n",
+ "
\n",
+ "
\n",
+ "
8838
\n",
+ "
0
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
10000 rows × 1 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " 72\n",
+ "6849 0\n",
+ "562 0\n",
+ "3824 0\n",
+ "1958 0\n",
+ "4523 0\n",
+ "... ..\n",
+ "4517 0\n",
+ "2893 0\n",
+ "3727 0\n",
+ "1209 0\n",
+ "8838 0\n",
+ "\n",
+ "[10000 rows x 1 columns]"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 4
+ }
+ ]
+ },
+ {
+ "metadata": {
+ "id": "vLNg2VxqhUZ",
+ "colab_type": "text"
+ },
+ "cell_type": "markdown",
+ "source": [
+ "Now, let's parse out the labels and features and look at a few examples. Note the use of `loc` which allows us to pull out columns based on original location, since we don't have a header row in this data set."
+ ]
+ },
+ {
+ "metadata": {
+ "id": "JfFWWvMWDFrR",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "cell_type": "code",
+ "source": [
+ "def parse_labels_and_features(dataset):\n",
+ " \"\"\"Extracts labels and features.\n",
+ " \n",
+ " This is a good place to scale or transform the features if needed.\n",
+ " \n",
+ " Args:\n",
+ " dataset: A Pandas `Dataframe`, containing the label on the first column and\n",
+ " monochrome pixel values on the remaining columns, in row major order.\n",
+ " Returns:\n",
+ " A `tuple` `(labels, features)`:\n",
+ " labels: A Pandas `Series`.\n",
+ " features: A Pandas `DataFrame`.\n",
+ " \"\"\"\n",
+ " labels = dataset[0]\n",
+ "\n",
+ " # DataFrame.loc index ranges are inclusive at both ends.\n",
+ " features = dataset.loc[:,1:784]\n",
+ " # Scale the data to [0, 1] by dividing out the max value, 255.\n",
+ " features = features / 255\n",
+ "\n",
+ " return labels, features"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "metadata": {
+ "id": "mFY_-7vZu8UU",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 350
+ },
+ "outputId": "be81a869-0655-47b9-b0eb-2f58e8a1b9e4"
+ },
+ "cell_type": "code",
+ "source": [
+ "training_targets, training_examples = parse_labels_and_features(mnist_dataframe[:7500])\n",
+ "training_examples.describe()"
+ ],
+ "execution_count": 6,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/html": [
+ "