Skip to content

Commit

Permalink
Update website to have RBMs, music pictures, and esperanto short story
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasericsson222 committed Oct 28, 2024
1 parent 5e6eec5 commit af2e0b7
Show file tree
Hide file tree
Showing 24 changed files with 645 additions and 196 deletions.
7 changes: 7 additions & 0 deletions astro.config.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { defineConfig } from 'astro/config';
import remarkMath from "remark-math";
import rehypeKatex from "rehype-katex";

// https://astro.build/config
export default defineConfig({
site: 'https://lucasericsson222.github.io',
markdown: {
remarkPlugins: [remarkMath],
rehypePlugins: [rehypeKatex],
//syntaxHighlight: "prism",
},
});
610 changes: 422 additions & 188 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
"astro": "astro"
},
"dependencies": {
"astro": "^4.5.9",
"@astrojs/check": "^0.5.10",
"astro": "^4.5.9",
"rehype-katex": "^7.0.1",
"remark-math": "^6.0.0",
"typescript": "^5.4.3"
}
}
}
8 changes: 8 additions & 0 deletions src/layouts/BaseLayout.astro
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ const { frontmatter } = Astro.props
<meta name="author" content="Lucas Ericsson"/>
<meta name="description" content="Computer Science and Linguistics Blog"/>
<title>{frontmatter.title}</title>
<!-- Katex -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css"
integrity="sha384-MlJdn/WNKDGXveldHDdyRP1R4CTHr3FeuDNfhsLPYrq2t0UBkUdK2jyTnXPEK1NQ"
crossorigin="anonymous"
/>

