-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
executable file
·515 lines (486 loc) · 44.2 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>Caleb Tham</title>
<link rel="icon" href="./assets/img/logo.png">
<link rel="stylesheet" href="https://use.typekit.net/xix3lha.css">
<link rel="stylesheet" href="./assets/fonts/font-awesome.min.css">
<link rel="stylesheet" href="./assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="./assets/css/custom.css">
<link rel="stylesheet" href="./assets/css/light-mode.css">
<link rel="stylesheet" href="./assets/css/mobile.css">
</head>
<body data-bs-spy="scroll" data-bs-target="#mainNav" data-bs-offset="77">
<!-- Navbar -->
<nav class="navbar navbar-light navbar-expand-md fixed-top" id="mainNav">
<div class="container"><a class="navbar-brand" id="navLogo" href="#">Caleb</a><button data-bs-toggle="collapse" class="navbar-toggler navbar-toggler-right" data-bs-target="#navbarResponsive" type="button" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation" value="Menu"><i class="fa fa-bars"></i></button>
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ms-auto">
<li class="nav-item nav-link"><a class="nav-link px-3 rounded-pill" href="#about">About</a></li>
<li class="nav-item nav-link"><a class="nav-link px-3 rounded-pill" href="#cv">CV</a></li>
<li class="nav-item nav-link"><a class="nav-link px-3 rounded-pill" href="#projects">Projects</a></li>
<li class="nav-item nav-link"><a class="nav-link px-3 rounded-pill" href="#contact">Contact</a></li>
</ul>
</div>
</div>
</nav>
<!-- Front cover -->
<header class="cover">
<div id="sunsetSun"></div>
<div id="sunsetWater"></div>
<div id="sunsetBoat"></div>
<div id="grindelwaldSky"></div>
<div id="grindelwaldMountain"></div>
<div class="container">
<div class="row w-100 m-auto h-screen d-flex align-items-center justify-content-center ">
<div class="col-lg-8 text-center">
<h1 class="brand-heading mb-3">Caleb Tham</h1>
<p class="intro-text">
Expressing creativity through code.
</p>
<button id="lightSwitch" class="btn btn-link btn-circle">
<i class="fa fa-sun-o"></i>
</button>
</div>
</div>
<div class="row w-100 m-auto d-flex align-items-center justify-content-center">
<a id="arrow" class="w-auto py-0 btn btn-link rounded-pill" role="button" href="#about">
<i class="fa fa-angle-down animated"></i>
</a>
</div>
</div>
<canvas id="star"></canvas>
</header>
<div class="separator"></div>
<!-- About section -->
<section class="text-start content-section" id="about">
<div class="container">
<div class="row">
<div class="about-section row col-lg-8 mx-auto py-5 px-4">
<div class="col-md-4 pb-3">
<img id="me" src="./assets/img/me.jpg" class="col-6 col-md-12 img-fluid rounded border-gradient" alt="Caleb Tham">
<div>
<button class="btn btn-lg btn-default w-auto mt-3 mr-3 rounded-pill" type="button" onclick="window.open('https://www.linkedin.com/in/calebtham/')">
<i class="fa fa-linkedin fa-fw"></i>
</button>
<button class="btn btn-lg btn-default w-auto mt-3 mr-3 rounded-pill" type="button" onclick="window.open('https://github.com/calebtham/')">
<i class="fa fa-github fa-fw"></i>
</button>
</div>
</div>
<div class="col-md-8">
<h1 class="pb-2 border-gradient">About me</h1>
<p>I am a motivated student and aspiring Software Engineer. I am in my final year studying Computer Science (MEng) at the University of Warwick.
<p>I have always been captivated by the pervasiveness of technology. Reading about the field's profound impact at an early age spurred me to pursue a career in Software Engineering. As I started to learn how to program, I immediately admired the combination of problem solving and creative thinking, which only furthered the industry's appeal. Areas I'm particularly passionate about are AI/ML and full stack development. I now find myself coding for my studies, for work (most recently as a Software Engineer intern for JPMorgan Chase & Co.), and for leisure!</p>
<p id="cv">In my spare time, I enjoy continuing to express my creative side through composing music, photography, and graphic design - even still, I find myself glued to a screen, using software such as Logic Pro and Adobe's Creative Suite. Moreover, since I love sharing my passions, I became Head of Marketing at Warwick Jazz Society.</p>
<h2 class="pb-2 border-gradient w-md-50">Curriculum Vitae</h2>
<p>Have a read through my <a href="./assets/pdf/cv.pdf" target="_blank" rel="noopener noreferrer">CV</a>. <span class="date">(Last updated: Nov 2023)</span></p>
</div>
</div>
</div>
</div>
</section>
<div class="separator"></div>
<!-- Projects section -->
<section class="text-start projects-section content-section" id="projects">
<div class="container">
<div class="col-lg-8 mx-auto">
<h1 class="pb-2 border-gradient">Personal Projects</h1>
<p>Follow my journey through programming with some of my personal favourite projects I have completed.</p>
</div>
</div>
<div class="col-lg-10 col-12 mx-auto row projects-container">
<!-- deJPEG -->
<div class="col-md-12 mb-3 p-0 px-md-3 pb-md-3">
<div class="card">
<h5 class="mb-2">
<span class="badge bg-primary mb-2">AI/ML research</span>
<span class="badge bg-primary mb-2">GAN</span>
<span class="badge bg-primary mb-2">CNN</span>
<span class="badge bg-primary mb-2">Web dev</span>
<span class="badge bg-secondary mb-2">Python</span>
<span class="badge bg-secondary mb-2">JavaScript</span>
<span class="badge bg-grey mb-2">TensorFlow 2</span>
<span class="badge bg-grey mb-2">React</span>
<span class="badge bg-grey mb-2">Flask</span>
</h5>
<h3 class="mb-1" style="text-transform: none;">deJPEG<span class="date mt-1">2023</span></h3>
<p class="mb-3">My third year dissertation title, "JPEG compression detection and restoration", for which I was awarded a First Class (86%). The detector and restorer models (and demo website) are available on my <a href="https://github.com/calebtham/deJPEG" target="_blank">GitHub repo</a>.</p>
<div class="inline mx-auto">
<div class="link" onclick="window.open('https://github.com/calebtham/deJPEG')">
<img src="./projects/deJPEG/finalsolution.jpg" class="img-fluid img-thumbnail col-lg-12" alt="deJPEG">
</div>
</div>
<div class="collapse mt-3" id="deJPEG">
<p>Abstract: "JPEG compression is commonly used to reduce the storage size of digital images. However, the process introduces complex artifacts that degrade the visual quality of images. This is particularly problematic for images that are compressed multiple times, often referred to as double compressed images. Due to the lossy nature of JPEG compression, we are unable to retrieve the original image. Still, it is possible to enhance the image’s visual appeal by estimating its appearance prior to its compression. To tackle this, we propose a system that detects whether an image has undergone JPEG compression and, if necessary, applies an artifact removal process. In particular, we develop a detector that uses a convolutional neural network to differentiate between single and double compressed images, achieving near state-of-the-art accuracy in this task, despite using a simpler architecture compared to existing methods. For the restorer, we use a generative adversarial network and demonstrate that it is equally effective on both single and double compressed images. Furthermore, by incorporating MS-SSIM and the widely used VGG-19 network into our perceptual loss function, as well as employing NoGAN training, we outperform a previous state-of-the-art method for JPEG artifact removal. We deploy our system as a web application."</p>
<p>While the ML research formed the bulk of the project, I also developed a website to demo the proposed ML models. This was mainly just an opportunity for me to learn React and refresh my knowledge on Flask! The website and models can be setup following instructions on my <a href="https://github.com/calebtham/deJPEG" target="_blank">Github repo</a>.</p>
</div>
<a class="more text-center mt-3" data-bs-toggle="collapse" href="#deJPEG" role="button" aria-expanded="false" aria-controls="deJPEG">
<i class="fa fa-angle-down"></i>
</a>
</div>
</div>
<!-- Coursework -->
<div class="col-md-12 mb-3 p-0 px-md-3 pb-md-3">
<div class="card">
<h5 class="mb-2">
<span class="badge bg-primary mb-2">AI</span>
<span class="badge bg-primary mb-2">Big Data</span>
<span class="badge bg-primary mb-2">Web Dev</span>
<span class="badge bg-primary mb-2">Multithreading</span>
<span class="badge bg-secondary mb-2">Java</span>
<span class="badge bg-secondary mb-2">Python</span>
<span class="badge bg-secondary mb-2">C</span>
<span class="badge bg-secondary mb-2">JavaScript</span>
<span class="badge bg-secondary mb-2">PHP</span>
<span class="badge bg-secondary mb-2">SQL</span>
<span class="badge bg-grey mb-2">Hadoop</span>
<span class="badge bg-grey mb-2">Hive</span>
<span class="badge bg-grey mb-2">JavaCC</span>
</h5>
<h3 class="mb-1">Coursework Highlights (5)<span class="date mt-1">2020 - 2024</span></h3>
<p class="mb-3">Individual coursework completed at the University of Warwick, including: big data analysis, a chore scheduling app, an AI scheduler, a multithreaded packet sniffer, and a parser/lexer/interpreter.</p>
<div class="collapse mt-3" id="warwick">
<div id="warwickCorousel">
<div class="mx-auto mb-3 text-center">
<button class="btn btn-carousel" type="button" data-bs-target="#warwickCorousel" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<span class="more">1 / 5</span>
<button class="btn btn-carousel" type="button" data-bs-target="#warwickCorousel" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
<div class="carousel-inner">
<div class="carousel-item active">
<h5 class="mb-1">Big data analysis</h5>
<p class="mb-3">Leveraging the MapReduce programming paradigm, in both Hadoop and Hive, I performed analysis on an organisation's massive dataset regarding their sales data. This involved using the HDFS architecture to reliably store the files across machines in a large cluster.</p>
<p class="mb-3">I implemented various queries in Hive for initial ad hoc analysis and later wrote them in Hadoop for optimized performance, using custom-written combiners and partitioners to achieve substantial speed up, resulting in the Hadoop queries to execute up to 8x faster than the equivalent Hive queries.</p>
<p class="mb-3">This coursework not only gave me experience with the MapReduce paradigm, but helped me understand the challenges of building distributed, scalable, and fault-tolerant infrastructure for large-scale computing.</p>
<p>For this coursework, I was awarded a First (90%).</p>
</div>
<div class="carousel-item">
<div class="row">
<div class="col">
<h5 class="mb-1">Enchore (a chore scheduling app)</h5>
<p class="mb-3">With PHP, JavaScript, and SQL, I implemented a chore scheduling web app, complete with a database, user authentication system, and push notifications.</p>
<p class="mb-3">Users may create, edit, delete their account. A user can create or join a house, for which chores can be organised and scheduled to repeat. Chores are assigned to a member of the house and can be edited and marked as complete. There is also a house leaderboard that ranks house members according to different factors (such as chore completion rate).</p>
<div class="row">
<div class="col-lg-5 mb-3">
<img src="./projects/coursework/enchore/dashboard-incomplete.png" class="img-fluid img-thumbnail" alt="edit a chore">
</div>
<div class="col-lg-5 mb-3">
<img src="./projects/coursework/enchore/dashboard-complete.png" class="img-fluid img-thumbnail" alt="account settings">
</div>
<div class="col-lg-4 col-10 mb-3">
<img src="./projects/coursework/enchore/chore.png" class="img-fluid img-thumbnail" alt="edit a chore">
</div>
<div class="col-lg-4 col-10 mb-3">
<img src="./projects/coursework/enchore/account.png" class="img-fluid img-thumbnail" alt="account settings">
</div>
</div>
<p class="mb-3">This coursework enhanced my web development skills, allowing me to better consider the significance of security best practices, intuitive user interface design, and accessibility features. It also demonstrated the usefulness of AJAX to create dynamic pages and improve the user experience.</p>
<p>I was awarded a First (96%) for this coursework.</p>
</div>
</div>
</div>
<div class="carousel-item">
<h5 class="mb-1">AI Scheduler</h5>
<p class="mb-3">I implemented, in Python, a program that takes as input a set of shows and comedians for a comedy club and outputs a legal minimum cost timetable according to some soft and hard constraints. AI techniques such as simulated annealing and backtracking were used.</p>
<p class="mb-3">This coursework emphasised the importance of choosing the most appropriate AI techniques and data structures for a given task with this significantly impacting accuracy and performance (both in terms of speed and memory).</p>
<p>For this coursework, I received a First (94%).</p>
</div>
<div class="carousel-item">
<h5 class="mb-1">Multithreaded Packet Sniffer</h5>
<p class="mb-3">Using C, I implemented a program that parses TCP/IP packets to detect malicious traffic. The program identifies SYN attacks, ARP poisoning attacks, and blacklisted URLs. The efficiency of the program was improved by making use of multithreaded programming (thread pool model) to process packets in parallel.</p>
<p class="mb-3">Having programmed in C, I now better understand how memory in programs is managed and how important it is to write code carefully as to avoid memory leaks. Moreover, implementing a thread pool demonstrated the necessity to properly synchronize threads, such as by using mutex locks.</p>
<p>This coursework was graded as a First.</p>
</div>
<div class="carousel-item">
<h5 class="mb-1">Parser, Lexer, and Interpreter</h5>
<p class="mb-3">In Java (JavaCC), I wrote a parser, lexer, and interpreter for a custom-defined programming language, which included arithmetic expressions and function calls.</p>
<p class="mb-3">This coursework demonstrated the usefulness of regular expressions and helped me better appreciate the stages involved in compilation.</p>
<p>I received a First (100%) for this coursework.</p>
</div>
</div>
</div>
</div>
<a class="more text-center mt-3" data-bs-toggle="collapse" href="#warwick" role="button" aria-expanded="false" aria-controls="warwick">
<i class="fa fa-angle-down"></i>
</a>
</div>
</div>
<!-- LLM Summarisation Chrome Extension -->
<div class="col-lg-6 col-md-12 mb-3 p-0 px-md-3 pb-md-3">
<div class="card">
<h5 class="mb-2">
<span class="badge bg-primary mb-2">Web Dev</span>
<span class="badge bg-primary mb-2">OOP</span>
<span class="badge bg-secondary mb-2">HTML</span>
<span class="badge bg-secondary mb-2">CSS</span>
<span class="badge bg-secondary mb-2">JavaScript</span>
<span class="badge bg-grey mb-2">Node.js</span>
<span class="badge bg-grey mb-2">Socket.IO</span>
<span class="badge bg-grey mb-2">Bootstrap</span>
</h5>
<h3 class="mb-1">LLM Summarisation Chrome Extension<span class="date mt-1">2023</span></h3>
<p class="mb-3">Leveraging Langchain to use GPT LLMs to summarise web articles, triggered by a Chrome extension. View the code on my <a href="https://github.com/calebtham/deJPEG" target="_blank">GitHub repo</a> (Work In Progress).</p>
<div class="inline mx-auto">
<div class="link" onclick="window.open('https://github.com/calebtham/llm-summarisation')">
<video autoplay loop class="img-fluid img-thumbnail col-12" muted>
<source src="./projects/llm-summarisation/llmsummarisation.webm" type="video/webm">
</video>
</div>
</div>
<div class="collapse mt-3" id="LLMsummarisation">
<p>To gain some experience with building tools leveraging LLMs, I developed a Chrome extension that performs summarisation of webpage content on the current tab using GPT models – via OpenAI’s API. This was also valuable experience in prompt engineering. I used Langchain to make the API calls and to create pipelines for summarisation. Two key pipelines were a map-reduce approach and LLM self-reflection. </p>
<p>Map-reduce enabled summarisation of long documents by independently summarising parts of the document (in parallel), and then combining the results into a final summary. This was needed since LLMs have a limited token context, so long documents cannot naively be used in the prompt.</p>
<p>Self-reflection involves using the LLM to reflect upon its results. The method used is simply feeding the original document and resulting summary to the LLM and ask it if each bullet point in the summary is in fact true (according to the original document). This helps eliminate hallucination in the final response.</p>
</div>
<a class="more text-center mt-3" data-bs-toggle="collapse" href="#LLMsummarisation" role="button" aria-expanded="false" aria-controls="multchess">
<i class="fa fa-angle-down"></i>
</a>
</div>
</div>
<!-- Multchess -->
<div class="col-lg-6 col-md-12 mb-3 p-0 px-md-3 pb-md-3">
<div class="card">
<h5 class="mb-2">
<span class="badge bg-primary mb-2">Web Dev</span>
<span class="badge bg-primary mb-2">OOP</span>
<span class="badge bg-secondary mb-2">HTML</span>
<span class="badge bg-secondary mb-2">CSS</span>
<span class="badge bg-secondary mb-2">JavaScript</span>
<span class="badge bg-grey mb-2">Node.js</span>
<span class="badge bg-grey mb-2">Socket.IO</span>
<span class="badge bg-grey mb-2">Bootstrap</span>
</h5>
<h3 class="mb-1">Multchess<span class="date mt-1">2021</span></h3>
<p class="mb-3">Online multiplayer chess web application made with Node.js and Socket.IO. Website: <a href="https://www.multchess.com/" target="_blank" rel="noopener noreferrer">multchess.com</a></p>
<div class="inline mx-auto">
<div class="link" onclick="window.open('https://multchess.com/')">
<img src="./projects/multchess/menu.png" class="img-fluid img-thumbnail col-5 d-lg-none" alt="multchess">
<img src="./projects/multchess/game.png" class="img-fluid img-thumbnail col-5 col-lg-12" alt="multchess">
</div>
</div>
<div class="collapse mt-3" id="multchess">
<p>I decided to expand upon the skills I obtained from my first year Web Development Technologies module by creating a functional and reliable online application with full duplex and low-latency capabilities. I very much enjoy Chess, and so it seemed a sensible game to implement.</p>
<p>The game is complete with game settings (such as timer duration and increment), in-game chat, and ability to: request a takeback, offer a draw, resign, and ask for a rematch.</p>
<p>The website was created with mobile devices in mind and so can be played on-the-move. Because of this - along with the application's reliability and game flexibility - I often use this website to challenge my friends to a game of chess.</p>
</div>
<a class="more text-center mt-3" data-bs-toggle="collapse" href="#multchess" role="button" aria-expanded="false" aria-controls="multchess">
<i class="fa fa-angle-down"></i>
</a>
</div>
</div>
<!-- Lockdown Learning -->
<div class="col-lg-6 col-md-12 mb-3 p-0 px-md-3 pb-md-3">
<div class="card">
<h5 class="mb-2">
<span class="badge bg-primary mb-2">Web Dev</span>
<span class="badge bg-secondary mb-2">HTML</span>
<span class="badge bg-secondary mb-2">CSS</span>
<span class="badge bg-secondary mb-2">JavaScript</span>
<span class="badge bg-grey mb-2">Node.js</span>
</h5>
<h3 class="mb-1">Lockdown Learning<span class="date mt-1">2020 - 2021</span></h3>
<p class="mb-3">Co-founded a tutor advertising organisation, for which I implemented a website. It lists partner tutors and has a search engine for students. Website (last maintained in 2021): <a href="http://www.lock-learn.co.uk/" target="_blank" rel="noopener noreferrer">lock-learn.co.uk</a></p>
<a href="http://www.lock-learn.co.uk/" target="_blank" rel="noopener noreferrer"><img src="./projects/lockdown-learning/website.png" class="img-fluid img-thumbnail " alt="Lockdown Learning website"></a>
<div class="collapse mt-3" id="lockdownlearning">
<p>During the first COVID-19 lockdown, I co-founded an organisation to advertise online GCSE/A-Level tutors. Our goal was to advertise tutors to students through our website and through leaflets sent to schools, so that tutors could find good work and students could continue their education through school closures.</p>
<p>Within two days, I learned essential web technologies, including HTML, CSS, and JavaScript (Node.js), and developed the organisation website. This quick turnaround allowed us to launch quickly at the beginning of the lockdown period - when advertising tutors would be most effective.
<p>We successfully found many students for tutors listed on our website.</p>
</div>
<a class="more text-center mt-3" data-bs-toggle="collapse" href="#lockdownlearning" role="button" aria-expanded="false" aria-controls="lockdownlearning">
<i class="fa fa-angle-down"></i>
</a>
</div>
</div>
<!-- TensorFlow 2 -->
<div class="col-lg-6 col-md-12 mb-3 p-0 px-md-3 pb-md-3">
<div class="card">
<h5 class="mb-2">
<span class="badge bg-primary mb-2">AI/ML</span>
<span class="badge bg-secondary mb-2">Python</span>
<span class="badge bg-grey mb-2">TensorFlow 2</span>
<span class="badge bg-grey mb-2">NumPy</span>
<span class="badge bg-grey mb-2">pandas</span>
<span class="badge bg-grey mb-2">Matplotlib</span>
</h5>
<h3 class="mb-1">TensorFlow 2 Handwriting OCR<span class="date mt-1">2021</span></h3>
<p class="mb-3">Handwriting classifier using a TensorFlow 2 CNN model trained on the EMNIST dataset</p>
<img src="./projects/ocr/architecture.png" class="img-fluid img-thumbnail col-8 col-lg-12" alt="OCR">
<div class="collapse mt-3" id="ocr">
<p>Having already completed the Machine Learning Course (by Stanford University) on Coursera and written MLPs both from scratch and in TensorFlow.js, I wanted to explore some more complex architectures - namely CNNs. So, I decided to take the "Getting started with TensorFlow 2" course on Coursera.</p>
<p>Using the skills obtained on the course, I created a CNN model that classifies alphanumeric characters, trained on the EMINST dataset. To prevent overfitting, I used dropout layers, batch normalization, and regularization - as well as callbacks that (i) saved the best model in training (after an epoch) and (ii) stopped training if validation accuracy had not improved in two epochs. </p>
<p class="mb-3">I also wrote my own custom callback that graphed, using Matplotlib, the model's prediction frequency distribution - this was to investigate how the model was learning. For example, it may be predicting 'b' much more often than '6', even though the validation set was balanced. I found that this issue was much less common with a model with regularization, batch normalization and dropout layers. Thus, this callback helped me determine the model architecture and fine-tune the hyperparameters.</p>
<img src="./projects/ocr/frequency.png" class="img-fluid img-thumbnail mb-3" alt="OCR">
<p>(This shows a model confusing 'L's with '1' and 'f's with 'F')</p>
<p>For the balanced (digits and letters merged) dataset, the model managed a test accuracy of 89.21%, and a test accuracy of 99.52% for the digits dataset.</p>
</div>
<a class="more text-center mt-3" data-bs-toggle="collapse" href="#ocr" role="button" aria-expanded="false" aria-controls="ocr">
<i class="fa fa-angle-down"></i>
</a>
</div>
</div>
<!-- p5 -->
<div class="col-md-12 mb-3 p-0 px-md-3 pb-md-3">
<div class="card">
<h5 class="mb-2">
<span class="badge bg-primary mb-2">Visualisation</span>
<span class="badge bg-primary mb-2">AI/ML</span>
<span class="badge bg-primary mb-2">Algorithms</span>
<span class="badge bg-secondary mb-2">JavaScript</span>
<span class="badge bg-grey mb-2">p5.js</span>
<span class="badge bg-grey mb-2">TensorFlow.js</span>
</h5>
<h3 class="mb-1">My p5.js Phase (3)<span class="date mt-1">2019 - 2020</span></h3>
<p class="mb-3">Various projects including: TensorFlow.js visualisation, Shortest path finding visualisation, and a SIR infection model simulation</p>
<div class="collapse mt-3" id="p5">
<p class="mb-3">During A-Levels, I enjoyed creating small visualisations for various concepts that I learned from school or through my own research. To do this, I used the p5.js library, which made it easy to draw graphics on a HTML canvas. (Note: the focus here was to draw on a canvas, and not to create functional websites).</p>
<p class="mb-0">Here are 3 of my favourite projects:</p>
<div id="p5Corousel">
<div class="mx-auto mb-3 text-center">
<button class="btn btn-carousel" type="button" data-bs-target="#p5Corousel" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<span class="more">1 / 3</span>
<button class="btn btn-carousel" type="button" data-bs-target="#p5Corousel" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
<div class="carousel-inner">
<div class="carousel-item active">
<a href="./projects/p5/tensorflow" target="_blank" rel="noopener noreferrer"><h5 class="mb-1"><i class="fa fa-link"> </i>TensorFlow.js Visualisation</h5></a>
<div class="row">
<a class="col-8 col-md-4" href="./projects/p5/tensorflow" target="_blank" rel="noopener noreferrer"><img src="./projects/p5/tensorflow/demo.png" class="img-fluid img-thumbnail my-3" alt="TensorFlow demo"></a>
<p class="col-md-8 my-3">This project uses a TensorFlow.js neural network to learn XOR. While this is a trivial task for an ANN, it allowed for the learning process to be visualised, with its outputs being drawn onto a grid. Here, the top-left and bottom-right of the grid are logical 0s, and the top-right and bottom-left are logical 1s. This is all the information the model is given to train, so it must find a way to extrapolate and segment the grid. Here, I enjoyed experimenting with different model architectures - especially with the optimizer.</p>
</div>
</div>
<div class="carousel-item">
<a href="./projects/p5/path-finding" target="_blank" rel="noopener noreferrer"><h5 class="mb-1"><i class="fa fa-link"> </i>Shorest Path Finding</h5></a>
<div class="row">
<a class="col-md-7" href="./projects/p5/path-finding" target="_blank" rel="noopener noreferrer"><img src="./projects/p5/path-finding/demo.png" class="img-fluid img-thumbnail my-3" alt="Path finding demo"></a>
<p class="col-md-5 my-3">After learning about Dijkstra's and A* algorithms for shortest path finding at A-Level, I decided to implement an interactive visualisation tool to show the process of both. (Note: not compatible on mobile)</p>
</div>
</div>
<div class="carousel-item">
<a href="./projects/p5/sir-model" target="_blank" rel="noopener noreferrer"><h5 class="mb-1"><i class="fa fa-link"> </i>SIR Infection Simulation</h5></a>
<div class="row">
<a class="col-10 col-md-6" href="./projects/p5/sir-model" target="_blank" rel="noopener noreferrer"><img class="img-fluid img-thumbnail my-3" src="./projects/p5/sir-model/demo.png" alt="SIR simulation demo"></a>
<p class="col-md-6 my-3" >During the COVID-19 pandemic, I read about the SIR model for spread of infection. Here, I created a ball collision model to approximate infection spread by simulation and estimate the SIR infection model.</p>
</div>
</div>
</div>
</div>
</div>
<a class="more text-center mt-3" data-bs-toggle="collapse" href="#p5" role="button" aria-expanded="false" aria-controls="p5">
<i class="fa fa-angle-down"></i>
</a>
</div>
</div>
<!-- 8 Ball Pool -->
<div class="col-lg-6 col-md-12 mb-3 p-0 px-md-3 pb-md-3">
<div class="card">
<h5 class="mb-2">
<span class="badge bg-primary mb-2">Physics</span>
<span class="badge bg-primary mb-2">OOP</span>
<span class="badge bg-primary mb-2">AI</span>
<span class="badge bg-secondary mb-2">VB.NET</span>
</h5>
<h3 class="mb-1">8 Ball Pool<span class="date mt-1">2020</span></h3>
<p class="mb-3">PC game with offline multiplayer mode and single player mode, with a self-devised AI (with user selected difficulty)</p>
<img src="./projects/8-ball-pool/game.png" class="img-fluid img-thumbnail" alt="8 Ball Pool">
<div class="collapse mt-3" id="pool">
<p>For my Computer Science A-Level NEA, I wanted to create something that combined concepts from all the subjects that I was studying. At the time, we had just learned the formulae for 2D collisions of spheres in Further Mathematics, and so 8 Ball Pool then seemed the perfect game to implement. The program combined formulas from Physics/Mathematics with OOP principles from Computer Science.</p>
<p>The game was complete with user-friendly GUI, user login (for a leaderboard), ability to save a game state, multiplayer mode, and single player mode (with user selected difficulty). The most challenging part was implementing the single player mode AI. With pen and paper, I derived the formula to obtain which angle the AI should hit the cue ball to pocket another ball. I also developed some heuristics for the AI to decide which ball to pocket, which hole to pocket into, and what power to hit the cue ball.</p>
<p>I received 100% for this coursework, which played a part in me being awarded the Computer Science Prize (given to the top CS student in the school).</p>
</div>
<a class="more text-center mt-3" data-bs-toggle="collapse" href="#pool" role="button" aria-expanded="false" aria-controls="pool">
<i class="fa fa-angle-down"></i>
</a>
</div>
</div>
<!-- Neuroevolution Flappy Bird -->
<div class="col-lg-6 col-md-12 mb-3 p-0 px-md-3 pb-md-3">
<div class="card">
<h5 class="mb-2">
<span class="badge bg-primary mb-2">AI/ML</span>
<span class="badge bg-primary mb-2">OOP</span>
<span class="badge bg-secondary mb-2">VB.NET</span>
</h5>
<h3 class="mb-1">Neuroevolution Flappy Bird<span class="date mt-1">2019</span></h3>
<p class="mb-3">Neural network (written from scratch) that learns how to play flappy bird through reinforcement learning</p>
<img src="./projects/flappy-bird/1.png" class="img-fluid img-thumbnail col-8" alt="Connect 4">
<div class="collapse mt-3" id="flappybird">
<p>Having completed the Machine Learning Course (by Stanford University) on Coursera, I decided to write my own neural networks (MLP) from scratch (including all Matrix operations) in VB.NET. This tested my mathematical proficiency as well as my OOP skills, which I recently just learned.</p>
<p>I then decided to use this MLP to learn to play the flappy bird game - of which I wrote a clone.</p>
<p>The MLP architecture used was simple - just five inputs (related to position and y-velocity of the bird, and position of the next pipe), one hidden layer (64 parameters), and one output (whether to jump or not).</p>
<p class="mb-3">As opposed to backpropagation, a genetic algorithm is used to train the MLP. In the initial stage of training, 1000 birds are initialised with random parameters, and they simultaneously play until all the birds die. The fitness function is simple: the longer they live, the higher the score. The parents for the next stage of evolution are chosen proportionally according to their fitness, and then new birds are created by crossover of the parents. Each new bird is also subject to random mutation of its parameters.</p>
<img src="./projects/flappy-bird/1000.png" class="img-fluid img-thumbnail col-8 mb-3" alt="Connect 4">
<p>The MLP was able to learn to play the game perfectly (without dying) in under 20 stages of training.</p>
</div>
<a class="more text-center mt-3" data-bs-toggle="collapse" href="#flappybird" role="button" aria-expanded="false" aria-controls="flappybird">
<i class="fa fa-angle-down"></i>
</a>
</div>
</div>
<!-- Connect 4 -->
<div class="col-lg-6 col-md-12 mb-3 p-0 px-md-3 pb-md-3">
<div class="card">
<h5 class="mb-2">
<span class="badge bg-primary mb-2">AI</span>
<span class="badge bg-primary mb-2">OOP</span>
<span class="badge bg-secondary mb-2">VB.NET</span>
</h5>
<h3 class="mb-1">Connect 4<span class="date mt-1">2019</span></h3>
<p class="mb-3">Multiplayer mode and single player mode (Minimax with Alpha-Beta Pruning)</p>
<img src="./projects/connect4/game.png" class="img-fluid img-thumbnail" alt="Connect 4">
<div class="collapse mt-3" id="connect4">
<p>In VB.NET, I created a Connect 4 PC application, complete with offline multiplayer mode and single player mode. For the single player AI, I used the minimax algorithm and improved its performance with alpha-beta pruning. For this, I derived my own heuristics, and even at low depths of search (5-6) the AI was able to reliably beat my A-Level classmates.</p>
<p>This project was inspired by AlphaZero's achievements in beating world champions at Go. Reading about this, I wanted to explore the applications of similar AI (albeit much simpler) for myself. The project also allowed me to learn how to create a user-friendly GUI and enabled me to implement my new-found knowledge of OOP principles.</p>
<p>VB.NET was used since it was the language we learned in A-Level Computer Science.</p>
</div>
<a class="more text-center mt-3" data-bs-toggle="collapse" href="#connect4" role="button" aria-expanded="false" aria-controls="connect4">
<i class="fa fa-angle-down"></i>
</a>
</div>
</div>
</div>
</section>
<div class="separator"></div>
<!-- Contact section -->
<section class="text-start content-section border-gradient" id="contact">
<div class="container">
<div class="row">
<div class="col-lg-8 mx-auto p-4">
<h1 class="pb-2 border-gradient">Contact me</h1>
<p>Feel free to contact me through any of the following media:</p>
<p><a href="mailto:[email protected]">[email protected]</a><br>
+44 7975 706885
</p>
<button class="btn btn-primary btn-lg w-auto mx-1 rounded-pill" type="button" onclick="window.open('https://www.linkedin.com/in/calebtham/')">
<i class="fa fa-linkedin fa-fw"></i>
</button>
<button class="btn btn-primary btn-lg w-auto mx-1 rounded-pill" type="button" onclick="window.open('https://github.com/calebtham/')">
<i class="fa fa-github fa-fw"></i>
</button>
</div>
</div>
</div>
</section>
<!-- Scripts -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<script src="./assets/bootstrap/js/bootstrap.min.js"></script>
<script src="./assets/js/navbar.js"></script>
<script src="./assets/js/scroll.js"></script>
<script src="./assets/js/card.js"></script>
<script src="./assets/js/light-mode-switch.js"></script>
</body>
</html>