{
  "id": 461264,
  "title": "#274: Learnings from generative models",
  "url": "/competitions/open-problems-single-cell-perturbations/discussion/461264",
  "author_name": "yhsure",
  "post_date": "2023-12-13T11:32:26.582000",
  "votes": 3,
  "comment_count": 0,
  "views": 0,
  "content": "<h1>Learnings from generative models</h1>\n<p>Disregarding good MRRMSE scores for this particular dataset, I focused on generative models for the single-cell transcript data. These generative models can be used in a larger variety of research tasks than the regression models that dominated the competition. Few teams attempted this route, so I believe one writeup is warranted.</p>\n\n<h2>1. Integration of biological knowledge</h2>\n<p>To handle the count data, I use a negative binomial (NB) posterior. Like the Poisson, this takes sequencing depths into account. The NB further accounts for overdispersion, and is empirically found to fit scRNA-seq data well — also outperforming zero-inflated versions (<a href=\"https://academic.oup.com/bioinformatics/article/36/16/4415/5838187\" target=\"_blank\">Grønbech, 2020</a>). The NB density for observing $k$ gene counts is parameterized by mean $m$ and dispersion $r$:</p>\n<p>$$ {NB}(k;m,r) = \\frac{\\Gamma(k+r)}{k!\\,\\Gamma(r)} \\left( \\frac{m}{r+m} \\right)^k<br>\n\\left( \\frac{r}{r+m} \\right)^r $$</p>\n<p>The generative model outputs the mean scaled by the max count for the sample, while one $r$ is learned for each gene (sample independent). </p>\n<p>Since the ATAC data does not have cell ids matching the scRNA-seq data, I did not integrate it into the model. </p>\n\n<h2>2. Exploration of the problem</h2>\n<p>In principle, generating cells in the 'requested' cell_type/compound pair and feeding them to Limma seems reasonable. However, running the provided <code>compute_de.ipynb</code> notebook gives a mismatch with the p-values of <code>de_train</code> (also after taking the <code>excluded_ids</code> file into account and fixing metadata slightly). This means that even if the generative model learns a perfect reconstruction of the training data, it will still have an MRRMSE offset of 0.0325. Further, limma is sensitive to the amount of cells in each covariate group, making the sampling of realistic cell counts with corresponding metadata non-trivial. These aspects favored directly regressing the DE results.</p>\n<p>From simple statistical measures, NK cells were found to overlap best with the cell types in the private test set. This was further noted by <a href=\"https://www.kaggle.com/competitions/open-problems-single-cell-perturbations/discussion/457793#2541075\" target=\"_blank\">others during the competition</a>. </p>\n<p>There is a large proportion of cells from the positive control compounds compared to the rest of the data; I found it better to remove these cells from the dataset. It might further be useful to remove outlier compounds with few cell measurements. </p>\n\n<h2>3. Model design</h2>\n<p>I experimented with the Deep Generative Decoder (DGD) of <a href=\"https://arxiv.org/abs/2110.06672\" target=\"_blank\">Schuster &amp; Krogh, 2023</a> and found it to achieve better scores (PB 1.39) than an NB-VAE variant (PB 1.81). Both types outperformed a traditional VAE on normalized data subsequently rescaled back. In each case, I maximize the ELBO using Pytorch with, e.g., NB negative log likelihood as reconstruction error and with early stopping to prevent overfitting. Annealing the KL term from 0 to 1 over 50 warmup epochs avoided some cases with exploding loss. The encoder/decoder architectures are fully connected networks with ReLU activations and three layers transformings the dimensions to [5; 256; 1024; 18211]. Models are visualized on the diagram below. </p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F7642360%2Fc8afef4f94c3d7e72d9a91a393a13d7a%2Fvaedgd_withC_nontransparent.png?generation=1702466649193114&amp;alt=media\" alt=\"\"></p>\n<p>When predicting compounds as a task, the latent space separates into meaningful clusters, but the model does not generalize well for compounds in the test set (perhaps due to the large imbalance of cell type classes). For the below image, a latent space of 2 dimensions was used with the DGD model — the clusters highly correspond to compounds, cell types and donors. </p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F7642360%2F5e40babd13a2a0ee7033e2bb453b7362%2Fclusters.png?generation=1702466667622762&amp;alt=media\" alt=\"\"></p>\n<p>Conditioning the generative model on the covariates necessary for the limma analysis (cell type; plate name; well) gave best results on the PB. These conditional variables correspond to the <code>c</code> in the earlier model overview. In practice, the models are thus a conditional-DGD and a conditional-NB-VAE, where the one-hot-encoded covariates are appended to the data before encoder and decoder forward passes. After conditioning, the cells do not form distinct clusters based on the metadata — a natural effect of the conditional variables (<a href=\"https://agustinus.kristia.de/techblog/2016/12/17/conditional-vae/\" target=\"_blank\">Kristiadl, 2016</a>). Instead, they appear to be completely mixed together in a N(0,1) distribution (see github notebook). To generate a realistic number of cells and library sizes, two random forests were trained using the covariates as one-hot features; this step is important to get better p-values from limma.</p>\n<p>Random forest regression directly on the pseudo-bulk counts yielded a better score (PB 1.01), while bleak compared to just the zero-matrix (PB 0.9) or an out-of-the-box XGBoost on the p-values (PB 0.62) with one-hot-encoded sm_name/cell_type features. Interestingly, when combining the regression XGB submission with the DGD submission, performance improved slightly (0.002 improvement). p-values from the generative AI -&gt; limma pipeline had much larger variance than XGB p-values (see figure below), which could be reduced by averaging over multiple runs, but time did not allow for this. In general, these results provide a large degree of skepticism towards either 1) the generalization ability of generative models for this data, or 2) the metric used. </p>\n<div>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F7642360%2F3081e6596cde902115fea777e4d397d2%2Fhistogram.png?generation=1702466720038500&amp;alt=media\">\n</div>\n<p>The performance of models already in the perturbation literature such as scGen (<a href=\"https://www.nature.com/articles/s41592-019-0494-8\" target=\"_blank\">Lotfollahi, 2019</a>), scTenifoldKnk (<a href=\"https://www.sciencedirect.com/science/article/pii/S2666389922000010\" target=\"_blank\">Osorio, 2022</a>), and CellOT (<a href=\"https://www.nature.com/articles/s41592-023-01969-x\" target=\"_blank\">Bunne, 2023</a>) would require more engineering to generate cells feasible for good limma p-values -- I did not have luck in initial experiments, which is why I sticked to the more direct approach of cell generation conditioned on the covariates. </p>\n\n<h2>4. Robustness</h2>\n<p>A validation set is always needed during the stochastic training of the model — we cannot be sure that by running it again with a full dataset that the training will go in the same way. Here, I used a small subset of randomly sampled points (3%) but manually including cells relevant to the test set in the training set. These relevant cells have either cell type or compound occurring in the test set. Randomly sampled cells remove some complexity regarding choice of validation scheme, and was feasible since the location of reconstruction minima was generally the same across cell types. I used the smallest set size where the validation loss was still stable during training. During development and to experiment with hyperparameters, the validation set was instead made by excluding some compounds with cell type NK from training, which were found to best overlap with the test cells. </p>\n \n<p>Instead of counts or p-values, a potential ideal task for estimating perturbations could be to compute the likelihood of private test counts under the density of parameterized distributions per gene per cell. The task would then be to give parameters which maximize the likelihood of the held-out data. In this setup, the metric would be the log-likelihood summed over all genes over all cells. Further, instead of removing the variability from technical sequencing effects, these could be used as just additional features. This gives some more leg room for model choice as it does not force teams to try predicting the distribution of the metadata in order to get good p-values from limma. </p>\n\n<h2>5. Documentation &amp; code style</h2>\n<p>The code is documented on <a href=\"https://github.com/yhsure/kaggle-perturbations\" target=\"_blank\">the Github page</a>. </p>\n\n<h2>6. Reproducibility</h2>\n<p>Code is available on GitHub: <a href=\"https://github.com/yhsure/kaggle-perturbations\" target=\"_blank\">https://github.com/yhsure/kaggle-perturbations</a>.<br>\nInstructions for running the project are available in the README.md file.</p>\n\n<h2>References</h2>\n<p>Grønbech, Christopher Heje, et al. \"scVAE: variational auto-encoders for single-cell gene expression data.\" Bioinformatics 36.16 (2020): 4415-4422.</p>\n<p>Schuster, Viktoria, and Anders Krogh. \"The Deep Generative Decoder: MAP estimation of representations improves modeling of single-cell RNA data.\" arXiv preprint arXiv:2110.06672 (2021).</p>\n<p>Kristiadi, Agustinus. \"Conditional Variational Autoencoder: Intuition and Implementation.\" (2016).</p>\n<p>Lotfollahi, Mohammad, F. Alexander Wolf, and Fabian J. Theis. \"scGen predicts single-cell perturbation responses.\" Nature methods 16.8 (2019): 715-721.</p>\n<p>Osorio, Daniel, et al. \"scTenifoldKnk: An efficient virtual knockout tool for gene function predictions via single-cell gene regulatory network perturbation.\" Patterns 3.3 (2022).</p>\n<p>Bunne, Charlotte, et al. \"Learning single-cell perturbation responses using neural optimal transport.\" Nature methods (2023): 1-10.</p>",
  "messages": [
    {
      "id": 2560222,
      "postDate": "2023-12-13T11:32:26.583Z",
      "content": "<h1>Learnings from generative models</h1>\n<p>Disregarding good MRRMSE scores for this particular dataset, I focused on generative models for the single-cell transcript data. These generative models can be used in a larger variety of research tasks than the regression models that dominated the competition. Few teams attempted this route, so I believe one writeup is warranted.</p>\n\n<h2>1. Integration of biological knowledge</h2>\n<p>To handle the count data, I use a negative binomial (NB) posterior. Like the Poisson, this takes sequencing depths into account. The NB further accounts for overdispersion, and is empirically found to fit scRNA-seq data well — also outperforming zero-inflated versions (<a href=\"https://academic.oup.com/bioinformatics/article/36/16/4415/5838187\" target=\"_blank\">Grønbech, 2020</a>). The NB density for observing $k$ gene counts is parameterized by mean $m$ and dispersion $r$:</p>\n<p>$$ {NB}(k;m,r) = \\frac{\\Gamma(k+r)}{k!\\,\\Gamma(r)} \\left( \\frac{m}{r+m} \\right)^k<br>\n\\left( \\frac{r}{r+m} \\right)^r $$</p>\n<p>The generative model outputs the mean scaled by the max count for the sample, while one $r$ is learned for each gene (sample independent). </p>\n<p>Since the ATAC data does not have cell ids matching the scRNA-seq data, I did not integrate it into the model. </p>\n\n<h2>2. Exploration of the problem</h2>\n<p>In principle, generating cells in the 'requested' cell_type/compound pair and feeding them to Limma seems reasonable. However, running the provided <code>compute_de.ipynb</code> notebook gives a mismatch with the p-values of <code>de_train</code> (also after taking the <code>excluded_ids</code> file into account and fixing metadata slightly). This means that even if the generative model learns a perfect reconstruction of the training data, it will still have an MRRMSE offset of 0.0325. Further, limma is sensitive to the amount of cells in each covariate group, making the sampling of realistic cell counts with corresponding metadata non-trivial. These aspects favored directly regressing the DE results.</p>\n<p>From simple statistical measures, NK cells were found to overlap best with the cell types in the private test set. This was further noted by <a href=\"https://www.kaggle.com/competitions/open-problems-single-cell-perturbations/discussion/457793#2541075\" target=\"_blank\">others during the competition</a>. </p>\n<p>There is a large proportion of cells from the positive control compounds compared to the rest of the data; I found it better to remove these cells from the dataset. It might further be useful to remove outlier compounds with few cell measurements. </p>\n\n<h2>3. Model design</h2>\n<p>I experimented with the Deep Generative Decoder (DGD) of <a href=\"https://arxiv.org/abs/2110.06672\" target=\"_blank\">Schuster &amp; Krogh, 2023</a> and found it to achieve better scores (PB 1.39) than an NB-VAE variant (PB 1.81). Both types outperformed a traditional VAE on normalized data subsequently rescaled back. In each case, I maximize the ELBO using Pytorch with, e.g., NB negative log likelihood as reconstruction error and with early stopping to prevent overfitting. Annealing the KL term from 0 to 1 over 50 warmup epochs avoided some cases with exploding loss. The encoder/decoder architectures are fully connected networks with ReLU activations and three layers transformings the dimensions to [5; 256; 1024; 18211]. Models are visualized on the diagram below. </p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F7642360%2Fc8afef4f94c3d7e72d9a91a393a13d7a%2Fvaedgd_withC_nontransparent.png?generation=1702466649193114&amp;alt=media\" alt=\"\"></p>\n<p>When predicting compounds as a task, the latent space separates into meaningful clusters, but the model does not generalize well for compounds in the test set (perhaps due to the large imbalance of cell type classes). For the below image, a latent space of 2 dimensions was used with the DGD model — the clusters highly correspond to compounds, cell types and donors. </p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F7642360%2F5e40babd13a2a0ee7033e2bb453b7362%2Fclusters.png?generation=1702466667622762&amp;alt=media\" alt=\"\"></p>\n<p>Conditioning the generative model on the covariates necessary for the limma analysis (cell type; plate name; well) gave best results on the PB. These conditional variables correspond to the <code>c</code> in the earlier model overview. In practice, the models are thus a conditional-DGD and a conditional-NB-VAE, where the one-hot-encoded covariates are appended to the data before encoder and decoder forward passes. After conditioning, the cells do not form distinct clusters based on the metadata — a natural effect of the conditional variables (<a href=\"https://agustinus.kristia.de/techblog/2016/12/17/conditional-vae/\" target=\"_blank\">Kristiadl, 2016</a>). Instead, they appear to be completely mixed together in a N(0,1) distribution (see github notebook). To generate a realistic number of cells and library sizes, two random forests were trained using the covariates as one-hot features; this step is important to get better p-values from limma.</p>\n<p>Random forest regression directly on the pseudo-bulk counts yielded a better score (PB 1.01), while bleak compared to just the zero-matrix (PB 0.9) or an out-of-the-box XGBoost on the p-values (PB 0.62) with one-hot-encoded sm_name/cell_type features. Interestingly, when combining the regression XGB submission with the DGD submission, performance improved slightly (0.002 improvement). p-values from the generative AI -&gt; limma pipeline had much larger variance than XGB p-values (see figure below), which could be reduced by averaging over multiple runs, but time did not allow for this. In general, these results provide a large degree of skepticism towards either 1) the generalization ability of generative models for this data, or 2) the metric used. </p>\n<div>\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F7642360%2F3081e6596cde902115fea777e4d397d2%2Fhistogram.png?generation=1702466720038500&amp;alt=media\">\n</div>\n<p>The performance of models already in the perturbation literature such as scGen (<a href=\"https://www.nature.com/articles/s41592-019-0494-8\" target=\"_blank\">Lotfollahi, 2019</a>), scTenifoldKnk (<a href=\"https://www.sciencedirect.com/science/article/pii/S2666389922000010\" target=\"_blank\">Osorio, 2022</a>), and CellOT (<a href=\"https://www.nature.com/articles/s41592-023-01969-x\" target=\"_blank\">Bunne, 2023</a>) would require more engineering to generate cells feasible for good limma p-values -- I did not have luck in initial experiments, which is why I sticked to the more direct approach of cell generation conditioned on the covariates. </p>\n\n<h2>4. Robustness</h2>\n<p>A validation set is always needed during the stochastic training of the model — we cannot be sure that by running it again with a full dataset that the training will go in the same way. Here, I used a small subset of randomly sampled points (3%) but manually including cells relevant to the test set in the training set. These relevant cells have either cell type or compound occurring in the test set. Randomly sampled cells remove some complexity regarding choice of validation scheme, and was feasible since the location of reconstruction minima was generally the same across cell types. I used the smallest set size where the validation loss was still stable during training. During development and to experiment with hyperparameters, the validation set was instead made by excluding some compounds with cell type NK from training, which were found to best overlap with the test cells. </p>\n \n<p>Instead of counts or p-values, a potential ideal task for estimating perturbations could be to compute the likelihood of private test counts under the density of parameterized distributions per gene per cell. The task would then be to give parameters which maximize the likelihood of the held-out data. In this setup, the metric would be the log-likelihood summed over all genes over all cells. Further, instead of removing the variability from technical sequencing effects, these could be used as just additional features. This gives some more leg room for model choice as it does not force teams to try predicting the distribution of the metadata in order to get good p-values from limma. </p>\n\n<h2>5. Documentation &amp; code style</h2>\n<p>The code is documented on <a href=\"https://github.com/yhsure/kaggle-perturbations\" target=\"_blank\">the Github page</a>. </p>\n\n<h2>6. Reproducibility</h2>\n<p>Code is available on GitHub: <a href=\"https://github.com/yhsure/kaggle-perturbations\" target=\"_blank\">https://github.com/yhsure/kaggle-perturbations</a>.<br>\nInstructions for running the project are available in the README.md file.</p>\n\n<h2>References</h2>\n<p>Grønbech, Christopher Heje, et al. \"scVAE: variational auto-encoders for single-cell gene expression data.\" Bioinformatics 36.16 (2020): 4415-4422.</p>\n<p>Schuster, Viktoria, and Anders Krogh. \"The Deep Generative Decoder: MAP estimation of representations improves modeling of single-cell RNA data.\" arXiv preprint arXiv:2110.06672 (2021).</p>\n<p>Kristiadi, Agustinus. \"Conditional Variational Autoencoder: Intuition and Implementation.\" (2016).</p>\n<p>Lotfollahi, Mohammad, F. Alexander Wolf, and Fabian J. Theis. \"scGen predicts single-cell perturbation responses.\" Nature methods 16.8 (2019): 715-721.</p>\n<p>Osorio, Daniel, et al. \"scTenifoldKnk: An efficient virtual knockout tool for gene function predictions via single-cell gene regulatory network perturbation.\" Patterns 3.3 (2022).</p>\n<p>Bunne, Charlotte, et al. \"Learning single-cell perturbation responses using neural optimal transport.\" Nature methods (2023): 1-10.</p>",
      "rawMarkdown": "# Learnings from generative models\nDisregarding good MRRMSE scores for this particular dataset, I focused on generative models for the single-cell transcript data. These generative models can be used in a larger variety of research tasks than the regression models that dominated the competition. Few teams attempted this route, so I believe one writeup is warranted.\n\n<!-- It was quickly found that the target and metric favored 'filling out' the missing DE results directly with regression; however, these models are very specialized to this particular competition setup and hardly generalize across research projects.  \n -->\n \n## 1. Integration of biological knowledge\nTo handle the count data, I use a negative binomial (NB) posterior. Like the Poisson, this takes sequencing depths into account. The NB further accounts for overdispersion, and is empirically found to fit scRNA-seq data well — also outperforming zero-inflated versions ([Grønbech, 2020][scVAE]). The NB density for observing $k$ gene counts is parameterized by mean $m$ and dispersion $r$:\n\n$$ {NB}(k;m,r) = \\frac{\\Gamma(k+r)}{k!\\,\\Gamma(r)} \\left( \\frac{m}{r+m} \\right)^k\n\\left( \\frac{r}{r+m} \\right)^r $$\n\nThe generative model outputs the mean scaled by the max count for the sample, while one $r$ is learned for each gene (sample independent). \n\nSince the ATAC data does not have cell ids matching the scRNA-seq data, I did not integrate it into the model. \n\n\n<!-- How does your model integrate biological knowledge into predictions? We want to know what you tried, and how it worked! This may include, but is not limited to:\n\n    How did you integrate the ATAC data? Which representation did you use?\n    How did you integrate LINCS data? How did this improve your model?\n    Did you use the chemical structures in your model?\n    Did you use other data sources? Which ones, why?\n    What representation of the single-cell data did you use? Did you reduce genes into modules? Did you learn a gene regulatory network? We want to know!\n    If adding a particular biological prior didn’t work, how did you judge this and why do you think this failed? -->\n\n\n\n## 2. Exploration of the problem\nIn principle, generating cells in the 'requested' cell_type/compound pair and feeding them to Limma seems reasonable. However, running the provided `compute_de.ipynb` notebook gives a mismatch with the p-values of `de_train` (also after taking the `excluded_ids` file into account and fixing metadata slightly). This means that even if the generative model learns a perfect reconstruction of the training data, it will still have an MRRMSE offset of 0.0325. Further, limma is sensitive to the amount of cells in each covariate group, making the sampling of realistic cell counts with corresponding metadata non-trivial. These aspects favored directly regressing the DE results.\n\nFrom simple statistical measures, NK cells were found to overlap best with the cell types in the private test set. This was further noted by [others during the competition][nk_cells]. \n\nThere is a large proportion of cells from the positive control compounds compared to the rest of the data; I found it better to remove these cells from the dataset. It might further be useful to remove outlier compounds with few cell measurements. \n\n\n<!-- We’re interested in understanding the problem of generalizing perturbation responses across cell lines. We hope this competition not only produces record-breaking models, but also helps us better understand the problem. Here are the kinds of questions we want you to help us answer:\n\n    Are there some cell types it’s easier to predict across? What about sets of genes?\n    Do you have any evidence to suggest how you might develop an ideal training set for cell type translation beyond random sampling of compounds in cell types?\n    What is the relationship between the number of compounds measured in the held-out cell types and model performance? Is there a sweet spot? -->\n\n\n\n## 3. Model design\nI experimented with the Deep Generative Decoder (DGD) of [Schuster & Krogh, 2023][DGD] and found it to achieve better scores (PB 1.39) than an NB-VAE variant (PB 1.81). Both types outperformed a traditional VAE on normalized data subsequently rescaled back. In each case, I maximize the ELBO using Pytorch with, e.g., NB negative log likelihood as reconstruction error and with early stopping to prevent overfitting. Annealing the KL term from 0 to 1 over 50 warmup epochs avoided some cases with exploding loss. The encoder/decoder architectures are fully connected networks with ReLU activations and three layers transformings the dimensions to [5; 256; 1024; 18211]. Models are visualized on the diagram below. \n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F7642360%2Fc8afef4f94c3d7e72d9a91a393a13d7a%2Fvaedgd_withC_nontransparent.png?generation=1702466649193114&alt=media)\n\nWhen predicting compounds as a task, the latent space separates into meaningful clusters, but the model does not generalize well for compounds in the test set (perhaps due to the large imbalance of cell type classes). For the below image, a latent space of 2 dimensions was used with the DGD model — the clusters highly correspond to compounds, cell types and donors. \n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F7642360%2F5e40babd13a2a0ee7033e2bb453b7362%2Fclusters.png?generation=1702466667622762&alt=media)\n\nConditioning the generative model on the covariates necessary for the limma analysis (cell type; plate name; well) gave best results on the PB. These conditional variables correspond to the `c` in the earlier model overview. In practice, the models are thus a conditional-DGD and a conditional-NB-VAE, where the one-hot-encoded covariates are appended to the data before encoder and decoder forward passes. After conditioning, the cells do not form distinct clusters based on the metadata — a natural effect of the conditional variables ([Kristiadl, 2016][cvae]). Instead, they appear to be completely mixed together in a N(0,1) distribution (see github notebook). To generate a realistic number of cells and library sizes, two random forests were trained using the covariates as one-hot features; this step is important to get better p-values from limma.\n\nRandom forest regression directly on the pseudo-bulk counts yielded a better score (PB 1.01), while bleak compared to just the zero-matrix (PB 0.9) or an out-of-the-box XGBoost on the p-values (PB 0.62) with one-hot-encoded sm_name/cell_type features. Interestingly, when combining the regression XGB submission with the DGD submission, performance improved slightly (0.002 improvement). p-values from the generative AI -> limma pipeline had much larger variance than XGB p-values (see figure below), which could be reduced by averaging over multiple runs, but time did not allow for this. In general, these results provide a large degree of skepticism towards either 1) the generalization ability of generative models for this data, or 2) the metric used. \n\n\n<div style=\"text-align: center;\">\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F7642360%2F3081e6596cde902115fea777e4d397d2%2Fhistogram.png?generation=1702466720038500&alt=media\" width=\"450\">\n</div>\n\nThe performance of models already in the perturbation literature such as scGen ([Lotfollahi, 2019][scGen]), scTenifoldKnk ([Osorio, 2022][scTenifoldKnk]), and CellOT ([Bunne, 2023][CellOT]) would require more engineering to generate cells feasible for good limma p-values -- I did not have luck in initial experiments, which is why I sticked to the more direct approach of cell generation conditioned on the covariates. \n\n\n<!-- It’s no secret that the top models on the leaderboard are often complex ensembles super-tuned to the test data, and this is amazing for our application. That said, we’re also interested in knowing if there are specific classes of models that perform especially well.\n\n    Is there certain technical innovation in your model that you believe represents a step-change in the field?\n    Can you show that top performing methods can be well approximated by a simpler model?\n    Is your model explainable? How well can you identify what is causing your model to respond to certain inputs? -->\n\n## 4. Robustness\nA validation set is always needed during the stochastic training of the model — we cannot be sure that by running it again with a full dataset that the training will go in the same way. Here, I used a small subset of randomly sampled points (3%) but manually including cells relevant to the test set in the training set. These relevant cells have either cell type or compound occurring in the test set. Randomly sampled cells remove some complexity regarding choice of validation scheme, and was feasible since the location of reconstruction minima was generally the same across cell types. I used the smallest set size where the validation loss was still stable during training. During development and to experiment with hyperparameters, the validation set was instead made by excluding some compounds with cell type NK from training, which were found to best overlap with the test cells. \n <!-- I found the NK cells to overlap best with the private test set cell types. -->\n\nInstead of counts or p-values, a potential ideal task for estimating perturbations could be to compute the likelihood of private test counts under the density of parameterized distributions per gene per cell. The task would then be to give parameters which maximize the likelihood of the held-out data. In this setup, the metric would be the log-likelihood summed over all genes over all cells. Further, instead of removing the variability from technical sequencing effects, these could be used as just additional features. This gives some more leg room for model choice as it does not force teams to try predicting the distribution of the metadata in order to get good p-values from limma. \n\n\n<!-- How robust is your model to variability in the data? Here are some ideas for how you might explore this, but we’re interested in unique ideas too.\n    Take subsets of the training data (e.g. 95%, 90%, …, 10%). How well does your model performs as a function of percentage of the training data?\n    Add small amounts of noise to the input data. What kinds of noise is your model invariant to? Bonus points if the noise is biologically motivated. -->\n\n## 5. Documentation & code style\nThe code is documented on [the Github page][github]. \n\n\n<!-- Here we want to make sure your model and analysis notebooks are well documented and follow a consistent code style. At a minimum, we want to see:\n\n    Documentation describes the general methodology of the solution\n    Documentation describes the required hardware and software dependencies, as well as how to install and run the software\n    Functions and their arguments are documented\n    Code follows basic good practices for the chosen programming language. For example: PEP8 for Python, tidyverse style guide for R\n    Code does not contain duplicated code -->\n\n## 6. Reproducibility\nCode is available on GitHub: https://github.com/yhsure/kaggle-perturbations.\nInstructions for running the project are available in the README.md file.\n\n\n<!-- \nHere we want to make sure your model and notebooks are reproducible by other scientists.\n\n    Code is available on GitHub\n    A list of required dependencies is available (e.g. dependencies.txt for Python)\n    Repository contains a Dockerfile or Viash component which can be used to train and run the model\n    Documentation contains an example of how to run the method using the Docker container or Viash component -->\n\n\n## References\nGrønbech, Christopher Heje, et al. \"scVAE: variational auto-encoders for single-cell gene expression data.\" Bioinformatics 36.16 (2020): 4415-4422.\n\nSchuster, Viktoria, and Anders Krogh. \"The Deep Generative Decoder: MAP estimation of representations improves modeling of single-cell RNA data.\" arXiv preprint arXiv:2110.06672 (2021).\n\nKristiadi, Agustinus. \"Conditional Variational Autoencoder: Intuition and Implementation.\" (2016).\n\nLotfollahi, Mohammad, F. Alexander Wolf, and Fabian J. Theis. \"scGen predicts single-cell perturbation responses.\" Nature methods 16.8 (2019): 715-721.\n\nOsorio, Daniel, et al. \"scTenifoldKnk: An efficient virtual knockout tool for gene function predictions via single-cell gene regulatory network perturbation.\" Patterns 3.3 (2022).\n\nBunne, Charlotte, et al. \"Learning single-cell perturbation responses using neural optimal transport.\" Nature methods (2023): 1-10.\n\n[scVAE]: https://academic.oup.com/bioinformatics/article/36/16/4415/5838187\n[nk_cells]: https://www.kaggle.com/competitions/open-problems-single-cell-perturbations/discussion/457793#2541075\n[DGD]: https://arxiv.org/abs/2110.06672\n[cvae]: https://agustinus.kristia.de/techblog/2016/12/17/conditional-vae/\n[scGen]: https://www.nature.com/articles/s41592-019-0494-8\n[scTenifoldKnk]: https://www.sciencedirect.com/science/article/pii/S2666389922000010\n[CellOT]: https://www.nature.com/articles/s41592-023-01969-x\n[github]: https://github.com/yhsure/kaggle-perturbations",
      "votes": 3
    }
  ],
  "comments": [],
  "raw_markdown_by_id": {
    "2560222": "# Learnings from generative models\nDisregarding good MRRMSE scores for this particular dataset, I focused on generative models for the single-cell transcript data. These generative models can be used in a larger variety of research tasks than the regression models that dominated the competition. Few teams attempted this route, so I believe one writeup is warranted.\n\n<!-- It was quickly found that the target and metric favored 'filling out' the missing DE results directly with regression; however, these models are very specialized to this particular competition setup and hardly generalize across research projects.  \n -->\n \n## 1. Integration of biological knowledge\nTo handle the count data, I use a negative binomial (NB) posterior. Like the Poisson, this takes sequencing depths into account. The NB further accounts for overdispersion, and is empirically found to fit scRNA-seq data well — also outperforming zero-inflated versions ([Grønbech, 2020][scVAE]). The NB density for observing $k$ gene counts is parameterized by mean $m$ and dispersion $r$:\n\n$$ {NB}(k;m,r) = \\frac{\\Gamma(k+r)}{k!\\,\\Gamma(r)} \\left( \\frac{m}{r+m} \\right)^k\n\\left( \\frac{r}{r+m} \\right)^r $$\n\nThe generative model outputs the mean scaled by the max count for the sample, while one $r$ is learned for each gene (sample independent). \n\nSince the ATAC data does not have cell ids matching the scRNA-seq data, I did not integrate it into the model. \n\n\n<!-- How does your model integrate biological knowledge into predictions? We want to know what you tried, and how it worked! This may include, but is not limited to:\n\n    How did you integrate the ATAC data? Which representation did you use?\n    How did you integrate LINCS data? How did this improve your model?\n    Did you use the chemical structures in your model?\n    Did you use other data sources? Which ones, why?\n    What representation of the single-cell data did you use? Did you reduce genes into modules? Did you learn a gene regulatory network? We want to know!\n    If adding a particular biological prior didn’t work, how did you judge this and why do you think this failed? -->\n\n\n\n## 2. Exploration of the problem\nIn principle, generating cells in the 'requested' cell_type/compound pair and feeding them to Limma seems reasonable. However, running the provided `compute_de.ipynb` notebook gives a mismatch with the p-values of `de_train` (also after taking the `excluded_ids` file into account and fixing metadata slightly). This means that even if the generative model learns a perfect reconstruction of the training data, it will still have an MRRMSE offset of 0.0325. Further, limma is sensitive to the amount of cells in each covariate group, making the sampling of realistic cell counts with corresponding metadata non-trivial. These aspects favored directly regressing the DE results.\n\nFrom simple statistical measures, NK cells were found to overlap best with the cell types in the private test set. This was further noted by [others during the competition][nk_cells]. \n\nThere is a large proportion of cells from the positive control compounds compared to the rest of the data; I found it better to remove these cells from the dataset. It might further be useful to remove outlier compounds with few cell measurements. \n\n\n<!-- We’re interested in understanding the problem of generalizing perturbation responses across cell lines. We hope this competition not only produces record-breaking models, but also helps us better understand the problem. Here are the kinds of questions we want you to help us answer:\n\n    Are there some cell types it’s easier to predict across? What about sets of genes?\n    Do you have any evidence to suggest how you might develop an ideal training set for cell type translation beyond random sampling of compounds in cell types?\n    What is the relationship between the number of compounds measured in the held-out cell types and model performance? Is there a sweet spot? -->\n\n\n\n## 3. Model design\nI experimented with the Deep Generative Decoder (DGD) of [Schuster & Krogh, 2023][DGD] and found it to achieve better scores (PB 1.39) than an NB-VAE variant (PB 1.81). Both types outperformed a traditional VAE on normalized data subsequently rescaled back. In each case, I maximize the ELBO using Pytorch with, e.g., NB negative log likelihood as reconstruction error and with early stopping to prevent overfitting. Annealing the KL term from 0 to 1 over 50 warmup epochs avoided some cases with exploding loss. The encoder/decoder architectures are fully connected networks with ReLU activations and three layers transformings the dimensions to [5; 256; 1024; 18211]. Models are visualized on the diagram below. \n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F7642360%2Fc8afef4f94c3d7e72d9a91a393a13d7a%2Fvaedgd_withC_nontransparent.png?generation=1702466649193114&alt=media)\n\nWhen predicting compounds as a task, the latent space separates into meaningful clusters, but the model does not generalize well for compounds in the test set (perhaps due to the large imbalance of cell type classes). For the below image, a latent space of 2 dimensions was used with the DGD model — the clusters highly correspond to compounds, cell types and donors. \n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F7642360%2F5e40babd13a2a0ee7033e2bb453b7362%2Fclusters.png?generation=1702466667622762&alt=media)\n\nConditioning the generative model on the covariates necessary for the limma analysis (cell type; plate name; well) gave best results on the PB. These conditional variables correspond to the `c` in the earlier model overview. In practice, the models are thus a conditional-DGD and a conditional-NB-VAE, where the one-hot-encoded covariates are appended to the data before encoder and decoder forward passes. After conditioning, the cells do not form distinct clusters based on the metadata — a natural effect of the conditional variables ([Kristiadl, 2016][cvae]). Instead, they appear to be completely mixed together in a N(0,1) distribution (see github notebook). To generate a realistic number of cells and library sizes, two random forests were trained using the covariates as one-hot features; this step is important to get better p-values from limma.\n\nRandom forest regression directly on the pseudo-bulk counts yielded a better score (PB 1.01), while bleak compared to just the zero-matrix (PB 0.9) or an out-of-the-box XGBoost on the p-values (PB 0.62) with one-hot-encoded sm_name/cell_type features. Interestingly, when combining the regression XGB submission with the DGD submission, performance improved slightly (0.002 improvement). p-values from the generative AI -> limma pipeline had much larger variance than XGB p-values (see figure below), which could be reduced by averaging over multiple runs, but time did not allow for this. In general, these results provide a large degree of skepticism towards either 1) the generalization ability of generative models for this data, or 2) the metric used. \n\n\n<div style=\"text-align: center;\">\n<img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F7642360%2F3081e6596cde902115fea777e4d397d2%2Fhistogram.png?generation=1702466720038500&alt=media\" width=\"450\">\n</div>\n\nThe performance of models already in the perturbation literature such as scGen ([Lotfollahi, 2019][scGen]), scTenifoldKnk ([Osorio, 2022][scTenifoldKnk]), and CellOT ([Bunne, 2023][CellOT]) would require more engineering to generate cells feasible for good limma p-values -- I did not have luck in initial experiments, which is why I sticked to the more direct approach of cell generation conditioned on the covariates. \n\n\n<!-- It’s no secret that the top models on the leaderboard are often complex ensembles super-tuned to the test data, and this is amazing for our application. That said, we’re also interested in knowing if there are specific classes of models that perform especially well.\n\n    Is there certain technical innovation in your model that you believe represents a step-change in the field?\n    Can you show that top performing methods can be well approximated by a simpler model?\n    Is your model explainable? How well can you identify what is causing your model to respond to certain inputs? -->\n\n## 4. Robustness\nA validation set is always needed during the stochastic training of the model — we cannot be sure that by running it again with a full dataset that the training will go in the same way. Here, I used a small subset of randomly sampled points (3%) but manually including cells relevant to the test set in the training set. These relevant cells have either cell type or compound occurring in the test set. Randomly sampled cells remove some complexity regarding choice of validation scheme, and was feasible since the location of reconstruction minima was generally the same across cell types. I used the smallest set size where the validation loss was still stable during training. During development and to experiment with hyperparameters, the validation set was instead made by excluding some compounds with cell type NK from training, which were found to best overlap with the test cells. \n <!-- I found the NK cells to overlap best with the private test set cell types. -->\n\nInstead of counts or p-values, a potential ideal task for estimating perturbations could be to compute the likelihood of private test counts under the density of parameterized distributions per gene per cell. The task would then be to give parameters which maximize the likelihood of the held-out data. In this setup, the metric would be the log-likelihood summed over all genes over all cells. Further, instead of removing the variability from technical sequencing effects, these could be used as just additional features. This gives some more leg room for model choice as it does not force teams to try predicting the distribution of the metadata in order to get good p-values from limma. \n\n\n<!-- How robust is your model to variability in the data? Here are some ideas for how you might explore this, but we’re interested in unique ideas too.\n    Take subsets of the training data (e.g. 95%, 90%, …, 10%). How well does your model performs as a function of percentage of the training data?\n    Add small amounts of noise to the input data. What kinds of noise is your model invariant to? Bonus points if the noise is biologically motivated. -->\n\n## 5. Documentation & code style\nThe code is documented on [the Github page][github]. \n\n\n<!-- Here we want to make sure your model and analysis notebooks are well documented and follow a consistent code style. At a minimum, we want to see:\n\n    Documentation describes the general methodology of the solution\n    Documentation describes the required hardware and software dependencies, as well as how to install and run the software\n    Functions and their arguments are documented\n    Code follows basic good practices for the chosen programming language. For example: PEP8 for Python, tidyverse style guide for R\n    Code does not contain duplicated code -->\n\n## 6. Reproducibility\nCode is available on GitHub: https://github.com/yhsure/kaggle-perturbations.\nInstructions for running the project are available in the README.md file.\n\n\n<!-- \nHere we want to make sure your model and notebooks are reproducible by other scientists.\n\n    Code is available on GitHub\n    A list of required dependencies is available (e.g. dependencies.txt for Python)\n    Repository contains a Dockerfile or Viash component which can be used to train and run the model\n    Documentation contains an example of how to run the method using the Docker container or Viash component -->\n\n\n## References\nGrønbech, Christopher Heje, et al. \"scVAE: variational auto-encoders for single-cell gene expression data.\" Bioinformatics 36.16 (2020): 4415-4422.\n\nSchuster, Viktoria, and Anders Krogh. \"The Deep Generative Decoder: MAP estimation of representations improves modeling of single-cell RNA data.\" arXiv preprint arXiv:2110.06672 (2021).\n\nKristiadi, Agustinus. \"Conditional Variational Autoencoder: Intuition and Implementation.\" (2016).\n\nLotfollahi, Mohammad, F. Alexander Wolf, and Fabian J. Theis. \"scGen predicts single-cell perturbation responses.\" Nature methods 16.8 (2019): 715-721.\n\nOsorio, Daniel, et al. \"scTenifoldKnk: An efficient virtual knockout tool for gene function predictions via single-cell gene regulatory network perturbation.\" Patterns 3.3 (2022).\n\nBunne, Charlotte, et al. \"Learning single-cell perturbation responses using neural optimal transport.\" Nature methods (2023): 1-10.\n\n[scVAE]: https://academic.oup.com/bioinformatics/article/36/16/4415/5838187\n[nk_cells]: https://www.kaggle.com/competitions/open-problems-single-cell-perturbations/discussion/457793#2541075\n[DGD]: https://arxiv.org/abs/2110.06672\n[cvae]: https://agustinus.kristia.de/techblog/2016/12/17/conditional-vae/\n[scGen]: https://www.nature.com/articles/s41592-019-0494-8\n[scTenifoldKnk]: https://www.sciencedirect.com/science/article/pii/S2666389922000010\n[CellOT]: https://www.nature.com/articles/s41592-023-01969-x\n[github]: https://github.com/yhsure/kaggle-perturbations"
  }
}