From 3f51f48ee55690c7f64e591a729d9cb034264ca4 Mon Sep 17 00:00:00 2001
From: SAM <8dmasters@gmail.com>
Date: Fri, 31 May 2024 10:00:10 +0530
Subject: [PATCH 001/159] Create Transformers.md
Added a empty .md file to be served as a guide for Transformers
---
contrib/machine-learning/Transformers.md | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 contrib/machine-learning/Transformers.md
diff --git a/contrib/machine-learning/Transformers.md b/contrib/machine-learning/Transformers.md
new file mode 100644
index 0000000..e69de29
From b832f8f0c90673462ecc990f45595761565b027d Mon Sep 17 00:00:00 2001
From: SAM <60264918+SAM-DEV007@users.noreply.github.com>
Date: Fri, 31 May 2024 13:40:20 +0530
Subject: [PATCH 002/159] Update Transformers.md
Added topics
---
contrib/machine-learning/Transformers.md | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/contrib/machine-learning/Transformers.md b/contrib/machine-learning/Transformers.md
index e69de29..7bcc102 100644
--- a/contrib/machine-learning/Transformers.md
+++ b/contrib/machine-learning/Transformers.md
@@ -0,0 +1,21 @@
+# Transformers
+## Introduction
+A transformer is a deep learning architecture developed by Google and based on the multi-head attention mechanism. It is based on the softmax-based attention
+mechanism. Before transformers, predecessors of attention mechanism were added to gated recurrent neural networks, such as LSTMs and gated recurrent units (GRUs), which
+processed datasets sequentially. Dependency on previous token computations prevented them from being able to parallelize the attention mechanism.
+
+## Key Concepts
+
+## Architecture
+
+## Implementation
+### Theory
+Text is converted to numerical representations called tokens, and each token is converted into a vector via looking up from a word embedding table.
+At each layer, each token is then contextualized within the scope of the context window with other tokens via a parallel multi-head attention mechanism
+allowing the signal for key tokens to be amplified and less important tokens to be diminished.
+
+### HuggingFace
+
+### Tensorflow and Keras
+
+### PyTorch
From 5b3c8d7ad108d4a65b4a946d719d242fe9eae308 Mon Sep 17 00:00:00 2001
From: SAM <60264918+SAM-DEV007@users.noreply.github.com>
Date: Fri, 31 May 2024 15:14:09 +0530
Subject: [PATCH 003/159] Update Transformers.md
Added information about Model Architecture
---
contrib/machine-learning/Transformers.md | 59 +++++++++++++++++++++++-
1 file changed, 57 insertions(+), 2 deletions(-)
diff --git a/contrib/machine-learning/Transformers.md b/contrib/machine-learning/Transformers.md
index 7bcc102..49a1b97 100644
--- a/contrib/machine-learning/Transformers.md
+++ b/contrib/machine-learning/Transformers.md
@@ -4,9 +4,53 @@ A transformer is a deep learning architecture developed by Google and based on t
mechanism. Before transformers, predecessors of attention mechanism were added to gated recurrent neural networks, such as LSTMs and gated recurrent units (GRUs), which
processed datasets sequentially. Dependency on previous token computations prevented them from being able to parallelize the attention mechanism.
-## Key Concepts
+## Model Architecture
+

