Skip to content

Commit 7dac460

Browse files
committed
comments to last code blocks
1 parent 37f26e2 commit 7dac460

File tree

1 file changed

+35
-30
lines changed

1 file changed

+35
-30
lines changed

lab2/solutions/Part2_FaceDetection_Solution.ipynb

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,13 @@
4848
"\n",
4949
"# Part 2: Diagnosing Bias in Facial Detection Systems\n",
5050
"\n",
51-
"In the second portion of Lab 2, we'll explore a prominent aspect of applied deep learning for computer vision: facial detection. \n",
51+
"In this lab, we'll explore a prominent aspect of applied deep learning for computer vision: facial detection. \n",
5252
"\n",
5353
"Consider the task of facial detection: given an image, is it an image of a face? This seemingly simple -- but extremely important and pervasive -- task is subject to significant amounts of algorithmic bias among select demographics, as [seminal studies](https://proceedings.mlr.press/v81/buolamwini18a/buolamwini18a.pdf) have shown.\n",
5454
"\n",
5555
"Deploying fair, unbiased AI systems is critical to their long-term acceptance. In this lab, we will build computer vision models for facial detection. We will extend beyond that to build a model to **uncover and diagnose** the biases and issues that exist with standard facial detection models. To do this, we will build a semi-supervised variational autoencoder (SS-VAE) that learns the *latent distribution* of features underlying face image datasets in order to [uncover hidden biases](http://introtodeeplearning.com/AAAI_MitigatingAlgorithmicBias.pdf).\n",
5656
"\n",
57-
"Our work here will set the foundation for Lab 3, where we'll build automated tools to mitigate the underlying issues of bias and uncertainty in facial detection.\n",
58-
"\n"
57+
"Our work here will set the foundation for the next lab, where we'll build automated tools to mitigate the underlying issues of bias and uncertainty in facial detection."
5958
]
6059
},
6160
{
@@ -190,7 +189,7 @@
190189
"source": [
191190
"### Thinking about bias\n",
192191
"\n",
193-
"We will be training our facial detection classifiers on the large, well-curated CelebA dataset (and ImageNet), and then evaluating their accuracy by testing them on an independent test dataset. Our goal is to identify any potential issues and biases that may exist with the trained facial detection classifiers, and then diagnose what those issues and biases are.\n",
192+
"We will be training our facial detection classifiers on the large, well-curated CelebA dataset (and ImageNet), and then evaluate their accuracy as well as inspect and diagnose their hidden flaws. Our goal is to identify any potential issues and biases that may exist with the trained facial detection classifiers, and then diagnose what those issues and biases are.\n",
194193
"\n",
195194
"What exactly do we mean when we say a classifier is biased? In order to formalize this, we'll need to think about [*latent variables*](https://en.wikipedia.org/wiki/Latent_variable), variables that define a dataset but are not strictly observed. As defined in the generative modeling lecture, we use the term *latent space* to refer to the probability distributions of the aforementioned latent variables. Putting these ideas together, we consider a classifier *biased* if its classification decision changes after it sees some additional latent features or variables. This definition of bias will be helpful to keep in mind throughout the rest of the lab."
196195
]
@@ -856,11 +855,11 @@
856855
"source": [
857856
"### Linking model performance to uncertainty and bias\n",
858857
"\n",
859-
"We begin by considering the examples in the test dataset with the highest loss. What can you tell about which features seemed harder to learn for the VAE? What might this tell us about where the model struggles, and what predictions it may be more biased or uncertain about?\n",
858+
"We begin by considering the examples in the dataset with the highest loss. What can you tell about which features seemed harder to learn for the VAE? What might this tell us about where the model struggles, and what predictions it may be more biased or uncertain about?\n",
860859
"\n",
861860
"#### **TODO: Analysis and reflection**\n",
862861
"\n",
863-
"Complete the analysis in the code block below. Write short answers to the following questions and include them in your Lab 2 submission to complete the `TODO`s!\n",
862+
"Complete the analysis in the code block below. Write short answers to the following questions and include them in your Debiasing Faces Lab submission to complete the `TODO`s!\n",
864863
"\n",
865864
"1. What, if any, trends do you observe comparing the samples with the highest and lowest reconstruction loss?\n",
866865
"2. Based on these observations, which features seemed harder to learn for the VAE?\n",
@@ -887,28 +886,13 @@
887886
"vae_loss = vae_loss.numpy()\n",
888887
"ind = np.argsort(vae_loss, axis=None)\n",
889888
"\n",
890-
"def create_grid_of_images(xs, size=(5,5)):\n",
891-
" grid = []\n",
892-
" counter = 0\n",
893-
" for i in range(size[0]):\n",
894-
" row = []\n",
895-
" for j in range(size[1]):\n",
896-
" row.append(xs[counter])\n",
897-
" counter += 1\n",
898-
" row = np.hstack(row)\n",
899-
" grid.append(row)\n",
900-
" grid = np.vstack(grid)\n",
901-
" return grid\n",
902-
"\n",
903-
"# mdl.util.create_grid_of_images\n",
904-
"\n",
905889
"# Plot the 25 samples with the highest and lowest reconstruction losses\n",
906890
"fig, ax = plt.subplots(1, 2, figsize=(16, 8))\n",
907-
"ax[0].imshow(create_grid_of_images(x[ind[:25]]))\n",
891+
"ax[0].imshow(mdl.util.create_grid_of_images(x[ind[:25]]))\n",
908892
"ax[0].set_title(\"Samples with the lowest reconstruction loss \\n\" + \n",
909893
" f\"Average recon loss: {np.mean(vae_loss[ind[:25]]):.2f}\")\n",
910894
"\n",
911-
"ax[1].imshow(create_grid_of_images(x[ind[-25:]]))\n",
895+
"ax[1].imshow(mdl.util.create_grid_of_images(x[ind[-25:]]))\n",
912896
"ax[1].set_title(\"Samples with the highest reconstruction loss \\n\" + \n",
913897
" f\"Average recon loss: {np.mean(vae_loss[ind[-25:]]):.2f}\");"
914898
]
@@ -929,7 +913,7 @@
929913
"\n",
930914
"#### **TODO: Analysis and reflection**\n",
931915
"\n",
932-
"Complete the analysis in the code blocks below. Carefully inspect the different latent variables and their corresponding frequency distributions. Write short answers to the following questions and include them in your Lab 2 submission to complete the `TODO`s!\n",
916+
"Complete the analysis in the code blocks below. Carefully inspect the different latent variables and their corresponding frequency distributions. Write short answers to the following questions and include them in your Debiasing Faces Lab submission to complete the `TODO`s!\n",
933917
"\n",
934918
"1. Pick two latent variables and describe what semantic meaning they reflect. Include screenshots of the realizations and probability distribution for the latent variables you select.\n",
935919
"2. For the latent variables selected, what can you tell about which features are under- or over-represented in the data? What might this tell us about how the model is biased?\n",
@@ -941,57 +925,78 @@
941925
"cell_type": "code",
942926
"source": [
943927
"#@title Change the sliders to inspect different latent features! { run: \"auto\" }\n",
944-
"idx_latent = 25 #@param {type:\"slider\", min:0, max:50, step:1}\n",
928+
"idx_latent = 25 #@param {type:\"slider\", min:0, max:31, step:1}\n",
945929
"num_steps = 15\n",
946930
"\n",
931+
"# Extract all latent samples from the desired dimension\n",
947932
"latent_samples = z_mean[:, idx_latent]\n",
948-
"density, latent_bins = np.histogram(latent_samples, num_steps, density=True)\n",
949933
"\n",
934+
"# Compute their density and plot\n",
935+
"density, latent_bins = np.histogram(latent_samples, num_steps, density=True)\n",
950936
"fig, ax = plt.subplots(2, 1, figsize=(15, 4))\n",
951937
"ax[0].bar(latent_bins[1:], density)\n",
952938
"ax[0].set_ylabel(\"Data density\")\n",
953939
"\n",
940+
"# Visualize reconstructions as we walk across the latent space\n",
954941
"latent_steps = np.linspace(np.min(latent_samples), np.max(latent_samples), num_steps)\n",
955-
"\n",
956942
"baseline_latent = tf.reduce_mean(z_mean, 0, keepdims=True)\n",
943+
"\n",
957944
"recons = []\n",
958945
"for step in latent_steps: \n",
946+
" # Adjust the latent vector according to our step\n",
959947
" latent = baseline_latent.numpy()\n",
960948
" latent[0, idx_latent] = step\n",
949+
" # Decode the reconstruction and store\n",
961950
" recons.append(dbvae.decode(latent)[0])\n",
962951
"\n",
963-
"ax[1].imshow(create_grid_of_images(recons, (1, num_steps)))\n",
952+
"# Visualize all of the reconstructions!\n",
953+
"ax[1].imshow(mdl.util.create_grid_of_images(recons, (1, num_steps)))\n",
964954
"ax[1].set_xlabel(\"Latent step\")\n",
965955
"ax[1].set_ylabel(\"Visualization\");\n"
966956
],
967957
"metadata": {
968-
"id": "8qcR9uvfCJku",
969-
"cellView": "form"
958+
"id": "8qcR9uvfCJku"
970959
},
971960
"execution_count": null,
972961
"outputs": []
973962
},
963+
{
964+
"cell_type": "markdown",
965+
"source": [
966+
"\n",
967+
"### Inspect how the accuracy changes as a function of density in the latent space\n"
968+
],
969+
"metadata": {
970+
"id": "3ExRRPO2z27z"
971+
}
972+
},
974973
{
975974
"cell_type": "code",
976975
"source": [
976+
"# Loop through every latent dimension\n",
977977
"avg_logit_per_bin = []\n",
978978
"for idx_latent in range(latent_dim): \n",
979979
" latent_samples = z_mean[:, idx_latent]\n",
980980
" start = np.percentile(latent_samples, 5)\n",
981981
" end = np.percentile(latent_samples, 95)\n",
982982
" latent_steps = np.linspace(start, end, num_steps)\n",
983983
"\n",
984+
" # Find which samples fall in which bin of the latent dimension\n",
984985
" which_latent_bin = np.digitize(latent_samples, latent_steps)\n",
986+
" \n",
987+
" # For each latent bin, compute the accuracy (average logit score)\n",
985988
" avg_logit = []\n",
986989
" for j in range(0, num_steps+1): \n",
987990
" inds_in_bin = np.where(which_latent_bin == j)\n",
988991
" avg_logit.append(y_logit.numpy()[inds_in_bin].mean())\n",
989992
"\n",
990993
" avg_logit_per_bin.append(avg_logit)\n",
991994
" \n",
995+
"# Average the results across all latent dimensions and all samples\n",
992996
"accuracy_per_latent = np.mean(avg_logit_per_bin, 0)\n",
993997
"accuracy_per_latent = (accuracy_per_latent - accuracy_per_latent.min()) / np.ptp(accuracy_per_latent)\n",
994998
"\n",
999+
"# Plot the results\n",
9951000
"plt.plot(np.linspace(start, end, num_steps+1), accuracy_per_latent,'-o')\n",
9961001
"plt.xlabel(\"Latent step\")\n",
9971002
"plt.ylabel(\"Relative accuracy\")"

0 commit comments

Comments
 (0)