Morse Code Neural Net

I created a text file that has the entire alphabet of numerical morse code. Meaning, "." is represented by the number "0.5" and "-" is represented by "1.0". This neural net is trained through that set until it's accuracy is 100%. Then, it is "tested" by user generated input. Once the weights are able to give the training set 100%, it will have 100% accuracy for all tested data, since the inputs do not change. Seeing if the neural network can determine similar but not exact test data requires the neural network to find the best fit function for data. In this neural network, it is not finding the "best-fit" function, but rather finding an exact function that satisfies the data. This isn't a question of how accurate the neural network can predict future data, but rather a question of how much does it take for a neural network to memorize perfect data.

I will be importing the neural net base code for this neural network.


In [1]:
import NeuralNetImport as NN
import numpy as np
import NNpix as npx
from IPython.display import Image

Visualize Morse Code

Notice that numbes are represented by differing numbers of components. Some letters have 4 components and some have as little as one.


In [2]:
npx.morse1


Out[2]:

Enter Morse Cord Sentence

Note, each letter is separated by a single space. And each word is separated by four spaces. To test every letter of the alphabet, use the sentence below:

"- .... . --.- ..- .. -.-. -.- -... .-. --- .-- -. ..-. --- -..- .--- ..- -- .--. . -.. --- ...- . .-. - .... . .-.. .- --.. -.-- -.. --- --."

FOR THIS NOTEBOOK NOT TO RAISE ERRORS, THERE MUST BE AN INPUT BELOW


In [39]:
enter = input("Enter Your Morse: ")


Enter Your Morse: 

Morse Code to 3D Number Array

Use two functions to turn a morse code sentence into a 3D array of numbers. This first function turns the morse code into string numbers. Each dot is "0.5" and each dash is "1.0". Each letter is an array, each word is an array of arrays, and each sentence is an array of arrays of arrays.


In [40]:
def morse_to_num_str(morse):
    """ Takes morse code and divides in into a 3D array, 1D for each letter, 2D for each word, and 3D for the sentence"""
    morse = morse.replace(".", "0.5,")
    morse = morse.replace("-", "1.0,")
    new = list(morse)
    for i in range(len(new)):
        if i > 1 and new[i-1] == "," and new[i] == " ":
            new[i-1] = " "
        if i == (len(new)-1):
            new[i] = ""
    new = "".join(new)
    a = new.split("     ")
    for i in range(len(a)):
        a[i] = a[i].split("  ")
    for h in range(len(a)):
        for j in range(len(a[h])):
            a[h][j] = a[h][j].split(",")
    
    return a

In [41]:
assert morse_to_num_str("-. --    -- ..") == [[['1.0', '0.5'], ['1.0', '1.0']], [['1.0', '1.0'], ['0.5', '0.5']]]

This second function turns each string number into a float. Because our neural net needs a constant value of inputs, and morse letters have 1 to 4 components, "0.0" is appened on to the end of each letter array that has less than four components.


In [42]:
def morse_str_to_float(morse):
    """ Turns the 3D array generated above into float"""
    """ Adds 0.0 for letters without 4 elements"""
    for i in range(len(morse)):
        for j in range(len(morse[i])):
            while len(morse[i][j]) != 4:
                morse[i][j].append("0.0")
            for k in range(len(morse[i][j])):
                morse[i][j][k] = float(morse[i][j][k])
    return np.array(morse)

In [43]:
assert np.all(morse_str_to_float([[['1.0', '0.5'], ['1.0', '1.0']], [['1.0', '1.0'], ['0.5', '0.5']]]) == np.array(([[[ 1. ,  0.5,  0. ,  0. ],
[ 1. ,  1. ,  0. ,  0. ]],[[ 1. ,  1. ,  0. ,  0. ],[ 0.5,  0.5,  0. ,  0. ]]])))

Create Input Array

This input array is the entire morse alphabet. Each letter has four number components that correspond to its dots and dashes. There are 4 inputs in the input layer.


In [44]:
""" The entire morse alphabet in numerical morse"""
all_in = np.genfromtxt("MorseTxt.txt", delimiter=",", usecols=(1,2,3,4))

Create Solution Array

There are 26 possible solutions and therefore 26 neurons in the output layer. Different letters are represented by their placement in the alphabet. A is 0. The 0th node "firing" represents an A.


In [45]:
""" The letters that correspond with all-in above"""
real_letters = np.genfromtxt("MorseTxt.txt", dtype=str, delimiter=",", usecols=(0))

""" 26 element array of all the ouputs"""
all_out = NN.create_training_soln(np.genfromtxt("MorseTxt.txt", dtype=str, delimiter=",", usecols=(0)),26)

Training the Neural Network

This Neural Network has a input for every output and a unique output for every input. Because of this, the neural network must be trained to 100% accuracy on the training set to get a correct translation. For this, the neural net requires 30 neurons in the hidden layer and 400 iterations with a learning rate of 0.7.


In [46]:
morse_net = NN.NN_training(all_in, all_out, 4, 26, 30, 400, 0.7)

I am commenting out the cell below. This is how you would calculate weights, but for the demonstration, I will load weights from a previous training.


In [47]:
# x,y = morse_net.train()

In [48]:
f = np.load("MorseWeights.npz")

In [49]:
x = f['arr_0']
y = f['arr_1']

In [50]:
assert len(x) == 30
assert len(y) == 26

Assert 100% Accuracy


In [51]:
morse_ask = NN.NN_ask(all_in, x, y)

In [52]:
comp_vals = [chr(morse_ask.get_ans()[i]+65) for i in range(26)]

In [53]:
assert np.all(comp_vals == real_letters)

Translate Morse

Because the Neural Network is perfectly trained, the accuracy of the "test data" will be 100%. Giving the neural net and morse code sentence will receive a perfect translation.


In [54]:
new_net = NN.NN_ask_morse(morse_str_to_float(morse_to_num_str(enter)), x, y)


---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-54-269aedaf6922> in <module>()
----> 1 new_net = NN.NN_ask_morse(morse_str_to_float(morse_to_num_str(enter)), x, y)

<ipython-input-42-83b8860d055e> in morse_str_to_float(morse)
      7                 morse[i][j].append("0.0")
      8             for k in range(len(morse[i][j])):
----> 9                 morse[i][j][k] = float(morse[i][j][k])
     10     return np.array(morse)

ValueError: could not convert string to float: 

In [55]:
ans = new_net.get_ans()

In [56]:
print("".join([chr(ans[i]) for i in range(len(ans))]))


K 

In [ ]:


In [ ]: