{ "cells": [ { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [], "source": [ "%matplotlib inline\n", "import numpy as np;\n", "from matplotlib import pyplot as plt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$\\LaTeX \\text{ commands here}\n", "\\newcommand{\\R}{\\mathbb{R}}\n", "\\newcommand{\\im}{\\text{im}\\,}\n", "\\newcommand{\\norm}[1]{||#1||}\n", "\\newcommand{\\inner}[1]{\\langle #1 \\rangle}\n", "\\newcommand{\\span}{\\mathrm{span}}\n", "\\newcommand{\\proj}{\\mathrm{proj}}\n", "$" ] }, { "cell_type": "markdown", "metadata": { "nbpresent": { "id": "0d550dc6-b222-4f90-8a5a-8fc373b860e9" }, "slideshow": { "slide_type": "slide" } }, "source": [ "
\n", "\n", "**Georgia Tech, CS 4540**\n", "\n", "# L5: Convex Functions & Multivariate Differentiation\n", "\n", "Jacob Abernethy\n", "\n", "*Tuesday, September 03, 2019*\n", "\n", "**Quiz password**: longweekend" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Multivariate Chain Rule\n", "\n", "For a good description, see [these notes](https://math.berkeley.edu/~nikhil/courses/121a/chain.pdf).\n", "\n", "Imagine we have $f : \\R^n \\to \\R^m$ and $g : \\R^m \\to \\R^k$. Then we want to compute the gradient (Jacobian) of the function $f \\circ g$. Is there any easy way to do this? The answer is YES, according to the **multivariate chain rule**:\n", "$$ D_{f \\circ g}[x] = D_f[g(x)] \\cdot D_g[x]$$\n", "This is a powerful statement, although it may not be clear why. It says we can obtain the gradient of the composed functions, by simply composing the gradients, treated as *linear transformations*." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Problem \n", "Let $f(x) = \\sum_{i=1}^m -\\log (A_i \\cdot x - b_i)$ where $A$ is an $m\\times n$ matrix. Notice that we can write $f(x) = h(g(x)) = h \\circ g (x)$ where $h(y) = -\\sum \\log y_i$ and $g(x) = A x - b$\n", "\n", "Use the multivariate chain rule to compute $\\nabla_x f$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Answer\n", "\n", "We can see that\n", "+ $D_h[y] = \\nabla h(y) = [-1/y_1, \\ldots, -1/y_m]$\n", "+ $D_g[x] = \\nabla g(x) = A$, a constant matrix\n", "\n", "So this means\n", "\\begin{eqnarray*}\n", "D_f[x] & = & D_h[g(x)] \\cdot D_g[x] = [-1/(A_1 x - b_1), \\ldots, -1/(A_m x - b_m)] \\cdot A \\\\\n", "& = & \\sum_{i=1}^m \\frac{-1}{A_i x - b_i}A_i\n", "\\end{eqnarray*}\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Problem:\n", "\n", "Let $f(x) = A(2x + \\mathbf{1})$ where $A$ is a matrix, and $\\mathbf{1}$ is the all ones vector.\n", "\n", "Let's write $f(x) = h \\circ g (x)$ where $g(x) = 2x + \\mathbf{1}$ and $h(x) = A x$. What is the gradient of $f$?" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Answer\n", "\n", "$D_g[x] = \\nabla g(x) = 2I$\n", "\n", "$D_h[x] = \\nabla h(x) = A$\n", "\n", "$D_f[x] = D_h[g(x)] \\cdot D_g[x] = 2AI = 2A$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Some Calc. Problems\n", "\n", "Let $w$ be an $n$-dim vector. Calculate the first and second derivatives of the following functions:\n", "+ $f(w) = \\frac 1 2 w^\\top w$\n", "+ $f(w) = w^\\top v$ where $v$ is some fixed vector" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#### Answer\n", "\n", "* $f(w) = \\frac 1 2 w^\\top w$:\n", " + $\\nabla f(w) = w$\n", " + $\\nabla^2 f(w) = I$, the identity matrix\n", "* $f(w) = w^\\top v$\n", " + $\\nabla f(w) = v$\n", " + $\\nabla^2 f(w) = 0$, the zero matrix" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### More Calc. Problems\n", "\n", "Let $w$ be an $n$-dim vector. Calculate the derivatives of the following functions:\n", "+ $f(w) = \\|w\\|_2$\n", "+ $f(w) = \\| w \\|_1$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "skip" } }, "source": [ "#### Answer\n", "+ $f(w) = \\|w\\|_2 \\implies \\nabla f(w) = \\frac{w}{\\|w\\|_2}$\n", "+ $f(w) = \\| w \\|_1 \\implies \\nabla f(w) = [\\text{sign}(w_i)]_{i=1\\ldots n}$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### More Calc. Problems\n", "\n", "Let $w$ be an $n$-dim vector. Calculate the derivatives of the following functions:\n", "+ $f(w) = \\frac 1 2 \\|w - v\\|_2^2$ where $v$ is some fixed vector\n", "+ $f(w) = \\frac 1 2 w^\\top M w$ (calculate the hessian for this one as well!)\n", "+ $f(w) = \\exp(w^\\top M w)$ where $M$ is some symmetric $n \\times n $ matrix" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "skip" } }, "source": [ "#### Answer\n", "\n", "+ $f(w) = \\frac 1 2 \\|w - v\\|_2^2 \\implies \\nabla f(w) = (w - v)^\\top w$\n", "+ $f(w) = \\frac 1 2 w^\\top M w \\implies \\nabla f(w) = \\frac 1 2 w^\\top(M + M^\\top)$\n", "+ $f(w) = \\exp(w^\\top M w) \\implies \\nabla f(w) = \\exp(w^\\top M w)Mw$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Positive Semidefinite Matrices\n", "\n", "**Definition**: A matrix $M \\in \\R^{n\\times n}$ is *positive semidefinite* if $x^\\top M x \\geq 0\\; \\forall x \\in \\R^n$\n", "\n", "Commonly, we work with matrices $M$ that are *symmetric* (that is, $M = M^T$). In this case, the following are equivalent:\n", "\n", "1. $M$ is positive semidefinite\n", "2. The eigenvalues of $M$ are all $\\geq 0$\n", "3. The matrix $M$ can be written as $B^\\top B$ for some $B \\in R^n$\n", "\n", "**Problem**: Show that (3) $\\implies$ (1) $\\implies$ (2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Answer\n", "\n", "If $M$ can be written as $B^TB$ for $B \\in R^n$, then:\n", "\n", "$$x^TMx = x^TB^TBx = (Bx)^T Bx = (Bx)^2 \\geq 0$$\n", "\n", "This shows (1).\n", "\n", "To show (1) implies (2), consider the eigenvectors of $M$ $v_i$ such that $Mv_i = \\lambda_i v_i$. Since $M$ is positive semidefinite:\n", "\n", "$$v_i^T M_i v_i = v_i^T \\lambda_i v_i = \\lambda v_i^T v_i = \\lambda \\|v_i\\|_2^2 \\geq 0$$\n", "\n", "Since $\\|v_i\\|_2^2 \\geq 0$, then it must be the case $\\lambda_i \\geq 0$." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Convex Functions\n", "\n", "A function $f : \\R^d \\to \\R$ is convex if, for any $x,y \\in \\text{dom}(f)$ and any $\\theta \\in [0,1]$, we have\n", "$$f(\\theta x + (1-\\theta)y) \\leq \\theta f(x) + (1-\\theta) f(y)$$\n", "\n", "**First-order Condition** When $f$ is differentiable, then $f$ is convex if and only if\n", "$$f(y) \\geq f(x) + \\nabla f(x)^\\top(y - x) \\quad \\text{ for any } x,y \\in \\text{dom}(f)$$\n", "\n", "**Second-order Condition** When $f$ is twice differentiable, then $f$ is convex if and only if\n", "$$u^\\top (\\nabla^2f(x)) u \\geq 0 \\quad \\text{ for any } x \\in \\text{dom}(f) \\text{ and any } u \\in \\R^d$$\n", "This last condition $\\equiv$ \"$f$ is convex if its hessian is always positive semi-definite\"" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Problem\n", "\n", "**First-order Condition** When $f$ is differentiable, then $f$ is convex if and only if\n", "$$f(y) \\geq f(x) + \\nabla f(x)^\\top(y - x) \\quad \\text{ for any } x,y \\in \\text{dom}(f)$$\n", "\n", "Use the first order condition to show that, for any convex and differentiable $f$, we have\n", "$$(\\nabla f(y) - \\nabla f(x))^\\top(y - x) \\geq 0 \\text{ for any } x,y \\in \\text{dom}(f)$$\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "skip" } }, "source": [ "#### Answer\n", "\n", "Let's apply the first order condition twice, once at $x$ and once at $y$:\n", "\\begin{eqnarray*}\n", "f(y) & \\geq & f(x) + \\nabla f(x)^\\top(y - x) \\\\\n", "f(x) & \\geq & f(y) + \\nabla f(y)^\\top(x - y).\n", "\\end{eqnarray*}\n", "Add these two inequalities together, and subtract $f(x) + f(y)$ from both sides and you are done!" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Problem\n", "\n", "**Second-order Condition** When $f$ is twice differentiable, then $f$ is convex if and only if\n", "$$u^\\top (\\nabla^2f(x)) u \\geq 0 \\quad \\text{ for any } x \\in \\text{dom}(f) \\text{ and any } u \\in \\R^d$$\n", "\n", "Find conditions under which the following function is convex $f(x) = \\frac 1 2 x^\\top A x$ for a symmetric matrix $A \\in \\R^{d \\times d}$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#### Answer\n", "\n", "As we computed earlier in lecture, for $f(x) = \\frac 1 2 x^\\top A x$, the hessian is $\\nabla^2 f(x) = A$. We know that a twice-differentiable function is convex if its hessian is positive semi-definite. Therefore, $f$ is convex if and only if $A$ is positive semi-definite." ] } ], "metadata": { "celltoolbar": "Slideshow", "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.16" }, "nbpresent": { "slides": { "00402695-e04c-4eef-89e0-d40218a4b0e7": { "id": "00402695-e04c-4eef-89e0-d40218a4b0e7", "prev": null, "regions": { "4448a694-c5c3-40bb-ab2b-ed9b29a5b571": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "id": "4448a694-c5c3-40bb-ab2b-ed9b29a5b571" } } }, "0265b550-c6b6-425a-9c52-f618822afef0": { "id": "0265b550-c6b6-425a-9c52-f618822afef0", "prev": "49ba58b9-fb36-4447-9811-c3ada1b777b6", "regions": { "b702ead7-d493-4d02-8d0f-23b216601150": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "a69ec655-4bfe-4a3f-9d26-9965eceb71df", "part": "whole" }, "id": "b702ead7-d493-4d02-8d0f-23b216601150" } } }, "1b9e5fe3-4efd-46d2-9af0-7648e295e4a2": { "id": "1b9e5fe3-4efd-46d2-9af0-7648e295e4a2", "prev": "885499a5-0dfb-4789-9555-6a95c5a3376e", "regions": { "556348bf-3f97-4a5d-952c-5ab545ee4992": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "ece64073-7cf1-4495-bfe4-337f1fa42390", "part": "whole" }, "id": "556348bf-3f97-4a5d-952c-5ab545ee4992" } } }, "2039394f-772d-4c00-b81e-83f05bc1dcd1": { "id": "2039394f-772d-4c00-b81e-83f05bc1dcd1", "prev": "94eabf87-a6d9-4ac8-a24e-dad8e0e4d8d8", "regions": { "63b012e8-1ac7-4c4e-b281-a80d944c12ae": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "29b540e4-7d19-4df6-b685-72c772a842d0", "part": "whole" }, "id": "63b012e8-1ac7-4c4e-b281-a80d944c12ae" } } }, "2db8174a-eab5-4a44-aa68-a816d759bda9": { "id": "2db8174a-eab5-4a44-aa68-a816d759bda9", "prev": "1b9e5fe3-4efd-46d2-9af0-7648e295e4a2", "regions": { "7539e7ab-53f5-417b-af25-a99f24b36e72": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "526a6929-1493-4efb-9580-8d532f1b1733", "part": "whole" }, "id": "7539e7ab-53f5-417b-af25-a99f24b36e72" } } }, "4329cc6d-7f9f-4b70-a761-2cb9d911ca0f": { "id": "4329cc6d-7f9f-4b70-a761-2cb9d911ca0f", "prev": "9b2467ee-a4a5-42ab-9028-de6057970611", "regions": { "4dc09d43-f722-4d98-99a1-5752221a2d67": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "ac1f6d59-30ec-4e45-ba35-254bfe82de2a", "part": "whole" }, "id": "4dc09d43-f722-4d98-99a1-5752221a2d67" } } }, "49ba58b9-fb36-4447-9811-c3ada1b777b6": { "id": "49ba58b9-fb36-4447-9811-c3ada1b777b6", "prev": "00402695-e04c-4eef-89e0-d40218a4b0e7", "regions": { "9fd470e1-9457-4fad-a69a-135027c528ae": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "0d550dc6-b222-4f90-8a5a-8fc373b860e9", "part": "whole" }, "id": "9fd470e1-9457-4fad-a69a-135027c528ae" } } }, "4f2e1449-4308-4724-b6b5-f1ce1967f8bb": { "id": "4f2e1449-4308-4724-b6b5-f1ce1967f8bb", "prev": "f0551436-2b74-43fd-b272-c48323a83773", "regions": { "a6956997-1dbe-417c-b982-aa9974af36a2": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "4da46af5-389b-422f-8723-2240bcb5e5cc", "part": "whole" }, "id": "a6956997-1dbe-417c-b982-aa9974af36a2" } } }, "6a9b86a5-72d4-4ea9-8160-3d55bae4c738": { "id": "6a9b86a5-72d4-4ea9-8160-3d55bae4c738", "prev": "4f2e1449-4308-4724-b6b5-f1ce1967f8bb", "regions": { "7a3484dc-5988-456c-b189-15cb1f18af1f": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "951424a9-7339-4487-bff2-66c64595ea34", "part": "whole" }, "id": "7a3484dc-5988-456c-b189-15cb1f18af1f" } } }, "788ca0e1-453f-4688-b082-ffde7b78e68c": { "id": "788ca0e1-453f-4688-b082-ffde7b78e68c", "prev": "2db8174a-eab5-4a44-aa68-a816d759bda9", "regions": { "fe4f47cd-4e72-4e30-970a-19547b803205": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "d70290b6-b579-4460-9035-1657b31857a4", "part": "whole" }, "id": "fe4f47cd-4e72-4e30-970a-19547b803205" } } }, "7a911c00-893a-4bdd-b842-fce896a21aae": { "id": "7a911c00-893a-4bdd-b842-fce896a21aae", "prev": "2039394f-772d-4c00-b81e-83f05bc1dcd1", "regions": { "2de9a398-fea4-4723-a8b6-55c33ce96eb1": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "b0a25cbc-b5fe-4080-bd6f-951ddfd7381f", "part": "whole" }, "id": "2de9a398-fea4-4723-a8b6-55c33ce96eb1" } } }, "829ba554-db30-4ece-af12-5488f4729294": { "id": "829ba554-db30-4ece-af12-5488f4729294", "prev": "7a911c00-893a-4bdd-b842-fce896a21aae", "regions": { "443f7e08-6b5f-4714-aed2-b8e910728910": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "56362fbe-c101-494a-bd32-3e1649e15643", "part": "whole" }, "id": "443f7e08-6b5f-4714-aed2-b8e910728910" } } }, "885499a5-0dfb-4789-9555-6a95c5a3376e": { "id": "885499a5-0dfb-4789-9555-6a95c5a3376e", "prev": "f3732cc4-6051-4998-a02c-0e5541a15f23", "regions": { "8b4717b8-bdd2-465b-96ad-407eacdbe34b": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "6f147f30-1ba3-4e9f-9653-e13a4257df6c", "part": "whole" }, "id": "8b4717b8-bdd2-465b-96ad-407eacdbe34b" } } }, "94eabf87-a6d9-4ac8-a24e-dad8e0e4d8d8": { "id": "94eabf87-a6d9-4ac8-a24e-dad8e0e4d8d8", "prev": "4329cc6d-7f9f-4b70-a761-2cb9d911ca0f", "regions": { "82549bbb-345d-423f-8229-7b5cd0628b14": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "8018269b-60c2-4a26-abe2-77c73cace5f6", "part": "whole" }, "id": "82549bbb-345d-423f-8229-7b5cd0628b14" } } }, "9b2467ee-a4a5-42ab-9028-de6057970611": { "id": "9b2467ee-a4a5-42ab-9028-de6057970611", "prev": "788ca0e1-453f-4688-b082-ffde7b78e68c", "regions": { "33ad7a50-cf56-40b7-b53b-552605f88fa5": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "6c33627a-8a43-4349-bf5e-9097b0e286f7", "part": "whole" }, "id": "33ad7a50-cf56-40b7-b53b-552605f88fa5" } } }, "ba0bf0ed-6cee-4c8c-bc7e-222a0f8e820d": { "id": "ba0bf0ed-6cee-4c8c-bc7e-222a0f8e820d", "prev": "829ba554-db30-4ece-af12-5488f4729294", "regions": { "7eb01692-dcb5-4ded-bd25-7e0d90f3fffc": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "6c53c225-83fe-4d41-8dca-0d1c9368584c", "part": "whole" }, "id": "7eb01692-dcb5-4ded-bd25-7e0d90f3fffc" } } }, "df3d62d2-e2b9-4ff7-978b-08c51a4f9ee8": { "id": "df3d62d2-e2b9-4ff7-978b-08c51a4f9ee8", "prev": "ba0bf0ed-6cee-4c8c-bc7e-222a0f8e820d", "regions": { "75cf714e-431e-4287-914d-b79312bcbfce": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "561a5ffb-7003-4ec0-a6bc-c3fd39204a40", "part": "whole" }, "id": "75cf714e-431e-4287-914d-b79312bcbfce" } } }, "f0551436-2b74-43fd-b272-c48323a83773": { "id": "f0551436-2b74-43fd-b272-c48323a83773", "prev": "0265b550-c6b6-425a-9c52-f618822afef0", "regions": { "9d1114ff-54fc-40c5-a3f1-4d094ab427d6": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "f14dd754-9e43-4014-8a09-be62ba0c3aed", "part": "whole" }, "id": "9d1114ff-54fc-40c5-a3f1-4d094ab427d6" } } }, "f3732cc4-6051-4998-a02c-0e5541a15f23": { "id": "f3732cc4-6051-4998-a02c-0e5541a15f23", "prev": "6a9b86a5-72d4-4ea9-8160-3d55bae4c738", "regions": { "dce19474-7bba-475a-a368-63f262661282": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "2b797236-c6a7-4860-b27b-ca4d8f381607", "part": "whole" }, "id": "dce19474-7bba-475a-a368-63f262661282" } } } }, "themes": { "default": "474559d9-b375-479a-ac75-71c3289ec9ff", "theme": { "474559d9-b375-479a-ac75-71c3289ec9ff": { "id": "474559d9-b375-479a-ac75-71c3289ec9ff", "palette": { "19cc588f-0593-49c9-9f4b-e4d7cc113b1c": { "id": "19cc588f-0593-49c9-9f4b-e4d7cc113b1c", "rgb": [ 252, 252, 252 ] }, "31af15d2-7e15-44c5-ab5e-e04b16a89eff": { "id": "31af15d2-7e15-44c5-ab5e-e04b16a89eff", "rgb": [ 68, 68, 68 ] }, "50f92c45-a630-455b-aec3-788680ec7410": { "id": "50f92c45-a630-455b-aec3-788680ec7410", "rgb": [ 155, 177, 192 ] }, "c5cc3653-2ee1-402a-aba2-7caae1da4f6c": { "id": "c5cc3653-2ee1-402a-aba2-7caae1da4f6c", "rgb": [ 43, 126, 184 ] }, "efa7f048-9acb-414c-8b04-a26811511a21": { "id": "efa7f048-9acb-414c-8b04-a26811511a21", "rgb": [ 25.118061674008803, 73.60176211453744, 107.4819383259912 ] } }, "rules": { "blockquote": { "color": "50f92c45-a630-455b-aec3-788680ec7410" }, "code": { "font-family": "Anonymous Pro" }, "h1": { "color": "c5cc3653-2ee1-402a-aba2-7caae1da4f6c", "font-family": "Lato", "font-size": 8 }, "h2": { "color": "c5cc3653-2ee1-402a-aba2-7caae1da4f6c", "font-family": "Lato", "font-size": 6 }, "h3": { "color": "50f92c45-a630-455b-aec3-788680ec7410", "font-family": "Lato", "font-size": 5.5 }, "h4": { "color": "c5cc3653-2ee1-402a-aba2-7caae1da4f6c", "font-family": "Lato", "font-size": 5 }, "h5": { "font-family": "Lato" }, "h6": { "font-family": "Lato" }, "h7": { "font-family": "Lato" }, "pre": { "font-family": "Anonymous Pro", "font-size": 4 } }, "text-base": { "font-family": "Merriweather", "font-size": 4 } } } } } }, "nbformat": 4, "nbformat_minor": 4 }