ZhiyuanChen commited on
Commit
cc730a8
·
verified ·
1 Parent(s): 973912b

Upload folder using huggingface_hub

Browse files
README.md ADDED
@@ -0,0 +1,300 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ language: rna
3
+ tags:
4
+ - Biology
5
+ - RNA
6
+ license: agpl-3.0
7
+ datasets:
8
+ - multimolecule/rfam
9
+ library_name: multimolecule
10
+ pipeline_tag: fill-mask
11
+ mask_token: "<mask>"
12
+ widget:
13
+ - example_title: "HIV-1"
14
+ text: "GGUC<mask>CUCUGGUUAGACCAGAUCUGAGCCU"
15
+ output:
16
+ - label: "U"
17
+ score: 0.25111356377601624
18
+ - label: "W"
19
+ score: 0.1200353354215622
20
+ - label: "K"
21
+ score: 0.10132723301649094
22
+ - label: "D"
23
+ score: 0.08383019268512726
24
+ - label: "A"
25
+ score: 0.05737845227122307
26
+ - example_title: "microRNA-21"
27
+ text: "UAGC<mask>UAUCAGACUGAUGUUG"
28
+ output:
29
+ - label: "U"
30
+ score: 0.36363866925239563
31
+ - label: "K"
32
+ score: 0.2319803684949875
33
+ - label: "G"
34
+ score: 0.14799022674560547
35
+ - label: "D"
36
+ score: 0.062339700758457184
37
+ - label: "W"
38
+ score: 0.04046041890978813
39
+ ---
40
+
41
+ # RNA-MSM
42
+
43
+ Pre-trained model on non-coding RNA (ncRNA) with multi (homologous) sequence alignment using a masked language modeling (MLM) objective.
44
+
45
+ ## Disclaimer
46
+
47
+ This is an UNOFFICIAL implementation of the [Multiple sequence alignment-based RNA language model and its application to structural inference](https://doi.org/10.1093/nar/gkad1031) by Yikun Zhang, Mei Lang, Jiuhong Jiang, Zhiqiang Gao, et al.
48
+
49
+ The OFFICIAL repository of RNA-MSM is at [yikunpku/RNA-MSM](https://github.com/yikunpku/RNA-MSM).
50
+
51
+ > [!WARNING]
52
+ > The MultiMolecule team is aware of a potential risk in reproducing the results of RNA-MSM.
53
+ >
54
+ > The original implementation of RNA-MSM used a custom tokenizer that does not append `<eos>` token to the end of the input sequence in consistent to MSA Transformer.
55
+ > This should not affect the performance of the model in most cases, but it can lead to unexpected behavior in some cases.
56
+ >
57
+ > Please set `eos_token=None` explicitly in the tokenizer if you want the exact behavior of the original implementation.
58
+ >
59
+ > See more at [issue #10](https://github.com/yikunpku/RNA-MSM/issues/10)
60
+
61
+ > [!TIP]
62
+ > The MultiMolecule team has confirmed that the provided model and checkpoints are producing the same intermediate representations as the original implementation.
63
+
64
+ **The team releasing RNA-MSM did not write this model card for this model so this model card has been written by the MultiMolecule team.**
65
+
66
+ ## Model Details
67
+
68
+ RNA-MSM is a [bert](https://huggingface.co/google-bert/bert-base-uncased)-style model.
69
+ RNA-MSM follows the [MSA](https://doi.org/10.1101/2021.02.12.430858) architecture, where it uses a column-wise attention and a row-wise attention to reduce the computational complexity over conventional self-attention.
70
+
71
+ RNA-MSM is pre-trained on a large corpus of non-coding RNA sequences with multiple sequence alignment (MSA) in a self-supervised fashion.
72
+ This means that the model was trained on the raw nucleotides of RNA sequences only, with an automatic process to generate inputs and labels from those texts.
73
+ Please refer to the [Training Details](#training-details) section for more information on the training process.
74
+
75
+ ### Model Specification
76
+
77
+ | Num Layers | Hidden Size | Num Heads | Intermediate Size | Num Parameters (M) | FLOPs (G) | MACs (G) | Max Num Tokens |
78
+ | ---------- | ----------- | --------- | ----------------- | ------------------ | --------- | -------- | -------------- |
79
+ | 10 | 768 | 12 | 3072 | 95.92 | 21.66 | 10.57 | 1024 |
80
+
81
+ ### Links
82
+
83
+ - **Code**: [multimolecule.rnamsm](https://github.com/DLS5-Omics/multimolecule/tree/master/multimolecule/models/rnamsm)
84
+ - **Weights**: [multimolecule/rnamsm](https://huggingface.co/multimolecule/rnamsm)
85
+ - **Data**: [Rfam](https://rfam.org)
86
+ - **Paper**: [Multiple sequence alignment-based RNA language model and its application to structural inference](https://doi.org/10.1093/nar/gkad1031)
87
+ - **Developed by**: Yikun Zhang, Mei Lang, Jiuhong Jiang, Zhiqiang Gao, Fan Xu, Thomas Litfin, Ke Chen, Jaswinder Singh, Xiansong Huang, Guoli Song, Yonghong Tian, Jian Zhan, Jie Chen, Yaoqi Zhou
88
+ - **Model type**: [BERT](https://huggingface.co/google-bert/bert-base-uncased) - [MSA](https://doi.org/10.1101/2021.02.12.430858)
89
+ - **Original Repository**: [yikunpku/RNA-MSM](https://github.com/yikunpku/RNA-MSM)
90
+
91
+ ## Usage
92
+
93
+ The model file depends on the [`multimolecule`](https://multimolecule.danling.org) library. You can install it using pip:
94
+
95
+ ```bash
96
+ pip install multimolecule
97
+ ```
98
+
99
+ ### Direct Use
100
+
101
+ #### Masked Language Modeling
102
+
103
+ You can use this model directly with a pipeline for masked language modeling:
104
+
105
+ ```python
106
+ >>> import multimolecule # you must import multimolecule to register models
107
+ >>> from transformers import pipeline
108
+ >>> unmasker = pipeline("fill-mask", model="multimolecule/rnamsm")
109
+ >>> unmasker("gguc<mask>cucugguuagaccagaucugagccu")
110
+
111
+ [{'score': 0.25111356377601624,
112
+ 'token': 9,
113
+ 'token_str': 'U',
114
+ 'sequence': 'G G U C U C U C U G G U U A G A C C A G A U C U G A G C C U'},
115
+ {'score': 0.1200353354215622,
116
+ 'token': 14,
117
+ 'token_str': 'W',
118
+ 'sequence': 'G G U C W C U C U G G U U A G A C C A G A U C U G A G C C U'},
119
+ {'score': 0.10132723301649094,
120
+ 'token': 15,
121
+ 'token_str': 'K',
122
+ 'sequence': 'G G U C K C U C U G G U U A G A C C A G A U C U G A G C C U'},
123
+ {'score': 0.08383019268512726,
124
+ 'token': 18,
125
+ 'token_str': 'D',
126
+ 'sequence': 'G G U C D C U C U G G U U A G A C C A G A U C U G A G C C U'},
127
+ {'score': 0.05737845227122307,
128
+ 'token': 6,
129
+ 'token_str': 'A',
130
+ 'sequence': 'G G U C A C U C U G G U U A G A C C A G A U C U G A G C C U'}]
131
+ ```
132
+
133
+ #### RNA Secondary Structure Prediction
134
+
135
+ You can use this model directly with a pipeline for secondary structure prediction:
136
+
137
+ ```python
138
+ >>> import multimolecule # you must import multimolecule to register models
139
+ >>> from transformers import pipeline
140
+ >>> predictor = pipeline("rna-secondary-structure", model="multimolecule/rnamsm")
141
+ >>> predictor("ggucuc")
142
+
143
+ {'sequence': 'G G U C U C',
144
+ 'secondary_structure': '......',
145
+ 'contact_map': [[0.0026149682234972715, 0.0022659720852971077, 0.0036333396565169096, 0.003973185084760189, 0.003466179594397545, 0.002944374457001686],
146
+ [0.0022659720852971077, 0.002837300067767501, 0.0037222092505544424, 0.0034382310695946217, 0.003498981473967433, 0.0030326175037771463],
147
+ [0.0036333396565169096, 0.0037222092505544424, 0.0026848132256418467, 0.002787569770589471, 0.0028246091678738594, 0.0030541368760168552],
148
+ [0.003973185084760189, 0.0034382310695946217, 0.002787569770589471, 0.0028833665419369936, 0.0027405559085309505, 0.0029016658663749695],
149
+ [0.003466179594397545, 0.003498981473967433, 0.0028246091678738594, 0.0027405559085309505, 0.002930475864559412, 0.003173925681039691],
150
+ [0.002944374457001686, 0.0030326175037771463, 0.0030541368760168552, 0.0029016658663749695, 0.003173925681039691, 0.003476994577795267]]}
151
+ ```
152
+
153
+ ### Downstream Use
154
+
155
+ #### Extract Features
156
+
157
+ Here is how to use this model to get the features of a given sequence in PyTorch:
158
+
159
+ ```python
160
+ from multimolecule import RnaTokenizer, RnaMsmModel
161
+
162
+
163
+ tokenizer = RnaTokenizer.from_pretrained("multimolecule/rnamsm")
164
+ model = RnaMsmModel.from_pretrained("multimolecule/rnamsm")
165
+
166
+ text = "UAGCUUAUCAGACUGAUGUUG"
167
+ input = tokenizer(text, return_tensors="pt")
168
+
169
+ output = model(**input)
170
+ ```
171
+
172
+ #### Sequence Classification / Regression
173
+
174
+ > [!NOTE]
175
+ > This model is not fine-tuned for any specific task. You will need to fine-tune the model on a downstream task to use it for sequence classification or regression.
176
+
177
+ Here is how to use this model as backbone to fine-tune for a sequence-level task in PyTorch:
178
+
179
+ ```python
180
+ import torch
181
+ from multimolecule import RnaTokenizer, RnaMsmForSequencePrediction
182
+
183
+
184
+ tokenizer = RnaTokenizer.from_pretrained("multimolecule/rnamsm")
185
+ model = RnaMsmForSequencePrediction.from_pretrained("multimolecule/rnamsm")
186
+
187
+ text = "UAGCUUAUCAGACUGAUGUUG"
188
+ input = tokenizer(text, return_tensors="pt")
189
+ label = torch.tensor([1])
190
+
191
+ output = model(**input, labels=label)
192
+ ```
193
+
194
+ #### Token Classification / Regression
195
+
196
+ > [!NOTE]
197
+ > This model is not fine-tuned for any specific task. You will need to fine-tune the model on a downstream task to use it for token classification or regression.
198
+
199
+ Here is how to use this model as backbone to fine-tune for a nucleotide-level task in PyTorch:
200
+
201
+ ```python
202
+ import torch
203
+ from multimolecule import RnaTokenizer, RnaMsmForTokenPrediction
204
+
205
+
206
+ tokenizer = RnaTokenizer.from_pretrained("multimolecule/rnamsm")
207
+ model = RnaMsmForNucleotidPrediction.from_pretrained("multimolecule/rnamsm")
208
+
209
+ text = "UAGCUUAUCAGACUGAUGUUG"
210
+ input = tokenizer(text, return_tensors="pt")
211
+ label = torch.randint(2, (len(text), ))
212
+
213
+ output = model(**input, labels=label)
214
+ ```
215
+
216
+ #### Contact Classification / Regression
217
+
218
+ > [!NOTE]
219
+ > This model is not fine-tuned for any specific task. You will need to fine-tune the model on a downstream task to use it for contact classification or regression.
220
+
221
+ Here is how to use this model as backbone to fine-tune for a contact-level task in PyTorch:
222
+
223
+ ```python
224
+ import torch
225
+ from multimolecule import RnaTokenizer, RnaMsmForContactPrediction
226
+
227
+
228
+ tokenizer = RnaTokenizer.from_pretrained("multimolecule/rnamsm")
229
+ model = RnaMsmForContactPrediction.from_pretrained("multimolecule/rnamsm")
230
+
231
+ text = "UAGCUUAUCAGACUGAUGUUG"
232
+ input = tokenizer(text, return_tensors="pt")
233
+ label = torch.randint(2, (len(text), len(text)))
234
+
235
+ output = model(**input, labels=label)
236
+ ```
237
+
238
+ ## Training Details
239
+
240
+ RNA-MSM used Masked Language Modeling (MLM) as the pre-training objective: taking a sequence, the model randomly masks 15% of the tokens in the input then runs the entire masked sentence through the model and has to predict the masked tokens. This is comparable to the Cloze task in language modeling.
241
+
242
+ ### Training Data
243
+
244
+ The RNA-MSM model was pre-trained on [Rfam](https://rfam.org).
245
+ The Rfam database is a collection of RNA sequence families of structural RNAs including non-coding RNA genes as well as cis-regulatory elements.
246
+ RNA-MSM used Rfam 14.7 which contains 4,069 RNA families.
247
+
248
+ To avoid potential overfitting in structural inference, RNA-MSM excluded families with experimentally determined structures, such as ribosomal RNAs, transfer RNAs, and small nuclear RNAs. The final dataset contains 3,932 RNA families. The median value for the number of MSA sequences for these families by RNAcmap3 is 2,184.
249
+
250
+ To increase the number of homologous sequences, RNA-MSM used an automatic pipeline, RNAcmap3, for homolog search and sequence alignment. RNAcmap3 is a pipeline that combines the BLAST-N, INFERNAL, Easel, RNAfold and evolutionary coupling tools to generate homologous sequences.
251
+
252
+ RNA-MSM preprocessed all tokens by replacing "T"s with "U"s and substituting "R", "Y", "K", "M", "S", "W", "B", "D", "H", "V", "N" with "X".
253
+
254
+ Note that [`RnaTokenizer`][multimolecule.RnaTokenizer] will convert "T"s to "U"s for you, you may disable this behaviour by passing `replace_T_with_U=False`. `RnaTokenizer` does not perform other substitutions.
255
+
256
+ ### Training Procedure
257
+
258
+ #### Preprocessing
259
+
260
+ RNA-MSM used masked language modeling (MLM) as the pre-training objective. The masking procedure is similar to the one used in BERT:
261
+
262
+ - 15% of the tokens are masked.
263
+ - In 80% of the cases, the masked tokens are replaced by `<mask>`.
264
+ - In 10% of the cases, the masked tokens are replaced by a random token (different) from the one they replace.
265
+ - In the 10% remaining cases, the masked tokens are left as is.
266
+
267
+ #### PreTraining
268
+
269
+ The model was trained on 8 NVIDIA V100 GPUs with 32GiB memories.
270
+
271
+ - Learning rate: 3e-4
272
+ - Weight decay: 3e-4
273
+ - Optimizer: Adam
274
+ - Learning rate warm-up: 16,000 steps
275
+ - Epochs: 300
276
+ - Batch Size: 1
277
+ - Dropout: 0.1
278
+
279
+ ## Citation
280
+
281
+ **BibTeX**:
282
+
283
+ ```bibtex
284
+ @article{zhang2023multiple, author = {Zhang, Yikun and Lang, Mei and Jiang, Jiuhong and Gao, Zhiqiang and Xu, Fan and Litfin, Thomas and Chen, Ke and Singh, Jaswinder and Huang, Xiansong and Song, Guoli and Tian, Yonghong and Zhan, Jian and Chen, Jie and Zhou, Yaoqi}, title = "{Multiple sequence alignment-based RNA language model and its application to structural inference}", journal = {Nucleic Acids Research}, volume = {52}, number = {1}, pages = {e3-e3}, year = {2023}, month = {11}, abstract = "{Compared with proteins, DNA and RNA are more difficult languages to interpret because four-letter coded DNA/RNA sequences have less information content than 20-letter coded protein sequences. While BERT (Bidirectional Encoder Representations from Transformers)-like language models have been developed for RNA, they are ineffective at capturing the evolutionary information from homologous sequences because unlike proteins, RNA sequences are less conserved. Here, we have developed an unsupervised multiple sequence alignment-based RNA language model (RNA-MSM) by utilizing homologous sequences from an automatic pipeline, RNAcmap, as it can provide significantly more homologous sequences than manually annotated Rfam. We demonstrate that the resulting unsupervised, two-dimensional attention maps and one-dimensional embeddings from RNA-MSM contain structural information. In fact, they can be directly mapped with high accuracy to 2D base pairing probabilities and 1D solvent accessibilities, respectively. Further fine-tuning led to significantly improved performance on these two downstream tasks compared with existing state-of-the-art techniques including SPOT-RNA2 and RNAsnap2. By comparison, RNA-FM, a BERT-based RNA language model, performs worse than one-hot encoding with its embedding in base pair and solvent-accessible surface area prediction. We anticipate that the pre-trained RNA-MSM model can be fine-tuned on many other tasks related to RNA structure and function.}", issn = {0305-1048}, doi = {10.1093/nar/gkad1031}, url = {https://doi.org/10.1093/nar/gkad1031}, eprint = {https://academic.oup.com/nar/article-pdf/52/1/e3/55443207/gkad1031.pdf},
285
+ }
286
+ ```
287
+
288
+ ## Contact
289
+
290
+ Please use GitHub issues of [MultiMolecule](https://github.com/DLS5-Omics/multimolecule/issues) for any questions or comments on the model card.
291
+
292
+ Please contact the authors of the [RNA-MSM paper](https://doi.org/10.1093/nar/gkad1031) for questions or comments on the paper/model.
293
+
294
+ ## License
295
+
296
+ This model is licensed under the [AGPL-3.0 License](https://www.gnu.org/licenses/agpl-3.0.html).
297
+
298
+ ```spdx
299
+ SPDX-License-Identifier: AGPL-3.0-or-later
300
+ ```
config.json ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "RnaMsmForPreTraining"
4
+ ],
5
+ "attention_bias": true,
6
+ "attention_dropout": 0.1,
7
+ "attention_type": "standard",
8
+ "bos_token_id": 1,
9
+ "embed_positions_msa": true,
10
+ "eos_token_id": 2,
11
+ "head": null,
12
+ "hidden_act": "gelu",
13
+ "hidden_dropout": 0.1,
14
+ "hidden_size": 768,
15
+ "id2label": null,
16
+ "initializer_range": 0.02,
17
+ "intermediate_size": 3072,
18
+ "label2id": null,
19
+ "layer_norm_eps": 1e-12,
20
+ "layer_type": "standard",
21
+ "lm_head": null,
22
+ "mask_token_id": 4,
23
+ "max_position_embeddings": 1024,
24
+ "max_tokens_per_msa": 16384,
25
+ "model_type": "rnamsm",
26
+ "null_token_id": 5,
27
+ "num_attention_heads": 12,
28
+ "num_hidden_layers": 10,
29
+ "num_labels": 1,
30
+ "pad_token_id": 0,
31
+ "position_embedding_type": "absolute",
32
+ "torch_dtype": "float32",
33
+ "transformers_version": "4.48.2",
34
+ "unk_token_id": 3,
35
+ "use_cache": true,
36
+ "vocab_size": 26
37
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:22a88c09adfceed95b4d01c758cce4a5e267d44d812c2a656006c1fce29ece1b
3
+ size 383723908
pytorch_model.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0b95b997fc889b8bf42473b7043ec9a7e9d603641aa38d36c84f6c21353f9d0d
3
+ size 383782098
special_tokens_map.json ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "additional_special_tokens": [
3
+ "<null>"
4
+ ],
5
+ "bos_token": "<cls>",
6
+ "cls_token": "<cls>",
7
+ "eos_token": "<eos>",
8
+ "mask_token": "<mask>",
9
+ "pad_token": "<pad>",
10
+ "sep_token": "<eos>",
11
+ "unk_token": "<unk>"
12
+ }
tokenizer_config.json ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "added_tokens_decoder": {
3
+ "0": {
4
+ "content": "<pad>",
5
+ "lstrip": false,
6
+ "normalized": false,
7
+ "rstrip": false,
8
+ "single_word": false,
9
+ "special": true
10
+ },
11
+ "1": {
12
+ "content": "<cls>",
13
+ "lstrip": false,
14
+ "normalized": false,
15
+ "rstrip": false,
16
+ "single_word": false,
17
+ "special": true
18
+ },
19
+ "2": {
20
+ "content": "<eos>",
21
+ "lstrip": false,
22
+ "normalized": false,
23
+ "rstrip": false,
24
+ "single_word": false,
25
+ "special": true
26
+ },
27
+ "3": {
28
+ "content": "<unk>",
29
+ "lstrip": false,
30
+ "normalized": false,
31
+ "rstrip": false,
32
+ "single_word": false,
33
+ "special": true
34
+ },
35
+ "4": {
36
+ "content": "<mask>",
37
+ "lstrip": false,
38
+ "normalized": false,
39
+ "rstrip": false,
40
+ "single_word": false,
41
+ "special": true
42
+ },
43
+ "5": {
44
+ "content": "<null>",
45
+ "lstrip": false,
46
+ "normalized": false,
47
+ "rstrip": false,
48
+ "single_word": false,
49
+ "special": true
50
+ }
51
+ },
52
+ "additional_special_tokens": [
53
+ "<null>"
54
+ ],
55
+ "bos_token": "<cls>",
56
+ "clean_up_tokenization_spaces": true,
57
+ "cls_token": "<cls>",
58
+ "codon": false,
59
+ "eos_token": "<eos>",
60
+ "extra_special_tokens": {},
61
+ "mask_token": "<mask>",
62
+ "model_max_length": 1024,
63
+ "nmers": 1,
64
+ "pad_token": "<pad>",
65
+ "replace_T_with_U": true,
66
+ "sep_token": "<eos>",
67
+ "tokenizer_class": "RnaTokenizer",
68
+ "unk_token": "<unk>"
69
+ }
vocab.txt ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <pad>
2
+ <cls>
3
+ <eos>
4
+ <unk>
5
+ <mask>
6
+ <null>
7
+ A
8
+ C
9
+ G
10
+ U
11
+ N
12
+ R
13
+ Y
14
+ S
15
+ W
16
+ K
17
+ M
18
+ B
19
+ D
20
+ H
21
+ V
22
+ .
23
+ X
24
+ *
25
+ -
26
+ I