boda commited on
Commit
d7e4f1f
1 Parent(s): bfb0af7

add MLP models

Browse files
app.py ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from model.generate import generate_names
3
+
4
+ col1, col2, col3 = st.columns([1,1,1])
5
+
6
+
7
+ st.markdown('''This is a simple MLP that predicts the next character given the context of the previous 5 characters!
8
+ If you want to play with this, see the repo [here](https://github.com/BodaSadalla98/Arabic_makemore)
9
+
10
+
11
+
12
+ ''')
13
+
14
+ option = col2.selectbox(
15
+ 'Select the language to generate the names with:',
16
+ ('Arabic', 'English'))
17
+ number = col2.number_input(label='Enter how many names to generate..', min_value=0, max_value=1000, value=5)
18
+
19
+ names = ''
20
+ if col2.button('Generate'):
21
+ if option =='English':
22
+ names = generate_names(number,'en')
23
+ else:
24
+ names = generate_names(number,'ar')
25
+
26
+
27
+ for name in names:
28
+ new_title = f'<p style="font-family:sans-serif;text-align: center; color:Purple; font-size: 30px;">{name}</p>'
29
+ col2.markdown(new_title, unsafe_allow_html=True)
30
+
31
+
32
+ st.markdown('''
33
+ If you have any questions, contact me: **@bodasadallah**
34
+ ''')
35
+ # st.write(names)
36
+
model/__pycache__/generate.cpython-310.pyc ADDED
Binary file (3.22 kB). View file
 
model/__pycache__/layers.cpython-310.pyc ADDED
Binary file (3.74 kB). View file
 
