new_contents: """
  We get the example from : "https://towardsdatascience.com/lstm-by-example-using-tensorflow-feb0c1968537"
  """
  
  import numpy as np
  import tensorflow as tf
  #import os
  #os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
  from UsefulTools.UtilsFunctions import *
  from UsefulTools.TensorFlowUtils import *
  corpus_raw = 'He is the king . The king is royal . She is the royal  queen .'
  # convert to lower case
  corpus_raw = corpus_raw.lower()
  
  words = []
  for word in corpus_raw.split():
      if word != '.': # because we don't want to treat . as a word
          words.append(word)
  words = set(words) # so that all duplicate words are removed
  word2int = {}
  int2word = {}
  vocab_size = len(words) # gives the total number of unique words
  for i,word in enumerate(words):
      word2int[word] = i
      int2word[i] = word
  
  pt("word2int", word2int)
  pt("int2word", int2word)
  
  raw_sentences = corpus_raw.split('.')
  pt("raw_sentences",raw_sentences)
  
  sentences = []
  for sentence in raw_sentences:
      sentences.append(sentence.split())
  pt("sentences",sentences)
  
  #training data
  data = []
  WINDOW_SIZE = 2
  for sentence in sentences:
      for word_index, word in enumerate(sentence):
          for nb_word in sentence[max(word_index - WINDOW_SIZE, 0) : min(word_index + WINDOW_SIZE, len(sentence)) + 1] :
              if nb_word != word:
                  data.append([word, nb_word])
  pt("data",data)
  
  # function to convert numbers to one hot vectors
  def to_one_hot(data_point_index, vocab_size):
      temp = np.zeros(vocab_size)
      temp[data_point_index] = 1
      return temp
  
  x_train = [] # input word
  y_train = [] # output word
  for data_word in data:
      x_train.append(to_one_hot(word2int[ data_word[0] ], vocab_size))
      y_train.append(to_one_hot(word2int[ data_word[1] ], vocab_size))
  # convert them to numpy arrays
  x_train = np.asarray(x_train)
  y_train = np.asarray(y_train)
  
  pt("x_train",x_train)
  pt("y_train",y_train)
  
  # making placeholders for x_train and y_train
  x = tf.placeholder(tf.float32, shape=(None, vocab_size))
  y_label = tf.placeholder(tf.float32, shape=(None, vocab_size))
  
  EMBEDDING_DIM = 5 # you can choose your own number
  W1 = tf.Variable(tf.random_normal([vocab_size, EMBEDDING_DIM]))
  b1 = tf.Variable(tf.random_normal([EMBEDDING_DIM])) #bias
  hidden_representation = tf.add(tf.matmul(x,W1), b1)
  
  W2 = tf.Variable(tf.random_normal([EMBEDDING_DIM, vocab_size]))
  b2 = tf.Variable(tf.random_normal([vocab_size]))
  prediction = tf.nn.softmax(tf.add( tf.matmul(hidden_representation, W2), b2))
  
  sess = initialize_session()
  # define the loss function:
  #cross_entropy_loss = tf.reduce_mean(-tf.reduce_sum(y_label * tf.log(prediction), reduction_indices=[1]))
  #cross_entropy_loss = tf.nn.sigmoid_cross_entropy_with_logits(labels=y_label,logits=prediction)
  cross_entropy_loss = tf.nn.softmax_cross_entropy_with_logits(labels=y_label,logits=prediction)
  
  # define the training step:
  optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1)
  train_op = optimizer.minimize(cross_entropy_loss)
  n_iters = 10000
  # train for n_iter iterations
  for _ in range(n_iters):
      pt(cross_entropy_loss.eval(feed_dict={x: x_train, y_label: y_train}))
      sess.run(train_op, feed_dict={x: x_train, y_label: y_train})
      print('loss is : ', sess.run(cross_entropy_loss, feed_dict={x: x_train, y_label: y_train}))
  
  pt("W1")
  vectors = sess.run(tf.add(W1, b1))
  pt("vectors",vectors)
  
  pt("Vector queen in word2int", vectors[ word2int['queen'] ])
  
  def euclidean_dist(vec1, vec2):
      return np.sqrt(np.sum((vec1-vec2)**2))
  
  def find_closest(word_index, vectors):
      min_dist = 10000 # to act like positive infinity
      min_index = -1
      query_vector = vectors[word_index]
      for index, vector in enumerate(vectors):
          if euclidean_dist(vector, query_vector) < min_dist and not np.array_equal(vector, query_vector):
              min_dist = euclidean_dist(vector, query_vector)
              min_index = index
      return min_index
  
  pt("Más cercano a king", int2word[find_closest(word2int['king'], vectors)])
  pt("Más cercano a queen", int2word[find_closest(word2int['queen'], vectors)])
  pt("Más cercano a royal", int2word[find_closest(word2int['royal'], vectors)])
  
  from sklearn.manifold import TSNE
  model = TSNE(n_components=2, random_state=0)
  np.set_printoptions(suppress=True)
  vectors = model.fit_transform(vectors)
  
  from sklearn import preprocessing
  normalizer = preprocessing.Normalizer()
  vectors =  normalizer.fit_transform(vectors, 'l2')
  
  import matplotlib.pyplot as plt
  fig, ax = plt.subplots()
  for word in words:
      print(word, vectors[word2int[word]][1])
      ax.annotate(word, (vectors[word2int[word]][0],vectors[word2int[word]][1] ))
  plt.show()
subject: Add Word2Vec Example modified with adam