Author: crowan26

  • Ashryver V1 Painting Classifier: Release Summary

    Ashryver V1 Painting Classifier: Release Summary

    Today, I finally finished setting up the Ashryver V1 Painting Classifier, my latest interactive web-based model, and placed a live embed on the AI, ML, and Web Projects page. You can now interact with the model right from your browser, and upload any painting you choose for the model to make predictions. Although the embed is a little small, and the formatting is still on the uneven side due to WordPress’s lack of flexibility, I hope to have these issues sorted out soon. Besides, my ultimate plan (perhaps once the final, non-prototype Ashryver V2 model comes out) is to place an active HuggingFace API instance of the model on one of my websites. I’ll have to wait until HuggingFace and Gradio sort out a CORS issue first, though, as there have been known issues across all platforms for the past few weeks.

    In this post, I’ll provide a brief summary of the training process, the overall model performance, and my future goals now that this project is “finished”.

    The Training Process

    I started working on the Ashryver V1 model about a week ago. I used the fast.ai foundational framework for this project, moving away from the clunky and cumbersome Tensorflow libraries I had been familiar with before. fast.ai is just an upper layer of Pytorch, which is the latest and most efficient machine learning library. I was blown away by how easy it is to instantly create and train a deep learning model; all it takes is just a few different code cells and some DataBlocks.

    As a brief reminder, this Ashryver V1 model is a painting classifier trained on images of 20 different Impressionistic and modern artists; I aimed for about 300-400 images per artist, yielding a total dataset of about 2,700 images (about 500 of which were split off for validation). Although this is a relatively modest dataset size, it ended up doing the job very well. I did have to go through several training runs to get the accuracy above its initial poor score of 0.60, but things turned out well in the end.

    At first I was using the resnet34 model, which was rumored to be exceptionally good at classifying paintings. This is one of PyTorch’s pretrained models, and it’s called resnet34 because it has 34 layers in its convolutional neural network. This worked out okay, but generally you want to be achieving higher than 0.60 validation accuracy for a classification model. So I decided to switch to the resnet50 model, which prefers an image size of 224 x 224 pixels and has 50 layers in its CNN. This model performed substantially better, first achieving an accuracy of 0.77 on the initial 1800-image dataset, and then 0.89 on the final 2700-image dataset.

    Once you have your data in the artist folders, this is all you need to do to train your model -- just two simple code cells.
    
    # Create the Datablock
    dls = DataBlock(
        blocks=(ImageBlock, CategoryBlock), 
        get_items=get_image_files, 
        splitter=RandomSplitter(valid_pct=0.2, seed=42), # split 20% of the data off for validation
        get_y=parent_label,
        item_tfms=[Resize(448, method='squish')]
    ).dataloaders(painting_data_updated, bs=32)
    
    dls.show_batch(max_n=20) # show a sample of 20 images that the model will be trained upon
    
    # Train the resnet50 model
    learn = vision_learner(dls, resnet50, metrics=error_rate)
    learn.fine_tune(4) # train for 4 epochs
    

    The Production Process

    Once I finished training the model and was satisfied with the result, I moved onto the production process. In the previous blog post, I touched on the difficulties I was having with HuggingFace in setting up a space for the model; I managed to resolve these issues a few days ago and get moving. The Ashryver V1 model (and any successive models) are running in a HuggingFace space, which I’ve set up and named ‘erilea-models’ to embody the fictional continent of Erilea. This space behaves somewhat like a GitHub repository, which you can clone down to your computer to add code and add models that can be represented using HuggingFace’s UI. All I had to do with this repository was drop in my pre-trained model in the form of a PKL file, and then call that file to make predictions using a simple notebook. That notebook then launched a Gradio interface (essentially what creates the graphical UI you see on the space itself) that allowed the model to make live predictions.

    This way, you don’t have to clone down the entire repository and install a bunch of insane packages to play around with the model. You can just go to the HuggingFace space (which I’ve made public), upload your own images, and have it make predictions. There’s actually even more I could do with this model, like using the Gradio API to place it on one of my own websites and use some custom JavaScript to make it look a bit different. However, the current HuggingFace solution works perfectly fine for this V1 model; I may consider switching to a more advanced API solution for V2.

    Next Steps

    Speaking of V2, let’s take a final look at my next steps for the Ashryver model. I’d like to improve the model’s reliability on Matisse paintings; right now it continually misclassifies Matisse’s tape drawing The Bees. I’m not sure how to deal with this one, as it isn’t a “painting” in the traditional sense, but users might still want to predict with that image. There have also been some isolated issues with other artists, where incorrect predictions crop up every so often.

    For V2, my plan is to find some way to deal with the ridiculous watermarked images or those that contain overlaid text in the training process, as these really seem to be sabotaging the model. I also would like to add a bit more data if possible, maybe for certain artists only, so the model can get a more comprehensive view of what’s going on. I may also add some additional artist categories (although this is optional), and I would definitely like to add a “sister” model that is designed to recognize the artistic era or period of a painting, and use that model to make “backup predictions” of a painting’s era in addition to the artist, in case you give the model a painting that it’s not familiar with. These enhancements should make the Ashryver model much smarter overall as a painting classifier; once I get these improvements done, I should be ready to move onto Unit 3 of the fast.ai Practical Deep Learning course.

    Don’t forget to check out the model on HuggingFace, or go to the AI, ML & Web Projects page to play around with the widget. Stay tuned for more updates!

  • Deep Learning Debacle: Deploying the Ashryver V1 Model (Painting Classifier)

    Deep Learning Debacle: Deploying the Ashryver V1 Model (Painting Classifier)

    Today (and this entire week) has been quite the adventure when it comes to deep learning AI models. I finally got off the ground on my latest project, the Ashryver model (the easy-to-remember codename for the 20-artist painting classifier). After building it locally with Jupyter Notebooks and Kaggle, I advanced to the next unit in the fast.ai Practical Deep Learning course, and started attempting to deploy it on a HuggingFace/Gradio space…

    …and promptly entered into a world of calamity.

    Creating an account on HuggingFace and setting up a space was pretty easy. But that was just the tip of the iceberg, as you might imagine. After that I had to figure out a way to set up an API key, clone HuggingFace’s Github-adjacent-but-not-really-Github repository down to my computer, add my pickle files for the Ashryver model, and deal with all the humongous files and conflicts. This quickly spiraled into hell. First of all, the API keys kept getting “into a stuck state” when attempting to commit changes to HuggingFace; apparently HuggingFace had deprecated a core feature that allowed users to authenticate with their HuggingFace password back in 2023, and you now had to use your cryptic API key. So I was forced to generate the in-universe “aelin” API key and use that, which fortunately worked.

    However, that wasn’t the end of the troubles. I then encountered issues committing any changes at all to HuggingFace, due to binary file limitations and Git LFS complications. At this point I was engaging in a lengthy back-and-forth conversation with Google Gemini, trying to figure out the best course of action for what I was facing. Every time I tried to turn on LFS or add the files, pushing any staged files would just lead to more and more errors. Eventually I just gave up and followed two core pieces of ML management advice: never upload your .PKL files or dataset files to source control because they can be a target for malware and bloat your repo. For now, I’m just leaving them untracked on my laptop, and not committing them to HuggingFace. After all, the model will be able to run live; users shouldn’t need to poke around in the source code this time.

    Speaking of poking around in the source code and my future plans for the Ashryver architecture, let’s dig into those topics now…

    Future Plans, Links, and Naming Conventions

    The current state of the HuggingFace space, displaying all model files

    Click to view the current HuggingFace space, which is still very work-in-progress.

    You may have noticed the rather unconventional name of the space itself, erilea-models, and the interesting name for the painting-classifier model architecture, Ashryver. If you’ve really been poking around in the Files section of the HuggingFace space, you may have noticed references to an “Aelin” or “Sam Cortland”. If you’re really receptive, you may have made the proper neural network connections and surmised that these are characters from a fictional series.

    If so, congratulations. To make things more interesting, and detract from the tradition of naming repositories and models boring things “like Testing Area 1 and Deep Learning Architecture System Version 1”, I decided to spice things up and give this space and its models some creative names. These are not so much “original” as “easy-to-remember”, which makes it more convenient to key in GitHub commands when all your filenames and model names are simple names. I plan on naming each successive model I release after a different character, improving upon each one with clear version numbers.

    As for my plans at the moment, I intend to continue working on getting the Ashryver V1 model into production. When that’s done, you’ll be able to go directly to that HuggingFace space (linked above), upload your own paintings, and have the model instantly make predictions. Right now, although the model has consistently been getting 0.89 accuracy on test runs, it still makes the occasional error when it comes to Henri Matisse’s paintings and tape drawings. This is an issue I plan to correct in Ashryver V2, which is where I might also introduce more artist categories. For now, though, all my time is probably going to be spent on getting Ashryver V1 into production.

    What all this means is that users will no longer have to clone cumbersome GitHub repositories and figure out ways to get my code to work on their very different machine, which sounds like a recipe for disaster. I’m planning on uploading my past models into that same HuggingFace space as well, or maybe a different one to improve organization. I’ll at least put the CIFAR Image Classifier on there, and maybe even the QuickDraw model if I can get it to work. After that, I intend to work on some more computer vision models, deep learning projects, and put something even more substantive than Ashryver out on the web.

    I’ll probably put up links to my various HuggingFace spaces eventually on this website, and they will serve as the “showcase sites” or portfolio pieces for the various AI models. This is what I’ve been working up to for quite a while, and it’s good that I’ve finally started working on a way to get these models into production.

    Well, that’s all for now on the deep learning front. Stay tuned for more calamitous updates!

  • Site Update: New Creative Works, Comments, and Inspirations

    I made some major changes to this website’s content and aesthetics this week, which you may or may not have noticed. First, I modified some of the fonts that are used, and installed a new minimalistic font that I felt went a bit better with the site’s theme. That font is now used on some of the page headings and titles across the website. Second, I completely revamped the Short Stories & Poetry page to better showcase my various poems and stories in a grid layout. Each piece has its own Inspirations & Comments section, where I attempt to convey what led me to compose the piece, and the meaning behind it.

    I’m still working on adding more of my poetry and short stories, but I have a semi-comprehensive list on the Short Stories & Poetry home page. In fact, I’m working on a rather unusual coming-of-age short story right now; it might be the submission for the 2027 Scholastic Art & Writing awards. Once that’s done, I’ll attempt to upload it to the website, and attach some comments. I’m contemplating adding a background-header sort of picture to the short stories & poetry page, similar to the large one on the homepage. However, I’d like the text to be overlaid upon the background image, and thus far, I haven’t found a way to do that with clunky WordPress.

    I’ve also made some minor tweaks to the Musical Works page, changing the names of some tabs and linking some of the most recent compositions. As a quick note, it is now possible for people to fill out the site’s Contact form to obtain copies of the scores; there is a one-page preview image available for some of the more recent pieces and a button to get to the Contact form. I don’t plan on charging money for the scores; this is just a mechanism to prevent bots (or people) from coming on and scamming the scores to a wide variety of unauthorized individuals.

    Deep Learning Course: Finally, Some Progress

    A code cell and output from the fast.ai painting classifier, displaying some sample photos that will be used to train the model.

    After about a week of screaming and coming close to quitting the entire course, I finally started making some progress on the fast.ai Practical Deep Learning for Coders course. Yesterday, I finished training the first major project, which is a painting classifier designed to identify the artist of a given painting image. Right now, I’m training it on the works of twenty different Impressionistic artists, with some more modern painters also included. I’m amazed at how much easier it is to use PyTorch to create a classifier than Tensorflow; all you need to do is pull down your images, create a DataBlock, and initiate your learner.

    The reason why I was getting so blocked on this model before was the stupid DuckDuckGo search issues, combined with issues with Kaggle. This sort of classifier relies on pulling down batch images from the DuckDuckGo search API, which is flaky at best and catastrophically time-consuming at worst. So why am I using DuckDuckGo, of all search APIs? Because Microsoft has gone bad and locked their Bing Search API behind a paywall. In a similar way, Google’s search system requires several different API keys, extensive verification, and massive amounts of credentials that make no sense for a small project like this one.

    At first, I thought I was going to have to quit out of this project and find a different data setup that didn’t rely on DuckDuckGo. But then, on Monday morning, I “magically” stopped getting 403 Ratelimit errors, and started downloading images as normal. So I jumped on the opportunity and immediately trained the model to completion with all 4,000 images; after doing some brief testing, it looked like the model was actually pretty good. I’m going to obtain some empirical data on the model’s performance–accuracy, loss, and others–shortly, and use that data to experiment with some different model architectures and data configurations.

    I also did some minor refactoring of the model’s code, which is now available in my official fast.ai course repository on GitHub (though I don’t recommend doing anything with it yet, as it’s still very preliminary, and the repo is still a mess). In unit 2 of the fast.ai deep learning course, I aim to release this painting classifier via a web API so you can interact with it directly; when that’s done I won’t have to deal with muddled GitHub repositories, local files, and broken Kaggle runtimes because the model is released into production already.

    Well, that concludes this regular site update. Stay tuned for further news on AI projects and creative pieces!

  • Update: New ML Courses and Deep Learning Exploration

    Update: New ML Courses and Deep Learning Exploration

    Subscribe to continue reading

    Subscribe to get access to the rest of this post and other subscriber-only content.

  • Reflection: 2026 Chamber Music Perspectives Workshop

    It’s been quite a busy past couple of weeks. The 2026 Chamber Music Perspectives composition workshop mentioned in the previous blog post has now ended, so it’s time to dig into a brief reflection on what happened and the interesting skills I learned during this camp. This will be a “bite-sized” reflection, an interesting technique to explore that forces you to compress your thoughts into a succinct 200-300 words.

    Collaborating and cueing other musicians

    This is probably one of the most important and valuable skills I took away from this workshop. When performing a piece, whether in rehearsal or otherwise, you must take care to Breathe Together in order to inform the other musicians where you are, and when you’ll be starting. If you don’t breathe together, you’ll end up starting off or getting off later in the piece. Another important part of this skill is maintaining a good balance- you don’t want too much of one instrument to soak through and disrupt the careful balance of the ensemble.

    The conductor will usually stop the situation and flag players that are disrupting this sound, but it’s important to recognize imbalances on your own so you can correct them by adjusting the playing.

    Know what the instruments can and cannot do

    This is more of a composition-related skill. When composing a piece for unfamiliar instruments (whether that’s a cello or a ranat ek), you have to be aware of the limits of the instrument, including the range, the intervals, the restrictions on playing techniques, and so on.

    Some instruments can’t play chords with four or five notes all at once without stranging the note or turning it into an appogiatura. I attempted to compose a piece containing several strange intervals that were not only difficult to play, but were very un-violinistic and un-cellinistic. I then had to go back and update this intervals, with the specific techniques and abilities of the violin and cello in mind, and use fourth and sixth intervals instead that are more commonly used. Other individuals who attempted to compose for unfamiliar instruments composed pieces that were on the more boring or uninteresting side, primarily because they were unable to leverage the specific powers of thsoe instruments.

    Improvisation isn’t just about making random screams in the ensemble

    When we started the Improv game near the beginning of the workshop, not knowing what the rules were and how to execuate a fully improvsed piece, we just thought it was about making random noises without any specific rules. However, it turned out that this wasn’t the case at all. Improvisation is actually about listening to what’s going on around you in the ensemble, and changing things up to respond to the other players. For example, in the piece we learned as the Improv game–a special arrangement of An Eye for Optical Theory by Michael Nyman–some of the violinists had the option to take off on their own and do a solo. In response, the four hands piano might end up dropping out temporarily to let the violin have a moment. If one of the cellos started playing a noisy pattern, the piano might double that pattern to increase the volume. These are the kinds of things that actually make Improv games organized and fun.

    Concluding remarks

    These bite-sized skills and interesting points I picked up over the course of the chamber music workshop don’t just apply to these specific pieces or ensembles. They’re useful for all kinds of musical collaborations and composition projects, and they enable you to see the larger picture when it comes to composing music or playing with others. Through this workshop, I discovered some extremely useful insights when it comes to how string instruments are played, as the composition I created was performed by actual string players. The improvisation games added a nice touch and extra material to the chamber music performance; I also learned several new composition techniques that take advantage of the unique abilities of all instruments.

    Stay tuned for more updates and news!

  • Summer Update: AI Models, Flames of Rebellion, Chamber Music

    Summer Update: AI Models, Flames of Rebellion, Chamber Music

    With the academic year classes having come to a conclusion, the summer has officially started. I made a goal for myself back in late April, when things were still extremely busy, that I would try to push harder on the fourth and final book in the Flames of Rebellion series when classes ended. I had just published Book 3.5 on Amazon and was feeling motivated to wrap up the series; Book 4 already had about 9,000 words of content in it from the previews I had written.

    Now, as of late May, I’ve mostly achieved that goal. Over the past few days, I’ve put down over 3,000 words into Book 4, The Conquest of Piece, reaching over 12,000 words. Things have gotten significantly more interesting than the first few chapters, and I’m using a rather chaotic mind map with sticky notes to keep track of this book’s plot. In a couple of chapters, the plan is to create a serious plot twist by adding an evacuation situation of the Tranquility’s Ozridia base due to a bomb threat (or possible actual bomb). I’d also like to fully develop and flesh out Jonathan and Lily’s romance, as this is the last book now. I’ve already added some romantic cues in the first few chapters; I intend to make Jonathan’s upcoming birthday party the culmination of their relationship.

    On the subject of artificial intelligence and machine learning, I’ve moved onto a new Kaggle challenge: house price prediction. After failing horribly to get the sentiment analysis model to work, I stopped trying to extract answers from Claude and pivoted to something else. This house price prediction challenge involves the creation of a model to predict the prices of houses in the Iowa area based on various attributes, like number of bedrooms, pool quality, fence presence, square footage, etc. The dataset is quite large; there are seventy-nine features available, all with varying correlations to the central SalePrice target variable. So far, I’ve analyzed the data using some Seaborn scatterplots, generated correlation matrices to see which features to encode, and gotten started on cleaning the data (which has involved deleting outliers and imputing NA values). I can already tell that this challenge, while still labeled “introductory”, is slightly more intensive in terms of data preparation and analysis than the Kaggle Titanic challenge.

    I’m also loosely working on the virtual card deck project, where I’m attempting to create a virtual cards app that people can customize to fit their specific needs. Right now, I have a modal where you can input the number of decks, the name of each deck, the background art, and the titles/descriptions for the cards in the deck. Most of the data is persisted, and the modal seems to be behave as expected. However, I’ve been running into trouble getting all the data to save to local Storage, not just the number of decks. I’ve asked lots of questions of Microsoft Copilot, but no real results have come yet. This project is one of the most complex undertakings for me yet when it comes to web design, HTML, and JavaScript, so I’m not expecting it to work perfectly for many more months.

    Tomorrow, I’m starting a chamber music perspectives (CMP) camp, which will run for about a week and a half and take place from 1:00 PM to 5:00 PM. This camp involves not only a series of small ensemble performances (piano trio and string quartet size), but also some composition masterclasses and the opportunity to compose a piece of your own for the ensemble to play. This will be the “Final Project”, as it’s been dubbed; it looks like this camp will be very fast-paced and packed with activities. This final project needs to be started from scratch on day one and completed by the tenth day, giving us less than two weeks to compose a fleshed-out, playable, and refined 3-5 minute piece. For context, it usually takes me about two months to compose a high-quality 5-minute multi-instrument piece; however, I only work about 45 minutes every other day. At this camp, we’ll likely spending at least an hour and a half every day on this final project.

    Some other miscellaneous endeavors from the past couple of weeks include an AI radio show, which I just finished today. This is the third such show I’ve completed now (well, fourth, if you count Why You Should Be Afraid of Physics Class, a 20-minute-long drama), and I’m using Fish Audio to generate all the voices. These shows generally run for 25-28 minutes, and this latest episode contains the guest host Sal Khan. You’re probably wondering: how did I possibly get Sal Khan to appear on a low-level AI-produced radio show? Because this isn’t an AI-produced show: the voices are all AI. I do the editing and the generating of the voices. Sal Khan is a cloned voice available on Fish Audio, and I’ve cloned a few others for use in these episodes. It’s quite an interesting process, actually. I’ll be using DaVinci Resolve’s Fairlight studio instead of the clunky Audacity to edit this show together. Hopefully it won’t be too much of a shock to use. (The video editor portion of DaVinci Resolve is actually quite easy to learn. I’ve put together quite a few videos with it now).

    Well, tomorrow’s going to be quite a busy day, with the starting of the CMP Chamber Music Perspectives camp. I’ll try to work on the AI models this weekend if possible, in addition to the usual (shortened) BeamNG Roleplay sessions. Stay tuned for more updates.

  • Kaggle Titanic Random Forest Model: Summary and Comments

    Kaggle Titanic Random Forest Model: Summary and Comments

    This month, I finished the final series of hyperparameter tuning and optimization on the Kaggle Titanic Random Forest Model. I constructed this model for the Kaggle Machine Learning from Disaster challenge, which is an introductory-level machine learning prediction competition. Users are supposed to construct a model that predicts whether or not a given person, among 800 people, survived the Titanic shipwreck. This was my first attempt at crafting a new AI model from (close to) scratch, given a fully-featured dataset. Although I probably could achieve higher Kaggle scores by trying out different architectures, I didn’t want to spend the entire year on one challenge, and left the model at a 0.788 public score.

    In this post, I explore some of the code and the inner workings behind the Kaggle Random Forest model. I also dive into a few of the challenges I encountered along the way. If you’d like to work off the model framework I’ve put on GitHub, you can feel free to do that, but I’d strongly recommend against it because I haven’t yet taken the time to make the code fully understandable and customizable. (Also, a serious Kaggle competitor will likely strive for a better model architecture that achieves a higher public score, so please find your own setup).

    Model Setup: From Logistic Regression to Random Forest

    Initially, I started off with a simple logistic regression model loosely based on a Kaggle starter tutorial. For the most part, the tutorial model didn’t involve any careful feature engineering, and primarily relied on the passenger name, class, sex, age, and fare (several of the most important features in the dataset). It used elementary techniques to learn patterns between these features and the survival, and this base model only achieved an accuracy of about 0.74 inside the code cell.

    Immediately realizing that I needed to do more with the model, I switched to a Random Forest architecture, as it seemed to be highly recommended for binary classification problems like this one. The important part about Random Forest is that the model automatically determines which features are the most important, regressing through all the available features in a large “tree”. So I was able to feed it a wide variety of featuers and have it discover the most important connections: the prominent features ended up being Sex, Pclass, and Fare/Age.

    The percentage of women who survived the Titanic shipwreck (in the sample data) was significantly higher than the percetange of men.

    As shown in the image above, I was able to discover that a significantly higher percentage of women survived than men (74% vs 18%). Historically, this was due to the “women and children first” directive on the ship. I used this basic pattern to train the original model, and the more advanced Random Forest model uncovered this connection as well. I prioritized the Sex feature (in addition to Pclass and Fare/Age) when feeding the features to the model.

    Advanced Feature Engineering: the Cabin Data

    When the Random Forest model based only on Sex, Pclass, and Fare/Age didn’t perform very well, I realized I was going to have to do a lot more feature engineering. After all, the data contains several features, ranging from the number of parents and children aboard the Titanic, to the passenger’s Ticket number, and the cabin number where the passenger stayed.

    Since the location of the passenger aboard the vessel seemed like an important data point, I constructed the next round of feature engineering around the Cabin column (and created a few new helpful features from the existing data, like IsAlone or FamilySize). I learned quite a bit about proper feature engineering practices in the process; with the help of Copilot and some Google searches, I was able to construct new engineered data for the model to train on.

    I also built a function to make observations on the correlation between people with no cabin data (we don’t know where they stayed) and passenger class (1st, 2nd, or 3rd class). I wrote these observations at the top of the rather long code cell shown below, and this info actually ended up being helpful in situations where the cabin data was missing.

    A sample of the very long code cell used to engineer the Cabin feature data

    Hyperparameter Tuning (with RandomizedSearchCV)

    After retraining the model with the engineered Cabin data, I was getting much-improved accuracy in the notebook (about 0.82 vs 0.79), but the Kaggle score wasn’t changing. I figured I was going to have to do some more serious hyperparameter tuning to boost the score, which usually only reacts to large-scale prediction changes.

    At first, I attempted to tune most of the important parameters (n_estimators, max_depth, max_features) by hand, doing Google searches to figure out the best values for a Random Forest model. But this quickly became tedious, as I had to retrain the model every time I made a minor change so see if it did anything. Instead, I switched to RandomizedSearchCV, which is an algorithmic method of finding a model’s best parameters povided by the Python library sklearn.

    Using RandomizedSearchCV was relatively simple (as shown in the code cell below). All I had to do was set up a parameter grid, where I told RandomizedSearchCV which hyperparameters I wanted it to optimize. Then, I asked the algorithm to fit on the training datasets of the model, and then output the best parameters using a simple print() statement. From there, I was able to go back and drop in the fine-tuned parameters to the final model. The parameter-discovery process did take a little while, so I had to set n_jobs = -1 to ensure the algorithm ran on all CPU cores.

    After the hyperparameter tuning, the model achieved 0.84 validation accuracy in the notebook, and a Kaggle public score of 0.788, which is in the mid-to-upper-tier for these kinds of Random Forest models. I haven’t been able to move above this score since then; however, if I manage to do so, I will update this blog post with those details.

    The model’s final accuracy, precision, and recall report after the final stage of hyperparameter tuning.

    To view this entire Titanic project (and the code files) on GitHub, click here. However, the code is primarily intended for reference, not for drop-in usage in a brand-new project.

  • Technology and Innovation: A Brief Remark

    Technology and Innovation: A Brief Remark

    This week in chemistry, I discovered the benefits and drawbacks of fuel-cell technology and photovoltaic energy. However, the chemistry textbook we’re using is more than a few years out of date—and when it comes to modern technology, even the smallest time frames can make a huge difference.

    Although the primary fuel cell technology mentioned in the book (Molten Carbonate Fuel Cells, or MCFCs) are still being improved upon, the industry’s current focus centers around Proton Exchange Membrane fuel cells and Solid Oxide (SOFC) fuel cells. These kinds eliminate the need for precious-metal catalysts like platinum, solving a key problem that the outdated chemistry textbook mentioned. The basic chemical concepts behind fuel cells and their reactions still apply—and will likely remain the same. But the ways in which we stretch and bend these concepts, in order to push past limitations, are constantly evolving.

    I noticed that the same is true for photovoltaic energy, or solar cells. Instead of relying on expensive interactions between the two main types of silicon, N and P, current PV technology has switched entirely to N-type crystal silicon. No longer bound by the constraints of costly materials like platinum, modern PV cells are able to achieve efficiencies between 22% and 26%, with certain cutting-edge types pushing 30%. (This may not sound very appetizing, but consider that when our chemistry textbook was written—sometime in 2023—the industry standard was only 15%).

    The bottom line? If we can master the basic chemical or physical properties behind a new technology, then there are thousands of ways we can continue to push the limits of our world and bend our knowledge to the limits. As Steve Jobs demonstrated with the revolutionary Macintosh in 1984, anyone can build a “satisfactory”, utilitarian computing device. But only the best—only those who think differently—can take fundamental concepts to dizzying new heights.

  • AI & Machine Learning Project Update: A Fresh Start

    AI & Machine Learning Project Update: A Fresh Start

    Today I returned to the AI & Machine Learning project repository I’d worked on intermittently over the past few months. It’s a GitLab environment with some Jupyter Notebooks and AI projects created on an excursion in summer 2025. I’d managed to make some good progress towards a finished QuickDraw Webcam project last year, but after that, things sort of fell apart. Now, returning to it many months later after system updates and code changes, I found that many of the Jupyter Notebooks (or Stupyter Notebooks, if you will) no longer worked.

    There were issues like missing packages and unresolved imports, likely arising from the three conflicting Python environments I’d foolishly installed. In general, things were a mess. I first tried switching kernels, enabling the older but sometimes more trustworthy Python 3.11.4. When that didn’t work–and the problems only got worse–I decided to break out the Google Gemini AI, asking for assistance on installing pip (which had mysteriously uninstalled itself from the OS) and getting up to speed on the issues I was experiencing.

    Unfortunately, nothing worked. I ended up having to go through and create a new Python virtual environment in the ai-projects directory, in hopes that it would clear things up a little bit. However, I was dreadfully wrong. The problems again only got worse, and Python threw numerous errors in the terminal upon attempting to run the malfunctioning code cells in the Jupyter Notebooks.

    So I decided to start from scratch. I went to GitHub, logged in, and dug up an old, empty Machine Learning repository I’d created many months ago. Since it was empty, I figured it would be the perfect candidate for a new project. I copied and pasted one of the malfunctioning Jupyter Notebooks from the other environment, and this time decided to set up a new Python virtual environment running version 3.12.2. This was a fresh repository without three different kernels or multiple packages installed, so the virtual environment cleared things up immediately. A virtual environment of Python is separate from the system install on your PC, so I was able to manually install all required AI-related packages without causing corruptions and dependency issues anywhere else.

    And that’s where we are now. I intend to continue working on a product review sentiment analysis model, in which an AI is apparently supposed to predict if a review is positive or negative based on certain keywords. After that, I’ll probably use the repository to explore more advanced AI concepts, possibly with the assistance of an online course. It’s simply supposed to be a general space where I can experiment with machine learning, and so far everything seems to be working. (We’ll see how long that lasts).

    Site Updates & Other News

    I’ve been trying to get some more pages created on this website for the past few weeks. I actually did manage to make some progress on the Short Stories & Poetry page, but WordPress had been acting stupid and I haven’t yet settled on a good design. I’m thinking about simply creating a series of dropdowns containing short story content, but that seems prone to issues and not a very good setup. So, you might find yourself looking at a completely separate blog on that page, or a gallery-style grid of clickable images and media. We’ll just have to see.

    I also started on a wireframe of the concept NoteMaster software, which is supposed to be a high-quality and low-priced alternative to other music notation softwares. The wireframe is coming along in Figma, and it’s going pretty well so far. The trickiest part will be the design of the scoring interface, and this will really test the features in the Figma free plan. (When the wireframe is complete, you can expect to see some prototype design photos on here and the Rustler website).

    With the New York trip over, and no more serious events on the calendar until late March, things are going along pretty smoothly. There are a couple of piano recitals scheduled for mid-April, but other than that, musical activities have slowed down significantly. I’m working on a couple of essay-writing contests and the NowBeat Commission and Concert (form now submitted). Flames of Rebellion: The Reckoning of The Past (book 3.5) is now in review, and the book cover is pretty much done. Progress on book 4 has stalled, but that’s normal for the next book in this series.

    Stay tuned for more information on the AI projects. Hopefully, the virtual environment remains working.

  • 2026 Ivy League Tour Log 3: UPenn and Princeton

    Here we are on the final log of the 2026 Ivy League Tour (although there might be a special fourth log containing some additional information about Columbia and Juilliard). On Wednesday, we visited the University of Pennsylvania and Princeton, which are about an hour and a half away from each other.

    I was thoroughly stunned by many aspects of Princeton, ranging from the breathtaking campus design, to the versatile student programs, and the expansive classrooms and halls. UPenn was slightly less memorable and notable, and ranked more among Brown and Harvard. Overall, it seemed like Princeton surpassed Yale in all categories, although the two colleges are still pretty close in overall score.

    University of Pennsylvania (Score: 3.8 / 5)

    Located in West Philadelphia, UPenn’s campus is about the same size as many of the other universities we toured. The university featuers many different departments and divisions, ranging from Penn Arts and Sciences to the Wharton school to Penn Medicine. On the tour, we entered some of the buildings from the Wharton school–and ate lunch there–and peeked inside the Penn visitor center.

    On the whole, though, I found the UPenn campus to be very bland and not as memorable as any of the other universities. I also didn’t get a very strong sense of values or missions from the university’s message, and I was left feeling a little unsure about the principles UPenn wants to uphold. With MIT, for example, there was a clear message of curiosity, authenticity, and imagination spread throughout the campus and its mission statements. UPenn, however, didn’t seem to have any of that. This was the primary reason for its lower score.

    Below, find a few photos of the UPenn campus that we took, some inside the Wharton school buildings and others inside the university’s visitor center.

    Princeton University (Score: 5.0 / 5; Tour Winner!)

    Our final elite university on the tour was Princeton, located in the aptly-named town of Princeton, New Jersey. It was about an hour-and-a-half drive from UPenn, and the trip took us through some remarkable winter scenery in the countryside. When we arrived, it wasn’t quite as cold as it had been at Harvard, but many of the trees were still decked out with snow, and the ground was frozen in many places.

    Almost immediately it became clear that Princeton wasn’t fooling around with its campus layout and architecture. The main gates were tall and ornate, and a colossal hall loomed just inside the entrance with grandiose, neo-gothic design. (There’s a myth about the main gate of the campus, in fact, that anyone who walks through it will never graduate and will be cursed with having to study for the rest of their life. So please make an attempt to walk through one of the flanking side gates). The campus was large and contained several open green spaces, and even a few paths where maintenance carts, small vehicles, and bicycles could move.

    We happened to have a student tour guide while visiting Princeton. He was a Mechanical Engineering major, and gave us some key insights into his admissions experience. Although his stats had not been impressive on a national level, he told us, his personal statement essay was so impressive that it enabled him to get into Princeton and one other college on his application list. However, he’d applied Early Decision (ED), so he was forced to attend Princeton. He definitely wasn’t regretting his choice, though; campus life was extraordinary with small eating clubs available to participate in for extra social stimulation.

    Our large amount of alloted time for this tour allowed us to enter several buildings, including a breathtaking sanctuary with ceilings at least eighty feet tall, and Room 302, where Albert Einstein once gave a lecture. We also walked past the many eating clubs on campus, one of which our tour guide was a member of personally. We also discovered that Princeton has a prominent music department, making the university another promising possibility in similar ways to Yale. However, you aren’t allowed to double major at Princeton, but that’s probably for the better.

    Overall, I found Princeton to be one of the most impressive universities on our tour, if not the most impressive one. Combined with its stunning campus layout, flexible programs, and outside social opportunities, this was definitely a more-than-notable college. Enjoy our many photos below!