-## Architecture
+### Encoder
+The encoder is composed of a stack of identical layers. Each layer has two sub-layers. The first is a multi-head self-attention mechanism, and the second is a simple, positionwise fully connected feed-forward network. Each encoder consists of two major components: a self-attention mechanism and a feed-forward neural network. The self-attention mechanism accepts input encodings from the previous encoder and weights their relevance to each other to generate output encodings. The feed-forward neural network further processes each output encoding individually. These output encodings are then passed to the next encoder as its input, as well as to the decoders.
+
+### Decoder
+The decoder is also composed of a stack of identical layers. In addition to the two sub-layers in each encoder layer, the decoder inserts a third sub-layer, which performs multi-head attention over the output of the encoder stack. The decoder functions in a similar fashion to the encoder, but an additional attention mechanism is inserted which instead draws relevant information from the encodings generated by the encoders. This mechanism can also be called the encoder-decoder attention.
+
+### Attention
+#### Scaled Dot-Product Attention
+The input consists of queries and keys of dimension dk, and values of dimension dv. We compute the dot products of the query with all keys, divide each by √dk, and apply a softmax function to obtain the weights on the values.
+
+> Attention(Q, K, V) = softmax(QKT / √dk) * V
+
+#### Multi-Head Attention
+Instead of performing a single attention function with dmodel-dimensional keys, values and queries, it is beneficial to linearly project the queries, keys and values h times with different, learned linear projections to dk, dk and dv dimensions, respectively.
+
+Multi-head attention allows the model to jointly attend to information from different representation
+subspaces at different positions. With a single attention head, averaging inhibits this.
+
+> MultiHead(Q, K, V) = Concat(head1, ..., headh) * WO
+
+where,
+
+> headi = Attention(Q * WiQ, K * WiK, V * WiV)
+
+where the projections are parameter matrices.
+
+#### Masked Attention
+It may be necessary to cut out attention links between some word-pairs. For example, the decoder for token position
+𝑡 should not have access to token position 𝑡+1.
+
+> MaskedAttention(Q, K, V) = softmax(M + (QKT / √dk)) * V
+
+### Feed-Forward Network
+Each of the layers in the encoder and decoder contains a fully connected feed-forward network, which is applied to each position separately and identically. This
+consists of two linear transformations with a ReLU activation in between.
+> FFN(x) = (max(0, (x * W1) + b1) * W2) + b2
+
+### Positional Encoding
+A positional encoding is a fixed-size vector representation that encapsulates the relative positions of tokens within a target sequence: it provides the transformer model with information about where the words are in the input sequence.
+
+The sine and cosine functions of different frequencies:
+> PE(pos,2i) = sin(pos/100002i/dmodel)
+
+> PE(pos,2i+1) = cos(pos/100002i/dmodel)
## Implementation
### Theory
@@ -19,3 +63,14 @@ allowing the signal for key tokens to be amplified and less important tokens to
### Tensorflow and Keras
### PyTorch
+
+## Application
+The transformer has had great success in natural language processing (NLP). Many large language models such as GPT-2, GPT-3, GPT-4, Claude, BERT, XLNet, RoBERTa and ChatGPT demonstrate the ability of transformers to perform a wide variety of such NLP-related tasks, and have the potential to find real-world applications.
+
+These may include:
+- Machine translation
+- Document summarization
+- Text generation
+- Biological sequence analysis
+- Computer code generation
+- Video analysis
From 35357d2fe3f6650faca3d0f19327fe4fa7e8629d Mon Sep 17 00:00:00 2001
From: SAM <60264918+SAM-DEV007@users.noreply.github.com>
Date: Fri, 31 May 2024 17:04:07 +0530
Subject: [PATCH 004/159] Update Transformers.md
Added Tensorflow implementation
---
contrib/machine-learning/Transformers.md | 136 ++++++++++++++++++++++-
1 file changed, 134 insertions(+), 2 deletions(-)
diff --git a/contrib/machine-learning/Transformers.md b/contrib/machine-learning/Transformers.md
index 49a1b97..a5a56ec 100644
--- a/contrib/machine-learning/Transformers.md
+++ b/contrib/machine-learning/Transformers.md
@@ -58,12 +58,144 @@ Text is converted to numerical representations called tokens, and each token is
At each layer, each token is then contextualized within the scope of the context window with other tokens via a parallel multi-head attention mechanism
allowing the signal for key tokens to be amplified and less important tokens to be diminished.
-### HuggingFace
+### Tensorflow
+Tensorflow provides the transformer encoder and decoder block that can be implemented by the specification of the user. Although, the transformer is not provided as a standalone to be imported and executed, the user has to create the model first. They also have a tutorial on how to implement the transformer from scratch for machine translation and can be found [here](https://www.tensorflow.org/text/tutorials/transformer).
-### Tensorflow and Keras
+More information on [encoder](https://www.tensorflow.org/api_docs/python/tfm/nlp/layers/TransformerEncoderBlock) and [decoder](https://www.tensorflow.org/api_docs/python/tfm/nlp/layers/TransformerDecoderBlock) block mentioned in the code.
+
+Imports:
+```
+import tensorflow as tf
+import tensorflow_models as tfm
+```
+
+Adding word embeddings and positional encoding:
+```
+class PositionalEmbedding(tf.keras.layers.Layer):
+ def __init__(self, vocab_size, d_model):
+ super().__init__()
+ self.d_model = d_model
+ self.embedding = tf.keras.layers.Embedding(vocab_size, d_model, mask_zero=True)
+ self.pos_encoding = tfm.nlp.layers.RelativePositionEmbedding(hidden_size=d_model)
+
+ def compute_mask(self, *args, **kwargs):
+ return self.embedding.compute_mask(*args, **kwargs)
+
+ def call(self, x):
+ length = tf.shape(x)[1]
+ x = self.embedding(x)
+ x = x + self.pos_encoding[tf.newaxis, :length, :]
+ return x
+```
+
+Creating the encoder for the transformer:
+```
+class Encoder(tf.keras.layers.Layer):
+ def __init__(self, num_layers, d_model, num_heads,
+ dff, vocab_size, dropout_rate=0.1):
+ super().__init__()
+
+ self.d_model = d_model
+ self.num_layers = num_layers
+
+ self.pos_embedding = PositionalEmbedding(
+ vocab_size=vocab_size, d_model=d_model)
+
+ self.enc_layers = [
+ tfm.nlp.layers.TransformerEncoderBlock(output_last_dim=d_model,
+ num_attention_heads=num_heads,
+ inner_dim=dff,
+ inner_activation="relu",
+ inner_dropout=dropout_rate)
+ for _ in range(num_layers)]
+ self.dropout = tf.keras.layers.Dropout(dropout_rate)
+
+ def call(self, x):
+ x = self.pos_embedding(x, length=2048)
+ x = self.dropout(x)
+
+ for i in range(self.num_layers):
+ x = self.enc_layers[i](x)
+
+ return x
+```
+
+Creating the decoder for the transformer:
+```
+class Decoder(tf.keras.layers.Layer):
+ def __init__(self, num_layers, d_model, num_heads, dff, vocab_size,
+ dropout_rate=0.1):
+ super(Decoder, self).__init__()
+
+ self.d_model = d_model
+ self.num_layers = num_layers
+
+ self.pos_embedding = PositionalEmbedding(vocab_size=vocab_size,
+ d_model=d_model)
+ self.dropout = tf.keras.layers.Dropout(dropout_rate)
+ self.dec_layers = [
+ tfm.nlp.layers.TransformerDecoderBlock(num_attention_heads=num_heads,
+ intermediate_size=dff,
+ intermediate_activation="relu",
+ dropout_rate=dropout_rate)
+ for _ in range(num_layers)]
+
+ def call(self, x, context):
+ x = self.pos_embedding(x)
+ x = self.dropout(x)
+
+ for i in range(self.num_layers):
+ x = self.dec_layers[i](x, context)
+
+ return x
+```
+
+Combining the encoder and decoder to create the transformer:
+```
+class Transformer(tf.keras.Model):
+ def __init__(self, num_layers, d_model, num_heads, dff,
+ input_vocab_size, target_vocab_size, dropout_rate=0.1):
+ super().__init__()
+ self.encoder = Encoder(num_layers=num_layers, d_model=d_model,
+ num_heads=num_heads, dff=dff,
+ vocab_size=input_vocab_size,
+ dropout_rate=dropout_rate)
+
+ self.decoder = Decoder(num_layers=num_layers, d_model=d_model,
+ num_heads=num_heads, dff=dff,
+ vocab_size=target_vocab_size,
+ dropout_rate=dropout_rate)
+
+ self.final_layer = tf.keras.layers.Dense(target_vocab_size)
+
+ def call(self, inputs):
+ context, x = inputs
+
+ context = self.encoder(context)
+ x = self.decoder(x, context)
+ logits = self.final_layer(x)
+
+ return logits
+```
+
+Model initialization that be used for training and inference:
+```
+transformer = Transformer(
+ num_layers=num_layers,
+ d_model=d_model,
+ num_heads=num_heads,
+ dff=dff,
+ input_vocab_size=tokenizers.pt.get_vocab_size().numpy(),
+ target_vocab_size=tokenizers.en.get_vocab_size().numpy(),
+ dropout_rate=dropout_rate
+)
+```
### PyTorch
+
+### HuggingFace
+
## Application
The transformer has had great success in natural language processing (NLP). Many large language models such as GPT-2, GPT-3, GPT-4, Claude, BERT, XLNet, RoBERTa and ChatGPT demonstrate the ability of transformers to perform a wide variety of such NLP-related tasks, and have the potential to find real-world applications.
From f56131349d1ad0e6e27209ea3d9217c13e695e8e Mon Sep 17 00:00:00 2001
From: SAM <60264918+SAM-DEV007@users.noreply.github.com>
Date: Fri, 31 May 2024 17:13:19 +0530
Subject: [PATCH 005/159] Update Transformers.md
Added python tag to code blocks
---
contrib/machine-learning/Transformers.md | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/contrib/machine-learning/Transformers.md b/contrib/machine-learning/Transformers.md
index a5a56ec..ffdea05 100644
--- a/contrib/machine-learning/Transformers.md
+++ b/contrib/machine-learning/Transformers.md
@@ -64,13 +64,13 @@ Tensorflow provides the transformer encoder and decoder block that can be implem
More information on [encoder](https://www.tensorflow.org/api_docs/python/tfm/nlp/layers/TransformerEncoderBlock) and [decoder](https://www.tensorflow.org/api_docs/python/tfm/nlp/layers/TransformerDecoderBlock) block mentioned in the code.
Imports:
-```
+```python
import tensorflow as tf
import tensorflow_models as tfm
```
Adding word embeddings and positional encoding:
-```
+```python
class PositionalEmbedding(tf.keras.layers.Layer):
def __init__(self, vocab_size, d_model):
super().__init__()
@@ -89,7 +89,7 @@ class PositionalEmbedding(tf.keras.layers.Layer):
```
Creating the encoder for the transformer:
-```
+```python
class Encoder(tf.keras.layers.Layer):
def __init__(self, num_layers, d_model, num_heads,
dff, vocab_size, dropout_rate=0.1):
@@ -121,7 +121,7 @@ class Encoder(tf.keras.layers.Layer):
```
Creating the decoder for the transformer:
-```
+```python
class Decoder(tf.keras.layers.Layer):
def __init__(self, num_layers, d_model, num_heads, dff, vocab_size,
dropout_rate=0.1):
@@ -151,7 +151,7 @@ class Decoder(tf.keras.layers.Layer):
```
Combining the encoder and decoder to create the transformer:
-```
+```python
class Transformer(tf.keras.Model):
def __init__(self, num_layers, d_model, num_heads, dff,
input_vocab_size, target_vocab_size, dropout_rate=0.1):
@@ -179,7 +179,7 @@ class Transformer(tf.keras.Model):
```
Model initialization that be used for training and inference:
-```
+```python
transformer = Transformer(
num_layers=num_layers,
d_model=d_model,
From ca9c6a9a1f23d1e6b5901954c8a5c5c772bd80a7 Mon Sep 17 00:00:00 2001
From: SAM <60264918+SAM-DEV007@users.noreply.github.com>
Date: Fri, 31 May 2024 17:44:28 +0530
Subject: [PATCH 006/159] Update Transformers.md
Added PyTorch implementation
---
contrib/machine-learning/Transformers.md | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/contrib/machine-learning/Transformers.md b/contrib/machine-learning/Transformers.md
index ffdea05..cb90cf1 100644
--- a/contrib/machine-learning/Transformers.md
+++ b/contrib/machine-learning/Transformers.md
@@ -56,7 +56,9 @@ The sine and cosine functions of different frequencies:
### Theory
Text is converted to numerical representations called tokens, and each token is converted into a vector via looking up from a word embedding table.
At each layer, each token is then contextualized within the scope of the context window with other tokens via a parallel multi-head attention mechanism
-allowing the signal for key tokens to be amplified and less important tokens to be diminished.
+allowing the signal for key tokens to be amplified and less important tokens to be diminished.
+
+The transformer uses an encoder-decoder architecture. The encoder extracts features from an input sentence, and the decoder uses the features to produce an output sentence. Some architectures use full encoders and decoders, autoregressive encoders and decoders, or combination of both. This depends on the usage and context of the input.
### Tensorflow
Tensorflow provides the transformer encoder and decoder block that can be implemented by the specification of the user. Although, the transformer is not provided as a standalone to be imported and executed, the user has to create the model first. They also have a tutorial on how to implement the transformer from scratch for machine translation and can be found [here](https://www.tensorflow.org/text/tutorials/transformer).
@@ -192,10 +194,30 @@ transformer = Transformer(
```
### PyTorch
+Unlike Tensorflow, PyTorch provides the full implementation of the transformer model that can be executed on the go. More information can be found [here](https://pytorch.org/docs/stable/_modules/torch/nn/modules/transformer.html#Transformer). A full implementation of the model can be found [here](https://github.com/pytorch/examples/tree/master/word_language_model).
+Imports:
+```python
+import torch
+import torch.nn as nn
+```
+
+Initializing the model:
+```python
+transformer = nn.Transformer(nhead=16, num_encoder_layers=8)
+```
+
+Sample Implementation:
+```python
+src = torch.rand((10, 32, 512))
+tgt = torch.rand((20, 32, 512))
+
+output = transformer(src, tgt)
+```
### HuggingFace
+
## Application
The transformer has had great success in natural language processing (NLP). Many large language models such as GPT-2, GPT-3, GPT-4, Claude, BERT, XLNet, RoBERTa and ChatGPT demonstrate the ability of transformers to perform a wide variety of such NLP-related tasks, and have the potential to find real-world applications.
From d81e875a3235d7c9f50f9a42bb359bf80d3146a1 Mon Sep 17 00:00:00 2001
From: SAM <60264918+SAM-DEV007@users.noreply.github.com>
Date: Fri, 31 May 2024 18:32:47 +0530
Subject: [PATCH 007/159] Update Transformers.md
Added outputs for PyTorch and HuggingFace implementation
---
contrib/machine-learning/Transformers.md | 114 ++++++++++++++++++++++-
1 file changed, 112 insertions(+), 2 deletions(-)
diff --git a/contrib/machine-learning/Transformers.md b/contrib/machine-learning/Transformers.md
index cb90cf1..e9e50e8 100644
--- a/contrib/machine-learning/Transformers.md
+++ b/contrib/machine-learning/Transformers.md
@@ -61,6 +61,8 @@ allowing the signal for key tokens to be amplified and less important tokens to
The transformer uses an encoder-decoder architecture. The encoder extracts features from an input sentence, and the decoder uses the features to produce an output sentence. Some architectures use full encoders and decoders, autoregressive encoders and decoders, or combination of both. This depends on the usage and context of the input.
### Tensorflow
+TensorFlow is a free and open-source software library for machine learning and artificial intelligence. It can be used across a range of tasks but has a particular focus on training and inference of deep neural networks. It was developed by the Google Brain team for Google's internal use in research and production.
+
Tensorflow provides the transformer encoder and decoder block that can be implemented by the specification of the user. Although, the transformer is not provided as a standalone to be imported and executed, the user has to create the model first. They also have a tutorial on how to implement the transformer from scratch for machine translation and can be found [here](https://www.tensorflow.org/text/tutorials/transformer).
More information on [encoder](https://www.tensorflow.org/api_docs/python/tfm/nlp/layers/TransformerEncoderBlock) and [decoder](https://www.tensorflow.org/api_docs/python/tfm/nlp/layers/TransformerDecoderBlock) block mentioned in the code.
@@ -193,7 +195,22 @@ transformer = Transformer(
)
```
+Sample:
+```python
+src = tf.random.uniform((64, 40))
+tgt = tf.random.uniform((64, 50))
+
+output = transformer((src, tgt))
+```
+
+O/P:
+```
+
+```
+
### PyTorch
+PyTorch is a machine learning library based on the Torch library, used for applications such as computer vision and natural language processing, originally developed by Meta AI and now part of the Linux Foundation umbrella.
+
Unlike Tensorflow, PyTorch provides the full implementation of the transformer model that can be executed on the go. More information can be found [here](https://pytorch.org/docs/stable/_modules/torch/nn/modules/transformer.html#Transformer). A full implementation of the model can be found [here](https://github.com/pytorch/examples/tree/master/word_language_model).
Imports:
@@ -207,7 +224,7 @@ Initializing the model:
transformer = nn.Transformer(nhead=16, num_encoder_layers=8)
```
-Sample Implementation:
+Sample:
```python
src = torch.rand((10, 32, 512))
tgt = torch.rand((20, 32, 512))
@@ -215,8 +232,101 @@ tgt = torch.rand((20, 32, 512))
output = transformer(src, tgt)
```
-### HuggingFace
+O/P:
+```
+tensor([[[ 0.2938, -0.4824, -0.7816, ..., 0.0742, 0.5162, 0.3632],
+ [-0.0786, -0.5241, 0.6384, ..., 0.3462, -0.0618, 0.9943],
+ [ 0.7827, 0.1067, -0.1637, ..., -1.7730, -0.3322, -0.0029],
+ ...,
+ [-0.3202, 0.2341, -0.0896, ..., -0.9714, -0.1251, -0.0711],
+ [-0.1663, -0.5047, -0.0404, ..., -0.9339, 0.3963, 0.1018],
+ [ 1.2834, -0.4400, 0.0486, ..., -0.6876, -0.4752, 0.0180]],
+ [[ 0.9869, -0.7384, -1.0704, ..., -0.9417, 1.3279, -0.1665],
+ [ 0.3445, -0.2454, -0.3644, ..., -0.4856, -1.1004, -0.6819],
+ [ 0.7568, -0.3151, -0.5034, ..., -1.2081, -0.7119, 0.3775],
+ ...,
+ [-0.0451, -0.7596, 0.0168, ..., -0.8267, -0.3272, 1.0457],
+ [ 0.3150, -0.6588, -0.1840, ..., 0.1822, -0.0653, 0.9053],
+ [ 0.8692, -0.3519, 0.3128, ..., -1.8446, -0.2325, -0.8662]],
+
+ [[ 0.9719, -0.3113, 0.4637, ..., -0.4422, 1.2348, 0.8274],
+ [ 0.3876, -0.9529, -0.7810, ..., -0.5843, -1.1439, -0.3366],
+ [-0.5774, 0.3789, -0.2819, ..., -1.4057, 0.4352, 0.1474],
+ ...,
+ [ 0.6899, -0.1146, -0.3297, ..., -1.7059, -0.1750, 0.4203],
+ [ 0.3689, -0.5174, -0.1253, ..., 0.1417, 0.4159, 0.7560],
+ [ 0.5024, -0.7996, 0.1592, ..., -0.8344, -1.1125, 0.4736]],
+
+ ...,
+
+ [[ 0.0704, -0.3971, -0.2768, ..., -1.9929, 0.8608, 1.2264],
+ [ 0.4013, -0.0962, -0.0965, ..., -0.4452, -0.8682, -0.4593],
+ [ 0.1656, 0.5224, -0.1723, ..., -1.5785, 0.3219, 1.1507],
+ ...,
+ [-0.9443, 0.4653, 0.2936, ..., -0.9840, -0.0142, -0.1595],
+ [-0.6544, -0.3294, -0.0803, ..., 0.1623, -0.5061, 0.9824],
+ [-0.0978, -1.0023, -0.6915, ..., -0.2296, -0.0594, -0.4715]],
+
+ [[ 0.6531, -0.9285, -0.0331, ..., -1.1481, 0.7768, -0.7321],
+ [ 0.3325, -0.6683, -0.6083, ..., -0.4501, 0.2289, 0.3573],
+ [-0.6750, 0.4600, -0.8512, ..., -2.0097, -0.5159, 0.2773],
+ ...,
+ [-1.4356, -1.0135, 0.0081, ..., -1.2985, -0.3715, -0.2678],
+ [ 0.0546, -0.2111, -0.0965, ..., -0.3822, -0.4612, 1.6217],
+ [ 0.7700, -0.5309, -0.1754, ..., -2.2807, -0.0320, -1.5551]],
+
+ [[ 0.2399, -0.9659, 0.1086, ..., -1.1756, 0.4063, 0.0615],
+ [-0.2202, -0.7972, -0.5024, ..., -0.9126, -1.5248, 0.2418],
+ [ 0.5215, 0.4540, 0.0036, ..., -0.2135, 0.2145, 0.6638],
+ ...,
+ [-0.2190, -0.4967, 0.7149, ..., -0.3324, 0.3502, 1.0624],
+ [-0.0108, -0.9205, -0.1315, ..., -1.0153, 0.2989, 1.1415],
+ [ 1.1284, -0.6560, 0.6755, ..., -1.2157, 0.8580, -0.5022]]],
+ grad_fn=)
+```
+```
+>> output.shape
+torch.Size([20, 32, 512])
+```
+
+### HuggingFace
+Hugging Face, Inc. is a French-American company incorporated under the Delaware General Corporation Law and based in New York City that develops computation tools for building applications using machine learning.
+
+It has a wide-range of models that can implemented in Tensorflow, PyTorch and other development backends as well. The models are already trained on a dataset and can be pretrained on custom dataset for customized use, according to the user. The information for training the model and loading the pretrained model can be found [here](https://huggingface.co/docs/transformers/en/training).
+
+In HuggingFace, `pipeline` is used to run inference from the trained model available in the Hub. This is very beginner friendly. The model is downloaded to the local system on running the script before running the inference. It has to be made sure that the model downloaded does not exceed your available data plan.
+
+Imports:
+```python
+from transformers import pipeline
+```
+
+Initialization:
+
+The model used here is BART (large) which was trained on MultiNLI dataset, which consist of sentence paired with its textual entailment.
+```python
+classifier = pipeline(model="facebook/bart-large-mnli")
+```
+
+Sample:
+
+The first argument is the sentence which needs to be analyzed. The second argument, `candidate_labels`, is the list of labels which most likely the first argument sentence belongs to. The output dictionary will have a key as `score`, where the highest index is the textual entailment of the sentence with the index of the label in the list.
+
+```python
+output = classifier(
+ "I need to leave but later",
+ candidate_labels=["urgent", "not urgent", "sleep"],
+)
+```
+
+O/P:
+
+```
+{'sequence': 'I need to leave but later',
+ 'labels': ['not urgent', 'urgent', 'sleep'],
+ 'scores': [0.8889380097389221, 0.10631518065929413, 0.00474683940410614]}
+```
## Application
The transformer has had great success in natural language processing (NLP). Many large language models such as GPT-2, GPT-3, GPT-4, Claude, BERT, XLNet, RoBERTa and ChatGPT demonstrate the ability of transformers to perform a wide variety of such NLP-related tasks, and have the potential to find real-world applications.
From 251c4d86894b26e113b1b4426aeaf412c0b4c977 Mon Sep 17 00:00:00 2001
From: SAM <60264918+SAM-DEV007@users.noreply.github.com>
Date: Fri, 31 May 2024 18:43:19 +0530
Subject: [PATCH 008/159] Update Transformers.md
Added Tensorflow output and fixed wrong mentions
---
contrib/machine-learning/Transformers.md | 93 +++++++++++++++++++++++-
1 file changed, 91 insertions(+), 2 deletions(-)
diff --git a/contrib/machine-learning/Transformers.md b/contrib/machine-learning/Transformers.md
index e9e50e8..d30bd63 100644
--- a/contrib/machine-learning/Transformers.md
+++ b/contrib/machine-learning/Transformers.md
@@ -189,8 +189,8 @@ transformer = Transformer(
d_model=d_model,
num_heads=num_heads,
dff=dff,
- input_vocab_size=tokenizers.pt.get_vocab_size().numpy(),
- target_vocab_size=tokenizers.en.get_vocab_size().numpy(),
+ input_vocab_size=64,
+ target_vocab_size=64,
dropout_rate=dropout_rate
)
```
@@ -205,7 +205,96 @@ output = transformer((src, tgt))
O/P:
```
+
+```
+```
+>>> output.shape
+TensorShape([64, 50, 64])
```
### PyTorch
From 44303ff8e04e496e0f545d92a60e9758b971e314 Mon Sep 17 00:00:00 2001
From: SAM <60264918+SAM-DEV007@users.noreply.github.com>
Date: Fri, 31 May 2024 18:45:07 +0530
Subject: [PATCH 009/159] Update Transformers.md
Extended Introduction
---
contrib/machine-learning/Transformers.md | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/contrib/machine-learning/Transformers.md b/contrib/machine-learning/Transformers.md
index d30bd63..97346bd 100644
--- a/contrib/machine-learning/Transformers.md
+++ b/contrib/machine-learning/Transformers.md
@@ -1,8 +1,9 @@
# Transformers
## Introduction
A transformer is a deep learning architecture developed by Google and based on the multi-head attention mechanism. It is based on the softmax-based attention
-mechanism. Before transformers, predecessors of attention mechanism were added to gated recurrent neural networks, such as LSTMs and gated recurrent units (GRUs), which
-processed datasets sequentially. Dependency on previous token computations prevented them from being able to parallelize the attention mechanism.
+mechanism. Before transformers, predecessors of attention mechanism were added to gated recurrent neural networks, such as LSTMs and gated recurrent units (GRUs), which processed datasets sequentially. Dependency on previous token computations prevented them from being able to parallelize the attention mechanism.
+
+Transformers are a revolutionary approach to natural language processing (NLP). Unlike older models, they excel at understanding long-range connections between words. This "attention" mechanism lets them grasp the context of a sentence, making them powerful for tasks like machine translation, text summarization, and question answering. Introduced in 2017, transformers are now the backbone of many large language models, including tools you might use every day. Their ability to handle complex relationships in language is fueling advancements in AI across various fields.
## Model Architecture

From f75b2bab640e8b52e94d383ad2805ef487d2984a Mon Sep 17 00:00:00 2001
From: Arihant Yadav <147732947+arihunter-18@users.noreply.github.com>
Date: Fri, 31 May 2024 22:22:54 +0530
Subject: [PATCH 010/159] Add files via upload
---
contrib/advanced-python/closures.md | 101 ++++++++++++++++++++++++++++
1 file changed, 101 insertions(+)
create mode 100644 contrib/advanced-python/closures.md
diff --git a/contrib/advanced-python/closures.md b/contrib/advanced-python/closures.md
new file mode 100644
index 0000000..87ad058
--- /dev/null
+++ b/contrib/advanced-python/closures.md
@@ -0,0 +1,101 @@
+# Closures
+In order to have complete understanding of this topic in python, one needs to be crystal clear with the concept of functions and the different types of them which are namely First Class Functions and Nested Functions.
+
+### First Class Functions
+These are the normal functions used by the programmer in routine as they can be assigned to variables, passed as arguments and returned from other functions.
+### Nested Functions
+These are the functions defined within other functions and involve thorough usage of **Closures**. It is also referred as **Inner Functions** by some books. There are times when it is required to prevent a function or the data it has access to from being accessed from other parts of the code, and this is where Nested Functions come into play. Basically, its usage allows the encapsulation of that particular data/function within another function. This enables it to be virtually hidden from the global scope.
+
+## Defining Closures
+In nested functions, if the outer function basically ends up returning the inner function, in this case the concept of closures comes into play.
+
+A closure is a function object that remembers values in enclosing scopes even if they are not present in memory. There are certain neccesary condtions required to create a closure in python :
+1. The inner function must be defined inside the outer function.
+2. The inner function must refer to a value defined in the outer function.
+3. The inner function must return a value.
+
+## Advantages of Closures
+* Closures make it possible to pass data to inner functions without first passing them to outer functions
+* Closures can be used to create private variables and functions
+* They also make it possible to invoke the inner function from outside of the encapsulating outer function.
+* It improves code readability and maintainability
+
+## Examples implementing Closures
+### Example 1 : Basic Implementation
+```python
+def make_multiplier_of(n):
+ def multiplier(x):
+ return x * n
+ return multiplier
+
+times3 = make_multiplier_of(3)
+times5 = make_multiplier_of(5)
+
+print(times3(9))
+print(times5(3))
+```
+#### Output:
+```
+27
+15
+```
+The **multiplier function** is defined inside the **make_multiplier_of function**. It has access to the n variable from the outer scope, even after the make_multiplier_of function has returned. This is an example of a closure.
+
+### Example 2 : Implementation with Decorators
+```python
+def decorator_function(original_function):
+ def wrapper_function(*args, **kwargs):
+ print(f"Wrapper executed before {original_function.__name__}")
+ return original_function(*args, **kwargs)
+ return wrapper_function
+
+@decorator_function
+def display():
+ print("Display function executed")
+
+display()
+```
+#### Output:
+```
+ Wrapper executed before display
+ Display function executed
+```
+The code in the example defines a decorator function: ***decorator_function*** that takes a function as an argument and returns a new function **wrapper_function**. The **wrapper_function** function prints a message to the console before calling the original function which appends the name of the called function as specified in the code.
+
+The **@decorator_function** syntax is used to apply the decorator_function decorator to the display function. This means that the display function is replaced with the result of calling **decorator_function(display)**.
+
+When the **display()** function is called, the wrapper_function function is executed instead. The wrapper_function function prints a message to the console and then calls the original display function.
+### Example 3 : Implementation with for loop
+```python
+def create_closures():
+ closures = []
+ for i in range(5):
+ def closure(i=i): # Capture current value of i by default argument
+ return i
+ closures.append(closure)
+ return closures
+
+my_closures = create_closures()
+for closure in my_closures:
+ print(closure())
+
+```
+#### Output:
+```
+0
+1
+2
+3
+4
+```
+The code in the example defines a function **create_closures** that creates a list of closure functions. Each closure function returns the current value of the loop variable i.
+
+The closure function is defined inside the **create_closures function**. It has access to the i variable from the **outer scope**, even after the create_closures function has returned. This is an example of a closure.
+
+The **i**=*i* argument in the closure function is used to capture the current value of *i* by default argument. This is necessary because the ****i** variable in the outer scope is a loop variable, and its value changes in each iteration of the loop. By capturing the current value of *i* in the default argument, we ensure that each closure function returns the correct value of **i**. This is responsible for the generation of output 0,1,2,3,4.
+
+
+For more examples related to closures, [click here](https://dev.to/bshadmehr/understanding-closures-in-python-a-comprehensive-tutorial-11ld).
+
+## Summary
+Closures in Python provide a powerful mechanism for encapsulating state and behavior, enabling more flexible and modular code. Understanding and effectively using closures enables the creation of function factories, allows functions to have state, and facilitates functional programming techniques.
\ No newline at end of file
From 50f1e2c3deb4d244b052fcc4c9e4b7d3b6836551 Mon Sep 17 00:00:00 2001
From: Arihant Yadav <147732947+arihunter-18@users.noreply.github.com>
Date: Fri, 31 May 2024 22:24:16 +0530
Subject: [PATCH 011/159] Updated index.md
---
contrib/advanced-python/index.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/contrib/advanced-python/index.md b/contrib/advanced-python/index.md
index b95e4b9..d9a9056 100644
--- a/contrib/advanced-python/index.md
+++ b/contrib/advanced-python/index.md
@@ -7,3 +7,4 @@
- [Regular Expressions in Python](regular_expressions.md)
- [JSON module](json-module.md)
- [Map Function](map-function.md)
+- [Closures](closures.md)
From f65c949564f003591c746088bf8c25be44a65853 Mon Sep 17 00:00:00 2001
From: Ritesh
Date: Sun, 2 Jun 2024 09:17:22 +0530
Subject: [PATCH 012/159] Create hierarchical-clustering.md
---
.../hierarchical-clustering.md | 119 ++++++++++++++++++
1 file changed, 119 insertions(+)
create mode 100644 contrib/machine-learning/hierarchical-clustering.md
diff --git a/contrib/machine-learning/hierarchical-clustering.md b/contrib/machine-learning/hierarchical-clustering.md
new file mode 100644
index 0000000..3f9e606
--- /dev/null
+++ b/contrib/machine-learning/hierarchical-clustering.md
@@ -0,0 +1,119 @@
+# Hierarchical Clustering
+
+Hierarchical Clustering is a method of cluster analysis that seeks to build a hierarchy of clusters. This README provides an overview of the hierarchical clustering algorithm, including its fundamental concepts, types, steps, and how to implement it using Python.
+
+## Table of Contents
+
+1. [Introduction](#introduction)
+2. [Concepts](#concepts)
+3. [Types of Hierarchical Clustering](#types-of-hierarchical-clustering)
+4. [Steps in Hierarchical Clustering](#steps-in-hierarchical-clustering)
+5. [Linkage Criteria](#linkage-criteria)
+6. [Implementation](#implementation)
+ - [Using Scikit-learn](#using-scikit-learn)
+ - [Code Example](#code-example)
+7. [Evaluation Metrics](#evaluation-metrics)
+8. [Conclusion](#conclusion)
+9. [References](#references)
+
+## Introduction
+
+Hierarchical Clustering is an unsupervised learning method used to group similar objects into clusters. Unlike other clustering techniques, hierarchical clustering does not require the number of clusters to be specified beforehand. It produces a tree-like structure called a dendrogram, which displays the arrangement of the clusters and their sub-clusters.
+
+## Concepts
+
+### Dendrogram
+
+A dendrogram is a tree-like diagram that records the sequences of merges or splits. It is a useful tool for visualizing the process of hierarchical clustering.
+
+### Distance Measure
+
+Distance measures are used to quantify the similarity or dissimilarity between data points. Common distance measures include Euclidean distance, Manhattan distance, and cosine similarity.
+
+### Linkage Criteria
+
+Linkage criteria determine how the distance between clusters is calculated. Different linkage criteria include single linkage, complete linkage, average linkage, and Ward's linkage.
+
+## Types of Hierarchical Clustering
+
+1. **Agglomerative Clustering (Bottom-Up Approach)**:
+ - Starts with each data point as a separate cluster.
+ - Repeatedly merges the closest pairs of clusters until only one cluster remains or a stopping criterion is met.
+
+2. **Divisive Clustering (Top-Down Approach)**:
+ - Starts with all data points in a single cluster.
+ - Repeatedly splits clusters into smaller clusters until each data point is its own cluster or a stopping criterion is met.
+
+## Steps in Hierarchical Clustering
+
+1. **Calculate Distance Matrix**: Compute the distance between each pair of data points.
+2. **Create Clusters**: Treat each data point as a single cluster.
+3. **Merge Closest Clusters**: Find the two clusters that are closest to each other and merge them into a single cluster.
+4. **Update Distance Matrix**: Update the distance matrix to reflect the distance between the new cluster and the remaining clusters.
+5. **Repeat**: Repeat steps 3 and 4 until all data points are merged into a single cluster or the desired number of clusters is achieved.
+
+## Linkage Criteria
+
+1. **Single Linkage (Minimum Linkage)**: The distance between two clusters is defined as the minimum distance between any single data point in the first cluster and any single data point in the second cluster.
+2. **Complete Linkage (Maximum Linkage)**: The distance between two clusters is defined as the maximum distance between any single data point in the first cluster and any single data point in the second cluster.
+3. **Average Linkage**: The distance between two clusters is defined as the average distance between all pairs of data points, one from each cluster.
+4. **Ward's Linkage**: The distance between two clusters is defined as the increase in the sum of squared deviations from the mean when the two clusters are merged.
+
+## Implementation
+
+### Using Scikit-learn
+
+Scikit-learn is a popular machine learning library in Python that provides tools for hierarchical clustering.
+
+### Code Example
+
+```python
+import numpy as np
+import pandas as pd
+import matplotlib.pyplot as plt
+from scipy.cluster.hierarchy import dendrogram, linkage
+from sklearn.cluster import AgglomerativeClustering
+from sklearn.preprocessing import StandardScaler
+
+# Load dataset
+data = pd.read_csv('path/to/your/dataset.csv')
+
+# Preprocess the data
+scaler = StandardScaler()
+data_scaled = scaler.fit_transform(data)
+
+# Perform hierarchical clustering
+Z = linkage(data_scaled, method='ward')
+
+# Plot the dendrogram
+plt.figure(figsize=(10, 7))
+dendrogram(Z)
+plt.title('Dendrogram')
+plt.xlabel('Data Points')
+plt.ylabel('Distance')
+plt.show()
+
+# Perform Agglomerative Clustering
+agg_clustering = AgglomerativeClustering(n_clusters=3, affinity='euclidean', linkage='ward')
+labels = agg_clustering.fit_predict(data_scaled)
+
+# Add cluster labels to the original data
+data['Cluster'] = labels
+print(data.head())
+```
+
+## Evaluation Metrics
+
+- **Silhouette Score**: Measures how similar a data point is to its own cluster compared to other clusters.
+- **Cophenetic Correlation Coefficient**: Measures how faithfully a dendrogram preserves the pairwise distances between the original data points.
+- **Dunn Index**: Ratio of the minimum inter-cluster distance to the maximum intra-cluster distance.
+
+## Conclusion
+
+Hierarchical clustering is a versatile and intuitive method for clustering data. It is particularly useful when the number of clusters is not known beforehand. By understanding the different linkage criteria and evaluation metrics, one can effectively apply hierarchical clustering to various types of data.
+
+## References
+
+- [Scikit-learn Documentation](https://scikit-learn.org/stable/modules/clustering.html#hierarchical-clustering)
+- [Wikipedia: Hierarchical Clustering](https://en.wikipedia.org/wiki/Hierarchical_clustering)
+- [Towards Data Science: Hierarchical Clustering Explained](https://towardsdatascience.com/hierarchical-clustering-explained-925d9e1600c1)
From 5b6cd66f79e2cc0341f94bd0ec3ee935ccf8a20c Mon Sep 17 00:00:00 2001
From: Ritesh
Date: Sun, 2 Jun 2024 09:21:45 +0530
Subject: [PATCH 013/159] Update index.md
---
contrib/machine-learning/index.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/contrib/machine-learning/index.md b/contrib/machine-learning/index.md
index b6945cd..20305dc 100644
--- a/contrib/machine-learning/index.md
+++ b/contrib/machine-learning/index.md
@@ -15,4 +15,5 @@
- [Logistic Regression](logistic-regression.md)
- [Types_of_Cost_Functions](cost-functions.md)
- [Clustering](clustering.md)
+- [Hierarchical Clustering](hierarchical-clustering.md)
- [Grid Search](grid-search.md)
From 8ef6a2febc2ec303ffdc0702d838e2caa1462b17 Mon Sep 17 00:00:00 2001
From: Soubeer Koley
Date: Sun, 2 Jun 2024 09:27:46 +0530
Subject: [PATCH 014/159] added ensemble learning
---
contrib/machine-learning/ensemble_learning.md | 140 ++++++++++++++++++
contrib/machine-learning/index.md | 3 +-
2 files changed, 142 insertions(+), 1 deletion(-)
create mode 100644 contrib/machine-learning/ensemble_learning.md
diff --git a/contrib/machine-learning/ensemble_learning.md b/contrib/machine-learning/ensemble_learning.md
new file mode 100644
index 0000000..940bd09
--- /dev/null
+++ b/contrib/machine-learning/ensemble_learning.md
@@ -0,0 +1,140 @@
+# Ensemble Learning
+
+Ensemble Learning is a powerful machine learning paradigm that combines multiple models to achieve better performance than any individual model. The idea is to leverage the strengths of different models to improve overall accuracy, robustness, and generalization.
+
+
+
+## Introduction
+
+Ensemble Learning is a technique that combines the predictions from multiple machine learning models to make more accurate and robust predictions than a single model. It leverages the diversity of different models to reduce errors and improve performance.
+
+## Types of Ensemble Learning
+
+### Bagging
+
+Bagging, or Bootstrap Aggregating, involves training multiple versions of the same model on different subsets of the training data and averaging their predictions. The most common example of bagging is the `RandomForest` algorithm.
+
+### Boosting
+
+Boosting focuses on training models sequentially, where each new model corrects the errors made by the previous ones. This way, the ensemble learns from its mistakes, leading to improved performance. `AdaBoost` and `Gradient Boosting` are popular examples of boosting algorithms.
+
+### Stacking
+
+Stacking involves training multiple models (the base learners) and a meta-model that combines their predictions. The base learners are trained on the original dataset, while the meta-model is trained on the outputs of the base learners. This approach allows leveraging the strengths of different models.
+
+## Advantages and Disadvantages
+
+### Advantages
+
+- **Improved Accuracy**: Combines the strengths of multiple models.
+- **Robustness**: Reduces the risk of overfitting and model bias.
+- **Versatility**: Can be applied to various machine learning tasks, including classification and regression.
+
+### Disadvantages
+
+- **Complexity**: More complex than individual models, making interpretation harder.
+- **Computational Cost**: Requires more computational resources and training time.
+- **Implementation**: Can be challenging to implement and tune effectively.
+
+## Key Concepts
+
+- **Diversity**: The models in the ensemble should be diverse to benefit from their different strengths.
+- **Voting/Averaging**: For classification, majority voting is used to combine predictions. For regression, averaging is used.
+- **Weighting**: In some ensembles, models are weighted based on their accuracy or other metrics.
+
+## Code Examples
+
+### Bagging with Random Forest
+
+Below is an example of using Random Forest for classification on the Iris dataset.
+
+```python
+import numpy as np
+import pandas as pd
+from sklearn.datasets import load_iris
+from sklearn.ensemble import RandomForestClassifier
+from sklearn.model_selection import train_test_split
+from sklearn.metrics import accuracy_score, classification_report
+
+# Load dataset
+iris = load_iris()
+X, y = iris.data, iris.target
+
+# Split dataset
+X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
+
+# Initialize Random Forest model
+clf = RandomForestClassifier(n_estimators=100, random_state=42)
+
+# Train the model
+clf.fit(X_train, y_train)
+
+# Make predictions
+y_pred = clf.predict(X_test)
+
+# Evaluate the model
+accuracy = accuracy_score(y_test, y_pred)
+print(f"Accuracy: {accuracy * 100:.2f}%")
+print("Classification Report:\n", classification_report(y_test, y_pred))
+```
+
+### Boosting with AdaBoost
+Below is an example of using AdaBoost for classification on the Iris dataset.
+
+```
+from sklearn.ensemble import AdaBoostClassifier
+from sklearn.tree import DecisionTreeClassifier
+
+# Initialize base model
+base_model = DecisionTreeClassifier(max_depth=1)
+
+# Initialize AdaBoost model
+ada_clf = AdaBoostClassifier(base_estimator=base_model, n_estimators=50, random_state=42)
+
+# Train the model
+ada_clf.fit(X_train, y_train)
+
+# Make predictions
+y_pred = ada_clf.predict(X_test)
+
+# Evaluate the model
+accuracy = accuracy_score(y_test, y_pred)
+print(f"Accuracy: {accuracy * 100:.2f}%")
+print("Classification Report:\n", classification_report(y_test, y_pred))
+```
+
+### Stacking with Multiple Models
+Below is an example of using stacking with multiple models for classification on the Iris dataset.
+
+```
+from sklearn.linear_model import LogisticRegression
+from sklearn.neighbors import KNeighborsClassifier
+from sklearn.svm import SVC
+from sklearn.ensemble import StackingClassifier
+
+# Define base models
+base_models = [
+ ('knn', KNeighborsClassifier(n_neighbors=5)),
+ ('svc', SVC(kernel='linear', probability=True))
+]
+
+# Define meta-model
+meta_model = LogisticRegression()
+
+# Initialize Stacking model
+stacking_clf = StackingClassifier(estimators=base_models, final_estimator=meta_model, cv=5)
+
+# Train the model
+stacking_clf.fit(X_train, y_train)
+
+# Make predictions
+y_pred = stacking_clf.predict(X_test)
+
+# Evaluate the model
+accuracy = accuracy_score(y_test, y_pred)
+print(f"Accuracy: {accuracy * 100:.2f}%")
+print("Classification Report:\n", classification_report(y_test, y_pred))
+```
+
+## Conclusion
+Ensemble Learning is a powerful technique that combines multiple models to improve overall performance. By leveraging the strengths of different models, it provides better accuracy, robustness, and generalization. However, it comes with increased complexity and computational cost. Understanding and implementing ensemble methods can significantly enhance machine learning solutions.
\ No newline at end of file
diff --git a/contrib/machine-learning/index.md b/contrib/machine-learning/index.md
index 073bca9..a46cd7a 100644
--- a/contrib/machine-learning/index.md
+++ b/contrib/machine-learning/index.md
@@ -9,4 +9,5 @@
- [TensorFlow.md](tensorFlow.md)
- [PyTorch.md](pytorch.md)
- [Types of optimizers](Types_of_optimizers.md)
-- [Random Forest](Random_Forest.md)
\ No newline at end of file
+- [Random Forest](Random_Forest.md)
+- [Ensemble Learning](ensemble_learning.md)
\ No newline at end of file
From 402289d3ceae6add26458f41d33364eff322f8e2 Mon Sep 17 00:00:00 2001
From: SAM <60264918+SAM-DEV007@users.noreply.github.com>
Date: Sun, 2 Jun 2024 10:23:09 +0530
Subject: [PATCH 015/159] Rename Transformers.md to transformers.md
---
contrib/machine-learning/{Transformers.md => transformers.md} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename contrib/machine-learning/{Transformers.md => transformers.md} (100%)
diff --git a/contrib/machine-learning/Transformers.md b/contrib/machine-learning/transformers.md
similarity index 100%
rename from contrib/machine-learning/Transformers.md
rename to contrib/machine-learning/transformers.md
From e13fb234f2829a1b918aac3c044e4feef5066d34 Mon Sep 17 00:00:00 2001
From: SAM <60264918+SAM-DEV007@users.noreply.github.com>
Date: Sun, 2 Jun 2024 10:23:56 +0530
Subject: [PATCH 016/159] Add transformers.md
---
contrib/machine-learning/index.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/contrib/machine-learning/index.md b/contrib/machine-learning/index.md
index b6945cd..13d9440 100644
--- a/contrib/machine-learning/index.md
+++ b/contrib/machine-learning/index.md
@@ -16,3 +16,4 @@
- [Types_of_Cost_Functions](cost-functions.md)
- [Clustering](clustering.md)
- [Grid Search](grid-search.md)
+- [Transformers](transformers.md)
From 229458043245de432c96f05457dd79330d568a92 Mon Sep 17 00:00:00 2001
From: SAM <60264918+SAM-DEV007@users.noreply.github.com>
Date: Sun, 2 Jun 2024 10:39:37 +0530
Subject: [PATCH 017/159] Update transformers.md
Added source for the image
---
contrib/machine-learning/transformers.md | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/contrib/machine-learning/transformers.md b/contrib/machine-learning/transformers.md
index 97346bd..9fbfa6d 100644
--- a/contrib/machine-learning/transformers.md
+++ b/contrib/machine-learning/transformers.md
@@ -6,7 +6,10 @@ mechanism. Before transformers, predecessors of attention mechanism were added t
Transformers are a revolutionary approach to natural language processing (NLP). Unlike older models, they excel at understanding long-range connections between words. This "attention" mechanism lets them grasp the context of a sentence, making them powerful for tasks like machine translation, text summarization, and question answering. Introduced in 2017, transformers are now the backbone of many large language models, including tools you might use every day. Their ability to handle complex relationships in language is fueling advancements in AI across various fields.
## Model Architecture
-
+
+ 
+Source: Attention Is All You Need - Figure 1
+
### Encoder
The encoder is composed of a stack of identical layers. Each layer has two sub-layers. The first is a multi-head self-attention mechanism, and the second is a simple, positionwise fully connected feed-forward network. Each encoder consists of two major components: a self-attention mechanism and a feed-forward neural network. The self-attention mechanism accepts input encodings from the previous encoder and weights their relevance to each other to generate output encodings. The feed-forward neural network further processes each output encoding individually. These output encodings are then passed to the next encoder as its input, as well as to the decoders.
From 07a1e737606d10d7e96e2291cec21003309bfbf0 Mon Sep 17 00:00:00 2001
From: SAM <60264918+SAM-DEV007@users.noreply.github.com>
Date: Sun, 2 Jun 2024 10:46:21 +0530
Subject: [PATCH 018/159] Update transformers.md
Added bibliography
---
contrib/machine-learning/transformers.md | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/contrib/machine-learning/transformers.md b/contrib/machine-learning/transformers.md
index 9fbfa6d..0799b7f 100644
--- a/contrib/machine-learning/transformers.md
+++ b/contrib/machine-learning/transformers.md
@@ -430,4 +430,11 @@ These may include:
- Text generation
- Biological sequence analysis
- Computer code generation
-- Video analysis
+
+## Bibliography
+- [Attention Is All You Need](https://arxiv.org/pdf/1706.03762)
+- [Tensorflow Tutorial](https://www.tensorflow.org/text/tutorials/transformer)
+- [Tensorflow Models Docs](https://www.tensorflow.org/api_docs/python/tfm/nlp/layers)
+- [Wikipedia](https://en.wikipedia.org/wiki/Transformer_(deep_learning_architecture))
+- [HuggingFace](https://huggingface.co/docs/transformers/en/index)
+- [PyTorch](https://pytorch.org/docs/stable/generated/torch.nn.Transformer.html)
From cbc72ef9d3c36fba38480709de60ec8ba06f578c Mon Sep 17 00:00:00 2001
From: Niyonika Gaur <83643952+niyonikagaur@users.noreply.github.com>
Date: Sun, 2 Jun 2024 11:31:01 +0530
Subject: [PATCH 019/159] Visualizing_nifti_files.md
---
.../Visualizing_nifti_files.md | 90 +++++++++++++++++++
1 file changed, 90 insertions(+)
create mode 100644 contrib/plotting-visualization/Visualizing_nifti_files.md
diff --git a/contrib/plotting-visualization/Visualizing_nifti_files.md b/contrib/plotting-visualization/Visualizing_nifti_files.md
new file mode 100644
index 0000000..4baaca3
--- /dev/null
+++ b/contrib/plotting-visualization/Visualizing_nifti_files.md
@@ -0,0 +1,90 @@
+## NIfTI Files
+Neuroimaging Informatics Technology Initiative is a data format for storage. Functional Magnetic Resonance Imaging (fMRI) and other medical images.
+## In this, we'll be using different packages:
+1. Matplotlib
+2. Nibabel: It gives access to a variety of imaging formats, it provides a common interface for various formats produced by different scanners.
+
+## Various Methods for viewing a NIfTI file
+### 1. Load NIfTI file
+```
+brain_vol = nib.load("") #Enter the path to NIfTI file here
+type(brain_vol)
+```
+### 2. View Metadata
+```
+print(brain_vol.header)
+```
+### Output
+```
+ object, endian='<'
+sizeof_hdr : 348
+data_type : b''
+db_name : b''
+extents : 0
+session_error : 0
+regular : b'r'
+dim_info : 54
+dim : [ 3 192 256 256 1 1 1 1]
+intent_p1 : 0.0
+intent_p2 : 0.0
+intent_p3 : 0.0
+intent_code : none
+datatype : int16
+bitpix : 16
+slice_start : 0
+pixdim : [1. 1. 1. 1. 2.3 0. 0. 0. ]
+vox_offset : 0.0
+scl_slope : nan
+scl_inter : nan
+slice_end : 0
+slice_code : unknown
+xyzt_units : 10
+cal_max : 0.0
+cal_min : 0.0
+slice_duration : 0.0
+toffset : 0.0
+glmax : 0
+glmin : 0
+descrip : b'TE=2.7;Time=150734.828;phase=1'
+aux_file : b''
+qform_code : scanner
+sform_code : scanner
+quatern_b : 0.00042526424
+quatern_c : -0.027039066
+quatern_d : 0.01571919
+qoffset_x : -81.5222
+qoffset_y : -130.72974
+qoffset_z : -144.47054
+srow_x : [ 9.9804670e-01 -3.1445995e-02 -5.4038301e-02 -8.1522202e+01]
+srow_y : [ 3.1400096e-02 9.9950546e-01 -1.7001767e-03 -1.3072974e+02]
+srow_z : [ 5.4065209e-02 4.7863640e-08 9.9853742e-01 -1.4447054e+02]
+intent_name : b''
+magic : b'n+1'
+```
+### 3. Access data in the NIfTI object
+```
+brain_vol_data = brain_vol.get_fdata()
+type(brain_vol_data)
+```
+### Output
+```
+numpy.ndarray
+```
+### Dimensions of the image
+```
+brain_vol_data.shape
+```
+### Output
+```
+(192, 256, 256)
+```
+### 4. Visualize a Slice
+```
+plt.imshow(brain_vol_data[96], cmap='bone')
+plt.axis('off')
+plt.show()
+```
+
+
+
+
From ad7ec8797e02a99f21194fbb3486f3cf8d039b96 Mon Sep 17 00:00:00 2001
From: Niyonika Gaur <83643952+niyonikagaur@users.noreply.github.com>
Date: Sun, 2 Jun 2024 11:37:11 +0530
Subject: [PATCH 020/159] Add files via upload
---
images/1.png | Bin 0 -> 267708 bytes
images/2.png | Bin 0 -> 761399 bytes
images/3.png | Bin 0 -> 1384689 bytes
3 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 images/1.png
create mode 100644 images/2.png
create mode 100644 images/3.png
diff --git a/images/1.png b/images/1.png
new file mode 100644
index 0000000000000000000000000000000000000000..bdf458ac3a056ee8d2e550ec215b8cbcd26f750a
GIT binary patch
literal 267708
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
7zLwu0;2P
zWWJn60p)d0kdN5;n)|RVRws~|^336(z4qMZkK-_E@Wqi%pf*p>W8JxNm|bCeK#>(%
zNNeqpX?Mk~E%&B=59yQ!*xmY}V`s_ONAlV^6an;yi5uqwAIlZ=rIp5cY8Gr<7l(pZ!Nufeb7beh8cXI$cA2(5V8~J3*XuCUqH;C_EAPC@aqMW3(eWulZqQ1
z5xnHvtcXRi;%aDLIz|9SwEcDd1b60hjBXs^g43>Csml;un~;8>T5y@5yv-kJ)9LH{
zY>bS}S@}tFQbyumVF^zZE?=;-+UDrCHZQU>6k)6`SbX3p03uoUq>pRRlvS=mA^y24
z*LO!c$~ZoP?uj_y92vfDduj!3Ob)O4{fjDEG!h&te~xgic{VKfq!&vX@HG+1ILp{_
z0gtI2cDZe~_t%(GejqMGR9DS@OHL)6e+HH!_pj=6c1dc
z2=BzSD4u_ZO`JcPW0gyag$1!Wv4qJF!kD}FzfJwF2!ah|W?i5i~LpC-^EuxFp9q{uG^
zJgs&jHrbBkNBz1)S^!^%16v4WQ#YwJ&xds@FL^bSjD|sfB{@l!oJmNNN&&wJ|Opw88E#Ih*#no3B
z#i19pn_a(i7~zGb7}vfQi`f7_KjOc|9S8QuZ}L=%zv_j{
zcx5RxYo-kSyCN41&_y`A)=%~*KJtC&xoHabQ}o%D*Bp#+*$XXFJUCTj`~q${H2CN3G*#y7lBNV-O73}#3m-PaDLvHE%X$0_MxrDU0{$Ib5z
zCZPJ!P@xVuZBKq38Y-ZYNmtQYZoyQo9btMRKA_!8`s{G>e4@@db=H_YbVYwdWycaan_qTS{s8VhENH*8}s6T1}<9S5m<5t*`#MJ{u9Y^ye
z)CU)~3T__*^f@uX8MJwgK7YLa@oq>(9(6C9q