{"id":21028114,"url":"https://github.com/leonjessen/keras_tensorflow_demo","last_synced_at":"2025-05-15T10:33:08.962Z","repository":{"id":145190202,"uuid":"110995075","full_name":"leonjessen/keras_tensorflow_demo","owner":"leonjessen","description":"Demonstration of using Keras to run a simple deep feed forward artificial neural network using Tensorflow as backbone in R","archived":false,"fork":false,"pushed_at":"2017-12-11T08:59:11.000Z","size":1629,"stargazers_count":8,"open_issues_count":1,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-03T08:02:47.703Z","etag":null,"topics":["datascience","deeplearning","demo","keras","machinelearning","neuralnetwork","r","rstats","rstudio","tensorflow","tidyverse","tutorial"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leonjessen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-11-16T16:26:15.000Z","updated_at":"2020-12-05T11:39:39.000Z","dependencies_parsed_at":null,"dependency_job_id":"ecef31de-c8c3-4dfc-8556-0b2b831a72bc","html_url":"https://github.com/leonjessen/keras_tensorflow_demo","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonjessen%2Fkeras_tensorflow_demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonjessen%2Fkeras_tensorflow_demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonjessen%2Fkeras_tensorflow_demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonjessen%2Fkeras_tensorflow_demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leonjessen","download_url":"https://codeload.github.com/leonjessen/keras_tensorflow_demo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254323242,"owners_count":22051745,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["datascience","deeplearning","demo","keras","machinelearning","neuralnetwork","r","rstats","rstudio","tensorflow","tidyverse","tutorial"],"created_at":"2024-11-19T11:53:57.084Z","updated_at":"2025-05-15T10:33:08.944Z","avatar_url":"https://github.com/leonjessen.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"Keras/TensorFlow in R Demo with Immunoinformatics as use-case\n================\n\nClick on each section to expand or jump directly to the section of interest\n\nIntroduction\n============\n\n\u003cdetails\u003e \u003csummary\u003eClick to expand\u003c/summary\u003e\n\n### Aim\n\nThe aim of this brief demo is to use deep learning to predict molecular interactions.\n\n### Background\n\nThe use case is within immunological bioinformatics also known as immunoinformatics. Briefly, a key component in immune activation is the binding of small fragments of proteins known as peptide to a special molecule. Proteins and therefore peptides are made up of amino acids. Peptides are represented as a combination of the following 20 letters: `ARNDCQEGHILKMFPSTWYV`, such that a `9-mer` could be e.g. `GRTAEWMRW`. The special molecule binding the peptides is called Major Histocompability Complex Type 1 (MHCI) MHCI is located on the surface of the cells in our body and together with the bound peptide, MHCI reflects the health of the individual cells. If a cell is sick, this will be visible to the immune system via the MHCI-peptide interaction, as illustrated here by [Lund et al., 2005](https://mitpress.mit.edu/books/immunological-bioinformatics):\n\n\u003cimg src=\"README_files/figure-markdown_github/MHCI_pathway_cartoon.png\" alt=\"Cartoon of the MHCI pathway\" width=\"300\" /\u003e\n\n### Data\n\nIn this demo, we will be predicting if a given `9-mer` peptide will be a 'strong-binder' `SB`, 'weak-binder' `WB` or a 'non-binder' `NB` to the MHCI variant `HLA-A*02:01`. We will be using a data set created by submitting 1,000,000 random `9-mers` to [`netMHCpan-4.0`](http://www.cbs.dtu.dk/services/%60netMHCpan-4.0%60/) and predicting binding affinty to `HLA-A*02:01`. Based on the continuous binding affinty, each peptide is labeled `SB`, `WB` or `NB`. As `n(SB) \u003c n(WB) \u003c\u003c n(NB)`, the data set was balanced by down-sampling, such that `n(SB) = n(WB) = n(NB) = 7920`. Thusly, the data set has a total of `n(all) = 23760` data points. The data set was furthermore split into a `train` and `test` set, by random sampling 10% of the peptides. The data set is available [here](https://raw.githubusercontent.com/leonjessen/keras_tensorflow_demo/master/data/ran_peps_netMHCpan40_predicted_A0201_reduced_cleaned_balanced.tsv). It should be noted that this data set is derived from a model, so our final model in this example, will be a model of a model.\n\n\u003c/details\u003e\n\nSetup\n=====\n\n\u003cdetails\u003e \u003csummary\u003eClick to expand\u003c/summary\u003e\n\nHave no fear, you're almost there!\n----------------------------------\n\nWe need a few things installed before we're good to go, but I promise it'll be quick and painless!\n\nGetting started\n---------------\n\nYou only need to do the following once!\n\nGo ahead and head on over to [The R Project for Statistical Computing](https://www.r-project.org/) and install the newest version of `R`. Then pop over to [RStudio](https://www.rstudio.com/products/rstudio/download/#download) and get their brilliant IDE.\n\nIn order to use [`Keras`](https://tensorflow.rstudio.com/) and [`TensorFlow`](https://tensorflow.rstudio.com/), we need to install them along with the [`TidyVerse`](https://www.tidyverse.org/) framework. We also need [`PepTools`](https://github.com/leonjessen/PepTools) for working with peptide data and lastly the [`ggseqlogo`](https://github.com/omarwagih/ggseqlogo) package for generating sequence logos. Fortunately, this is all straight forward using the ever brilliant [Hadley Wickham](https://pbs.twimg.com/profile_images/905186381995147264/7zKAG5sY.jpg)'s `devtools`:\n\n``` r\ninstall.packages(\"devtools\")\n```\n\nNow we load the `devtools` library, which will enable us to install the remaining requirements:\n\n``` r\nlibrary(\"devtools\")\n```\n\nand then install requirements\n\n``` r\ninstall.packages(\"tidyverse\")\ndevtools::install_github(\"rstudio/keras\")\ndevtools::install_github(\"omarwagih/ggseqlogo\")\ndevtools::install_github(\"leonjessen/PepTools\")\n```\n\nNow simply run:\n\n``` r\nlibrary(\"keras\")\n```\n\nFollowed by\n\n``` r\ninstall_keras()\n```\n\nThat's it! Now we have all we need to be Data Science masters of the machine learning universe! \u003c/details\u003e\n\nDeep Feed Forward Artificial Neural Network\n===========================================\n\nHere is a basic example of a deep FFWD ANN workflow (This example is adapted from this [RStudio Keras](https://keras.rstudio.com/) tutorial).\n\nGetting Started\n---------------\n\nFirst we clear the workspace to avoid unintentional reuse of old variables\n\n``` r\nrm(list=ls())\n```\n\nThen we load the needed libraries\n\n``` r\nlibrary(\"keras\")\nlibrary(\"tidyverse\")\nlibrary(\"ggseqlogo\")\nlibrary(\"PepTools\")\n```\n\nThen we load the example data\n\n``` r\npep_file = \"https://raw.githubusercontent.com/leonjessen/keras_tensorflow_demo/master/data/ran_peps_netMHCpan40_predicted_A0201_reduced_cleaned_balanced.tsv\"\npep_dat  = read_tsv(file = pep_file)\n```\n\nUnderstand the Data\n-------------------\n\nThe example peptide data looks like this\n\n``` r\npep_dat\n```\n\n    ## # A tibble: 23,760 x 4\n    ##      peptide label_chr label_num data_type\n    ##        \u003cchr\u003e     \u003cchr\u003e     \u003cint\u003e     \u003cchr\u003e\n    ##  1 LLTDAQRIV        WB         1     train\n    ##  2 LMAFYLYEV        SB         2     train\n    ##  3 VMSPITLPT        WB         1      test\n    ##  4 SLHLTNCFV        WB         1     train\n    ##  5 RQFTCMIAV        WB         1     train\n    ##  6 HQRLAPTMP        NB         0     train\n    ##  7 FMNGHTHIA        SB         2     train\n    ##  8 KINPYFSGA        WB         1     train\n    ##  9 WLLIFHHCP        NB         0     train\n    ## 10 NIWLAIIEL        WB         1     train\n    ## # ... with 23,750 more rows\n\nWhere `peptide` is a set of `9-mer` peptides, `label_chr` defines whether the peptide was predicted by [`netMHCpan-4.0`](http://www.cbs.dtu.dk/services/%60netMHCpan-4.0%60/) to be a strong-binder `SB`, weak-binder `WB` or `NB` non-binder to `HLA-A*02:01`. `label_num` is equivalent to `label_chr`, only the predicted binding is coded into three numeric classes. Finally `data_type` defines whether the particular data point is part of the training set or the ~10% data left out and used for final evaluation. The data has been balanced, which we can see using `TidyVerse` methods to summarise the input data:\n\n``` r\npep_dat %\u003e% group_by(label_chr, data_type) %\u003e% summarise(n = n())\n```\n\n    ## # A tibble: 6 x 3\n    ## # Groups:   label_chr [?]\n    ##   label_chr data_type     n\n    ##       \u003cchr\u003e     \u003cchr\u003e \u003cint\u003e\n    ## 1        NB      test   782\n    ## 2        NB     train  7138\n    ## 3        SB      test   802\n    ## 4        SB     train  7118\n    ## 5        WB      test   792\n    ## 6        WB     train  7128\n\nWe can use the very nice `ggseqlogo` package to visualise the sequence motif for the strong binders:\n\n``` r\npep_dat %\u003e% filter(label_chr=='SB') %\u003e% pull(peptide) %\u003e%\n  pssm_freqs %\u003e% pssm_bits %\u003e% t %\u003e% ggseqlogo(method=\"custom\")\n```\n\n\u003cimg src=\"README_files/figure-markdown_github/seq_logo-1.png\" style=\"display: block; margin: auto;\" /\u003e\n\nFrom the sequence logo, it is evident that positions 2 and 9 in the peptide are of paramount importance for the MHCI-peptide binding. In fact these positions are known as the anchor positions.\n\nUnderstand the encoding\n-----------------------\n\nEach peptide is encoded using the [BLOSUM62 matrix](https://www.ncbi.nlm.nih.gov/Class/FieldGuide/BLOSUM62.txt), such that each peptide becomes an 'image' matrix with 9 rows and 20 columns - Think of it as a QR code. We can visualise a peptide 'image' using `pep_plot_images()`:\n\n``` r\npep_ran(n = 1, k = 9) %\u003e% pep_plot_images\n```\n\n\u003cimg src=\"README_files/figure-markdown_github/visualise_peptide_encoding-1.png\" style=\"display: block; margin: auto;\" /\u003e\n\nEach of these 'QR codes' define whether a given peptide is a strong-binder, weak-binder or non-binder. It is now our task to identify the pattern in the 'image' define which of the 3 classes the peptide belong to.\n\nPrepare Data for TensorFlow\n---------------------------\n\nWe are creating a model `f`, where `x` is the peptide and `y` is one of three classes `SB`, `WB` and `NB`, such that `y ~ f(x)`. We need to define the `x_train`, `y_train`, `x_test` and `y_test`:\n\n``` r\nx_train = pep_dat %\u003e% filter(data_type == 'train') %\u003e% pull(peptide)   %\u003e% pep_encode\ny_train = pep_dat %\u003e% filter(data_type == 'train') %\u003e% pull(label_num) %\u003e% array\nx_test  = pep_dat %\u003e% filter(data_type == 'test')  %\u003e% pull(peptide)   %\u003e% pep_encode\ny_test  = pep_dat %\u003e% filter(data_type == 'test')  %\u003e% pull(label_num) %\u003e% array\n```\n\nThe x data is a 3-d array (a tensor) with `n_rows x n_columns x n_slices = n_peptides x l_peptide x l_enc = 21384 x 9 x 20`, i.e. all the 'images'/'QR codes' we generated. To prepare the data for training we convert the tensor into a matrix by reshaping width and height into a single dimension (9 x 20 peptide ‘images’ are flattened into vectors of lengths 180 and stacked as rows)\n\n``` r\nx_train = array_reshape(x_train, c(nrow(x_train), 180))\ndim(x_train)\n```\n\n    ## [1] 21384   180\n\n``` r\nx_test  = array_reshape(x_test,  c(nrow(x_test), 180))\ndim(x_test)\n```\n\n    ## [1] 2376  180\n\nThe y data is an integer vector with values ranging from 0 to 2. To prepare this data for training we encode the vectors into binary class matrices using the Keras `to_categorical` function:\n\n``` r\ny_train = to_categorical(y_train, y_train %\u003e% table %\u003e% length)\ndim(y_train)\n```\n\n    ## [1] 21384     3\n\n``` r\ny_train %\u003e% head(3)\n```\n\n    ##      [,1] [,2] [,3]\n    ## [1,]    0    1    0\n    ## [2,]    0    0    1\n    ## [3,]    0    1    0\n\n``` r\ny_test  = to_categorical(y_test,  y_test  %\u003e% table %\u003e% length)\ndim(y_test)\n```\n\n    ## [1] 2376    3\n\n``` r\ny_test %\u003e% head(3)\n```\n\n    ##      [,1] [,2] [,3]\n    ## [1,]    0    1    0\n    ## [2,]    0    1    0\n    ## [3,]    0    1    0\n\nNow that we have the data, we can proceed to creating our TensorFlow model.\n\nDefining the model\n------------------\n\nThe core data structure of Keras is a model, a way to organize layers. The simplest type of model is the Sequential model, a linear stack of layers. We begin by creating a sequential model and then adding layers:\n\n``` r\nmodel = keras_model_sequential() \nmodel %\u003e% \n  layer_dense(units  = 180, activation = 'relu', input_shape = 180) %\u003e% \n  layer_dropout(rate = 0.4) %\u003e% \n  layer_dense(units  = 90, activation  = 'relu') %\u003e%\n  layer_dropout(rate = 0.3) %\u003e%\n  layer_dense(units  = 3, activation   = 'softmax')\n```\n\nThe input\\_shape argument to the first layer specifies the shape of the input data (a length 180 numeric vector representing a peptide 'image'). The final layer outputs a length 3 numeric vector (probabilities for each class `SB`, `WB` and `NB`) using a softmax activation function.\n\nWe can use the `summary()` function to print the details of the model:\n\n``` r\nsummary(model)\n```\n\n    ## ___________________________________________________________________________\n    ## Layer (type)                     Output Shape                  Param #     \n    ## ===========================================================================\n    ## dense_1 (Dense)                  (None, 180)                   32580       \n    ## ___________________________________________________________________________\n    ## dropout_1 (Dropout)              (None, 180)                   0           \n    ## ___________________________________________________________________________\n    ## dense_2 (Dense)                  (None, 90)                    16290       \n    ## ___________________________________________________________________________\n    ## dropout_2 (Dropout)              (None, 90)                    0           \n    ## ___________________________________________________________________________\n    ## dense_3 (Dense)                  (None, 3)                     273         \n    ## ===========================================================================\n    ## Total params: 49,143\n    ## Trainable params: 49,143\n    ## Non-trainable params: 0\n    ## ___________________________________________________________________________\n\nNext, compile the model with appropriate loss function, optimizer, and metrics:\n\n``` r\nmodel %\u003e% compile(\n  loss      = 'categorical_crossentropy',\n  optimizer = optimizer_rmsprop(),\n  metrics   = c('accuracy')\n)\n```\n\nTraining and evaluation\n-----------------------\n\nWe use the fit() function to train the model for 150 epochs using batches of 50 peptide ‘images’:\n\n``` r\nhistory = model %\u003e% fit(\n  x_train, y_train, \n  epochs = 150, batch_size = 50, validation_split = 0.2)\n```\n\nVisualise training\n------------------\n\nWe can visualise the training progress in each epoch using `ggplot`:\n\n``` r\nplot_dat = tibble(epoch = rep(1:history$params$epochs,2),\n                  value = c(history$metrics$acc,history$metrics$val_acc),\n                  dtype = c(rep('acc',history$params$epochs),\n                            rep('val_acc',history$params$epochs)) %\u003e% factor)\nplot_dat %\u003e%\n  ggplot(aes(x = epoch, y = value, colour = dtype)) +\n  geom_line() +\n  theme_bw()\n```\n\n![](README_files/figure-markdown_github/visualise_training-1.png)\n\nPerformance\n-----------\n\nFinally we can evaluate the model’s performance on the original ~10% left out test data:\n\n``` r\nperf = model %\u003e% evaluate(x_test, y_test)\nperf\n```\n\n    ## $loss\n    ## [1] 0.1823313\n    ## \n    ## $acc\n    ## [1] 0.9372896\n\nand we can visualise the predictions:\n\n``` r\nacc     = perf$acc %\u003e% round(3) * 100\ny_pred  = model %\u003e% predict_classes(x_test)\ny_real  = y_test %\u003e% apply(1,function(x){ return( which(x==1) - 1) })\nresults = tibble(y_real = y_real, y_pred = y_pred,\n                 Correct = ifelse(y_real == y_pred,\"yes\",\"no\") %\u003e% factor)\nresults %\u003e%\n  ggplot(aes(x = y_pred, y = y_real, colour = Correct)) +\n  geom_point() +\n  xlab(\"Measured (Real class, as predicted by netMHCpan-4.0)\") +\n  ylab(\"Predicted (Class assigned by Keras/TensorFlow deep FFWD ANN)\") +\n  ggtitle(label    = \"Performance on 10% unseen data\",\n          subtitle = paste0(\"Accuracy = \", acc,\"%\")) +\n  scale_x_continuous(breaks = c(0,1,2), minor_breaks = NULL) +\n  scale_y_continuous(breaks = c(0,1,2), minor_breaks = NULL) +\n  geom_jitter() +\n  theme_bw()\n```\n\n![](README_files/figure-markdown_github/visualise_preds-1.png)\n\nThat the end of this small demo - I hope you had fun!\n\nLeon Eyrich Jessen\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleonjessen%2Fkeras_tensorflow_demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleonjessen%2Fkeras_tensorflow_demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleonjessen%2Fkeras_tensorflow_demo/lists"}