Inthisnotebook,we'll see how to develop two implementations of this algorithm in numpy. **If you'reprimarilyinterestedinacceleration,feelfreetojustskimthisnotebookwithoutrunningit!**Infuturenotebooks,you'll learn how to accelerate your implementation with JAX. The implementation we'lldevelopisaprototype—therearelotsofthingsyoumightwanttoimproveorchangebeforeusingitinarealsystem—butitwillshowhowwecanacceleratearelativelyrealisticcodebaserealizingamoreinvolvedMLtechnique.
"""
))
return
@app.cell
def_():
importnumpyasnp
return(np,)
@app.cell(hide_code=True)
def_(mo):
mo.md(r"""There are several ways to initialize a self-organizing map. Here, we'll initialize our map with random vectors. The result of this function is a matrix with a row for every element in a self-organizing map; each row contains uniformly-sampled random numbers between 0 and 1.""")
mo.md(r"""It's often helpful to visualize the results of our code. Here we'll plot an example random map of three-element vectors, interpreting each vector as a color by interpreting each feature value as a red, green, or blue intensity. Because our code will refer to maps with x- and y-coordinates but represent them as matrices (where we'd list rows first and then columns), we will often rearrange or transpose our data (with methods like `reshape` and `swapaxes` or `T`) before plotting it.""")
mo.md(r"""Our neighborhood function describes the part of the map influenced by a given sample. It takes two ranges (corresponding to every index along the x dimension and every index along the y dimension), the coordinates of the center of the neighborhood, and the radiuses of influence along each dimension.""")
mo.md(r"""We'll now introduce a small class to track our history at each training epoch or example -- this is useful for debugging and visualizing an entire training process.""")
return
@app.class_definition
classHistoryCallback(object):
def__init__(self,xdim,ydim,fdim,epoch_pred):
self.frames=dict()
self.meta=dict()
self.xdim=xdim
self.ydim=ydim
self.fdim=fdim
self.epoch_pred=epoch_pred
def__call__(self,epoch,ex,hood,som,**meta):
ifself.epoch_pred(epoch):
self.frames[epoch]=(ex,hood,som.copy())
ifmetaisnotNone:
self.meta[epoch]=meta
@app.cell(hide_code=True)
def_(mo):
mo.md(r"""Here we'll train a small map on random color data, storing one history snapshot for every 20 examples.""")
return
@app.cell
def_(np,train_som_online):
fc=HistoryCallback(240,135,3,lambdax:x%20==0)
color_som=\
train_som_online(np.random.random(size=(1000,3)),
240,135,
120,70,
50000,None,fc)
return(color_som,)
@app.cell(hide_code=True)
def_(mo):
mo.md(
r"""
✅Mouseovertheabovecell.Howlongdidittaketoexecute?
Here's a little example function you can pass a history callback object to in order to save every updated map to a PNG file: