{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Lecture 23: Online Learning\n",
"\n",
"## CS4787 — Principles of Large-Scale Machine Learning Systems\n",
"\n",
"$\\newcommand{\\R}{\\mathbb{R}}$\n",
"$\\newcommand{\\norm}[1]{\\left\\| #1 \\right\\|}$"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## The Course So Far\n",
"\n",
"So far, we've looked at how to train models efficiently at scale, how to use capabilities of the hardware such as parallelism to speed up training, and even how to run inference efficiently.\n",
"\n",
"However, all of this has been in the context of so-called \"batch learning\" (also known as the traditional machine learning setup).\n",
"\n",
"In ML theory, this corresponds to the setting of PAC learning (probably approximately correct learning)."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## PAC Learning (Roughly)\n",
"\n",
"This is the classic ML pipeline setup.\n",
"\n",
"\n",
"\n",
"* There is typically some fixed dataset $\\mathcal{D}$ of labeled training examples $(x,y)$, and we assume it is drawn from the same population that we will be using the model to make predictions on\n",
"\n",
"* This dataset is cleaned and preprocessed, then split into a training set, a validation set, and a test set.\n",
"\n",
"* An ML model is trained on the training set using some large-scale optimization method (or other method), using the validation set to evaluate and set hyperparameters.\n",
"\n",
"* The trained model is then evaluated once on the test set to see if it performs well.\n",
"\n",
" * The system is evaluated only **after all learning is completed**.\n",
"\n",
"* The trained model is possibly compressed for efficient deployment and inference.\n",
"\n",
"* Finally, the trained model is deployed and used for whatever task it is intended. Importantly, once deployed, the model does not change!\n",
"\n",
" * Only after learning is completed is the trained model used for inference."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## PAC Learning More Formally\n",
"\n",
"Formally, in ML theory, PAC learning is defined in terms of whether a problem class/hypothesis class is **PAC learnable** i.e. whether it can be learned by a learning algorithm under the PAC learning setup. For classification, this boils down to the claim that:\n",
"\n",
"* there is some algorithm $\\mathcal{A}$\n",
"* such that for any $\\epsilon, \\delta > 0$,\n",
"* there exists some training set size $n$\n",
"* such that if we run $\\mathcal{A}$ on a random training set of size at least $n$ (drawn independently from the population associated with the problem), then\n",
"* with probability at least $1 - \\delta$, the expected error on new examples drawn from the same population will be at most $\\epsilon$.\n",
"\n",
"That is, by increasing the size of the training set, we can achieve arbitrarily low error with arbitrarily high probability.\n",
"\n",
"* This is why it is called \"**P**robabilistically **A**pproximately-**C**orrect\" Learning."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## This batch learning setting is not the only setting in which we can learn, and not the only setting in which we can apply our principles!\n",
"\n",
"Do we really need to separate learning and inference like we do in the batch learning/PAC learning setting?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Online learning\n",
"\n",
"Not this kind of online learning...\n",
"\n",
""
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Online learning\n",
"\n",
"Online learning is a different setting, where learning and inference are **interleaved** rather than happening in two separate phases.\n",
"\n",
"Online learning on a population with distribution $\\mathcal{D}$ works by looping the following steps:\n",
"\n",
"* A new labeled example $(x_t,y_t)$ is sampled from $\\mathcal{D}$.\n",
"* The learner is given the example $x_t$ and must make a prediction $\\hat y_t = h_{w_t}(x_t)$.\n",
"* The learner is penalized by some loss function $\\ell(\\hat y_t, y_t)$.\n",
"* The learner is given the label $y$ and can now update its model parameters $w_t$ using $(x,y)$ to produce a new vector of parameters $w_{t+1}$ to be used at the next timestep.\n",
"\n",
" * Sometimes in practice, the learner does not get the label $y$ immediately but rather a short time later."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Online learning metrics\n",
"\n",
"With the batch learning setup, we often train by minimizing the **training loss** and evaluate by looking at the **validation error/loss** and **test error/loss**. All these metrics are inherently a function of batches i.e. bulk datasets...How does this translate to the online learning setting where we do not have batches?\n",
"\n",
"One way to state the goal of online learning is to minimize the **regret**.\n",
"\n",
"For any fixed parameter vector $w$ and number of examples $T$, the regret relative to $h_w$ is defined to be the worst-case extra loss incurred by not consistently predicting using the parameters $w$, that is\n",
"\n",
"$$R(w, T) = \\sup_{(x_1,y_1), \\cdots, (x_T, y_T)} \\; \\left( \\sum_{t=1}^T \\ell(\\hat y_t, y_t) - \\sum_{t=1}^T \\ell(h_w(x_t), y_t) \\right),$$\n",
"\n",
"where $\\hat y_t$ is the prediction actually made by the learning algorithm on this dataset at iteration $t$.\n",
"The regret relative to the entire hypothesis class is the worst-case regret relative to any assignment of the parameters,\n",
"$$R(T) = \\sup_w R(w, T) = \\sup_{(x_1,y_1), \\cdots, (x_T, y_T)} \\; \\left( \\sum_{t=1}^T \\ell(\\hat y_t, y_t) - \\inf_w \\sum_{t=1}^T \\ell(h_w(x_t), y_t) \\right).$$\n",
"You may recognize this last infimum as looking a lot like empirical risk minimization!\n",
"We can think about the regret as being the amount of extra loss we incur by virtue of learning in an online setting, compared to the training loss we would have incurred from solving the ERM problem exactly in the batch setting."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"What are some applications where we might want to use an online learning setup rather than a traditional batch learning approach?"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Algorithms for Online Learning\n",
"\n",
"One popular algorithm for online learning that is very similar to what we've discussed so far is **online gradient descent**.\n",
"\n",
"_It's exactly what it sounds like._\n",
"\n",
"At each step of the online learning loop, it runs\n",
"$$w_{t+1} = w_t - \\alpha \\nabla_{w_t} \\ell(h_{w_t}(x_t), y_t).$$\n",
"\n",
"This should be very recognizable as the same type of update loop as we used in SGD!\n",
"\n",
"* And we should be able to use most of the techniques we discussed in this course to make it scalable."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"In fact, we can use pretty much the same analysis that we used for SGD to bound the regret."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Online Gradient Descent Convergence\n",
"\n",
"**Assume** that each of the functions $f_t(w) = \\ell(h_w(x_t), y_t)$ is convex, no matter what example $(x_t, y_t)$ is chosen.\n",
"We can equivalently write this as\n",
"$$f_t(w) - f_t(v) \\le \\nabla f_t(w)^T (w - v).$$\n",
"(This is just the first-order definition of a convex function, and says that the function lies above the tangent line to the function at any point. It is equivalent to...)\n",
"$$f_t(v) \\ge f_t(w) + \\nabla f_t(w)^T (v - w).$$"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Suppose that we are at the $t$th iteration and the current parameter value is $w_t$. Then for any possible parameter value $\\hat w$, the squared-distance to $\\hat w$ at the next timestep will be\n",
"\\begin{align*}\n",
"\t\\norm{ w_{t+1} - \\hat w }^2\n",
"\t&=\n",
"\t\\norm{ w_t - \\alpha \\nabla f_t(w_t) - \\hat w }^2 \\\\ \n",
"\t&=\n",
"\t\\norm{ w_t - \\hat w }^2\n",
"\t-\n",
"\t2 \\alpha (w_t - \\hat w)^T \\nabla f_t(w_t)\n",
"\t+\n",
"\t\\alpha^2 \\norm{ \\nabla f_t(w_t) }^2 \\\\\n",
"\t&\\le\n",
"\t\\norm{ w_t - \\hat w }^2\n",
"\t-\n",
"\t2 \\alpha \\left( f_t(w_t) - f_t(\\hat w) \\right)\n",
"\t+\n",
"\t\\alpha^2 \\norm{ \\nabla f_t(w_t) }^2.\n",
"\\end{align*}\n",
"Here, in the last line we applied our inequality from the fact that $f_t$ is convex."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Next, if we sum this up across $T$ total steps, we get\n",
"\\begin{align*}\n",
"\t\\sum_{t=1}^T \\norm{ w_{t+1} - \\hat w }^2\n",
"\t&\\le\n",
"\t\\sum_{t=1}^T \\norm{ w_t - \\hat w }^2\n",
"\t-\n",
"\t2 \\alpha \\sum_{t=1}^T \\left( f_t(w_t) - f_t(\\hat w) \\right)\n",
"\t+\n",
"\t\\alpha^2 \\sum_{t=1}^T \\norm{ \\nabla f_t(w_t) }^2.\n",
"\\end{align*}"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"This is equivalent to\n",
"\\begin{align*}\n",
" \\norm{ w_{t+1} - \\hat w }^2\n",
" +\n",
"\t\\sum_{t=2}^{T} \\norm{ w_t - \\hat w }^2\n",
"\t&\\le\n",
" \\norm{ w_1 - \\hat w }^2\n",
" +\n",
"\t\\sum_{t=2}^T \\norm{ w_t - \\hat w }^2\n",
"\t-\n",
"\t2 \\alpha \\sum_{t=1}^T \\left( f_t(w_t) - f_t(\\hat w) \\right)\n",
"\t+\n",
"\t\\alpha^2 \\sum_{t=1}^T \\norm{ \\nabla f_t(w_t) }^2.\n",
"\\end{align*}"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Canceling out all by the non-overlapping terms from the first two sums, and moving the terms about, gives us\n",
"\\begin{align*}\n",
"\t2 \\alpha \\sum_{t=1}^T \\left( f_t(w_t) - f_t(\\hat w) \\right)\n",
"\t&\\le\n",
"\t\\norm{ w_1 - \\hat w }^2\n",
"\t-\n",
"\t\\norm{ w_{T+1} - \\hat w }^2\n",
"\t+\n",
"\t\\alpha^2 \\sum_{t=1}^T \\norm{ \\nabla f_t(w_t) }^2 \\\\\n",
"\t&\\le\n",
"\t\\norm{ w_1 - \\hat w }^2\n",
"\t+\n",
"\t\\alpha^2 \\sum_{t=1}^T \\norm{ \\nabla f_t(w_t) }^2.\n",
"\\end{align*}\n",
"And dividing by $2 \\alpha$,\n",
"$$\\sum_{t=1}^T \\left( f_t(w_t) - f_t(\\hat w) \\right)\n",
"\t\\le\n",
"\t\\frac{1}{2 \\alpha} \\norm{ w_1 - \\hat w }^2\n",
"\t+\n",
"\t\\frac{\\alpha}{2} \\sum_{t=1}^T \\norm{ \\nabla f_t(w_t) }^2.$$"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"The first expression on the left can be seen to be close to $\\alpha$ times the regret, since\n",
"\\begin{align*}\n",
"R(\\hat w, T) \n",
"&= \n",
"\\sup_{(x_1,y_1), \\cdots, (x_T, y_T)} \\; \\left( \\sum_{t=1}^T \\ell(\\hat y_t, y_t) - \\sum_{t=1}^T \\ell(h_{\\hat w}(x_t), y_t) \\right) \n",
"\\\\&=\n",
"\\sup_{(x_1,y_1), \\cdots, (x_T, y_T)} \\; \\left( \\sum_{t=1}^T \\ell(h_{w_t}(x_t), y_t) - \\sum_{t=1}^T \\ell(h_{\\hat w}(x_t), y_t) \\right) \n",
"\\\\&=\n",
"\\sup_{(x_1,y_1), \\cdots, (x_T, y_T)} \\; \\left( \\sum_{t=1}^T f_t(w_t) - f_t(\\hat w) \\right).\n",
"\\end{align*}\n",
"And since the above analysis was done **for any samples $(x_t,y_t)$**, it follows that\n",
"$$\tR(\\hat w, T)\n",
"\t\\le\n",
"\t\\frac{\\norm{ w_1 - \\hat w }^2}{2 \\alpha}\n",
"\t+\n",
"\t\\frac{\\alpha}{2} \\sum_{t=1}^T \\norm{ \\nabla f_t(w_t) }^2.$$"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"If we add the additional **assumptions** that\n",
"\n",
"* (1) we are limiting the range of parameter vectors we are learning over to a region of diameter at most $D$\n",
" * this requires a little bit of tinkering in practice to project back onto that region if we ever go outside it, but here for simplicity we'll ignore that\n",
"\n",
"* (2) the magnitude of the gradients is always at most $G$, i.e. $\\norm{\\nabla f_t(w)} \\le G$,\n",
"\n",
"then we can say something about the regret relative to the entire hypothesis class:\n",
"\n",
"$$R(T) \\le \\sup_{\\hat w} \\; R(\\hat w, T)\n",
"\t\\le\n",
"\t\\frac{D^2}{2 \\alpha}\n",
"\t+\n",
"\t\\frac{\\alpha}{2} \\cdot T \\cdot G^2.$$"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"And now if we pick step size to minimize this of\n",
"\n",
"$$\\alpha = \\frac{D}{G \\cdot \\sqrt{T}} = \\mathcal{O}\\left(\\frac{1}{\\sqrt{T}}\\right),$$\n",
"\n",
"then \n",
"\n",
"$$R(T) \\le D G \\sqrt{T} = \\mathcal{O}\\left( \\sqrt{T} \\right).$$"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Interpreting this result.\n",
"\n",
"In the online setting, regret grows naturally with time in a way that is very different from loss in the batch setting.\n",
"If we look at the definition of regret, at each timestep it's adding a new component\n",
"$$\n",
"\t\\ell(\\hat y_t, y_t) - \\ell(h_w(x_t), y_t)\n",
"$$\n",
"which tends to be positive for an optimally-chosen $w$.\n",
"\n",
"For this reason, we can't expect the regret to go to zero as time increases: the regret will be increasing with time, not decreasing.\n",
"\n",
"Instead, for online learning we generally want to get what's called **sublinear regret**: a regret that grows sublinearly with time.\n",
"\n",
"Equivalently, we can think about situations in which the **average regret**\n",
"$$\n",
"\t\\frac{R(T)}{T} = \\frac{1}{T} \\sum_{t=1}^T \\ell(\\hat y_t, y_t) - \\inf_w \\frac{1}{T} \\sum_{t=1}^T \\ell(h_w(x_t), y_t)\n",
"$$\n",
"goes to zero.\n",
"We can see that this happens in the case of online gradient descent, where\n",
"$$\n",
"\tR(T) = O(\\sqrt{T}) = o(T).\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Making online learning scalable.\n",
"\n",
"Most of the techniques we've discussed in class are readily applicable to the online learning setting.\n",
"\n",
"* For example, we can easily define minibatch versions of online gradient descent,\n",
"* use adaptive learning rate schemes, \n",
"* and even use hardware techniques like parallelism and low precision.\n",
"\n",
"If you're interested in more details about how to do this, there are a lot of papers in the literature.\n",
"\n",
"Many online-setting variants of SGD are subject to ongoing active research, particularly the question of how we should build end-to-end systems and frameworks to support online learning."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Applications of online learning: learning in real time.\n",
"\n",
"A major application of online learning is to deal with **real-time streams of data** where we want to simultaneously\n",
"\n",
"* Learn from the data as we observe it, and\n",
"* Make predictions to drive some real-time decisions.\n",
"\n",
"Online learning algorithms let us naturally update our models to \"follow\" small changes in the data distribution over time.\n",
"\n",
"* This is great for applications where new classes of examples may arise over small time intervals.\n",
"* Also very good for robots adapting to new environments.\n",
"* Particularly exciting because it seems to match how humans learn!\n",
"\n",
""
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"A classic example of this is **spam detection**.\n",
"\n",
"Of course, for a spam detection system to be useful for spam filtering, it needs to make predictions about what emails are spam, and it needs to make those predictions in real time.\n",
"\n",
"But it also needs to learn from new spam emails, so that it can quickly adapt to new patterns in spam.\n",
"\n",
"* Spam email patterns change continuously over time, and we don't want to have to have a human in the loop to retrain a model in response to changes in spam patterns.\n",
"\n",
"What problems might we encounter when trying to do spam detection in an online learning setting?"
]
}
],
"metadata": {
"@webio": {
"lastCommId": null,
"lastKernelId": null
},
"celltoolbar": "Slideshow",
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"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.17"
},
"rise": {
"scroll": true
}
},
"nbformat": 4,
"nbformat_minor": 2
}