Jekyll2023-12-29T12:38:50+00:00/Raihan SaputraPersonal website of RaihanLessons Learned from Olive Oil classification2022-11-14T00:00:00+00:002022-11-14T00:00:00+00:00/2022/11/14/timeseries-oliveail-lessons-learned<p>Right now I’m really interested in fine-tuning image classification models for whatever i can get my hands on. After the <a href="/2022/11/14/locating-urban-scenes-with-image-classification.html">locating images assignment</a>, I want to run a well known example of using image classification images to classify a timeseries data, as shown in the <a href="https://github.com/fastai/fastbook/blob/master/01_intro.ipynb">fastai book chapter one</a>.<br />
I found <a href="https://gist.github.com/oguiza/c9c373aec07b96047d1ba484f23b7b47">the notebook</a>, and tried to rerun it to find out whether newer models can perform better.</p>
<h2 id="notes-of-the-original-notebook">Notes of the original notebook</h2>
<ul>
<li>I have downloaded the dataset from the mentioned source, but after rerunning the same cells from the notebook, I did not find the same pattern from the data. I presume that the data in the notebook has some errors, as in bitflips or improper decompression. This also makes it clear that the data from the source is already normalized in some way, so most of the data preprocessing is not needed.</li>
</ul>
<table>
<thead>
<tr>
<th><img src="/static/images/oo-origraph.png" alt="original graph with clear outlier data" /></th>
<th><img src="/static/images/oo-rerungraph.png" alt="rerun data with much less variance" /></th>
</tr>
</thead>
<tbody>
<tr>
<td>original graph with clear outlier data</td>
<td>rerun data with much less variance</td>
</tr>
</tbody>
</table>
<ul>
<li>The image saved from the notebook still contains the background and axis marks and ticks, instead of just the plot. This still preserves the 570x570 raw pixels though.</li>
</ul>
<table>
<thead>
<tr>
<th><img src="/static/images/oo-origadf.png" alt="original input data, with axes in the file" /></th>
<th><img src="/static/images/oo-rerungadf.png" alt="rerun input data, plot only" /></th>
</tr>
</thead>
<tbody>
<tr>
<td>original input data, with axes in the file</td>
<td>rerun input data, plot only</td>
</tr>
</tbody>
</table>
<ul>
<li>The total training images produced are unclear. I assume the 30 original images are augmented with 30 noise add images.
<h2 id="modifications-in-my-run">Modifications in my run</h2>
</li>
<li>As the fastai module has progressed a lot since the time the notebook was published, I opt to fine tune the model using the .fine_tune convenience function, instead of running the functions manually.</li>
<li>I’m only using the GADF plot as it is the best performing in the original notebook. I’m saving only the plot, without ticks and axis.
<h2 id="original-rerun">Original rerun</h2>
<p><img src="/static/images/oo-resnetlogs.png" alt="Rerun training logs" /></p>
</li>
<li>I found that the mentioned performance is achievable, but through several runs and longer epochs. It’s probable that the data artifact in the original notebook is what causing the difference. But this rerun shows that the performance of fine-tuning image classifier models, on transformed timeseries dataset, is still very good.
<h2 id="experimenting-with-transformer-model">Experimenting with Transformer Model</h2>
</li>
<li>There’s a newer architecture called Vision Transformer that possibly can perform better, so I tried it with the original 30/30 training-test split.</li>
<li>A hurdle in this is the timm sourced ViT model cannot accept larger images as the input. The ViT Model only accepts 384*384 input. This should be possible as described in the DEiT and SWIN papers (fine-tuning transformers using larger inputs results in better performance), but I have not found a way. So the images are resized using RandomResizedCropGPU to 384 pixels.</li>
<li>I assume this would perform much worse as there will be data lost in the resize, as each pixel represents one time unit.<br />
<img src="/static/images/oo-vitlogs.png" alt="ViT training logs" /></li>
<li>Interestingly, after an unexpected training graph, the ViT model still can work fine, reaching similar performance levels of ResNet with the proper image.
<h2 id="experimenting-with-rendering-colormap">Experimenting with rendering colormap</h2>
</li>
<li>The original notebook uses the <code class="highlighter-rouge">viridis</code> colormap for GADF plots, but it only uses G and B pixels to render the map. I decided to try comparing the ‘rainbow’ cmap to the ‘viridis’ CMAP to find out if there is any difference.</li>
<li>There is a slight difference and expected, as the viridis plots only uses 2 channels of information ,while the rainbow plot uses all three RGB channels. This might be an important point in using image classification techniques for timeseries data.</li>
</ul>
<table>
<thead>
<tr>
<th><img src="/static/images/oo-rainbow.png" alt="rainbow cmap" /></th>
<th><img src="/static/images/oo-rerungadf.png" alt="viridis cmap" /></th>
</tr>
</thead>
<tbody>
<tr>
<td>rainbow cmap</td>
<td>viridis cmap</td>
</tr>
</tbody>
</table>
<h2 id="next">Next</h2>
<ul>
<li>For the topic of classifying time series data through image classification, there are several things I want to investigate, such as:
<ul>
<li>Inputting the 1:1 representation to a transformer model</li>
<li>Using the transformer architecture to infer arbitrary length timeseries data</li>
<li>Cross Validation of the techniques using a different split of training/test data (40:20 or 45:15 or 50:10)</li>
</ul>
</li>
</ul>Right now I’m really interested in fine-tuning image classification models for whatever i can get my hands on. After the locating images assignment, I want to run a well known example of using image classification images to classify a timeseries data, as shown in the fastai book chapter one. I found the notebook, and tried to rerun it to find out whether newer models can perform better. Notes of the original notebook I have downloaded the dataset from the mentioned source, but after rerunning the same cells from the notebook, I did not find the same pattern from the data. I presume that the data in the notebook has some errors, as in bitflips or improper decompression. This also makes it clear that the data from the source is already normalized in some way, so most of the data preprocessing is not needed.Locating Urban Scenes through Fine Tuning of Pre-trained Deep Learning Models2022-11-14T00:00:00+00:002022-11-14T00:00:00+00:00/2022/11/14/locating-urban-scenes-with-image-classification<p><em>This is a summary of my group project done for the DATA7703 course for my Masters of Data Science study at the University of Queensland.</em></p>
<p>Geoguessr is a game where players are given a picture of a Google Street View imagery and try to guess where the image comes from. Players usually rely on man made features, like road markings or traffic signs to determine the location. Sometimes billboards come into play and show the language to narrow down possible locations. Although high level players like RAINBOLT have insane intuitions of colors and other features.. but I digress. But then, is it possible to create a bot that identifies the location of images by looking at the images?<br />
<a href="https://www.youtube.com/watch?v=aD_rtwofvgU"><img src="https://img.youtube.com/vi/aD_rtwofvgU/0.jpg" alt="RAINBOLT" /></a></p>
<p>There have been various efforts in identifying locations of pictures through machine learning, through location compression like <a href="https://openaccess.thecvf.com/content_ECCV_2018/papers/Eric_Muller-Budack_Geolocation_Estimation_of_ECCV_2018_paper.pdf">GeoEstimation</a>. The approach used in GeoEstimation is the classification of images to <a href="https://s2geometry.io/devguide/s2cell_hierarchy.html">S2 cells</a> which represent specific geographic boundaries on the surface of the earth. While this approach theoretically can be very accurate, it does raise some questions in regards to class relatedness (close areas should be more likely to be predicted) and the amount of labeled data we need. We want to reduce the scope to what would be useful in playing GeoGuessr, and also limit our training/input to dashcam-like images where images are captured onboard a vehicle, with mostly a view of the road ahead. Although Geoguessr does take geographic coordinates as an input for score, sampling down to the specific country is an easier output to do, and shifts the problem from classifying a photo to S2 cells, to photo -> country label.<br />
When talking about image classification, most people would be thinking about classifying general objects, which is a problem that is quite popular and has been tackled by big teams with big resources. The first breakout Image Classification model using Neural Networks was the <a href="https://papers.nips.cc/paper/2012/hash/c399862d3b9d6b76c8436e924a68c45b-Abstract.html">AlexNet</a>, which needed to use the full ImageNet dataset which consists of 1.2 million images. The more recent improvements still also need at least that amount of training data, or even in the case of <a href="https://arxiv.org/abs/2010.11929">Vision Transformer</a>, it uses 303 million images to train the model. Even if we have access to all of the images that Google Street View has, we probably don’t have the resources and time to train it.<br />
Fortunately, there’s a technique that can exploit the pre-trained general classification models for our own use, called Transfer Learning or Fine Tuning a model. Some prominent examples of this are <a href="http://vision.stanford.edu/aditya86/ImageNetDogs/">the Stanford Dogs dataset</a>, <a href="https://www.robots.ox.ac.uk/~vgg/data/flowers/102/">the Oxford Flowers-102 dataset</a>, and <a href="http://ai.stanford.edu/~jkrause/cars/car_dataset.html">the Stanford Cars dataset</a>. For image classification tasks, the Fine Tuning process exploits the fact that the general classifiers have learned basic features of the images (as seen <a href="https://arxiv.org/abs/1311.2901">here</a>), and we only need to change some parameters to use it for our specific problem, in this case classifying location based on features in the image.
We feel that the problem we are solving here is different to the usual fine-tuning problem as we are not trying to identify the same objects and classify them, and the objects of interest are not the main object of the image. Usual fine-tuning tasks have the main interest/class as the main object of the image, while classifying locations means having to identify unique, small features of the image to classify a single class, with varying amount of features and visibility for each class. We want to see how fine-tuning models fare in this regard.
As much as we’d love to use the Google Street View dataset, the access to it is paid, and that makes it not feasible to use. We instead found the Mapillary Traffic Sign dataset suitable for our use. It is a dataset that is compiled to train and evaluate object detection models for traffic signs. It is suitable for our use case as it consists mainly of forward-facing onboard images, and likely has man made features seen in the images. The Mapillary dataset needed some work to get the geographic data of lat, lon (scraping + API access). Once done, we can reverse geocode and list the available images by country. Due to the limited data available, we are classifying the top-5 available countries, which are AU, JP, US, BR, and DE. After data cleanup, we have max 300 training images and 40 test images per label, totalling 1500 training images and 200 test images.</p>
<table>
<thead>
<tr>
<th style="text-align: center">Country Code</th>
<th style="text-align: center">Image Count</th>
<th style="text-align: center">Country Code</th>
<th style="text-align: center">Image Count</th>
<th style="text-align: center">Country Code</th>
<th style="text-align: center">Image Count</th>
<th style="text-align: center">Country Code</th>
<th style="text-align: center">Image Count</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">US</td>
<td style="text-align: center">1824</td>
<td style="text-align: center">IT</td>
<td style="text-align: center">192</td>
<td style="text-align: center">CN</td>
<td style="text-align: center">119</td>
<td style="text-align: center">RO</td>
<td style="text-align: center">58</td>
</tr>
<tr>
<td style="text-align: center">AU</td>
<td style="text-align: center">851</td>
<td style="text-align: center">CO</td>
<td style="text-align: center">188</td>
<td style="text-align: center">CL</td>
<td style="text-align: center">101</td>
<td style="text-align: center">AE</td>
<td style="text-align: center">56</td>
</tr>
<tr>
<td style="text-align: center">BR</td>
<td style="text-align: center">554</td>
<td style="text-align: center">IN</td>
<td style="text-align: center">180</td>
<td style="text-align: center">ID</td>
<td style="text-align: center">88</td>
<td style="text-align: center">MA</td>
<td style="text-align: center">56</td>
</tr>
<tr>
<td style="text-align: center">JP</td>
<td style="text-align: center">480</td>
<td style="text-align: center">MX</td>
<td style="text-align: center">174</td>
<td style="text-align: center">SE</td>
<td style="text-align: center">87</td>
<td style="text-align: center">DK</td>
<td style="text-align: center">54</td>
</tr>
<tr>
<td style="text-align: center">DE</td>
<td style="text-align: center">479</td>
<td style="text-align: center">NL</td>
<td style="text-align: center">168</td>
<td style="text-align: center">BE</td>
<td style="text-align: center">80</td>
<td style="text-align: center">NO</td>
<td style="text-align: center">49</td>
</tr>
<tr>
<td style="text-align: center">TH</td>
<td style="text-align: center">303</td>
<td style="text-align: center">GB</td>
<td style="text-align: center">162</td>
<td style="text-align: center">UA</td>
<td style="text-align: center">76</td>
<td style="text-align: center">TW</td>
<td style="text-align: center">47</td>
</tr>
<tr>
<td style="text-align: center">FR</td>
<td style="text-align: center">275</td>
<td style="text-align: center">ES</td>
<td style="text-align: center">136</td>
<td style="text-align: center">AT</td>
<td style="text-align: center">74</td>
<td style="text-align: center">EC</td>
<td style="text-align: center">46</td>
</tr>
<tr>
<td style="text-align: center">CA</td>
<td style="text-align: center">257</td>
<td style="text-align: center">AR</td>
<td style="text-align: center">130</td>
<td style="text-align: center">HU</td>
<td style="text-align: center">73</td>
<td style="text-align: center">CH</td>
<td style="text-align: center">45</td>
</tr>
<tr>
<td style="text-align: center">RU</td>
<td style="text-align: center">255</td>
<td style="text-align: center">PL</td>
<td style="text-align: center">127</td>
<td style="text-align: center">MY</td>
<td style="text-align: center">64</td>
<td style="text-align: center">VN</td>
<td style="text-align: center">43</td>
</tr>
<tr>
<td style="text-align: center">ZA</td>
<td style="text-align: center">222</td>
<td style="text-align: center">NZ</td>
<td style="text-align: center">124</td>
<td style="text-align: center">PE</td>
<td style="text-align: center">62</td>
<td style="text-align: center">PY</td>
<td style="text-align: center">42</td>
</tr>
</tbody>
</table>
<p>We are also interested in seeing how much data is needed to fine-tune to a specific problem, so we are fine-tuning the models with 100, 200, and 300 training images per label to see the difference.
To save time, we pre-resized the data to 800x800 pixels and squished it to a 1:1 aspect ratio. For the batch transformation, we used RandomResizedCropGPU to 224 pixels, brightness, and contrast augmentations. We do admit that this process is not optimum, and will touch on this later.
<img src="/static/images/geolocate-finetune.png" alt="" />
For the model selection, Jeremy Howard has an evaluation of the Best vision models for fine tuning, and we’ll be using that as a basis. We feel that our specific problem has more similarity to the Kaggle Planet dataset in the evaluation. From this reference, we decided to evaluate ResNet, ResNet-d, ConvNExT, Vision Transformer (ViT), DEiT, and SWINv2. ResNet and ResNet d are chosen as the baseline models which are widely used for fine tuning use cases. ViT, ConvNext, DEiT and SWINv2 are chosen due to their good performance in the evaluation.
ResNet, ResNet-d, and ConvNExT are image classification models that uses convolutional architecture based on AlexNet and added Residual skip layers to enable deeper models. ResNet was the best performer when it was published and has been the default base of fine-tuned models. ResNet-D is an improved version of ResNet with some tricks. ConvNeXt applies lessons learned from Visual Transformers to convolutional neural networks to achieve similar performance.
Visual Transformer (ViT) is an image classification model based on the Transformer architecture that is predominantly used in Natural Language Processing tasks. Although it needs a lot of training data, it shows SOTA performance when it was published. DeiT is a Data Efficient variant of ViT that manages similar performance through modifications of architecture, training procedure and distillation. SWIN is a modified ViT by using hierarchical shifted windows to parse the image instead of just dividing the models to tokens.</p>
<table>
<thead>
<tr>
<th>Base Architecture</th>
<th>Model Architecture</th>
<th>Tiny Variant</th>
<th>Small Variant</th>
<th>Base Variant</th>
</tr>
</thead>
<tbody>
<tr>
<td>ResNet</td>
<td>ResNet</td>
<td>resnet18 (6M)</td>
<td>resnet50 (25M)</td>
<td>resnet101 (45M)</td>
</tr>
<tr>
<td> </td>
<td>ResNet-d</td>
<td>resnet18d (6M)</td>
<td>resnet50d (25M)</td>
<td>resnet101d (45M)</td>
</tr>
<tr>
<td> </td>
<td>ConvNext</td>
<td> </td>
<td>convnext-t (29M)</td>
<td>convnext-s (50M)</td>
</tr>
<tr>
<td>Visual Transformer (ViT)</td>
<td>ViT</td>
<td>vit-tiny (6M)</td>
<td>vit-small (22M)</td>
<td>vit-base (87M)</td>
</tr>
<tr>
<td> </td>
<td>DEiT</td>
<td>deit-tiny (6M)</td>
<td>deit-small (22M)</td>
<td>deit-base (87M)</td>
</tr>
<tr>
<td> </td>
<td>SWINv2</td>
<td> </td>
<td>swinv2-tiny (28M)</td>
<td>swinv2-small (50M)</td>
</tr>
</tbody>
</table>
<p>All models will be fine tuned to 100 epochs with 1 epoch of last layer training. Ideal learning rate will be evaluated before the training. We’ll be evaluating the models through the accuracy_multi and f1_score metrics.</p>
<h2 id="results">Results</h2>
<p><img src="/static/images/geolocate-performance.png" alt="" />
<strong>IMPACT OF TRAINING DATA AMOUNT</strong></p>
<p>From the groph, it is clear that more data certainly helps any model to perform better. Using newer architectures such as ConvNext and ViT based architecture, the lack of data can be compensated by increasing the complexity of the model. Using 100 training images and tiny model variants limits the performance while using the same amount of training data and more complex models achieves similar performance to tiny models using more training data.
This need for tiny models to train on a lot of data also shows the inverse. The newer tiny models can perform surprisingly well when trained with more data.
The most flexible and resilient model seems to be ViT-Small and ViT-Base. It has a lower variance between 100-300 trained images and still achieves top 10 results in each case.</p>
<p><strong>BEST PERFORMANCE</strong><br />
When a good amount of training data is available, the next consideration will be the size of the model and best performance available. Vit-base shows the best absolute performance here. Bigger sized model does not guarantee better performance, shown in the case of DeiT small vs base. Even though there is a significant improvement in each model variant, it has to be kept in mind that the unneeded complexity will impact in inference latency due to the size of the model.
<img src="/static/images/geolocate-training-throughput.png" alt="" />
<strong>TRAINING THROUGHPUT</strong></p>
<p>Bigger models need more time to fit, as shown in this graph. The impact from going to a vit-small model to Vit-Base model is roughly a 30% slower training period. It needs to be kept in mind that with 100 epochs, even the Vit-Base model only took around 35-40 minutes. The worst case model is the ConvNeXt models that takes around 1 hour to train for 100 epochs. This matters more in iterating the approach to the final model instead of having to wait for hours or days for the next model to evaluate.</p>
<p><strong>INFERENCE THROUGHPUT</strong></p>
<p>We took measurements of inference time from inference our test set. From the results we can see that the bigger models do have a latency penalty in inferencing. There is also a clear tradeoff between inference throughput and model performance, with 5% worse throughput and 5% better F1 Score by moving from Tiny models to Small models, and a further 10% worse throughput with 5% better F1 Score moving from Small models to Base models.
ViT, SWINv2, and ConvNext models scale as expected while DEiT-Base achieves worse F1 Score compared to DEiT Small.</p>
<h2 id="conclusion">Conclusion</h2>
<p>We believe that we have demonstrated that medium-complexity classification models can be created through fine-tuning/transfer learning techniques, with resources that are easily attainable by small teams or individuals. The results we get, with the best performing models having >0.9 F1 score on Base models and >0.85 F1 score on Small models, is clearly satisfactory. We have managed to do this with a reasonable amount of training dataset, with a maximum of 340 images per label, 300 training images and 40 test images per label. All of our training can be done with easily attainable resources, being done on 16GB GPU Paperspace machines (Free-RTX5000) that cost us USD 8 per month to access. If we are not evaluating many models, we can see more performant models through iterating on the training hyperparameters and data augmentation.</p>
<p>We also have proven that although various architectures are available and perform well, each specific classification task would need to evaluate several models to fit their needs. In general, newer models perform better through their architecture improvements. Small, newer models perform really well beyond expectations, so choosing them to start creating models is a good default. Although our best performing models are quite big on parameter size (ViT-Small 22M, Swinv2-Small 50M, ViT-Base 80M), there’s possible improvements coming through model compression such as MiniViT and TinyVit.</p>
<p>We have demonstrated that more images has a direct impact on the performance of the models, but the amount of data is not prohibitive. Although we have not exhaustively tested this, the amount of images that we tested reflects a possible range for other similarly difficult tasks. We also found that cleaning the data from irrelevant/low-quality images brings better performance, which matters more than the raw amount of data available.</p>
<p>An interesting point that we discover is that the ungeneralizable performance rankings of general image classification tasks such as ImageNet for specific classification tasks. From the published papers, ConvNext, DEiT, and SWINv2 have better performance than ViT of similar size in image classification tasks, but it is not the case here. It is possible that the larger size or inefficiency of the base ViT model has the extra space for the embedded knowledge needed for our specific classification tasks.</p>
<h2 id="next">Next</h2>
<p>Unfortunately we did not have time to dig deeper into the model and evaluate specifically how these models accomplish the classification. Some methods are available to evaluate these, like creating maximum activation images, attention maps or <a href="https://arxiv.org/abs/2012.09838">Transformer-specific interpretability techniques</a>. We tried creating maximum activation images for some earlier ResNet models that we trained, but did not get satisfactory results.</p>
<p>Relatedly, there are improvements in the models that we use as the base models. There are improvements from the size constraints like <a href="https://arxiv.org/abs/2204.07154">MiniViT</a> variants of DEiT and SWIN, also <a href="https://arxiv.org/abs/2207.10666">TinyViT</a>. For performance and more robust learning, there’s also <a href="https://arxiv.org/abs/2206.01161">the modified RobustViT and RobustDeiT models</a> that have been trained to learn from the object itself instead of background features, which we assume would perform better.</p>
<p>For the problem side, we wish to be able to evaluate the ultimate performance of classifier models, by training with more data and labels.</p>This is a summary of my group project done for the DATA7703 course for my Masters of Data Science study at the University of Queensland.Digital garden inspirations2020-07-23T00:00:00+00:002020-07-23T00:00:00+00:00/2020/07/23/digital-garden-inspirations<p>Joel Hook’s <a href="https://joelhooks.com/digital-garden">digital garden</a> is definitely a model. I don’t think a blog is bad for me, but readers don’t want to wade through the mix of personal writings and more interesting stuff. (Do they? Honestly I enjoy it, but I don’t know about others.)</p>
<p>Paul Graham’s site is <a href="http://paulgraham.com/articles.html">a collection of essays</a>. I really admire it. Having a clear and long arguments about something while being relatable without being judgy is really something else. He doesn’t really have.. references? Maybe because he’s already experienced what he’s saying. Sometimes his posts are short too. And interestingly he set a pretty short linebreak, so his paragraphs are actually not that long each, but looks proportional. I really love how he starts with a central idea (<a href="http://paulgraham.com/wealth.html"><em>If you wanted to get rich, how would you do it? I think your best bet would be to start or join a startup.</em></a>) and delves down on the idea, scale, opposing views, and takes you on a tour.</p>
<p><a href="">Pawlean.com</a> is a really personal blog. I still feel a bit too.. vulnerable to write like that. But I like the fact that it’s not about being authoritative or even guiding, but just telling her experience.</p>
<p><a href="">jenny.world</a> is also a very personal and mixed site. Kinda like tumblr (is it tumblr? it is). I really, really like <a href="https://www.jenny.world/post/614068853608185856/vacuuming">Vacuuming</a>. On another note, giving up hosting/other stuff to tumblr is a good idea. But I’ll stick with jekyll for now.</p>
<p><a href="">notes.andymatuschak.org</a> is a really experimental UI. Well at the end of the day it’s for me to look at how to take notes more properly instead of a blog. The really interesting idea for me right now seems to be <a href="https://notes.andymatuschak.org/About_these_notes?stackedNotes=z3SjnvsB5aR2ddsycyXofbYR7fCxo7RmKW2be&stackedNotes=z4SDCZQeRo4xFEQ8H4qrSqd68ucpgE6LU155C&stackedNotes=zg3fYweZpbHeBTpcYke5mF4ZfrJutYcQEtFo&stackedNotes=z71FeBJGqZdyA78UNTwXCWcMGUVCWk1XsLvPS&stackedNotes=z5aJUJcSbxuQxzHr2YvaY4cX5TuvLQT7r27Dz&stackedNotes=z8d4eJNaKrVDGTFpqRnQUPRkexB7K6XbcffAV">Close open loops</a>. I like the sentence-as-title system he got there too. How to succinctly express an idea and have it as a relationship. Have to start taking more notes, honestly.</p>
<p>I also want a /now page like sivers.org/nowff describes. Or make that my main page (<a href="https://sivers.org/">his front page</a> is pretty cool too). Listing all the things I’m into right now (tech stack, FE learnings, hobby (simracing), ideas floating in my head.) and last updated is pretty important too.</p>
<p>Simon Willison’s <a href="https://simonwillison.net">site</a> is also freaking great. I love the fact that he has both a blog standard (‘entries’) and other random stuff curated (‘til’, ‘links’ and ‘quotes’). I don’t know whether I post often enough to do that, but it is cool to see that separation. <a href="https://simonwillison.net/2020/Jul">Monthly entry archive</a> vs a <a href="https://simonwillison.net/2020/Jul/18/">daily view</a> that includes quotes and links. Turns out the tag (example: <a href="https://simonwillison.net/tags/datasette/">datasette tag</a>) also displayes all links and quotes related to that. I wonder what’s the difference between these in-the-moment short content and longer ‘entries’. It’s a weird mix between a publishing platform and a personal knowledge management thing for him.</p>
<p>The biggest thing from Simon’s site is that I want to use that format to curate what I come across on twitter/other daily or even from my library. Setting things up to be curated piecemeal but merged into tags. I already have several pieces related to a topic, but not organized into tags. Example: <a href="/2018/04/with-enough-sacrafices-you-can-be-anything-you-want-to-be/">With enough sacrafices..</a>, <a href="/2018/05/fate-destiny-life/">Fate/Destiny/Life</a>, <a href="/2018/05/our-life-is-not-ours/">Our Life is Not Ours</a>.</p>
<p>Some more inspiration that’s stuck on my curation: <a href="https://battlepenguin.com/philosophy/faith/fate-and-destiny/">Khanism’s Fate and Destiny</a> (I think there’s a specific post that really resonates with me but can’t find the link) and Melting Asphalt’s <a href="https://meltingasphalt.com/a-natural-history-of-beauty/">A Natural History of Beauty</a>.</p>
<p>Honestly, all this stuff is useless if I don’t write. This is why I posted this up on the blog. Let’s keep this going. ✌️</p>Joel Hook’s digital garden is definitely a model. I don’t think a blog is bad for me, but readers don’t want to wade through the mix of personal writings and more interesting stuff. (Do they? Honestly I enjoy it, but I don’t know about others.)Endless Starts2020-07-21T00:00:00+00:002020-07-21T00:00:00+00:00/2020/07/21/again<p>I just seem to have a lot of false starts and holes in my writing. But reading back through these pieces reminds me that a lot of things are the same. I’m still scared to be vulnerable as my career goes on, as I felt <a href="/2018/04/space/">over 2 years ago</a>. I’m splitting up this website to separate my blog posts and other more “safe” writing. But is this right? Should I step forward with all my faults or should I craft my image?</p>
<p>I’m still not sure, as ever. I want to write publicly again. I don’t have any constant readers, as far as I know. I don’t have any or a lot of projects that’s documented well enough to be published. But I guess this blog should be more of a.. personal yet public page to share my thoughts and feelings. Instead of a platform to broadcast who I want to be seen by people I don’t know about.</p>
<p>What I do have is a.. possibility. To curate. I don’t know how stuff will link, or how I can package them. Instead of remixing content, I’m leaning towards just finding really good gems in the dirt, or even extracting what I think is the central piece of an idea. Or a piece that resonated a lot and can be applied more generally.</p>
<p>We’ll see. I don’t want to be preachy. I don’t want to be seen as an expert in topics that I’m not well versed in. I want to be more of a tour guide. A journey through what I think would be interesting for my friends.</p>
<p>On the topic of personal posts. I’ll put up some of my other writings here from my journal or other places where I wrote. Just to make it more complete. And I’ll also date them at the time I wrote them. Should be interesting..</p>I just seem to have a lot of false starts and holes in my writing. But reading back through these pieces reminds me that a lot of things are the same. I’m still scared to be vulnerable as my career goes on, as I felt over 2 years ago. I’m splitting up this website to separate my blog posts and other more “safe” writing. But is this right? Should I step forward with all my faults or should I craft my image?Restarting, Again2018-08-05T00:00:00+00:002018-08-05T00:00:00+00:00/2018/08/05/restarting-again<p>So. After a few months of silence I’m finally back on here. I wrote a lot less, and, as always, I don’t like it.</p>
<p>I don’t really have anything to blame but myself. I’ve been pretty stringent with my media intake (no instagram, no reddit until this Friday, 3 days ago), yet I still have a lot of things that I spend too much time on (read: Hacker News).</p>
<p>I’ve concocted a plan to get away from it, making the HN Wisdom summary from my favorite comments and making an Action Plan from it, which I intended to straighten me up in my recent, and current, slump. Yet I still got back.</p>
<p>I’m busy, yes, but it has always been since I got back in December. I’m tired, yes, but it’s always like that.</p>
<p>I’m not sure what’s happening, as ever.</p>
<p>I needed something easy to work on, so I decided to move my blogging (again) to Jekyll. I just don’t feel like paying DigitalOcean $10 every month anymore (sorry, DO).</p>
<p>I decided to build on Jekyll because I’m currently in the progress of rebuilding an e-commerce-ish site for my mom’s business, which was built with Wordpress for the customer-facing site. It’s abhorrently slow, and almost impossible to transfer to a VPS. (Which needs another hosting fee every month.) I’ve dug into JAMstacks and serverless hype, and got back to Jekyll to do it, and decided to try it on my blog first.</p>
<p>My intention from the start has always been to deploy it on Netlify, but when pushing this to GitLab I realized they also have GitLab Pages available as a service. Yet when I tried it, the GitLab Pages didn’t run, and netlify ran really smoothly.</p>
<p>One thing I decided was to port some of my old posts back to this blog. I envy people who has years of posts archived instead of months, yet I always avoid it due to feeling vulnerable (first) and the posts are on another platform (second). But I decided it would be worth it and ported my posts from my 2016 blog. I decided to not move posts from my 2017 blog yet because it’s mainly just a blog for my DECO2200 class, with only 1 post on an app design feedback.</p>
<p>I guess vulnerability is the name of the game. We live solitary lives inside our mind, and sometimes the thoughts are not pretty, or flat-out wrong. Yet being humans, perfection is unattainable and to learn is only through failures.</p>
<p>I hope this site will live for longer than what was my previous blogs.</p>
<p>(btw, I need to backup all my pictures/images from my old blogs to.. somewhere. I love/hate WP automated caching.)</p>
<p>See you around.</p>So. After a few months of silence I’m finally back on here. I wrote a lot less, and, as always, I don’t like it.Good Enough2018-05-21T08:14:32+00:002018-05-21T08:14:32+00:00/2018/05/good-enough<p>Happiness = Reality – Expectation</p>
<p>Seems like a simple enough formula. One thing that’s fickle is the human that’s running the equation. The parameter that keeps on changing is the expectation part. To expect, in our mind, is to hold on to a fantasy.</p>
<p>The only thing that keeps this away is to make your expectations real. Write it down, talk about it. Or your expectations will just float like a kite without a string.</p>
<p>To actually remember what was good enough yesterday is to not make today’s good enough expectations a way to chase an unattainable perfection, throwing away what you already have for an imagined nirvana.</p>rsHappiness = Reality – ExpectationOur Life is Not Ours2018-05-10T13:31:15+00:002018-05-10T13:31:15+00:00/2018/05/our-life-is-not-ours<p>Maybe I’m late to realise this. But our life is not truly ours. Whether it’s the deities we choose to believe in, the family we’re born to, the nation we live in, or even the friends we choose to make.</p>
<p>Each of them (and many more) is about expectation. We expect something out of them, and we, in turn, are expected something out of ourselves.</p>
<p>Our choices then must also take them into account. And their choices affects us too.</p>
<p>To be free is to choose which ones do we want to keep and sometimes how much hurt you cause that you can forgive yourself for.</p>
<p>To be free is to sacrifice: the bonds, the expectations, and the uncertainty of what’s ahead.</p>rsMaybe I’m late to realise this. But our life is not truly ours. Whether it’s the deities we choose to believe in, the family we’re born to, the nation we live in, or even the friends we choose to make.Fate/Destiny/Life2018-05-01T17:44:52+00:002018-05-01T17:44:52+00:00/2018/05/fate-destiny-life<p><em>This is a rambling after reading Freakonomics. Yes I just finished that book now.</em></p>
<blockquote class="wp-block-quote">
<p>
“The two biggest lotteries in life are the country you were born in and the parents you were born to.”
</p>
<cite>A quote from somebody that I most definitely butchered</cite>
</blockquote>
<p>Our lives, like it or not, are not totally in our control. What shapes us today, were decided years, decades, or even centuries ago by the unintended action of those who before us. And this also happens for what shapes us tomorrow.</p>
<p>Power is what all humans desire. Maybe you (and me) does not desire to be in power of a nation, but to have power is still in our desire. For me, the definition of power is the capability to bend others to our will. Not just other humans, but all other things in this world. It’s carpentry to bend wood to furniture. It’s code to bend data to something useful. It’s our hands to bend the direction of the car. It’s ad to bend our wills to buy stuff. To alter the course of others is power.</p>
<p>So if a lot of our parts of our life has been decided, it’s a logical consequence that we do not have power over it.</p>
<p>And decided does not mean predictable. What seems good in the past may be trash tomorrow.</p>
<p>This conundrum is what being human is: to keep living and keep pushing through, knowing whatever we do, we are not in control. That we are partial gods, trying to wrestle our own lives under control and be happy when we know it’s impossible.</p>rsThis is a rambling after reading Freakonomics. Yes I just finished that book now.Engulfing2018-04-23T20:34:41+00:002018-04-23T20:34:41+00:00/2018/04/engulfing<p>Life takes you around.<br />
From feeling excited to feeling lethargic.<br />
From feeling like you can take over the world to feeling like you can’t even get over yourself.</p>
<p>And sometimes you get this feeling taking over you,<br />
the thoughts consuming,<br />
the idea poking you through your waking hours,</p>
<p>in the midst of all the uncertainty of what it will be.</p>
<p>But one thing it definitely feels like;<br />
far more lively than what I’ve got going right now.</p>rsLife takes you around. From feeling excited to feeling lethargic. From feeling like you can take over the world to feeling like you can’t even get over yourself.With enough sacrafices, you can be anything you want to be.2018-04-21T08:23:01+00:002018-04-21T08:23:01+00:00/2018/04/with-enough-sacrafices-you-can-be-anything-you-want-to-bers