|By Rachel Rosenberg|
Introduction
I started practicing yoga five years ago. I was tight from frequent running, living in Ohio and in need of a creative and active outlet. While I was initially drawn to the immediate endorphins from yoga, I stuck around for the variety of movement and continued challenge that it offered. I completed teacher training last summer before moving to Chicago, and I currently teach three classes per week around the city to people of all ages, places, and walks of life. Teaching is challenging in a completely new way; it forces me to think more about the big picture of the class, to create sequences that will make students feel both challenged and successful, and to foster a sense of curiosity and presence that some students may not get elsewhere.
One afternoon in my teacher training, the instructor told us that we would be leading our own practices for the first time. We would be responsible for sequencing an hour on our own, with the added caveat that we could use only beginners’ poses. We accepted this warmly, sequenced our classes, and practiced them in the hot loft studio we used. At the end, we were chastised for the better part of an hour for including poses that were too advanced, such as inversions, complex transitions, and complicated poses. This was not solely our practice anymore; we had to sequence for others, for whoever happened to join the class.
It was an important lesson: We would be responsible for others’ safety and enjoyment of the class. With this check, however, the instructor was careful to give us freedom: “Look at all of the different sequences you all made. If you are creative, it is possible to combine these beginner poses into a huge number of variations.” The challenge became crafting appropriate challenges for a variety of students, and reigning in our impulses to sneak in fancy or unfitting moves.
As teachers we become familiar with this constraint; it can be easy to get in a rut of repeatedly teaching the same poses or sequences. The style of vinyasa yoga is intentionally free-form, eschewing the rigidity of more traditional kinds of yoga. Yet there exist unwritten “rules” in most vinyasa classes: sun salutations must be used as a warm-up, Pigeon Pose signals the end of the “hard part” of class, and open-hip poses need to come after closed-hip poses. Though these rules generally serve some purpose (if only just to keep classes familiar from one studio to the next), I wanted to see if it could be possible to decrease the predictability of my classes and reinvigorate a sense of curiosity, challenge, and freshness, for my students and for myself. I also wanted to create a tool that could be useful to other teachers who may be facing similar challenges.
As an answer to these challenges of teaching, I created a Markov Chain model that “builds” a yoga class based on a few key attributes of successful multilevel classes. It feeds off of data from classes that I and others have written. It is intended to supplement a teacher’s own knowledge as he or she builds a class, serving as inspiration during times of writer’s block and challenging the teacher to think creatively. The data, model, and methodology used for this project will be discussed below.
It is important to note that there are many other challenges of teaching yoga that are not addressed here, including but not limited to first-time students, injured students, students with varying body types and learning styles, and varying student expectations. This method seeks to aid, not replace, the competent, responsive teacher.
The Data
The data set I used to train the Markov Chain (Table 1) comprised of 1500+ combinations of about 130 common yoga poses, across 40 classes (about half of which were written by myself over the past year). Each class averages about 48 poses and lasts approximately 60 minutes. Each class is listed down the column.
Though data that I created is easily accessible, one of my goals for the project was to foster creativity, so I wanted some variation to come in the form of classes written and taught by others. Several of the classes in the dataset are copies (or very close replicas) of classes taught by my teachers; for a few years, I have been in the habit of writing down clever sequences when I see them.
The remainder are classes from Yoga Journal, a well-known site that provides advice, sequences, and short classes to other teachers and students. The Yoga Journal sequences introduced quite a bit of randomness into the dataset; they are often unorthodox sequences that, while using poses that are familiar to the average student, do not always use easy transitions. This is good for the generator because it introduces combinations of poses that are unintuitive to me; this gives the generator some unpredictability and creates low-probability options for common poses to lead to less common ones.
Also, a note on vocabulary: I have stripped much Sanskrit text from the pose names in an effort to increase readability. In cases where Sanskrit names are primarily used in my classes or in others, I have included English translations.
The Model
During my initial brainstorming, I thought of several types of models that could be used to create this generator. The first was the Long Short-Term Memory (LSTM) model, a deep-learning black-box model that uses the previous character in a word to predict the next. LSTMs are frequently used for text generation; it would be possible to create a sequence generator using an LSTM with poses rather than characters. A similar but more complex model could be created with a bi-directional LSTM, which would be able to comb the sequence both forward and backward to make predictions. However, both of these methods would require a huge amount of data, which I did not have. Therefore, I decided to use a slightly less complex model called a Markov Chain, which creates powerful algorithms (like Google’s PageRank) to create my generator.
Markov Chains contain a discrete set of concrete “states.” States are connected by “edges,” which represent the probability of transitioning from one state to another. In this case, the states are the poses themselves and the edges are the probabilities of transitioning from one pose to another. For example, at the top of the transition diagram (Figure 1), there is a 33% chance of moving to Crescent Pose once in Downward-Facing Dog (downdog), and a 25% chance that, once in Crescent, the next pose would be Chair.
In discrete-time Markov Chains, the probability of moving to the next state depends only on the current state and not on previous states. While this project could also be done using a convolutional neural network such as an LSTM, a Markov Chain achieves the same result, is much more simple to describe, and requires much less data. While the transition diagram for the full set of poses is very complex, the diagram for the top 10 most frequent poses (seen in Figure 1) is a good sample of the process.
The idea here is that each pose can lead to a set of other poses; Downward-Facing Dog can move forward into High Plank, can be used as a transition into standing poses, or can be the last pose before stepping to the top of the mat and standing at the end of a sequence. Each prediction is based only upon the current state of the system. Each of these outcomes gets associated with a probability based on the data the model is fed. Then, based on the current state of the model, the next pose is chosen from the set of other poses the current pose has led to in the past, weighted by the probabilities that the current pose ends in each of its potential followers. In this way, the model is able to create a sequence that is both creative and familiar, unusual and comfortable.
There are a couple of key attributes to a “successful” yoga class, which I used to measure and improve the model while developing it. A model would be considered a success if it produced a class with the following attributes:
Variety: The class must contain some variety of poses. Assuming a 60-minute class, students will not typically want to engage in too much repetition, especially if repetitive poses are challenging. A successful class will target similar muscle groups in several different ways, crafting a class that is challenging and targeted without being boring or monotonous. Some repetition is acceptable; when developing the model, I looked for sequences that did not use the same pose more than three times in 25 poses.
Challenge: The class must be challenging to a wide variety of students. Students will come in with wide varieties of skill and experience levels; the class should accommodate both experienced and new students, incorporating modifications and options so that students can take as much or as little challenge as they need or want. The most useful model sequences are those that have a mix of safe but challenging poses like Airplane Pose, which can be modified by bending the knee or dropping the lifted leg. To achieve this attribute in the model, I included a reasonable number of poses that are both difficult yet modifiable for beginners or those with physical constraints. I also only included poses in the corpus that will be familiar to most students. Many students do come to yoga classes to relax, so I didn’t want to introduce unusual poses and inadvertently make the class stressful. While the sequence itself should have some variety, the poses included in each class should remain fairly consistent.
Accessibility: The class must be accessible to students with different bodies, abilities, and skill levels. A large amount of fulfilling this requirement falls on the teacher’s ability to offer options to the students in the moment: to put a knee down, or take a backbend with less depth, or to use a block under a hand to bring the ground closer. However, some of this also relies upon the model’s ability to contain poses that are modifiable; for this reason, I omitted poses from the corpus that would be prohibitively difficult for new students or those with injuries. Accessibility lies in balance with challenge; as my teacher taught me, it is important in any class to craft an interesting (and challenging) sequence that is still possible and rewarding for a beginner.
Rhythm: The class must have a gradual rise-and-fall shape. This means that difficult poses need some warm-up, cooling poses need to fall after the peak, and Savasana, corpse pose, should always be the final pose. To meet this attribute, I broke the corpus of poses into five classifications and ordered them as such; this process is discussed in more detail below.
Methods
All analysis was completed in Python. Initial analysis primarily involved creating a transition matrix, visualizing results from the transition matrix, and creating a class for the Markov Chain that would retrieve rudimentary class sequences.
The first goal of the project was to create a transition matrix from the data. This required quite a bit of data cleaning and standardization (for example, “open to Warrior 2” had to be changed to “Warrior 2” for consistency). I created a list of all of the states in the original data, representing all of the poses in the set. I then subtracted all of the poses that appeared only once or that were inaccessible to beginners (to help fulfill the “accessibility” goal for the project). This left a set of 132 states used for the project.
Next, I calculated the transition matrix for the states in the data set. This is a 132 x 132 matrix, with a row and column for each pose, representing each transition in the data. When one pose, m, leads to another, n, the index [m, n] in the matrix M is incremented by one. Then, each value in the row is divided by the row total to yield a probability that the current state m results in the next state n. This creates a transition matrix (Figure 2).
A heatmap of the 15 most common poses (Figure 3) shows the wide variety of options for the most widely used poses. This shows that poses like Downward-Facing Dog tend to go one of two ways – toward Crescent Pose or toward Anjaneyasana. Poses like Child’s Pose are much more versatile and thus have a high probability of resulting in one of many poses (Warrior Two, for example, can lead to any of 10 of the most common poses, as well as several of the less common poses).
Analysis of the 15 most versatile poses (Figure 4) revealed huge variation in which poses may lead to others. While there is some overlap between most common poses and most versatile poses, there are a couple of illuminating differences. For example, it is interesting that Chair Pose appears in the most versatile poses but not in most common; it is frequently used as a strong transition for other poses, but it is difficult for students to hold, so it tends to be used less frequently in public classes (which must be accessible to beginners as well as more advanced students).
On the opposite side of the spectrum, Standing Leg Raise appears strongly in the most commonly used poses but does not appear in most versatile poses. This is likely because, for public classes, Standing Leg Raise can be used primarily as a transition to Tree Pose, Eagle Pose, or Hand To Foot Pose, though in more advanced classes Standing Leg Raise would be a gateway to several arm balances and more advanced standing balances.
After creating the transition matrix, I created a class for the Markov Chain object. The MarkovChain class has functions to generate a single next state and to generate a sequence of n states based on a user-defined or random initial state. The class relies heavily on NumPy’s random choice function, which selects a value “randomly” from a list and allows each candidate value to be weighted, in this case by a probability defined by the transition matrix. This ensures that the generator will choose a next option, after each pose, proportional to the various options given to the current pose in the dataset.
The first several results (Figure 5a) were somewhat nonsensical; though they made sense based on the data, they may not have been possible to teach in an actual class. The first gets stuck in a repetitive loop of starting poses; this happened after I introduced a specific class of starting poses (more on this later), and it resulted in a class that was possibly very simple but probably not very interesting.
The second of the sample initial results (Figure 5b) definitely made more sense but still had several odd transitions. For example, Warrior 2 to Crow Pose happens twice during this sequence, though it happens zero times in the training data; this was because the matrix was being flattened over rows rather than columns. Once I fixed this, and removed accidental preferences for starting classes, sequences began to make remarkably more sense.
Model Refining
Once the initial class was built and working, I started to refine the model so that results would make more sense, possibly enough to be taught in a class setting. These fixes primarily involved classifying poses to appear in certain parts of each class and ensuring that a single pose could not appear many times in the same sequence.
The first step to take was separating the corpus of poses into five primary classes: Starting Poses, Centering Poses, Warming Poses, Standing Poses, and Cooling Poses. Examples and quantities of each are seen in Table 2.
There was also some overlap between the poses. For this reason, they all had to be manually classified. For example, Supine Twists are frequently used both at the beginning and at the end of a class, particularly when the class involves standing twists. Core work (Boat Pose, High Plank) may be used at the beginning of a class to warm up students or toward the end of a class to get a final burn before rest.
One of my success metrics was that a class have a flowing rhythm. While creativity in a class is desirable, it should not be distracting or cause confusion or awkwardness. For this reason, I built a structure into the generator. Given N number of poses in a sequence, the generator will provide one starting pose and one centering pose (a breathing exercise or simple stretch) and will fill the remaining space with 25% warming poses, 50% standing poses, and 25% cooling poses. This yields results (Figure 6a and Figure 6b) that are much more reasonable, and which very possibly could be taught to a public class of all levels and meet the criteria of a) variety, b) challenge, c) accessibility, and d) rhythm.
Visualizations
The ideal use case for this application would be for instructors to gain inspiration for sequences to use. Teachers typically engage with this kind of content in clean, clear, grid-based sets of sequences like one would find on Pinterest (Figure 7); they may also share sequences that are either exceptionally clever or visually stunning on their pages or with other teachers. It is easy to create a beautiful image; it is more difficult to deliver a particularly unique sequence that is both aesthetically pleasing and practically effective.
This type of image could be highly useful to students who practice from home and are tired of seeing the same videos or images over and over; for this audience it is also critical to display this information visually. From the standpoint of possible end users, it is important to have visually appealing designs and sequences.
The first of my grid-based visualizations (Figure 8), created using Python’s Pillow package for images, was plain and lacked both strong design elements and consistency. I didn’t like that the photos (stock photos chosen from an internet search) didn’t match or that the text was simple. I wanted the final product to be clean, clear, and approachable; I wanted it to look like something that would actually be taught.
To remedy this, I took and added my own clean, standardized photos to the same grid-based style of visualization (Figure 9) using Canva and Adobe Lightbox. This version is more likely to be seen and shared because it is clear, consistent, and free from distractions. Because it is more eye-catching, it may be more engaging to the intended audience of teachers and self-taught students, while providing examples of correct alignment in each of the poses.
In the future, the model may be extended to automate design of the final visualization. I took and saved photos of nearly every pose in the corpus; these could be added to a template in a package like Pillow or Matplotlib and retrieved along with the generated sequence list. Future steps and recommendations will be discussed in the next section.
Conclusion
Completing this project helped me to create material to teach, to visualize my own teaching via heatmaps, and to dive deep into the combination of two things I love, analytics and yoga. I have used several generated sequences in my own classes, and my teacher friends have also expressed interest in seeing generated sequences if this were in the form of a web app. The final results successfully recommend combinations of poses that are surprising, unique, and interesting and that also meet success criteria of being challenging and accessible while having rhythm and variety of poses.
This generator has potentially wide use for teachers who search for new combinations of poses and novel ways to keep classes interesting and engaging. It may also allow for people practicing at home to follow along with a sequence that they have never tried, or seen, before. There are 5.9×1026 combinations of these 132 poses, assuming 25 poses per class, so the possibilities are practically endless. It would also be possible to use the generator for other sequenced classes, such as barre, Pilates, or acro yoga.
While teaching yoga classes and simultaneously developing this model, I was reminded of how much goes into teaching yoga besides the poses themselves: the cues, the tone of voice, the gradual rise and fall of the class like the rise and fall of the breath, the modifications to most poses that must be offered to accommodate students of all body types and comfort levels, and the improvisation that comes with teaching public classes.
In the past few weeks, I have had first-time students, a pregnant student on a day that I had planned twists (this is a big no-no), and a student with bad wrists on a day that I had planned a sequence on hands and knees. These situations require the ability to think on-the-fly and adapt the sequence to the students who show up for the class, as opposed to the “ideal” student. Not every person can do every pose; not every sequence will work for every body. No human, nor any computer, can prepare for every possibility. The real value in the generator is its ability to suggest unorthodox combinations of poses and to inspire creativity in its user.
Future Work
In the future, I would want to improve the generator by making the model more complex, adding a wider variety of poses, the ability to consider specific limitations, and adding the option to choose goals or themes for generated classes.
One goal is to manually define much less of the sequence. This way, the generator would gradually be able to find a rhythmic rise and fall of a class without being specifically directed to do so. I could achieve this by using either a multi-step Markov Chain (an algorithm that would make predictions based on the previous two or three steps) or an LSTM. Because this project focuses on generation of a sequence, an LSTM or bi-directional LSTM would be a great candidate. Either of these models could be made to generate a class pose by pose rather than character by character (as would be the case in a traditional LSTM). A bi-directional LSTM could add visibility into previous poses to help determine the next; widening the number of previous steps considered could prevent repetition and aid in making sequences more novel and interesting.
I also want to allow for more complex sequences and for more difficult postures in the model. One famous teacher, Sri Dharma Mittra, recognized over 1,350 poses; this model contains fewer than 10% of his available options. A generator with more variety may tend to target more advanced students; however, those students may be more comfortable with creativity and uncertainty, and so this could be quite well-received.
Many successful classes work as well toward a specific goal, such as a peak pose or a certain body part to stretch out. I would like to implement this idea into the generator and have it, for example, generate a class that is heavy in backbends or that prepares the student for a more advanced arm balance. This also may come from feeding more data (likely labelled data would work best) and/or from using a more complex model.
Jaiswal, S. (2018, May 1). Markov Chains in Python: Beginner Tutorial. Retrieved May 22, 2019, from https://www.datacamp.com/community/tutorials/markov-chains-python-tutorial
Molina, A. (2018, November 26). Markov Chains with Python. Retrieved May 22, 2019, from https://medium.com/@__amol__/markov-chains-with-python-1109663f3678
Moore, C. (2014, April 14). 8 Yoga Poses for Neck and Shoulders. Retrieved from https://www.yogabycandace.com/blog/yoga-for-neck-shoulders
Rosen, R. (2014, April 14). Sequencing Primer: 9 Ways to Plan a Yoga Class. Retrieved May 22, 2019, from https://www.yogajournal.com/teach/sequences-for-your-teaching
Huge thanks to the teachers at YoYoYogi in Portland, OR and to Carol Murphy of Green Lotus Yoga in Cork, Ireland for teaching trainings and pose inspiration. Thanks also to Borchuluun Yadamsuren and Nancy Rosenberg for copyediting and Finn Qiao for photography.