model/generate.py ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from model.layers import *
3
+ # from layers import *
4
+
5
+ import pathlib
6
+ from pathlib import Path
7
+
8
+
9
+ CONTEXT_SIZE = 5
10
+ n_hidden = 100
11
+ n_embed = 10
12
+ EN_VOCAB_SIZE = 27
13
+ AR_VOCAB_SIZE = 37
14
+ ACTIVATION = 'relu'
15
+
16
+ ar_itos = {0: '.', 1: 'ء', 2: 'آ', 3: 'أ', 4: 'ؤ', 5: 'إ', 6: 'ئ', 7: 'ا', 8: 'ب', 9: 'ة', 10: 'ت', 11: 'ث', 12: 'ج', 13: 'ح', 14: 'خ', 15: 'د', 16: 'ذ', 17: 'ر', 18: 'ز', 19: 'س', 20: 'ش', 21: 'ص', 22: 'ض', 23: 'ط', 24: 'ظ', 25: 'ع', 26: 'غ', 27: 'ف', 28: 'ق', 29: 'ك', 30: 'ل', 31: 'م', 32: 'ن', 33: 'ه', 34: 'و', 35: 'ى', 36: 'ي'}
17
+ en_itos= {0: '.', 1: '-', 2: 'a', 3: 'b', 4: 'c', 5: 'd', 6: 'e', 7: 'f', 8: 'g', 9: 'h', 10: 'i', 11: 'j', 12: 'k', 13: 'l', 14: 'm', 15: 'n', 16: 'o', 17: 'p', 18: 'q', 19: 'r', 20: 's', 21: 't', 22: 'u', 23: 'v', 24: 'w', 25: 'y', 26: 'z'}
18
+ arabic_layers = [
19
+ Linear(CONTEXT_SIZE*n_embed , n_hidden),BatchNorm(n_hidden), Activation(ACTIVATION),
20
+ Linear(n_hidden, n_hidden),BatchNorm(n_hidden), Activation(ACTIVATION),
21
+ Linear(n_hidden, n_hidden),BatchNorm(n_hidden), Activation(ACTIVATION),
22
+ Linear(n_hidden , AR_VOCAB_SIZE)
23
+ ]
24
+
25
+ english_layers = [
26
+ Linear(CONTEXT_SIZE*n_embed , n_hidden),BatchNorm(n_hidden), Activation(ACTIVATION),
27
+ Linear(n_hidden, n_hidden),BatchNorm(n_hidden), Activation(ACTIVATION),
28
+ Linear(n_hidden, n_hidden),BatchNorm(n_hidden), Activation(ACTIVATION),
29
+ Linear(n_hidden , EN_VOCAB_SIZE)
30
+ ]
31
+
32
+
33
+
34
+ parent_path = Path(__file__).parent
35
+ arabic_dict = torch.load(Path.joinpath(parent_path,'weights/ar_dataset_weights.pt'))
36
+ english_dict= torch.load(Path.joinpath(parent_path,'weights/en_dataset_weights.pt'))
37
+
38
+ ## Weights
39
+ arabic_params = arabic_dict['params']
40
+ english_params = english_dict['params']
41
+
42
+ ## Batch norm means ans stds
43
+ arabic_bn_conf = arabic_dict['bn_conf']
44
+ english_bn_conf = english_dict['bn_conf']
45
+
46
+
47
+ # Load embeddings
48
+ arabic_embedding = arabic_params[0]
49
+ english_embedding = english_params[0]
50
+
51
+ ## Load weights
52
+ j = 0
53
+ for i,l in enumerate(arabic_layers):
54
+ l.set_parameters( arabic_params[i+1] )
55
+ if l.__class__.__name__ == "BatchNorm":
56
+ l.set_mean_std(arabic_bn_conf[j])
57
+ j+=1
58
+
59
+ j = 0
60
+ for i,l in enumerate(english_layers):
61
+ l.set_parameters( english_params[i+1] )
62
+ if l.__class__.__name__ == "BatchNorm":
63
+ l.set_mean_std(english_bn_conf[j])
64
+ j+=1
65
+
66
+ def forward(x_batch, is_training,lang):
67
+
68
+ if lang =='ar':
69
+ embedding = arabic_embedding
70
+ layers = arabic_layers
71
+
72
+ elif lang =='en':
73
+ embedding = english_embedding
74
+ layers = english_layers
75
+
76
+
77
+ x_batch = embedding[x_batch]
78
+ x = x_batch.view(x_batch.shape[0], -1)
79
+ for layer in layers:
80
+ x = layer(x, is_training)
81
+ return x
82
+
83
+
84
+ def generate_name(lang):
85
+
86
+ w = ''
87
+ last_ch = [0]* CONTEXT_SIZE
88
+ while True:
89
+ last_ch = torch.tensor(last_ch).unsqueeze(0)
90
+
91
+
92
+ x = forward(last_ch, False, lang)
93
+ p = torch.softmax(x, dim=1)
94
+ next_ch = torch.multinomial(p, num_samples=1, replacement=True).item()
95
+ if lang =='ar':
96
+ w += ar_itos[next_ch]
97
+ elif lang == 'en':
98
+ w += en_itos[next_ch]
99
+
100
+ last_ch = last_ch.clone().detach().squeeze(0)
101
+ last_ch = last_ch.tolist()
102
+ last_ch = last_ch[1:] + [next_ch]
103
+ if next_ch == 0:
104
+ break
105
+
106
+ return w[:-1]
107
+
108
+ def generate_names(n,lang):
109
+ ret = []
110
+ for i in range(n):
111
+ ret.append(generate_name(lang))
112
+
113
+ return ret
114
+
115
+
116
+ if __name__ == '__main__':
117
+
118
+ pass
model/layers.py ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+
3
+
4
+
5
+ class Linear():
6
+ def __init__(self, in_n, out_n, bias=True) -> None:
7
+ self.params = []
8
+ self.have_bias = bias
9
+ self.weight = torch.randn((in_n,out_n)) / (in_n**0.5)
10
+ self.params.append(self.weight)
11
+
12
+ self.bias = None
13
+ if self.have_bias:
14
+ self.bias = torch.zeros(out_n)
15
+ self.params.append(self.bias)
16
+
17
+ def __call__(self,x, is_training =True):
18
+ self.is_training = is_training
19
+
20
+ self.out = x @ self.params[0]
21
+ if self.have_bias:
22
+ self.out += self.params[1]
23
+ return self.out
24
+
25
+ def set_parameters(self,p):
26
+ self.params = p
27
+ # self.weight = p[0]
28
+ # self.bias = p[1]
29
+ # self.params = [p]
30
+
31
+ def parameters(self):
32
+ return self.params
33
+
34
+
35
+ class BatchNorm():
36
+ def __init__(self, in_n,eps=1e-5, momentum = 0.1) -> None:
37
+ self.eps = eps
38
+ self.is_training = True
39
+ self.momentum = momentum
40
+ self.running_mean = torch.zeros(in_n)
41
+ self.running_std = torch.ones(in_n)
42
+ self.gain = torch.ones(in_n)
43
+ self.bias = torch.zeros(in_n)
44
+ self.params = [self.gain , self.bias]
45
+
46
+
47
+ def __call__(self, x, is_training= True):
48
+
49
+ self.is_training = is_training
50
+ if self.is_training:
51
+ mean = x.mean(0,keepdims= True)
52
+ ## unbiased??
53
+ std = x.std(0,keepdims= True)
54
+
55
+ self.out = self.params[0] * (x - mean / (std + self.eps**0.5)) + self.params[1]
56
+
57
+ with torch.no_grad():
58
+ self.running_mean = self.running_mean * (1- self.momentum) \
59
+ + self.momentum * mean
60
+ self.running_std = self.running_std * (1- self.momentum) \
61
+ + self.momentum * std
62
+
63
+ else:
64
+ # print(self.running_mean , self.running_std)
65
+ self.out = self.params[0] * (x - self.running_mean / (self.running_std + self.eps**0.5)) + self.params[1]
66
+
67
+
68
+
69
+ return self.out
70
+
71
+ def set_parameters(self,p):
72
+ self.params = p
73
+ # self.gain = p[0]
74
+ # self.bias = p[1]
75
+ # self.params = [self.gain , self.bias]
76
+ def set_mean_std(self, conf):
77
+ self.running_mean = conf[0]
78
+ self.running_std = conf[1]
79
+ def get_mean_std(self):
80
+ return [self.running_mean, self.running_std]
81
+
82
+ def parameters(self):
83
+ return self.params
84
+
85
+ class Activation():
86
+ def __init__(self, activation='tanh'):
87
+ self.params = []
88
+ if activation == 'tanh':
89
+ self.forward = self._forward_tanh
90
+ elif activation == 'relu':
91
+ self.forward = self._forward_relu
92
+ else:
93
+ raise Exception('Only tanh, and relu activations are supported')
94
+
95
+ def _forward_relu(self,x):
96
+ return torch.relu(x)
97
+ def _forward_tanh(self,x):
98
+ return torch.tanh(x)
99
+
100
+ def __call__(self, x, is_training= True):
101
+
102
+ self.is_training = is_training
103
+
104
+
105
+ self.out = self.forward(x)
106
+ return self.out
107
+
108
+ def set_parameters(self,p):
109
+ self.params = p
110
+ def parameters(self):
111
+ return self.params
model/weights/ar_dataset_weights.pt ADDED
Binary file (128 kB). View file
 
model/weights/en_dataset_weights.pt ADDED
Binary file (123 kB). View file
 
requirmenets.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ torch