</head>
<body>
<Nav/>
Expand Down
3 changes: 2 additions & 1 deletion src/pages/[category].astro
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ switch (category) {
allPosts = await Astro.glob('../pages/language/*.md');
break;
};
allPosts = allPosts.reverse()
function formatDate(input: Date): String {
let day = input.getDate()
let month = input.getMonth()
let year = input.getFullYear()
return `${year}-${month}-${day}`
return `${year}-${month + 1}-${day + 1}`
}
export function getStaticPaths() {
return [
Expand Down
4 changes: 2 additions & 2 deletions src/pages/constellation.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ title: "Constellation"

Here is a collection of websites which are all amazing.

- [https://localhost]()
- [https://aquarmity.github.io/]()
- [https://localhost](https://localhost)
- [https://aquarmity.github.io/](https://aquarmity.github.io/)
2 changes: 1 addition & 1 deletion src/pages/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ title: "Lucas Ericsson's Homepage"
Itho! I am Lucas Ericsson, an Electrical Engineering and Computer Science major at UC Berkeley.
For fun, I compose songs and work with Conlangs, while learning more about programming.

I'm currently learning about Restricted Boltzmann Machines and Quantum Computing, but I also enjoy
I'm currently learning about [Restricted Boltzmann Machines](/programming/restricted-boltzmann-machine) and Quantum Computing, but I also enjoy
web design projects.

I am learning [toki pona](https://tokipona.org/) and [Esperanto](https://en.wikipedia.org/wiki/Esperanto),
Expand Down
4 changes: 3 additions & 1 deletion src/pages/language/apmaumur.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ layout: '../../layouts/BaseLayout.astro'
title: "Apmau'mur: a Constructed Language"
pubDate: 2024-03-24
description: 'A constructed language appreciates the glottal stop.'
author: 'kasisuli, aquarmity, john scarce'
author: 'Lucas Ericsson, Miguel Diaz, and Tejas Patel'
---

<h1><span class="tokipona" lang="tok"> toki pi soweli telo </span> Apmau'mur</h1>

*by Lucas Ericsson, Miguel Diaz, and Tejas Patel*

>
> And so it is that languages, unlike any of the people who speak them,
> need never grow infirm, or die.
Expand Down
29 changes: 29 additions & 0 deletions src/pages/language/vivodelumo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
layout: '../../layouts/BaseLayout.astro'
title: "Vivo de Lumo"
pubDate: 2024-10-27
description: 'A short story about glowing magic in Esperanto'
author: 'Lucas Ericsson'
---

<h1><span class="tokipona" lang="tok">lon suno</span> Vivo de Lumo</h1>

*by Lucas Ericsson*

La herbo ondetas en movadoj de malhela verdo, kun la nuboj kopiantaj responde. La nokto komenciĝis kaj la varma vento varmigas ĉiun herbfolion. Je ĉi tiu horo de la nokto, la steloj videblas, kaj oni ĵurus ke ankaŭ ili volas moviĝi. Nenio estas vidata ĉar estas mallume, ĝis multaj malgrandaj lumoj vekas la kolorojn en la dormantaj floroj. La fulgoroj alvenas el la grundo kaj lumigas la nokton.

Se la nokto estas malfrua, estas frua por la homo kiu vidas ĉi tiun scenon. Ri certe venis ĉi tien rekte de laboro ĉar ria nigra laborokostumo nur elstaras kiam ĝi kovras la stelojn. Ri marŝas tra la ondoj de herbo kaj serĉas ion en la ĉielo. La steloj restu samaj kiel antaŭe.

La fulgoroj, tamen, ŝajnas ŝati la homon kaj lumigi la paŝojn kiujn la homo forlasis. La homo svingas la brakon por formovi ilin, kiel oni gvidas infanojn. La fulgoroj flugas for, disvastiĝante super la herbo. Se ili estus infanoj, ili babilus inter si – iliaj lumoj flagras rapide. La steloj kaj la fulgoroj fariĝas simetriaj. La homo malaperas. La fulgoroj silentiĝas; la nokto estas malluma denove.

En kio ŝajnas esti malluma koridoro, la homo aperas. La koridoro estas liniita per kaĝoj de fulgoroj kies lumoj estas malfortigitaj. La ŝtona vojo ondetas en la nefidinda lumo. La homo marŝas plu, estos savo por ili baldaŭ. La seka ŝtono cedas al ŝtona pordo kiu malfermiĝas sub la mano de la homo. Estas hele ekster ĉi tiu koridoro, sed la homo estas preparita.

La blanka ĉielo kun bluaj nuboj salutas la homon. Kun la ĉielo, multaj konstruaĵoj batalas por ria vido. Ĉiuj konstruaĵoj estas kreitaj el ŝtono, sed anstataŭ unikajn kolorojn ili havas unikajn teksturojn. Ĉi tiu urbo montras multajn flagojn kun unu blanka stelo sur bluo. La vojoj estas herbo kaj multaj homoj tramarŝas. Ĉiu homo havas sakon enhavantan fluantan lumon. Mortintaj rondoj de herbo ekzistas inter la sana herbo.

Malgrandaj ŝtonaj estaĵoj manĝas movantaj vermojn dum irado preter la homo. La homo iras al sia destino kiu similas kavernon. En ĉi tiu loko, la tegmento efektive estas fenestro al la ĉielo, do la konstruaĵo ne bezonas alian lumon. Ri marŝas al pordo ĉe la malantaŭo de la konstruaĵo, preter la homoj kiuj ŝajnas aĉeti ardantan plumon, kaj la kvanto da mono aspektas granda.

Preter la pordo estas farmisto kiu vidas la eniranton. Dum li rigardas, ri diras “nun estas la tempo.” La homo, amiko de fulgoroj, iras eksteren, foriras la farmisto kiu nun sentas timon. “La ŝtonuloj sufiĉe longe faris abomenaĵojn,” ri murmuras. La homo komencas kuri. Ri kuras tra la enirejo, tra la sana kaj mortinta herbo. La aliaj homoj, kiuj estis ekstere, scivolas kion ri estas faranta, sed ili ne havas ajnan kapablon halti ĉi tion.

Guto de sango falis el la ĉielo de la subtera urbo. La lumo de vivo estas kio ĝi estas. La homo daŭre kuras, rekte al la plej granda konstruaĵo. Ri elprenas botelon kiu enhavas ardantan manon kaj ĵetas ĝin al la ŝtono. La botelo rompiĝas. Blankaj flamoj manĝas la ŝtonon. La homo rapide forbrulas. La urbo rapide forbrulas. La homoj kuras sed multaj ne eskapas. Multaj homoj ponardas sian sakon kaj malaperas.

La ĉielo mallumas. La urbo estas for.
38 changes: 38 additions & 0 deletions src/pages/music.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
import BaseLayout from "../layouts/BaseLayout.astro";
import Image from "astro/components/Image.astro";
const images = await Astro.glob("/src/pages/music/*.{jpeg,jpg,png,gif}")
---
<BaseLayout frontmatter={{title: "Music"}}>

<div class="grid">
{images.map((img) =>
<Image src={img.default} alt="Hello There" class="ablum-cover"></Image>
)}
</div>

</BaseLayout>

<style>
.grid {
display:flex;
width: 100%;
flex-wrap: wrap;
justify-content: center;
}
.grid img {
width: 10rem;
height: 10rem;
filter: grayscale(100%);
transition: filter 0.5s, opacity 0.2s, transform 0.2s;
opacity: 50%;
margin: 1rem;
}
.grid img:hover {
filter: grayscale(0%);
opacity: 100%;
transform: scale(1.2);
}
</style>
Binary file added src/pages/music/_AlienPlanet.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/pages/music/_Hills.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/pages/music/_Laser.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/pages/music/_Mars.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/pages/music/_Mountain.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/pages/music/_NightBridge.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/pages/music/_Outside.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/pages/music/_Ribs.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/pages/music/_SkyFountain.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/pages/music/_SnowCabin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/pages/music/_Temple.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/pages/programming/haskell/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ author: 'kasisuli'

<h1><span class="tokipona" lang="tok"> lawa pakala</span> Haskell</h1>

*by Lucas Ericsson*

So, my first experience with Haskell was through this research article:

I found it by:
Expand Down
120 changes: 120 additions & 0 deletions src/pages/programming/restricted-boltzmann-machine/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
---
layout: '/src/layouts/BaseLayout.astro'
title: "Restricted Boltzmann Machines"
pubDate: 2024-10-10
description: 'All about Restricted Boltzmann Machines'
author: 'Lucas Ericsson'
---
<h1><span class="tokipona" lang="tok"> ilo toki pi nanpa kama nasa</span> Restricted Boltzmann Machines</h1>

*by Lucas Ericsson*

A Boltzmann Machine is a fully connected generative neural network,
where the probability of the network being in a specific state
follows the [Boltzmann Distribution](https://en.wikipedia.org/wiki/Boltzmann_distribution).
It can easily learn distributions of unlabeled data and generates samples from those distributions.

The Boltzmann Distribution is defined as

$$p_i \propto \exp(-\frac{E(\sigma)}{kT})$$

Where $T$ is the temperature, and $E(\sigma)$ is the energy function of a state $\sigma$.

<aside>
Temperature is a hyperparameter (non-learnable parameter) which controls the "randomness" of the model. A higher temperature means that the model will output a wider collection of results.
</aside>

For a Boltzmann Machine, the energy is defined as

$$E(\sigma) = - \displaystyle\sum_{i,j} \sigma_i \sigma_j w_{ij} - \sum_i b_i \sigma_i$$

where $i \ne j$, $w_{ij}$ is the weight of the edge between two nodes/vertices $i$ and $j$, and $b_i$ is the bias of vertex $i$.

Each neuron node has a binary value of either 0 or 1. Some other designs use -1/1 as the states, but these are interchangeable with some slight modifications to the sampling algorithm.
There have been experiements into [Guassian distributed boltzmann machines](https://arxiv.org/pdf/1701.03647), but they won't be covered here.

From this definition, we can derive a method for this network to learn any distribution of data,
whether it be the inputs and outputs of an AND gate, or the pixels of handwritten numbers (MNIST).

## Restricted Boltzmann Machine

The Restricted Boltzmann Machine "restricts" the type of graph being used as the neural network to a bipartite graph of visible and hidden nuerons.

This changes the energy formula to be something like:

$$E(v, h) = - \displaystyle \sum_{i,j} v_i h_j w_{ij} - \sum_i b_i v_i - \sum_i c_i h_i$$

This restriction will make more sense when we talk about sampling from the Boltzmann machine.

# Sampling

Calculating the probability of a specific state is infeasable to calculate, due to definition of the probability distribution.

In order to calculate $p(\sigma)$ one would have to calculate the values of $\exp\left(-\frac{E(\sigma)}{kT}\right)$ for every value of $\sigma$ to normalize the probability distribution.

That's the hidden problem with $\propto$, the actual distribution is:

$$\displaystyle p_i = \frac {\exp\left(-\frac{E(\sigma)}{kT}\right)}{Z}$$

where $Z=\displaystyle \sum_\sigma\exp\left(-\frac{E(\sigma)}{kT}\right)$

$Z$ is sometimes called the "Partition Function" but it is intractable, as the number of items to add grows exponentially with the size of the state dimension.

If we are using a Restricted Boltzmann Machine, we can use [Gibb's Block Sampling](https://en.wikipedia.org/wiki/Gibbs_sampling), a [Monte Carlo Markov Chain](https://www.deeplearningbook.org/contents/monte_carlo.html) method, in order to draw samples from the distribution without calculating the partition function.

In an RBM, we have to layers of neurons and each nueron is only dependent on input from neurons in the opposing layer. This means that we have a set up of independent "blocks" of neurons.

If we can calculate $p(h_i = 1|v)$ then we can probabilistically flip the value of $h$. This will result in the hidden nuerons being distributed according to $h|v$.
Since the shape of the RBM is symmetric, if we can calculate $p(h_i = 1|v)$ then we can calculate $p(v_i = 1|h)$.

So, now we can essentially do "hops" to and from the hidden nuerons like so:
$$P(h|v) \rightarrow P(v'|h) \rightarrow P(h'|v') \rightarrow \dots$$

By defining this as a Markov Chain, we can show that this eventually converges to $P(v,h)$ which is the probability distribution we were having trouble calculating values from in the first place.

Since the Restricted Boltzmann Machine visible nuerons are conditionally independent from each other given the hidden nuerons, we are able to batch-process all of the visible neurons in one block and all of the hidden neurons in one block.

[A RBM paper by Asja Fischer and Christian Igel](http://cms.dm.uba.ar/academico/materias/1ercuat2018/probabilidades_y_estadistica_C/5a89b5075af5cbef5becaf419457cdd77cc9.pdf) shows that

$$P(h_i = 1|v)=\sigma(\sum_j w_{ij}v_j + c_i)$$

$$P(v_j = 1|h)=\sigma(\sum_i w_{ij}h_i + b_j)$$

where $\sigma(z) = \frac{1}{1+e^{-z}}$ is the sigmoid function.

Some psuedocode for the Gibb's sampling might look like:

```python
import numpy as np
rbm = RBM()
# rbm.weights is a matrix where the columns
# correspond to the hidden neuron is connected to,
# and the rows to the visible nuerons
v = normal(0, 1, rbm.visible_biases.shape)
h = normal(0, 1, rbm.hidden_biases.shape)
while (sampling):
# visible -> hidden
dist = sigmoid(
(rbm.hidden_biases + (v.T @ rbm.weights).T )
/ rbm.temp)
unif = np.random.rand(dist.shape)
h = (unif <= dist).astype(int)

# hidden -> visible
dist = sigmoid(
(rbm.visible_biases + rbm.weights @ h)
/ rbm.temp)
unif = np.random.rand(dist.shape)
v (unif <= dist).astype(int)

# now (v,h) ~ p(v,h)
```

Note that the hidden nuerons are being updated all at the same time (and likewise the visible neurons).
This is the significant reason why Restricted Boltzmann Machines are commonly used more than their unrestricted counterpart.

Instead of having just a forward and a backward pass, a Boltzmann Machine would have to step through each neuron individually and update it depending on it's neighbors.

# Training

to be continued...
8 changes: 7 additions & 1 deletion src/styles/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ body {
background-color: rgb(31, 31, 31);
background-repeat: repeat;
background-attachment: fixed;
color: rgb(221, 221, 221);
color: rgb(199, 199, 199);

display: flex;
flex-direction: column;
Expand All @@ -55,6 +55,9 @@ p, ul, li {
font-size: 14pt;
line-height: 1.7rem;
}
.katex {
font-size: 14pt;
}
tbody tr:nth-child(even) {
background-color: rgba(255, 255, 255, 0.134);
}
Expand Down Expand Up @@ -114,6 +117,9 @@ blockquote {
}
}
@media (max-width: 999px) {
aside {
margin-left: 3em;
}
}

hr {
Expand Down

0 comments on commit af2e0b7

Please sign in to comment.