text:
A Second Approach To Automating Detection of "Random-Looking" Domain Names: Neural Networks/Deep Learning
Tuesday, July 9, 2019 By Joe St Sauver
"Why this name, Keras? Keras (κέρας) means horn in Greek. It is a reference to a literary image from ancient Greek and Latin literature, first found in the Odyssey, where dream spirits (Oneiroi, singular Oneiros) are divided between those who deceive men with false visions, who arrive to Earth through a gate of ivory, and those who announce a future that will come to pass, who arrive through a gate of horn." https://keras.io/#why-this-name-keras
"Keras (Indonesian): Hard"	https://translate.google.com/
Section 1. Introduction
In part one of this series, Automating Detection of "Random-Looking" Algorithmic Domain Names, we described a method that we could use to find particularly-"random-looking" domain names present in SIE Channel 204 DNS traffic. That approach looked for domains that contained no English or foreign language words, and found 5,337 unique random-looking domains out of a five minute long/ten million record sample of SIE Channel 204 data. (We undoubtedly missed other names that were also truly random.)
Now, in part two of the series, we wanted to see if we could use neural networks/deep learning as an alternative way to uncover random-looking domains from that same traffic, training the neural network based on names we'd already found in part one.
We embarked on this work with some trepidation:
•	Neural networks are at their best when detecting patterns, but we're interested in identifying "random-looking" domain names, names that are basically "pattern-free." Would this even work? We took solace from the "universality theorem,"1 but worried that our own limited neural network/deep learning skills MIGHT not be equal to the subtleties of this problem (then again, leveraging Cunningham's Law,2 maybe one of you reading this can come up with a more elegant solution).
•	As someone who formerly supported statistical users, I've always thought that theoretical considerations were key to developing a sound model. For example, in the "good old days," you wouldn't just run a stepwise regression and see what ad hoc "discovered" variables seemed to result in a model that appeared to deliver a "good fit"3 for one dataset.
•	We know that neural networks/deep learning have achieved astronomical levels of hype,4 much like a handful of other technologies (such as blockchain5). This article is, or is meant to be, "hype free," and attempts to focus strictly on what we tried and what we found. Our primary goal is to show another approach to categorizing domains, and, perhaps, to also illustrate how complex neural networks/deep learning still can be, even when using "user-friendly" software tools.
•	We also want to acknowledge up front the reality that truly understanding and explaining neural networks/deep learning requires advanced mathematics. Unfortunately, this blog is not really the right place for complex mathematical content. We've done our best to finesse that issue in the text below, sharing "rules of thumb" and "best practices" but omitting the math underlying and justifying those choices. We have provided references for most if not all of the rubrics used so that those who are prepared for more detail can dig in.
•	While GPUs have come way down in price6 and can greatly accelerate the matrix operations underpinning machine learning, we're just going to use a laptop for training our model. This limits our ability to employ some of the more sophisticated approaches simply because we don't have weeks or months to devote to building and training a model for a blog article. Then again, we believe working with basic facilities helps to "keep this all real."
Section 2. Tools
The first question to be faced is "what neural network/deep learning software should we use?" We decided on Keras7 with a backend of Theano8, running under Python39 with NumPy10 and Pandas11. Why those tools?
Quoting from the article "Top 8 open source AI technologies in machine learning",12
2. Keras.
Initially released in 2015, Keras is an open source software library designed to simplify the creation of deep learning models. It is written in Python and can be deployed on top of other AI technologies such as TensorFlow, Microsoft Cognitive Toolkit (CNTK), and Theano.
Keras is known for its user-friendliness, modularity, and ease of extensibility. It is suitable if you need a machine learning library that allows for easy and fast prototyping, supports both convolutional and recurrent networks, and runs optimally on both CPUs (central processing units) and GPUs (graphics processing units).
Keras relies on either TensorFlow or Theano for the backend. That same article spoke highly of the venerable Theano as well:
5. Theano
Initially released in 2007, Theano is an open source Python library that allows you to easily fashion various machine learning models. Since it's one of the oldest libraries, it is regarded as an industry standard that has inspired developments in deep learning.
At its core, it enables you to simplify the process of defining, optimizing, and assessing mathematical expressions. [continues]
While those choices were right for us, if you're just getting going, you may want to make different ones. For example, you may prefer TensorFlow to Theano since the venerable Theano is reportedly no longer under active development.13
Besides Keras and Theano, as previously mentioned, we also relied on NumPy, and Pandas. These libraries are well-known core components of Anaconda14, "The World's Most Popular Python/R Data Science Platform."
Section 3. Installing The Software We're Using
There are many ways to install the required Python-based software.15 We already had Python 3 installed, and since we like to have fine-grained control over what we install (and we prefer platform-independent native methods), we used pip3 to install the other packages we needed:16
# pip3 install numpy
# pip3 install pandas
# pip3 install theano
# pip3 install keras
Because functionality may fundamentally vary with the version of the packages used, we note for the record the versions of the products we installed:
$ python3 --version
$ python3 -c 'import numpy; print(numpy.__version__)'
$ python3 -c 'import pandas; print(pandas.__version__)'
$ python3 -c 'import theano; print(theano.__version__)'
$ python3 -c 'import keras; print(keras.__version__)'
Using Theano backend.
Later versions of those packages will also typically be fine (we don't mean to ever discourage you from updating!)
FWIW, if you decide that you would rather use TensorFlow instead of Theano for your Keras backend, you can change that fundamental default in your .keras/keras.json preferences file.
My .keras/kersas.json file looks like:
"floatx": "float32",
"epsilon": 1e-07,
"backend": "theano",
"image_data_format": "channels_last"
Section 4. Pre-Processing A Domain Name Training Dataset, Based On Data From Part I of This Blog Series
In order to be able to run any machine learning analysis, you need data, ideally LOTS of data. Fortunately, we have boodles of domain names from the Farsight Security Information Exchange. [see https://www.farsightsecurity.com/solutions/security-information-exchange/ ]
We also have a strategy for distinguishing random-looking domains from normal domains, as outlined in part one of this blog series – this means that we have what we'll need to train a new neural network/deep learning model on "pre-categorized" data.
It is critical that we correctly pre-process and then properly represent the underlying domain data. In particular, note that neural networks cannot directly ingest and process raw files of alphanumeric domain names – those names MUST be numerically coded. But how? Our pre-processing will take the domain name through a series of stages:
•	Stage 1 - Original Data: Domain names will initially begin as a lowercase string (such as sample.com)
•	Stage 2 - Vector of Individual Characters: We'll then break that string apart into a vector of individual characters. For example, the 10 character string sample.com would get transformed into a vector of ten individual letters, ["s", "a", "m", "p", "l", "e", ".", "c", "o", "m"].
•	Stage 3 - Index Of Each Character: We can then get the index (position/location) for each character from a defined list of characters such as 'abcdefghijklmnopqrstuvwxyz01234567890-_.'
We could also simply have taken the ordinal value of the characters from the ASCII character set, but that means starting with lowercase "a"=97 (decimal). We prefer having smaller numeric indicies, such as "a"=1, "b"=2, etc.
We can write a small Python3 code to demonstrate what we mean by this approach:
$ cat char-to-ord.py
#!/usr/local/bin/python3
string = "sample.com"
print ("Original string = ", string)
charvec = list(string)
print ("Vector of characters = ", charvec)
print ("Vector of coded values =", end =" ")
d = []
while (i < len(string)):
temp = ord(charvec[i])
d.append(temp)
print (d)
charset = "abcdefghijklmnopqrstuvwxyz0123456789-_."
dprime = []
temp = charset.find(charvec[i])+1
if (temp != 0):
dprime.append(temp)
dprime.append(0)
$ python3 char-to-ord.py
Original string =  sample.com
Vector of characters = ['s', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm']
Vector of coded values = [19, 1, 13, 16, 12, 5, 39, 3, 15, 13]
You can imagine encoding each of our normal or random-looking domains using this create-a-vector-of-codes approach, and in fact that's what we've done, albeit with a small GNU Fortran program we call convert5.f (see Appendix I)
Our starting dataset is a file called combined.csv that contains both regular domain names and random-looking domain names from the first part of this blog series. Some of the domain names in that file are quite long, while others are rather short. Because neural networks/deep learning works best with uniform length training data, we are faced with the need to:
Pad the short names to the length of the longest name,
Truncate (chop) the too-long names to some common length we select, or
Discard the too-long names entirely.
We decided to exclude any domains that are more than 20 characters long, and pad any names shorter than that length out to 20 characters.
Discarding domains greater than 20 characters in length is not as daring as it may seem since most names are actually twenty characters or less as shown in Figure 3 from part one of this series:
Figure 1. Distribution of domain lengths (from Part 1 of this blog series, figure 3)
We'll do this "pruning" and "padding" with a little Perl17 script called trim-too-long, as shown in Appendix II. In this specific case, we'll say:
$ trim-too-long 22 < combined.csv > combined-20-or-less.dat
The alert reader will note that we're actually triming to 22 characters, rather than 20 characters. That's because the first two spaces on each line are actually taken up with the class into which that domain was placed (either 1 for random-looking, or 0 for normal)), followed by a comma separator. That's then immediately followed by the domain names in string form. The breakdown of random-looking vs normal domains for the 20 character or less data looks like:
Table 1. Summary Class Statistics for Domains Length <= 20 (Training Data From Blog Part I)
Ratio (Normal:Random)
normal 0 3,036,657 99.830% ~590:1
random-looking 1 5,145 0.169%
Total: 3,041,802 100.00%
That's a dramatically asymetric class distribution: 99.83% of our cases are regular domains, and just 0.169% are random-looking domains. Given that imbalance, imagine a classification rule that says, "Just assume all observations are regular domains." That simplistic rule would be "right" 99.83% of the time, even if that misses the whole point of this exercise!18
We can attempt to overcome this "prejudice" by weighting the data, as described in "How to set class weights for imbalanced classes in Keras?"19 However, ultimately, we decided that we needed to oversample additional random-looking domain names, collecting supplemental random-looking domains for model-training purposes. We went back to SIE Channel 204 and pulled/processed an addition 1.5 billion records:
$ nmsgtool -C ch204 -c 1500000000 -J - | \
> jq --unbuffered -r '"\(.message.rrname) \(.message.rrtype)"' > one.txt
[Exclude RRSIG, NSEC3, IDN and .arpa domains]
$ cat one.txt | grep -v " NSEC3" | grep -v " RRSIG" | grep -v "xn--" | \
> grep -v "\.arpa\. " | awk '{print $1}' > two.txt
$ wc -l two.txt
1,168,890,556 two.txt    [commas added for readability]
[reduce the domains to effective 2nd-level domains only]
$ 2nd-level-dom-large < two.txt > three.txt
[sort and uniquify the effective 2nd-level domains]
$ sort -T. three.txt > four.txt
$ uniq < four.txt > five.txt
$ wc -l five.txt
98,853,330 five.txt [commas added for readability]
[exclude names that contain an English or foreign language word >= 3 characters]
$ find-words.py < five.txt > six.txt
$ wc -l six.txt
226,185 six.txt   [commas added for readability]
[keep names that are <= 20 chars, allowing 2 chars for the class field]
$ trim-too-long 22 < six.txt > seven.txt
$ wc -l seven.txt
224,511 seven.txt [commas added for readability]
[merge random-looking domains with the old combined data, eliminating any duplicates]
$ cat combined-20-or-less.dat seven.txt | sort -u > new-combined-20-or-less-sorted.txt
$ wc -l new-combined-20-or-less-sorted.txt
3,264,272 new-combined-20-or-less-sorted.txt    [commas added for readability]
$ awk '{print $1}' < new-combined-20-or-less-sorted.txt | sort | uniq -c
3,036,657 0         [commas added for readability]
Oversampling class 1 (the random-looking domains) substantially improved the distribution of our training data:
Table 2. Summary Class Statistics for The Upsampled Class=1 Domain Data, Length <= 20
normal 0 3,036,657 93.03% ~13.3:1
random-looking 1 227,615 6.97%
We're now ready to process our augmented domains with convert5.f (see Appendix I)
Assuming you have GNU Fortran20 installed, compile and run that code by saying:
$ gfortran -o convert5 convert5.f
$ ./convert5 > new-tokenized-20-char.txt
After the code finishes running, we compress the output file with gzip21 since Pandas and friends can automatically cope with compressed data files:
$ gzip -9 new-tokenized-20-char.txt
Uncompressed, new-tokenized-20-char.txt runs about 158MB; compressed, that data runs just 20 MB or so.
Section 5. Dealing With The Fact That Domain Names Are Inherently Categorical Data
There's one more issue we need to address: the numerically-encoded characters from Section 4 are categorical measurements, and are not interval/ratio nor ordinal data.22 Numerically-encoded character code values aren't things we normally measure the way we do length, mass, velocity, temperature, crop yields in bushels-per-acre, contamination levels in parts-per-million, etc. This means that we can't meaningfully perform mathematical operations on that data – we can't add "r" to "s" and divide by "q" (even if numerically-encoded character values may make it appear as if that should be possible). We can't even meaningfully "order" or "rank" numerically-encoded character values (except by superficially applying an agreed-upon mechnical collating sequence).23 This means that we also can't even apply non-parametric methods to that data.24
We're left with an ugly reality: the characters making up domain names are categorical (or "nominal") data, and must be treated as such. When coding categorical data for an observation, something either "is" (or "has") a particular categorical attribute, or it doesn't. This status is normally represented using "dummy" or "indicator" variables (the machine learning community often prefers to refer to these as "one hot" variables).25 Those variables are set to 1 if the attribute is present and 0 if the attribute isn't present. Given a set of ten potential classes for a categorical variable, one class will normally be taken as the "default" class and the impact of the other nine attributes will be represented by a set of nine dummy variables.
Let's now try to apply this approach to our domain names. If we assume each character in a domain name can be:
One of the 26 lowercase letter from a to z
One of the 10 digits from 0 to 9, or
A dash, underbar character or dot
that implies 26+10+3=39 potential values for each character in a domain name, assuming an ASCII space (as used for padding) is our "base" category.
As previously mentioned, the number of characters in a domain name will vary, but we need a consistent length for our observations. Recall that figure 1, above, showed us that most of our names were 20 characters or less in length.
Therefore, we're adopting a maximum domain name length of 20 by default for our encoded domain name representation, and trimming our dataset to only include domains of that length (or less) using the little piece of perl code that you can see in Appendix II.
So given all of the above, think of each dummy-coded domain name as consisting of 20 lines of data, one line for each character in the name.
1                   2                   3
1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 - _ .
1  s   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2  a   1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
3  m   0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
4  p   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
5  l   0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
6  e   0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
7  .   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
8  c   0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
9  o   0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
10  m   0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[followed by 10 rows of "all zeros" to get to 20 rows for the name]
Figure 2. Dummy Coding "sample.com"
A few final "fixups" we still needed to make to that:
•	Rather than having 20 separate lines of 39 indicator variables, we'll just string the whole set of 20 lines of 39 characters together, one after another, for each domain name. This means that each line will have 20*39=780 values per line.
•	We'll preface each of the lines with the actual class assignment we made during part one of this series, either 1 (random-looking) or 0 (normal), as shown in the original data file.
Obviously, attempting to dummy code our domains as categorical data this way is pretty inefficient and quickly becomes unwieldy/impracticable.
The "Keras way" around this problem is through the use of "embeddings," which essentially map categorical variables into a multidimensional space. Some excellent introductions to the topic of embeddings include:
•	Rutger Ruizendaal's "Deep Learning #4: Why You Need to Start Using Embedding Layers," see https://towardsdatascience.com/deep-learning-4-embedding-layers-f9a02d55ac12
•	Will Koehrsen's "Neural Network Embeddings Explained: How deep learning can represent War and Peace as a vector," see https://towardsdatascience.com/neural-network-embeddings-explained-4d028e6f0526 and
•	Cristopher Olah's "Deep Learning, NLP, and Representations," see http://colah.github.io/posts/2014-07-NLP-RNNs-Representations/
We'll illustrate the use of embedding layers as part of formulating our model, below.
Section 6. Reading In Our Data and Extracting the X's and Y
First, however, let's read in our coded data.
All neural network/deep learning programs lean heavily on third party libraries. Our first job is to bring in the ones we'll be using with import statements. We've prefaced each import with a comment explaining where that library/routine is explained or illustrated:
# http://www.numpy.org/
# https://pandas.pydata.org/
# https://docs.python.org/3/library/sys.html
# https://stackoverflow.com/questions/7370801/measure-time-elapsed-in-python
from timeit import default_timer as timer
# https://keras.io/losses/
# https://keras.io/optimizers/
from keras import losses, optimizers
# https://keras.io/callbacks/
from keras.callbacks import History
# https://keras.io/layers/convolutional/
from keras.layers.convolutional import Conv1D
# https://keras.io/layers/core/
from keras.layers import Activation, Dense, Dropout
# https://keras.io/layers/embeddings/#embedding
from keras.layers import Embedding, Flatten
# https://keras.io/layers/pooling/
from keras.layers.convolutional import MaxPooling1D
# https://keras.io/getting-started/sequential-model-guide/
from keras.models import Sequential
# https://keras.io/utils/
from keras.utils import np_utils
Once we have those imports out of the way, the code to load our data looks like:
print("Reading in the preprocessed data...")
# pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html
df = pd.read_csv("new-tokenized-20-char.txt.gz", header=None, dtype=np.int8)
# Describe what we've read-in
print ("Raw dataframe...")
# pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.shape.html
count_row = df.shape[0]
print ("rows =",count_row)
count_col = df.shape[1]
print ("cols =",count_col)
# pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.info.html
df.info()
# Now break out the Y and the X's from the consolidated training file
print ("Y data...")
# pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.iloc.html
Y = df.iloc[:,0]
count_row_Y = Y.shape[0]
print ("rows =",count_row_Y)
print (Y.value_counts())
X = df.iloc[:,1:21]
print ("X data...")
X.info()
Running just the imports and the read-the-data-in statements we've just shown, we see:
$ python3 just-the-first-part.py
Reading in the preprocessed data...
Raw dataframe...
rows = 3264272
cols = 21
RangeIndex: 3264272 entries, 0 to 3264271
0     int8
20    int8
dtypes: int8(21)
memory usage: 65.4 MB
Y data...
0    3036657
1     227615
Name: 0, dtype: int64
X data...
That all looks about the way we'd expect. Now it's time to dig into the "red meat" of our neural network model.
Section 7. The Keras Sequential Model
You can read a nice overview of the Keras sequential model at https://keras.io/getting-started/sequential-model-guide/
The Keras sequential model is built up in layers. In a typical Keras sequential model there will be an input layer, one or more intermediate ("hidden") layers, and an output layer.
If you review "How to choose the number of hidden layers and nodes in a feedforward neural network?"26 you'll learn that:
• The Input Layer:
"With respect to the number of neurons comprising this layer, this parameter is completely and uniquely determined once you know the shape of your training data. Specifically, the number of neurons comprising that layer is equal to the number of features (columns) in your data."
• The Hidden Layer(s):
"In sum, for most problems, one could probably get decent performance (even without a second optimization step) by setting the hidden layer configuration using just two rules: (i) number of hidden layers equals one; and (ii) the number of neurons in that layer is the mean of the neurons in the input and output layers."
Another response from that same thread commented:
"Problems that require two hidden layers are rarely encountered. However, neural networks with two hidden layers can represent functions with any kind of shape. There is currently no theoretical reason to use neural networks with any more than two hidden layers."
When it comes to the number of neurons to use in each of those hidden layers,
"There are many rule-of-thumb methods for determining the correct number of neurons to use in the hidden layers, such as the following:
The number of hidden neurons should be between the size of the input layer and the size of the output layer.
The number of hidden neurons should be 2/3 the size of the input layer, plus the size of the output layer.
The number of hidden neurons should be less than twice the size of the input layer."
• The Output Layer:
"If the [Neural Network] is a classifier, then it also has a single node unless softmax is used in which case the output layer has one node per class label in your model."
In our case, the sequential model we finally ended up with was as follows:
1)	We know that our first layer will be an embedding layer because that layer, if used, must be the first layer in your model.27 Recall that we needed an embedding layer because we had an unworkable number of dummy coded/indicator/"one hot" variables, 39 dummy variables for each letter in up-to-20-character-long domain names.
2)	Then we'll have a Conv1D convolution layer. Why use a convolutional layer? Well, as was noted in Isak Bosman's "A Convolutional Neural Network Tutorial in Keras and Tensorflow 2:"28
"When identifying images or objects a great solution is to look for very similar pixel arrangements or patterns (features). But image recognition or object classifications are not the only uses for CNN's. They have proven useful in many general classification problems. By using smaller regions or filters a Convolutional Neural Networks scale[s] far better than regular neural networks and makes it a great starting point for any classification problem."
3)	Then we'll add a MaxPooling1D layer. Again quoting from Bosman:
"A pooling layer is responsible for dimensionality reduction to ultimately prevent overfitting. By reducing the computations and parameters of the network it allows the network to scale better and at the same time provide regularization. Regularization allows the network to generalize better which ultimately improves the performance of the network over unseen data. The most common pooling layer types are Max Pooling and Average Pooling. In the practical CNN example later in the article, we will look at how the Max Pooling layer is used. Max pooling is by far the most common pooling layer as it produces better results."
4)	Next comes a Flatten layer. The Flatten layer reformats multidimensional data received from a previous layer down to a single dimension.29
5)	Then there will be a hidden dense layer30 of size 40.
6)	Then we'll add a 2nd hidden dense layer of size 20 (even though we shouldn't need it, it seems to help).
7)	And finally, given that we're interested in categorization/predicting class membership, we know that our last layer will be a 3rd dense layer of size 1.
Putting that all together, the model building statements look like:
print ("Starting to build a Sequential model...")
model = Sequential()
print ("Adding embedding...")
model.add(Embedding(40+1, 20, input_length=20))
print ("Adding convolution layer...")
model.add(Conv1D(filters=40, kernel_size=6, activation='relu'))
print ("Adding MaxPooling1D layer...")
model.add(MaxPooling1D(pool_size=3))
print ("Adding Flatten layer...")
model.add(Flatten())
print ("Adding 1st Dense layer...")
model.add(Dense(40, activation='relu'))
print ("Adding 2nd Dense layer...")
print ("Adding 3nd Dense (output) layer...")
model.add(Dense(1, kernel_initializer='uniform', activation='sigmoid'))
Section 8. Layer Parameters
You'll notice in the above model that at least some layers require additional parameters. Where did we come up with those?
For example, what did we use for an activation function? And what IS an "activation function?" Wikipedia knows: "In artificial neural networks, the activation function of a node defines the output of that node given an input or set of inputs."31 Think of an activation function as being like an audio "sound mixer" or like a "truth table" in logic.32
So which activation function do we want to use? Quoting "A Practical Guide to ReLU: Start using and understanding ReLU without BS or fancy equations,"33
"ReLU is the most commonly used activation function in neural networks, especially in [convolutional neural networks]. If you are unsure what activation function to use in your network, ReLU is usually a good first choice."
See also "Activation functions and it's types-Which is better?"34 which states:
"Almost all deep learning Models use ReLu nowadays. But its limitation is that it should only be used within Hidden layers of a Neural Network Model."
So what are we going to do for our NON-hidden binary categorization output layer? We'll try Sigmoid35 for the output layer given that this is a binary categorization problem.
Now, how about initializers? First, what are they? Quoting "What are kernel initializers and what is their significance?"36
"The neural network needs to start with some weights and then iteratively update them to better values. The term kernel_initializer is a fancy term for which statistical distribution or function to use for initialising the weights. In case of statistical distribution, the library will generate numbers from that statistical distribution and use as starting weights."
We'll use "uniform" (aka RandomUniform) for our initializer. There's evidence in favor of more complex initializers,37 but RandomUniform has worked well in our tests and is conceptually simpler than some alternative initializer distributions.
Section 9. Compilation, Training and Saving The Model
When our model is complete, we'll "compile it" within Keras. in this case, that means using commands such as:
sgd = optimizers.SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='binary_crossentropy', optimizer=sgd, metrics=['accuracy'])
After the model is compiled, it then needs to be trained. This is the step that often can take some time.
Since we're still unbalanced with respect to our classes (albeit not as badly as initially), we'll use class weights to further upweight the "looks-random" class:
class_weight = {0: 1.,
1: 13.}
results = model.fit(X,Y,epochs=3,batch_size=32,class_weight=class_weight)
Once we've fit our model,38 we'll want to save it, so we don't need to retrain the model every time we want to use it to make predictions:
model_json = model.to_json()
with open("model.json", "w") as json_file:
json_file.write(model_json)
model.save_weights("model.h5")
Compiling and training our model requires us to specify (or accept a default value for):
An optimizer
A loss function, and
A metric.
When it comes to the optimizer, we chose Stochastic Gradient Descent (SGD) combined with "mini-batches"39 and with Nesterov40 enabled. As noted in "Types of Optimization Algorithms used in Neural Networks and Ways to Optimize Gradient Descent,"41
"An improvement to avoid all the problems and demerits of SGD and standard Gradient Descent would be to use Mini Batch Gradient Descent as it takes the best of both techniques and performs an update for every batch with n training examples in each batch. […] Mini-batch gradient descent is typically the algorithm of choice when training a neural network nowadays."
When it comes to the loss function, the tutorial "How to Choose Loss Functions When Training Deep Learning Neural Networks"42 states:
"Binary Cross-Entropy Loss
Cross-entropy is the default loss function to use for binary classification problems. It is intended for use with binary classification where the target values are in the set {0, 1}. Mathematically, it is the preferred loss function under the inference framework of maximum likelihood. It is the loss function to be evaluated first and only changed if you have a good reason. Cross-entropy will calculate a score that summarizes the average difference between the actual and predicted probability distributions for predicting class 1. The score is minimized and a perfect cross-entropy value is 0. Cross-entropy can be specified as the loss function in Keras by specifying 'binary_crossentropy' when compiling the model."
And finally, when considering metrics, we'll use "accuracy" since this is a classification model. https://keras.io/metrics/ states that
"A metric function is similar to a loss function, except that the results from evaluating a metric are not used when training the model. You may use any of the loss functions as a metric function."
Section 10. Running and Saving The Model
The full deep learning/neural network program can be found in Appendix III.
We'll run that program by saying:
$ python3 run-model-embeddings.py > run-model-embeddings.out
Disregarding the "reading-in-the-data" output we've already considered, the output in run-model-embeddings.out lets us watch how our model run:
Starting to build a Sequential model...
Adding embedding...
Adding convolution layer...
Adding MaxPooling1D layer...
Adding Flatten layer...
Adding 1st Dense layer...
Adding 2nd Dense layer...
Adding 3nd Dense (output) layer...
Compiling...
Fit...
Epoch 1/3
32/3264272 [..............................] - ETA: 26:04:01 - loss: 1.7335 - acc: 0.5938
4288/3264272 [..............................] - ETA: 20:41 - loss: 1.3414 - acc: 0.1905
11360/3264272 [..............................] - ETA: 12:45 - loss: 0.7840 - acc: 0.6533
43776/3264272 [..............................] - ETA: 8:33 - loss: 0.2527 - acc: 0.9005
1055712/3264272 [========>.....................] - ETA: 5:12 - loss: 0.0399 - acc: 0.9900
3264272/3264272 [==============================] - 450s 138us/step - loss: 0.0259 - acc: 0.9939
We ran for 3 epochs because the model rapidly converged – when we tried running for a longer number of epochs, the loss and accuracy functions did not materially improve
Section 11. Applying the Estimated Model To Some New Data
All of the above aside, how well does the model find examples of random-looking domains in new data?
We'll use another tranche of encoded SIE Channel 204 data to find out (domain names with more than 20 characters were dropped):
$ wc -l data-for-evaluation-up-to-20-only.dat
2,297,048 data-for-evaluation-up-to-20-only.dat     [commas added for readability]
When compressed with gzip -9, that file is about 14MB in size. We'll run that new data against the previously-fitted-model using the code shown in Appendix IV.
When run, the output of that code shows that 7,701 domains were identified by the neural network as being likely random-looking. That amounts to 1/3rd of 1% (7701/(7701+2289347))*100=0.335%) of all the observations in that file. We saved the probability of each record belonging to class 1, (e.g., of being "random-looking") to predictions.txt. Those entries consisted of the observation number (starting with zero) and the associated probability of that particular observation being a random-looking domain name.
$ head predictions.txt
0 0.00022143000000000000
$ tail predictions.txt
2297038 0.00000000000406899560
We sorted those lines with the command:
$ sort -k2 -k1 -g < predictions.txt > predictions2.txt
$ head predictions2.txt
132 0.00000000000000000000
$ tail predictions2.txt
47029 0.99999154000000001208
826923 0.99999212999999997908
Graphing the row-number-in-the-sorted-file vs the probability-of-membership-in-class=1, we got a graph with a very sharp knee:
Figure 3. Probability of Membership in Class=1 vs. Dataset Row Number in Sorted File
This graph illustrates the fact that the model was "quite sure" that the vast majority of the observations were NOT random (e.g., there was very little degree of uncertainty for the wide flat region). For most observations in the test dataset, the model predicted virtually no chance of membership in class=1.
With a normal threshold of >=0.5, just ~1/3 of 1% of all observations were predicted as being being in class=1 (e.g., "random-looking"), see the "vertical" piece of the graph.
Even if we tag everything with a >= 0.05 chance-of-being-class=1 (a very, very, very permissive threshold) as actually being class=1, that still only brings us up to 0.58 of 1% of observations. See Table 3:
Table 3. Called Class Membership Probability Distribution
Class=1 Call   First seen in         Remaining      Remaining
Probability    predictions2.txt      Obs After      Percentage
0              --> 0                 2,297,047      100%
0.0001         --> 2,234,545            62,503      2.72%
0.001          --> 2,259,382            37,666      1.64%
0.01           --> 2,277,785            19,263      0.84%
0.1            --> 2,285,302            11,746      0.51%
0.3            --> 2,287,807             9,241      0.40%
0.9999         --> 2,297,048                 0      0%
But what do the 7,701 observations that are at or above 0.5 probability for class=1 membership look like? Has the neural network/deep learning model actually worked? Do those observations actually appear "random looking?" We'll need to dig into those observations to see.
We could just use awk to print the hits (e.g., imagine a script with 7701 lines that look like)
awk 'NR == 838543+1' sorted-and-uniqued-for-keras-test-20-or-less.txt
awk 'NR == 86223+1' sorted-and-uniqued-for-keras-test-20-or-less.txt
Each of those statements would work to print one domain name from the test dataset,43 however that's a crude approach and slow to execute. We'll sort the list of hits in ascending order, and then use the little python3 script shown in Appendix V instead.
The contents of extracted-records.txt as output by that program looks like:
000222y8.com
000365dd.com
001yixue.com
0022hhgj.com
006qd4pi.com
zzxydqwx.com
zzyc88888.com
zzyzx888.com
zzz01234.com
zzzzz666.net
Those sure seem like some pretty random-looking domains! After a superficial look, we're cautiously optimistic. But what do we see if we then run those results through the find-words.py script from Part 1 of this blog?
Section 12. Dictionary "Pollution" in The Dictionary From Part 1; Dictionary Oversights/Omissions
Surprisingly, when we attempted to cross-validate the full set of "class=1" results found by the neural network/deep learning model with our find-words.py code from part I of this blog, we found some results that the neural network/deep learning model flagged as random looking (and which looked random to us), but which find-words.py reported as containing "words."
Looking at one result flagged as "random" by the neural network (but which had many "words" when checked with find-words.py), we saw:
15 sdfghjkl com ['dfgh', 'dfghj', 'dfghjk', 'fgh', 'fghj', 'fghjk', 'fghjkl', 'ghj', 'ghjk', 'ghjkl', 'hjk', 'hjkl', 'sdfg', 'sdfgh', 'sdfghj']
Candidly, we're not very impressed with the quality of some of the "words" find-words.py found. So how did those "words" get into the word list or "dictionary" that drives find-words.py? We believe our dictionary of words (as used in Part I of this blog series) may have been "polluted" by our decision to add some inadequately-screened "word lists" that were created for use in conjunction with password cracking.
In this particular case, if you look at the middle alphabetic row of a normal western keyboard, you'll notice "sdfghjkl" is the sequence of letters making up the middle row. Thus, from a password cracking perspective, it makes sense to include "sdfghjkl" (and subruns thereof) since users are known to routinely employ runs of characters from their keyboard's physical layout as their password. In fact, however, those "words" are NOT what most people would consider to be real English (or foreign language) words (as that term is normally used).
Another example of how we may have issues around word quality in our consolidated "dictionary:"
9 xclwxhjwudftlpnxm me ['dft', 'hjw', 'lpn', 'nxm', 'pnx', 'tlp', 'udf', 'wud', 'wxh']
That name sure looks like a random domain to us – and to our neural network – despite having nine "words" from our original "dictionary."44 A final clearly-random-looking example with four low-quality "words:"
4 yxvxsdncysvxvcykv la ['cyk', 'ncy', 'sdn', 'svx']
At the same time we reached the conclusion that there are some "words" that clearly need to come out of our consolidated dictionary, we also noticed that there are still some all-too-common words that are unexpectedly missing from our dictionary, such as the "pseudo-word" "www".
Clearly, further review and curation of our dictionary is warranted. Once that's completed, the training data can then be recategorized, the models retrained, and the test dataset re-evaluated, etc. For that reason, we're not going to show detailed comparisons of categorization accuracy, etc., in this article.
Section 13. Conclusion
You've now seen how neural networks can be used to successfully categorize domain names as "random-looking" or normal domains.
You've also seen how neural networks can highlight issues with other approaches to name categorization, such as issues with dictionary contents in our "look-for-English-or-foreign-language-words" approach.
We hope that you'll be inspired to develop your own models (and word lists!) to identify random-looking domains, perhaps trying alternative neural network architectures such as recurrent ("LSTM")45 models.
And if you need data for that testing, consider talking to Farsight Security sales about access to Channel 204 at the Security Information Exchange. With access to Channel 204, you could see how your own ideas for spotting algorithmic domain names measure up!
The Farsight Security Sales Team can be reached at sales@farsightsecurity.com or give them a call at +1-650-489-7919.
Acknowledgements: I'd like to thank my Farsight colleague Kelvin Dealca for his comments on a draft version of this article. That said, any/all issues that may remain are solely the responsibility of the author.
Appendix I. convert5.f
! compile with: $ gfortran -o convert5 convert5.f
! following text uses a tab for the initial spacing on each line
! convert Y (1st column), space, then up to 20 char domains
character*20 domainname
character*39 validchars
character*1 char_to_match
integer class
integer location
integer maxwidth
integer maxcols
integer i,j
! domain name max width
maxwidth = 20
! valid characters: 26 letters + 10 number + 3 punctuation=39 chars
validchars = 'abcdefghijklmnopqrstuvwxyz0123456789-_.'
maxcols = 39
open(5,file="combined-20-or-less.dat", status='old',
1 action='read')
100	read (5,"(I1, X, A20)",end=99999) class, domainname
write (*,"(I1,',')",advance="no") class
do j=1,maxwidth     ! characters to translate
! what character are we looking for?
char_to_match= trim(domainname(j:j))
! find the index of that char in validchars
location=index(validchars,char_to_match)
write(*,"(i2,',')",advance="no") location
write (*,"(X)")
goto 100
99999	continue
Appendix II. trim-too-long
my $threshold;
my $length;
my $line;
$threshold = $ARGV[0];
if ( $#ARGV == -1) {die "must specify maximum OK length as first command line ar
gument\n"};
if ( $threshold <=0 ) { die "maximum length must be > 0!\n" };
while ( $line = <STDIN> ) {
chomp( $line );
$length=length( $line );
if ( $length <= $threshold ) { printf( "%s\n", $line ); }
Appendix III. run-model-embeddings.py
start = timer()
# we have unequal class counts, so we need to weight the 1's more heavily
# ref https://datascience.stackexchange.com/questions/13490/how-to-set-class-weights-for-imbalanced-classes-in-keras
# read the combined training data frame (the frame contains both
# a class variable we want to predict (Y) and a set of attributes (X's))
# ref https://www.shanelynn.ie/using-pandas-dataframe-creating-editing-viewing-data-in-python/
# data-for-training.dat looks like...
# 1 Y, 20 encoded X values (zero padded on the right for short names)
# the domain names were encoded a priori using convert5.f (outside of python)
print("Reading in the tokenized data...",flush=True)
end = timer()
print ("After reading in training data, elapsed time in seconds =",(end-start))
print ("Raw dataframe...",flush=True)
print ("rows =",count_row,flush=True)
print ("cols =",count_col,flush=True)
# https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.info.html
print ("-------------------------")
# the first column (column 0) is Y
# (Y's coding: 0 ==> regular domain, 1 ==> random-looking domain)
print ("Y dataframe")
print ("our Y values look like...")
# https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.value_counts.html
# we've padded domains less than 20 chars long with zeros (blanks) on the
# right hand side of the row as part of our convert5.f processing, leaving
# us with uniform rows at this point
# https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.iloc.html
print ("our X values look like...")
# see https://machinelearningmastery.com/tutorial-first-neural-network-python-keras/
# https://keras.io/layers/embeddings/
from matplotlib import pyplot
from sklearn.manifold import TSNE
def plot_embeddings(embeddings, names):
model = TSNE(n_components=2, random_state=0)
vectors = model.fit_transform(embeddings)
x, y = vectors[:, 0], vectors[:, 1]
fig, ax = pyplot.subplots()
ax.scatter(x, y)
for i, tname in enumerate(names):
ax.annotate(tname, (x[i], y[i]))
pyplot.show()
embeddings = model.layers[0].get_weights()[0]
names = list(X.keys())
# plot_embeddings(embeddings, names)
print ("Compiling...")
print ("Fit...")
history = model.fit(X,Y,epochs=3,batch_size=32,class_weight=class_weight)
print ("After fitting the model, elapsed time in seconds =",(end-start))
print ("Evaluate...")
scores = model.evaluate(X, Y, verbose=0)
print("%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))
print ("Summarizing...")
print("model.summary()=",model.summary())
print ("Saving the model")
# https://machinelearningmastery.com/save-load-keras-deep-learning-models/
# serialize model to JSON
# serialize weights to HDF5
print("Saved model to disk")
print ("Post model save, elapsed time in seconds =",(end-start))
Appendix IV. run-model-embeddings-2.py
from keras.models import model_from_json
# load already built and estimate model
json_file = open('model.json', 'r')
loaded_model_json = json_file.read()
json_file.close()
model = model_from_json(loaded_model_json)
model.load_weights('model.h5')
print("Loaded model from disk")
print("Reading in the eval data...",flush=True)
df2 = pd.read_csv("data-for-evaluation-up-to-20-only.dat.gz",
header=None, dtype=np.int8)
count_row = df2.shape[0]
count_col = df2.shape[1]
Xprime = df2.iloc[:,0:20]
print ("Predicting...")
Yprime = model.predict_classes(Xprime)
Yprime_probability = model.predict_proba(Xprime)
count_row = Yprime.shape[0]
count_col = Yprime.shape[1]
value, count = np.unique(Yprime, return_counts=True)
print (value,count)
# get ALL the results, not just a taste
np.set_printoptions(threshold=sys.maxsize)
f = open("predictions.txt","w+")
for i in range(len(Yprime)):
value = float(str(Yprime_probability[i]).replace('[','').replace(']',''))
value = f'{value:.20f}'
print(i, value, file=f)
Appendix V. print-hits.py
# note that hits.txt MUST be sorted in ascending order
myhits = open ('hits.txt', 'r')
domains = open ('sorted-and-uniqued-for-keras-test-20-or-less.txt', 'r')
matches = open ('extracted-records.txt', 'w+')
linenumber = 0
domain = domains.readline().rstrip('\n')
myhit = myhits.readline()
while ((domain != '') and (myhit != '')):
if (int(myhit) == linenumber):
print (domain, file=matches)
linenumber = linenumber + 1
myhits.close()
domains.close()
matches.close()
Joe St Sauver Ph.D. is a Distinguished Scientist with Farsight Security®, Inc. **
I quote:
"No matter what function we want to compute, we know that there is a neural network which can do the job. What's more, this universality theorem holds even if we restrict our networks to have just a single layer intermediate between the input and the output neurons - a so-called single hidden layer. So even very simple network architectures can be extremely powerful."
See http://neuralnetworksanddeeplearning.com/chap4.html
↩
See https://meta.wikimedia.org/wiki/Cunningham%27s_Law ↩
See for example https://www.stata.com/support/faqs/statistics/stepwise-regression-problems/ ↩
A particularly scathing review: "The BS-Industrial Complex of Phony A.I.; How hyping A.I. enriched investors, fooled the media, and confused the hell out of the rest of us," https://web.archive.org/web/20190626012618/https://gen.medium.com/the-bs-industrial-complex-of-phony-a-i-44bf1c0c60f8:
"For the last few years, startups have shamelessly re-branded rudimentary machine-learning algorithms as the dawn of the singularity, aided by investors and analysts who have a vested interest in building up the hype. Welcome to the artificial intelligence bullshit-industrial complex."
Is blockchain living up to the hype? ↩
An NVIDIA DGX-2 (see https://www.nvidia.com/en-gb/data-center/dgx-2/ at a mere ~$400K per https://www.zdnet.com/article/nvidia-dgx-2-review-more-ai-bang-for-a-lot-more-bucks/ sure would be handy, but even a $99 128-core NVIDIA Jetson Nano board would likely lower neural network training times (see https://smile.amazon.com/NVIDIA-Jetson-Nano-Developer-Kit/dp/B07PZHBDKT ↩
https://keras.io/ ↩
http://www.deeplearning.net/software/theano/ ↩
https://www.python.org/ ↩
https://www.numpy.org/ ↩
https://pandas.pydata.org/ ↩
https://opensource.com/article/18/5/top-8-open-source-ai-technologies-machine-learning ↩
https://groups.google.com/forum/#!topic/theano-users/7Poq8BZutbY ↩
https://www.anaconda.com/distribution ↩
Python Environment ↩
https://pypi.org/project/pip/ ↩
https://www.perl.org/ ↩
We're reminded of "The Surprising Creativity of Digital Evolution: A Collection of Anecdotes from the Evolutionary Computation and Artificial Life Research Communities", https://arxiv.org/abs/1803.03453v1 ↩
https://datascience.stackexchange.com/questions/13490/how-to-set-class-weights-for-imbalanced-classes-in-keras ↩
https://gcc.gnu.org/fortran/ ↩
https://www.gnu.org/software/gzip/ ↩
https://en.wikipedia.org/wiki/Level_of_measurement ↩
https://en.wikipedia.org/wiki/Collation ↩
https://en.wikipedia.org/wiki/Nonparametric_statistics ↩
https://machinelearningmastery.com/how-to-one-hot-encode-sequence-data-in-python/ ↩
https://stats.stackexchange.com/questions/181/how-to-choose-the-number-of-hidden-layers-and-nodes-in-a-feedforward-neural-netw ↩
https://keras.io/layers/embeddings/ explicitly says "This layer can only be used as the first layer in a model." ↩
https://mc.ai/a-convolutional-neural-network-tutorial-in-keras-and-tensorflow-2/ ↩
https://keras.io/layers/core/ ↩
https://keras.io/layers/core ↩
https://en.wikipedia.org/wiki/Activation_function ↩
https://en.wikipedia.org/wiki/Truth_table ↩
https://medium.com/tinymind/a-practical-guide-to-relu-b83ca804f1f7 ↩
https://towardsdatascience.com/activation-functions-and-its-types-which-is-better-a9a5310cc8f ↩
https://medium.com/aidevnepal/for-sigmoid-funcion-f7a5da78fec2 ↩
https://datascience.stackexchange.com/questions/37378/what-are-kernel-initializers-and-what-is-their-significance ↩
https://becominghuman.ai/priming-neural-networks-with-an-appropriate-initializer-7b163990ead ↩
https://machinelearningmastery.com/save-load-keras-deep-learning-models/ ↩
Revisiting Small Batch Training for Deep Neural Networks ↩
https://wiseodd.github.io/techblog/2016/06/22/nn-optimization/ ↩
https://towardsdatascience.com/types-of-optimization-algorithms-used-in-neural-networks-and-ways-to-optimize-gradient-95ae5d39529f ↩
https://machinelearningmastery.com/how-to-choose-loss-functions-when-training-deep-learning-neural-networks/ ↩
The row number needs to be incremented by one because python is zero origin (it counts from zero), while awk counts from 1. ↩
I'm willing to stipulate that "lpn" is a valid abbreviation for "licensed practical nurse", and "tlp" is a valid abbreviation for "trust level protocol", but nonetheless. ↩
See https://en.wikipedia.org/wiki/Long_short-term_memory (an excellent example of using LSTM to detect DGA domains can be seen at https://www.endgame.com/blog/technical-blog/using-deep-learning-detect-dgas) ↩
Next in The TXT Record: Creating Pandas Dataframes and CSV Files from DNSDB API Output Using Python3


Theallet, 52, is a French-born designer who grew to prominence by dressing current first lady Michelle Obama on quite a lot of events. Colleges providing particular trend design applications have increased dramatically as demand has elevated and based on the Nationwide Affiliation of Colleges of Artwork and Design , there are greater than 300 institutions that supply accredited degree applications in art and design and lots of of those establishments have particular degree packages in style design or style merchandising.
Will Vogue Designers Embrace Melania Trump?
Trend design is a difficult, inventive field that requires business, art and design abilities. But if you want to enter the dynamic realm of vogue designing, you will must be in a classroom or studio setting to interact with textiles and fabrics and perceive how they'll drape on a mannequin. There are a variety of specialised art schools and design colleges worldwide that offer degrees in vogue design and vogue design expertise. There are other ways a self-employed style designer can earn a residing too.
In accumulation to creating a certainly sizzling and smelly logic, lengthy sleeves test the simple effort of arms to some range. Accreditation ensures a high quality program reviewed by tutorial peers, might allow you to seek monetary support, and makes sure that your credit will transfer for those who move or go to a different faculty in a while. Since NASAD is slowly accrediting online packages you could have some difficulty finding on-line faculties with their seal of approval, though regional accrediting bodies readily approve online applications.
The bottom 10 percent of fashion designers earned a median annual salary of lower than $34,a hundred and ten while the top 10 p.c earned a median annual wage of greater than $126,290 as wage and earnings fluctuate relying on the employer and experience of the designer.
Vogue Designer: Fashion Icon is a sport for the Nintendo DS, developed by Artistic Patterns and printed by 505 Games. Some positions require that the designer has graduated from a style design program, while others will simply depend on the talent and experience of the fashion designer. However, just a few of the most successful self-employed style designers earn many occasions the wage of the best paid salaried designers. The fashion trade is extremely competitive; solely pursue a profession in vogue if it you're one hundred pc devoted to the field.
The International Design Awards is looking for style designers who know easy methods to make an impression. This assortment line includes quick in length shirts, these shirts have been completely set These Kaliyan by Z.S Textiles summer season clothes 2016 are elaborated within the printed patterns, thread work is there too on the shirts. Thanks for sharing beneficial details about the great vogue designers and good photograph are the inspiration for a lot of upcoming style designers and offered roots for the style designing subject. This step is a continuing responsibility for a Trend Designer, additionally some of the pleasing!


text:
Filmmakers' wishes to see their films distributed and screened in cinemas. There is no single route to the cinema screen and with over thousands plus theatrical distributors of all shapes and sizes, from Warner Brothers to self distribution models worldwide; it can be daunting for filmmakers to choose the method which is right for their film.
The traditional route for a film seeking distribution to be shown in cinemas is to enter a major international film festival such as Cannes, Berlin, Sundance or Toronto. If a film is lucky enough to be selected for these A list international festivals, they provide an invaluable shop window for the global distribution markets. A film selected for these festivals will be seen by the world's distributors and if you're lucky they will bid against each other for the right to distribute your film in their respective countries (both theatrically and in the home). In any major film festival showing 200 or more feature films, at least 50% of these will never get distribution and will not be seen again on a cinema screen in that country. In the UK in 2012 over 600 films were distributed theatrically which means intense competition for screen space. But put that number against how many features are made every year globally and at best 10% of features produced will see the inside of a cinema.
Equally important as distributors are international sales agents. These companies will assess new films and buy worldwide rights which they then sell on to distributors across the planet. They often have excellent relationships with festivals and distributors of all sizes in all markets. They are invaluable for getting the best deal in territories most filmmakers may not even have thought of. A distributor will be much more likely to take a film seriously as a commercial proposition if it has been presented to them by a recognised sales agent.
However if your film is perhaps not strictly a commercial genre film, what can you do? You can still approach festivals directly but also individual distributors in your country, and beyond, which have a track record distributing films of a similar nature/genre to yours and see if they will do the same for you. If they do, then wonderful. If not, then you can consider self-distribution.
Self-distribution is where you produce your own marketing materials (posters, trailers, prints etc.), book and pay for your own advertising (depending on your resources this can be a vast expenditure or a single ad on the day of release in a major national newspaper such as The Telegraph or Times of India).
You will need to hire a specialist PR company to ensure the national film press (print and online) see your film in advance and write about it/review it on the day of your release. Reviews are free advertising and a good one is a huge aid to getting your film into cinemas. Selling the film to cinemas can be a tough job. You need to convince them that your film should be chosen over the other 10-15 or so releases opening every week in cinemas. This is a combination of communicating what is great about your film, but also convincing exhibitors that your film will have the visibility it needs to find an audience. This visibility comes from advertising, festival exposure, reviews, word of mouth on preview screenings and is one of the hardest things to secure and to convince others you will have. A Studio will typically spend 7 figures in ensuring the visibility of their big blockbuster releases, an art house independent will spend 5 figures. A filmmaker needs to think how they can achieve this visibility through other means - editorial is free so working the press. What is it about your film that is unique and will drive an audience to see it?
There are different methods to generate revenue from a film. The platforms can be summed up as:
Theatrical Distribution
Non-Theatrical and Video Rental Rights
Sell Through Video & DVD and pay Television.
Internet Marketing and Sales in different platforms worldwide
Self Distribution Rights

redpajama_set_name: RedPajamaCommonCrawl


Good but not great Chinese in a super-swank underground lair near the Embarcadero. I felt unshowered and underdress (ok, I *was* unshowered and underdressed) but loved having a cocktail at lunch in a dark, red booth. Also, attached to the restaurant is a members only cigar lounge complete with cigar lockers.


Who can resist the magic of this epic musical? And seeing it at the State Theatre is truly something special. First, you get to see the classic movie on the big screen in full beautiful Technicolor glory, and you can sing along with your fellow fans to every one of the wonderful Rodgers and Hammerstein songs.
Finally, we encourage anyone who wants to do so to come to the show in a SOUND OF MUSIC costume. We're talking nuns, Austrian schoolchildren, swanky Baronesses, lovely Liesels and even the occasional Rae a Drop of Golden Sun. We'll offer prizes for the best outfits, so put that imagination to work.
No matter how many times you may have seen "The Sound of Music" you have never experienced it like this before. So grab your ticket and get ready to "Climb Every Mountain" because we are sure this holiday family event will be one of your favorite things! Tickets $5!
Widower Captain von Trapp needs yet another governess for his rowdy brood, and Mother Abbess has just the girl to whip them into shape: soon-to-be nun Maria. When Maria discovers the children share her love of music, it's as easy as "Do-Re-Mi"… that is until her songs start to melt the Captain's cold heart. But what about his pesky fiancé, Baronness Schraeder? Based on real-life von Trapp singers, and set in stunning Salzburg, Austria amid the rise of Hitler's Third Reich, this Rodgers and Hammerstein musical set box office records and won 5 Academy Awards, including Best Picture.


Sunnyvale, Calif. – June 5, 2018 – Ruckus Networks, an ARRIS company, today announced that Ruckus technology will be used in Google Station Wi-Fi hotspots in India, Indonesia and Mexico. Under the terms of the deal, Ruckus will provide devices and technologies enabling carrier-grade networks at Google Station hotspots. Ruckus will supply its virtual SmartZone™ controller, which can manage a virtual instance of the SmartZone controller, as well as indoor and outdoor Wi-Fi access points.
Google Station is a high-speed, high-quality public Wi-Fi platform that provides an easy set of tools to roll out Wi-Fi hotspots in public places, such as high-traffic locations like airports, malls, universities, railways and mass transit stations. These hotspots deliver high-performance Wi-Fi using Ruckus' patented adaptive antenna BeamFlex™ technology for increased connectivity performance and range, better signals and maximized power efficiency.
Ruckus technologies are currently deployed across hundreds of Wi-Fi hotspots for Google Stations in India, Mexico and Indonesia.


HomePriceRecords.com Medford is the simplest spot to find home price and home buying information for the entire Medford area. We're working to make the data fresher and more relevant to real estate agents.
This site is the easiest spot for investors to find real estate statistics for the Medford area. We hope you can use this real estate appraisal information.
It is the easiest spot in Medford to find home sale price data which help greatly in real estate investment and investing. We've seen this place become increasingly popular among real estate appraisers and real estate agents.


text:
Lt.-Col. Charles Ralph Borlase Wingfield
M, #86081, b. 1873, d. 1 February 1923
Lt.-Col. Charles Ralph Borlase Wingfield was born in 1873. He married Mary Nesta Harriet Williams, daughter of Major Charles Henry Bennett Williams and Hon. Mabel Emma Boscawen, on 20 June 1916.1 He died on 1 February 1923.
He was 3rd Battalion KSLI.1 He lived Onslow.1 He lived at Onslow, Shrewsbury, Shropshire, EnglandG.
Children of Lt.-Col. Charles Ralph Borlase Wingfield and Mary Nesta Harriet Williams
Charles John Wingfield+ b. 9 May 1917
Owen Penrhyn Wingfield b. 20 Jul 1918
Rosemary Joy Wingfield b. 20 Apr 1923
Henrietta Margaret Williams
F, #86082, b. circa 1846, d. 29 July 1885
Henrietta Margaret Williams was born circa 1846. She was the daughter of Sir Hugh Williams, 3rd Bt. and Henrietta Charlotte Williams-Wynn. She married Edmund Peel on 1 February 1866.1 She died on 29 July 1885.1
Her married name became Peel.
Children of Henrietta Margaret Williams and Edmund Peel
Margaret Anne Peel+ d. 15 Jun 1923
Ethel Mary Peel+
Linda Peel d. 16 Feb 1880
Major Hugh Edmund Ethelston Peel+ b. 13 Nov 1871, d. 25 Jun 1950
Charles Wicksted Ethelston Peel b. 1873, d. 1873
Herbert Wicksted Ethelston Peel b. 4 Nov 1881, d. 13 Mar 1915
Ernest Ethelston Peel+ b. 6 Jun 1884
Edmund Peel
M, #86083, b. 1826, d. 27 March 1903
Edmund Peel was born in 1826. He married Henrietta Margaret Williams, daughter of Sir Hugh Williams, 3rd Bt. and Henrietta Charlotte Williams-Wynn, on 1 February 1866.1 He died on 27 March 1903.
He lived at Bryn-y-Pys, WalesG.
Children of Edmund Peel and Henrietta Margaret Williams
Edith Sarah Williams
F, #86084, b. circa 1848, d. 6 September 1920
Edith Sarah Williams was born circa 1848. She was the daughter of Sir Hugh Williams, 3rd Bt. and Henrietta Charlotte Williams-Wynn. She married Salusbury Kynaston Mainwaring, son of Charles Kynaston Mainwaring, on 30 May 1869.1 She died on 6 September 1920.1
Her married name became Mainwaring.
Children of Edith Sarah Williams and Salusbury Kynaston Mainwaring
Major Charles Francis Kynaston Mainwaring+ b. 17 Dec 1871, d. 30 Jan 1949
Colonel Sir Watkin Randle Kynaston Mainwaring+ b. 22 Aug 1875, d. 1944
Salusbury Kynaston Mainwaring
M, #86085, b. 1844, d. 22 August 1895
Salusbury Kynaston Mainwaring was born in 1844. He was the son of Charles Kynaston Mainwaring. He married Edith Sarah Williams, daughter of Sir Hugh Williams, 3rd Bt. and Henrietta Charlotte Williams-Wynn, on 30 May 1869.1 He died on 22 August 1895.
He held the office of Justice of the Peace (J.P.)2 He held the office of Deputy Lieutenant (D.L.)2 He lived at Oteley Park, Shropshire, EnglandG.2
Children of Salusbury Kynaston Mainwaring and Edith Sarah Williams
Charles John Wingfield
M, #86086, b. 9 May 1917
Charles John Wingfield was born on 9 May 1917. He is the son of Lt.-Col. Charles Ralph Borlase Wingfield and Mary Nesta Harriet Williams.
Child of Charles John Wingfield and Cecily Meighan-Lovett
John George Owen Wingfield b. 1957
Cecily Meighan-Lovett
Child of Cecily Meighan-Lovett and Charles John Wingfield
John George Owen Wingfield
John George Owen Wingfield was born in 1957. He is the son of Charles John Wingfield and Cecily Meighan-Lovett.
Owen Penrhyn Wingfield
M, #86089, b. 20 July 1918
Owen Penrhyn Wingfield was born on 20 July 1918. He is the son of Lt.-Col. Charles Ralph Borlase Wingfield and Mary Nesta Harriet Williams.
Rosemary Joy Wingfield
Rosemary Joy Wingfield was born on 20 April 1923. She is the daughter of Lt.-Col. Charles Ralph Borlase Wingfield and Mary Nesta Harriet Williams.


Tilt sensors are used for monitoring the rotation of structures.
Automatic levelling of a structure can be undertaken using liquid levelling systems.
To support our suite of structural monitoring sensors we also undertake 3D surveys and precise levelling.


text:
Subcontractors & Vendors
Total Administrative Services Corporation
Total Administrative Services CorporationHeather Manke2016-07-21T13:46:47+00:00
Vogel Bros. built a building at two different locations for TASC. The first location was a new office building with a structural steel frame and wood exterior that featured 11,700 square feet of leasable tenant space. The second building was a two-story office building with steel frame structure, wood cladding and composite metal panel insets. This building features an aluminum curtain wall, EPDM roof system, hydraulic elevator and shelled office areas. Scope of work included the build-out of 4,400 square feet for the IT department.
Civic & Commercial
2302, 2409 International Lane, Madison, WI
Flad & Associates
Type of Project:
Fujifilm Cellular Dynamics, Inc
Willy Street Co-Op: North
Willy Street Co-Op: West
Greenwoods State Bank
Copyright 2016 Vogel Bros. Building Co. All Rights Reserved. Contact Us | Subcontractors & Vendors | Careers


text:
TOMBS Announces Virtual Performance via Bandcamp
FIREWIND Releases Music Video For 'Devour'
MÖTLEY CRÜE To Begin Year-Long 40th-Anniversary Celebrations
Watch TRANSATLANTIC New Video & Single "Looking for the Light" from Upcoming Mammoth Studio Album "The Absolute Universe"
Ominous Glory – The Elven Dream (Album Review)
ARC OF LIFE Share New Single "Just In Sight" From Upcoming Album
The Dead Daisies – Holy Ground (Album Review)
CHEZ KANE Announces Debut Solo Album and Releases First Single
SONICPERSPECTIVES
Browsing: Video Series
By Editorial Team August 14, 2020
ANTHRAX's "Persistence of Time" Tour Stories: Filling in for PUBLIC ENEMY's Flavor Flav, Fishing with JERRY CANTRELL, and Tour, Tour, Tour
One week from today, the 30th anniversary deluxe edition of Anthrax's fifth studio album, "Persistence of Time" will be released. Over the two-and-a-half years that the…
ANTHRAX Co-Stars In An Episode of "Married with Children" During 4th Installment of "Persistence Of Time" Video Series
Anthrax's "Persistence of Time" two year album and tour "cycle" (1990-92) was loaded with all kinds of good trouble. The band toured with Iron Maiden on "Monsters…
By Editorial Team July 30, 2020
ANTHRAX Releases Episode Three Of "Persistence Of Time" Video Series, Discussing Touring with IRON MAIDEN
Back in 1988, all of the members of Anthrax were big Iron Maiden fans. Not only did they love Maiden's music, but they appreciated and…
ANTHRAX Releases Episode Two Of "Persistence Of Time" Video Series, Discussing Collaboration with PUBLIC ENEMY
Anthrax invite you to get the inside story behind the making and promotion of the band's fifth album, "Persistence of Time" and its 30th Anniversary…
By Editorial Team July 7, 2020
Watch ANTHRAX Pulling Back the Curtain on the "Persistence of Time" Album and Touring Cycle in First of Six Video Series: Episode One – "Dali"
HELP US TO KEEP INFORMING YOU
We work hard to bring high quality editorial content to our readers, and we are glad you keep coming back to us! Wanna walk the extra mile? You might consider helping us using the button below. We'll be eternally grateful!
In Album Reviews
3.2 (ROBERT BERRY) Releases New Single "A Bond of Union"
"The Go-Gos" Documentary Film to be Released on Digital Formats
LUNA 13 Share Video For Single "Sacrificial Lamb"
AVATAR – Avatar Ages Livestream [Part I – Age Of Dreams] (January 9th, 2021)
In Concert Reviews
RHINO to Release Deluxe Versions of BLACK SABBATH's "Heaven and Hell" and "Mob Rules" on March 5th
U.D.O. Announce Release of "Live In Bulgaria 2020 – Pandemic Survival Show"
Winterage – The Inheritance of Beauty (Album Review)
Subscribe to our newsletter for weekly dose of insighful posts about the world of music
We speak music, the universal language of mankind. From music news, to concert reviews, interviews, album reviews, exclusive features and more…
Copyright © Sonic Perspectives - All rights reserved. Website design by Norrsken Photography and Design


text:
Aiken Standard, S.C.
North Augusta celebrates start of Christmas season with tree lighting
Samantha Winn, Aiken Standard, S.C.
Dec. 1—The holiday lights and spirit came to life in North Augusta.
The city of North Augusta officially kicked off the holiday season with their annual Christmas tree lighting at Calhoun Park on Nov. 30. The event featured a colorfully lit tree at the corner of the park, spirited performances from Paul Knox and North Augusta Middle School bands, and a visit from the Clauses.
The tree, located in Calhoun Park in front of the famous Lookaway Inn, sits at the fork in the road between Carolina and Georgia Avenues. Families and friends were able to partake in the Christmas tradition.
Justin Trinca, along with his family, came out to experience the holiday festivities in North Augusta.
"Our little one is 14 months now, and she is getting old enough to get excited about things," Trinca said. "We happened to see it online I think and we are right around the corner so we wanted to come out and see what it's all about."
"Last year was definitely different around the holidays. So it is nice to see everybody out, see kids running around and see people handing out s'mores and hot chocolates," Trinca added.
Mayor Briton Williams is happy to ring in the holiday season with this tradition.
"I think it is exciting. After everything we went through last year, even though we did it last year, most people not having to wear masks and it's just a great way to lead into the holidays," Williams said. "I think people are ready to get back to a new normal."
As Mayor, Williams picked Ella Hooker, 4, to turn the light switch in the park on to signal the start of the holiday season.
Families had the chance to roast marshmallows with the Boy Scouts and write letters to Santa while spending quality time with family.
"I think the tree lighting marks the beginning of it for everybody," Aimee Lester, a committee member with Boy Scouts Troop 7 said. "We are officially past Thanksgiving and it's officially Christmas time."
"It's really awesome. It actually means a lot," Amanda Wehunt said. "I am from Augusta and Augusta never had anything like this, so coming over here to North Augusta, it's great. It really feels like a family over here."
North Augusta's holiday festivities continue throughout the weekend with the 40th annual North Augusta Lions Club Christmas parade on Dec. 5.
Samantha Winn covers the city of North Augusta, with a focus on government and community oriented business. Follow her on Twitter: @samanthamwinn and on Facebook and Instagram: @swinnnews.
'The Princess,' a Horrifying New Princess Diana Documentary, Kicks Off Virtual Sundance
8 takeaways from Delaware Gov. John Carney's 2022 State of the State address
Delaware Online | The News Journal
Packed with history, General Patton Memorial Museum at Chiriaco Summit a must-see destination
Federal grand jury indicts Louisville man accused of opening fire on officers serving warrant
WLKY - Louisville Videos
Father arrested for attempted murder of son, 5, after both rescued from icy water
KMGH - Denver Scripps
Tell us, how do you feel about the search process for Miami-Dade Schools' new superintendent?
Father-Son Baseball Camp returns for 14th year this weekend
"Magical" massive coral reef discovered deep below surface in Tahiti "twilight zone"
CBS News Videos
Florida rides Sergei Bobrovsky's best game as a Panther to a blowout win in Edmonton


text:
PhD in Italian
The Italian Section in Cambridge has seven full-time faculty members available to supervise doctoral research. Their research interests span a broad range of topics in the languages, literatures, visual cultures and history of the Italian peninsula, from the medieval period to the present day.
Details of individual specialisms can be found on the section's webpages. We have a lively group of doctoral students in the section at any one time working across periods and topics, supported by careful one-on-one supervision and mentoring, in the context of a rich research culture of seminars, symposia, conferences, lectures, and postgraduate training. Visiting scholars and students from other institutions regularly contribute to the section's research culture. Students are also free to undertake comparative work across languages and national boundaries, supported by the wide range of expertise within the Faculty of Modern and Medieval Languages and Cambridge as a whole.
In British universities the PhD (Doctorate of Philosophy) is traditionally awarded solely on the basis of a thesis, a substantial piece of writing in English which reports original research into a closely defined area of enquiry. The completion of the PhD thesis generally expected to take three to four years, and most funding is based on this assumption. It's also possible to take a part-time route through research degrees, and the expected timeframe would be five to seven years.
During your research, you will have the opportunity to work closely with a Supervisor who is a specialist in your research area. In addition to your supervisor, you will normally also be able to draw on the help and support of one further academic advisor and to consult other academics working in related fields. You might reasonably expect to see your supervisor fortnightly or at least three times per term.
In addition to providing specialist supervision, the Faculty runs a programme of professional training for the benefit of all research students. The programme includes seminars and workshops on library resources, giving conference papers, publishing, applications and interviews, teaching skills, specialist linguistics training, and film-making. The School of Arts and Humanities runs a central programme covering a range of topics from PhD skills training, to language training and writing and editing skills. If you wish, you are likely to be given the opportunity of gaining experience in small group teaching from colleges. There may also be opportunities to gain some experience in language teaching in the Faculty.
For those applying to continue from the MPhil to PhD, the minimum academic standard is an overall distinction on the MPhil.
Faculty of Modern and Medieval Languages and Linguistics
Department of Italian
Department of Italian This course is advertised in multiple departments. Please see the Overview tab for more details.
Lent 2022 (Closed)


text:
NGO DIRECTORY 2014 FORMAT
Affiliate Members of CAMPE
PROYASH
Proyash Published in 2018
PAHOR
Shakkharata Bulletin
Tales Told by Teenagers
Skill Based Continuing Education Material
National Education Policy 2010: Teachers Should Know
Community Participation in Education
Education Budget in Bangladesh
Quality Educators for Generation to Come
Glorious 14 Years
Framework for Action- Education 2030 in Bangladesh
Shikhar Chalchitra
Materials for Primary Education
Post-2015 Sustainable Development Agenda
Flexible School Calendar 2013
Education Watch Report (Full Version)
Education Watch Report (Popular Version)
Education Watch Report (User Friendly Version in Bangla)
Spotlight Report
NFE Mapping Report
The state of un-served children in Education
EFA Post 2015
Report Card Survey
Main Report
Popular Version
Baseline Report (CEWG)
Adarsha Polli Unnayan Sangstha (APUS)
ASED Habiganj
ASHROY Foundation
Grameen Jono Unnayan Sangstha (GJUS)
Manob Unnayan Kendra (MUK)
National Development Programme (NDP)
Socio-Economic & Rural Advancement Association (SERAA)
Udayan Swabolambi Sangstha (USS)
Teachers for the Next Generation
Main Report (Quality Education)
Popular Version (Quality Education)
Objectives of CAMPE
Operational Structure of CAMPE
Mandate of CAMPE
Management of CAMPE
Role of CAMPE
CAMPE Council
How is the Current education system in Bangladesh?
Not Right
Networking and linkage
Excluded Peoples Rights in Bangladesh (EPR)
A three years project (2019-2021) "Excluded Peoples Rights in Bangladesh (EPR)" supported by Manusher Jonno Foundation (MJF), the fund is originated from UKaid through Department for International Development (DFID).
Project Goal: The overall goal of the project is to contribute towards ensuring education and health rights of excluded children through strengthening community participation.
Outcome 1 : Enhanced efficiency and effectiveness in govt. primary school focusing on accessibility of marginalized and excluded children;
Outcome 2: Local duty bearers for primary health care and primary education are more accountable and responsive towards delivering quality education and health services;
Outcome 3 : The local community are engaged and play watchdog role to ensure accountable education and health system.
Major Problems to be addresses:
1). Teacher Absenteeism, high dropout rate, poor educational services;
2). Doctor and nurse absenteeism, shortage of equipment, poor access of excluded peoples and poor services in health centers
Background, Problem analysis and Rationales:
Currently the world is facing a serious learning crisis. A new World Bank dataset illustrates the bleak outlook: in developing countries. It is found that less than 50 percent of students are achieving proficiency in basic skills, compared to 86 percent in developed countries. Despite great gains in enrollment and an ambitious goal (SDG4), education quality worldwide is failing children, affecting their empowerment, employability, future earnings, health, and society's overall growth potential. The recent World Development Report 2018 identifies three policy actions that can lead to real change: 1) assessing learning, to make it a serious goal; 2) acting on evidence, to make schools work for learners; and 3) aligning actors, to make the system work for learning. Approaches towards implementing these recommendations are both technical and systemic, as well as political in nature. The Global Education Monitoring Report (2017/18) also underlines that everyone has a role to play in improving education.
Government of Bangladesh has made remarkable progress in human development, poverty reduction and economic growth. GNI per capita has grown from around US$780 in 2010 to US$1,330 in 2016, (The World Bank, 20216) and thus allowed the country to cross the LDC to become a developing and lower middle-income country. The economy of Bangladesh has been predicted to have grown at 6.8% over 2016-17 period which was restricted over a decade at 6.0% on an average. Poverty has been reduced to 24.3% with increased income at all level. While striving towards attaining the EFA and MDGs, Bangladesh achieved significant in gaining gender parity and also in increasing enrolment up to 98% particularly in primary education. Primary education is the foundation of all learning. A large primary education sector is managed by Bangladesh government covering 126,615 formal and non-formal primary level educational institutions. Given the huge dependence of poor households on government services, primary education provision for all is highly subsidized and financed by the government as committed in the Article 17 of Bangladesh Constitution. Among different types of public and private primary institutions 50% are directly delivered and managed by the government (APSC 2016).
Bangladesh is committed to achieve the Sustainable Development Goals. The government also believe that without reasonable improvement of health and education the other goals could not be achieved and even the achievement will not be sustainable. Government has recently approved 4th Health Sector Program (2017-2021) of the Ministry of Health and Family Welfare (MOHFW), will put the country on track to attaining the targets by 2030. The Health, Population and Nutrition Sector Development Program (HPNSDP) played an important role in achieving better health indicators. Health policies and reforms in Bangladesh primarily aim at providing basic healthcare to all. It is to be recalled here that, health has been acknowledged as a right in the National Health Policy 2011. The policy aims to strengthen primary health and emergency care for all, and expand availability of client-centred, equity-focused and high-quality healthcare services. It advocates for equitable access to health outcomes care by gender, disability and poverty to achieve better health for all. In order to bring primary healthcare services to the doorsteps of people, 10,723 community clinics (CCs) at a ratio of one CC for every 6,000 populations were established during 1998-2001. In 2009, the CC initiatives were revitalized by the government. It has been reported that, at present there are 13,500 CCs in the rural areas, and another 4,500 CCs will be set up soon.
Despite these quantitative progress in health indicators, the quality of healthcare in both public and private health services is not satisfactory. Resource constraints, lack of professionalism, poor management and inadequate policy initiatives are the major reasons. Besides, several emerging issues are posing challenges in the health sector of Bangladesh. For example, the burden of non-communicable disease has been on the rise. There are inequities as regards accessing health services which is reflected through differential health outcomes for different groups of people based on their economic condition, geographical location and gender. This is evident in case of early childhood mortality, neonatal mortality, infant mortality, under-five mortality, vaccination coverage, child nutritional status and utilization of antenatal care by women (WHO, 2015; Rahman et al., 2017).
The poor are also exposed to a number of diseases caused by living conditions and lifestyles, and this is true for both rural and urban areas. Due to exposure to new infections, lack of access to safe and clean environments, and poor-quality healthcare, they are exposed to various health risks. Climate-induced health risks affect the poor most. Primary health coverage in urban areas, particularly among slums and street dwellers, remain a challenge. Doctor shortage and absenteeism is another challenges to provide quality health services.
Rational of the Proposed Project
Despite impressive development achievements, significant challenges still persist for the country. Inequality is visible as per BBS 2016 report showing some 10 per cent of the poor owns only one per cent of total income. Generally poor socio-economic situation impacts on education to certain extent and increases inequality. Wider inequalities in society also has adverse impact on the school system and partly determine patterns of education inequality. Particularly in primary education, dropout rate is 19.2 % (boys 22.3% and girls 16.1%) in 2016 while the repetition rate stands 6.1% (boys 6.4% and girls 5.8%) in all grades. Though the rate of students' absenteeism is gradually declining, it is still 12.5 % where boys are 12.8% and girls 12.3%. Regular absenteeism leads those students to eventually drop out. 65.3% students facing physical punishment in schools and 64.3% guardians accepted the. Though Government declared the expansion of primary education up to grade viii from grade V, no concrete initiative has been taken to realize this gigantic task. As per the NSA data, student proficiency rate is less than 30%.
Decision making process is highly centralized in Ministry of Education and Ministry of Primary and Mass Education. It is also likely that poor governance has a disproportionate effect on the poor and is important in explaining levels of education inequality. Therefore, sector governance and government education policy in particular, are likely to have important consequences for educational access and quality. Lack of accountability and good governance in education are the most important factors behind failure in quality service delivery. For ensuring transparency, responsiveness and accountability in education, the key concern is to respond to the gap that exists between citizens and institutions. So, there is a need to simultaneously strengthen the accountability and responsiveness of educational institutions and policies through changes in institutional practice and a focus on the enabling structures for good governance. When accountability works, citizens especially the marginalized groups are able to claim demands on institutions and ensure that those demands are met. This can enable them to realize their rights, and gain access to resources and services.
Though the government has established number health centers both in rural and urban areas but the service is not adequate. Most of the cases the excluded peoples not access or limited access in the health centers and the health centers could not provide enough services due to shortage of doctors, medical equipment, shortages of medicine and rigorous doctor absenteeism.
Relevance of the project:
Campaign for Popular Education (CAMPE) is an advocacy, research and campaign network promoting quality education, retention and completion of primary & secondary education cycle of both boys and girls. It has gradually grown into a well-known credible coalition of about 1000 education NGOs, researchers, education rights' campaigners and teacher associations sharing similar vision and mission.
As part of promoting good governance in education, CAMPE has been closely working with teachers, SMC members, UP Standing Committee, local education officials, community people and focusing on effectiveness of SLIP, SAC, PTA etc. CAMPE has also experience on the use of social accountability tools i.e. citizens' report card, community score card, citizen charter, social audit, interface meeting etc. through implementation of different initiatives. These tools helped to collect feedback of the parents on the quality of and access to services available in government primary schools. The journey has been satisfying and encouraging.
Currently with the adoption of SDGs particularly Goal 4 for education there is urgent need for CAMPE to continue its watchdog role and to undertake further interventions in order to achieve the goal through promoting transparency and accountability of relevant duty bearers. Hence, CAMPE feels the need for strengthening and expanding this initiative keeping in mind the experience and lesson learnt. CAMPE also experience to work with local government officials, local government bodies and local services provider authorities.
Organizational relevant experience and learning and they will be fed into the project
1. CAMPE has long experience to work on promoting voice and accountability for quality education through facilitating `Community Education Watch Groups' at the local level. The Groups were formed to strengthen accountability mechanism and to promote `Enrolment, Retention and Completion' of primary education with quality. During the last few years, CAMPE facilitated 32 CEWG in 32 unions of 8 districts. The initiative created a space for community engagement and raising voice for quality education and provided CAMPE with enough experience of working on issues like education governance, accountability and transparency of stakeholders. The CWG process address the excluded peoples considering sex, PWD, ethnic minority, people live in hard to reach areas and on board them in local development process through raising their voice demanding accountable governance.
2. CAMPE also has vast experience for addressing the excluded people rights since 1991. CAMPE has designed and implement number of projects on inclusive education focusing education of children with disability, education of ethnic minority children with their own language, education of hard to reach area's children etc.
3. So, CAMPE will apply its proven result oriented approach "Community Watch Group" in EPR project, which will address the excluded peoples in project areas and ensure their rights and access in education and health system through promoting accountable governance.
Implementation strategies to be followed:
Strategy-1: The activities will be carried out in three level - a) grassroots level, b) subnational level and c) national level. CWG will carry out the the grassroots level activities, partner organizations will carry out the project activities and interaction at sub national level and CAMPE will take the issues at the national level and advocating with policy makers, relevant ministries, directorates, development partners.
Strategy-2: It will work through partnership with 2 selected partner organizations on the basis of their capacity, legal identity, previous experience and interest. Total 6,195 students and 45,971 excluded peoples will be reached through the project. Project locations have been selected based on criteria of poor literacy rate, poor socio-economic situation, ethnic minority centered areas and former enclaves.
Strategy-3: CWG will play a key role for community engagement process to accountable the duty bearer and generate data. CAMPE will use these data for national level advocacy to bring about policy changes and thereby establish voice and accountability. The PNGOs will be a bridging point for data transformation from grassroots to national and also disseminate at subnational level.
Sustainability plan and Exit Strategy
In first year, the project investment will be merely to CEWG group formation, their capacity building, relation development between CEWG and public institution and last year the CEWG will work indecently as a community institution. The project expects the awareness and capacity building of the local actors. In last year the project will give more emphasis on exit plan and prepare the community and local partner organization to run it independently with minimum cost managed by local resource. At national level CAMPE and MJF will jointly advocating to the government and development partners to replicate the methods to other government primary school through their government programs.
Exit Strategy:
CAMPE will transfer the knowledge, experience and expertise gained through the project to the local partners, CWG, government and other CSO groups for their future work. After the project, CAMPE will continue regular follow up through its partner organization and try to assist them for managing resource and their capacity building.
Project Duration: January 2019 to December 2021
Total Budget: BDT 30,000,000
Page hit 1058757 Times


text:
package logging

import (
	"io"
	"log"
)

var (
	infoLogger  *log.Logger
	errorLogger *log.Logger
)

func InitLoggers(infoHandle io.Writer, errorHandle io.Writer) {
	infoLogger = log.New(infoHandle, "INFO: ", log.Ldate|log.Ltime|log.Lshortfile)
	errorLogger = log.New(infoHandle, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile)
}

func Error(str string, v ...interface{}) {
	errorLogger.Printf(str, v...)
}

func Info(str string, v ...interface{}) {
	infoLogger.Printf(str, v...)
}

redpajama_set_name: RedPajamaGithub