Habergebenen

Habergebenen said the GPS one day. I am spelling it just like it sounds in the GPS-speech. It was one of those nice weather days, visiting Ithaca, New York, the home of the famous Cornell University.
Besides Cornell, Ithaca is known for its many gorges and water falls. It also has a great variety of foods to offer. One good place for food is Greenstar Food Coop, or as the GPS lady likes to call it, Greenster. So on this one particular day traveling from the west side of Cayuga lake, navigating in the general direction of Ithaca and the eventual destination of Greenstar, the GPS went off the rails. I assume it’s a software bug but, it reset, sort of in a partial reboot sort of way, out of the blue.
Habergebenen was what it said as I was not quite following it’s directions. This was new and unexpected. I heard a few other words I could recognize like rechts, which is German for right, as in “turn right “. So it was German-ish. But, not quite. Upon arrival at Greenstar, I looked at the settings and the language had set itself to Afrikaans, which is the first one in the list of many languages. I give them credit, whoever designed it thought of the whole world.
As you might have imagined by now the GPS was saying it’s typical recalculating in Afrikaans which sounds like habergebenen . It’s a word that sticks in your mind and now it’s gotten to have a bigger meaning.
Recalculating and Habergebenen
From Urban Dictionary…
A polite way of saying “you screwed up, idiot, try it again.”
A GPS says “recalculating” after you miss a turn it told you to take, then it comes up with a new route based on your current position. It doesn’t call you a dumbass, it simply says “recalculating” which lets everyone in the car know you are a dumbass without it having to actually say so.
Recalculating for me means, I walked into a room and forgot what I was in there looking for, or a general loss of a train of thought. But, habergebenen means some big recalculating as in deep rethinking of a situation that is fundamental or potentially off the rails in a great way. It happens when you have a dark night of the soul. Or the light version that shows up when you have lots of insomnia. I call it the moonlit night of the soul, as it is dim and not quite dark. It is a reboot and recalculating situation for your life and doesn’t always make sense when you are in the moment but, always does from a future vantage point.
Translations
Using Google translate, I get
Herbereken
for recalculating in Afrikaans.
In Dutch which is the root language of Afrikaans, I get
herberekenen
which is closer to what it sounds like what the GPS is says But still not what I hear in the GPS-speech.
Totally random but in Esperanto it’s
rekalkuli
which at least hints at recalculating and sounds cool too.
This is my first post using an iPad and it went OK. It was alright using hunt and peck on the keyboard. The word suggestions are generally helpful along with the word competition that either the iPad or the WordPress editor is handling. Next post I will try dictation out.

Buttermilk Falls
Buttermilk Falls in Ithaca, New York has a trail that runs up the gorge next to the falls and provides for some great views. In the middle of winter some times it will warm up into the 60’s. This winter 2019-2020 has been one of those very warm winters and is a good example of one that warms up nice. When it does warm up and the snow melts the falls can run pretty hard.
trying out min-char-rnn and lstm
Text Generation
In early 2018, I started researching machine learning. I was curious about it and also looking for anything that could be useful in the space of machine learning to perform functions in code, specifically trading algorithms. I looked for code that would be easy to get started with, easy to pick apart and understand. I knew it would take time to understand and I was fine taking some sidetracks down some territory that would be interesting to play with.
I quickly came across various versions of text generation code. I won’t get into the theory here as there is a ton of information on it already and I have included my sources as links in the post.
Basically, this post will focus on the use of a well documented version char-rnn specifically min-char-rnn and an improved version that uses lstm.
This post is a brief dump on my toying around at text generation with machine learning. I may cover it further in more detail in the future.
To see some cutting edge examples of text generation, that is pretrained on a corpus using GPT-2, see the following post…
GPT-2 the Next Level in Text Generation for now at least
Currently I am trying out RNN Text Generation using Tensorflow and plan on posting some results in the future…
https://github.com/spiglerg/RNN_Text_Generation_Tensorflow
char-rnn code
I started out with Andrej Karpathy’smin-char-rnn initially when I was in machine learning research mode early in 2018. During the early fall of 2018 I found posts by Eli Bendersky that gave a good break down of min-char-rnn, including code that had more comments and a few other pieces of code. The two other pieces of code was a Markov Model text generator and lstm extension to min-char-rnn. In theory the lstm version of min-char-rnn should perform the best. I wound up with the best results (Python only code) using this version with modifications. The three modifications were the ability to save the output text while it was running and the ability to trim down the learning rate progressively while it was running and to specify a file name at the command line. I did this after I noticed that the loss was oscillating and not decreasing under certain conditions, playing with the coefficients for the code. Such as layers and the amount of lookback of the characters. Trying to decrease the learning rate can help with this behavior.
Beyond this code a more sophisticated way to do text generation is to go to using Lua Torch and running torch-rnn. This requires downloading and installing all of the packages in Linux required to run it.
Comparing the Versions
To start, min-char-rnn performance can be compared against the lstm version. In this example I am using the US Constitution as it is a document that is widely available and many people are familiar with. In the future I will cover running the text from this site through text generation code.
After 99000 loops of min-char-rnn on the US Constitution.
iter 99900, loss: 34.083777 ---- , Reach witle from to the Lice of shall degrest and unccive athins or propinds, ploovate one shall eptemitlatiall un ligre shall have hake by the Ugiters shall no no be as writh two 2hs -quals and of
You can see it is trying to pick up on something and a few of the words are actually legitimate English.
Now the lstm version created by Eli Bendersky, minimal-character-based-lstm-implementation…
iter 99800 (p=18160), loss 9.844710 ---- shall receire ffour Houser, hred in overyof morty Cowcurthir such onf grate, shall then callary, and sittin dutler, shall, with an electors and Elections, which shall be a President. 3. Nuties, Impos
This version shows some hope as it is forming some more structure, better words and parts of sentences. The loss is lower as well.
What if the LTSM version runs longer, like a million cycles?
iter 999000 (p=17184), loss 4.694482 iter 999200 (p=20384), loss 4.734232 iter 999400 (p=23584), loss 4.815483 iter 999600 (p=26784), loss 4.979268 iter 999800 (p=29984), loss 5.165326 ---- shall consisted; but the Congress may by Congress, becommit, shall be a Senator or Representative intee any Department or Trust under the Laws Spojgiled to consirques hating been creary shall prioriti ----
It is getting a bit better, less broken words, formation of a sort of paragraph.
How about ten million cycles, where the loss seems to bottom out in the 2.5 range…
iter 10096200 (p=21776), loss 2.487097 iter 10096400 (p=24976), loss 2.517261 iter 10096600 (p=28176), loss 2.605424 iter 10096800 (p=31376), loss 2.556021 ---- against the sements whereor who shall return in Consent whations whict: Amend Mander State. a Treason of Disubility to lis arming the cume aftered thanney. Ir, or Conventions as the lise dusceptraray
I concatenated some more of the output….
to post a Member in their borth intomie States, the Vice President and denuinned. Amendment 10 The powers not the twerfth not betilizent of this article the Vicembagion and such Pentitias of the seve s the United Stated; under their Party; without the United States. Article 36. When mademe Court of the United States which shall not be retsion age State. Andain duty a stanly such Majority, or the ited States or by any State. No Prefered, the President proviit for President; necestald a majority be a Members, and the Legitlationen for the law of the President, to be the Eduld a Memberd to ever ne of the seber to the Approparal Becomes of Blesident within the United States un nunis primas to which the District hensbill, such Presented by incohringle shall be tax having States, and transmit t
Modifications of min-char-lstm.py
The following was created by modifying the code at https://github.com/eliben/deep-learning-samples/blob/master/min-char-rnn/min-char-lstm.py
The modifications are, 1 to be able to allow for a learning rate that starts higher and declines. I was experimenting with using the min-char-ltsm.py code on the contents of the blog posts on this site and I noticed that the learning rate would decline to a point and then oscillate up and down. By starting with a higher learning rate and then trimming it lower and lower, I was hoping to get the oscillations to settle and achieve a better loss rate. The other modification is that it will not print text to the screen until the loss declines by half. It also saves the text that is generated after the loss drops to a quarter of the original. Saving the text allows for optional post analysis, for instance of keywords.
Code for min-char-lstm-mod-2.py is pasted at the bottom of this post.
python min-char-lstm-mod-2.py us-constitution.txt 2019-02-21 21:58:36.456591: iter 13238027 (p=48), loss 5.571070 ---- f Hear Porty, or Vice President equal, as Vares possary, having to nimpost to the President, dofe, for the Senate, the first Meeting of the first Summarma onle Jonn admius lesments shall exercise they shall not be consthuled for tainamanment mort himal of the President shall consist of a sever Years as of the United States; To recass on the Congress may be admints, Cans; the proprictions herein becom tamy and Partarittent; or transting Surdsation shall immentent no State, or abilitives shall b ---- Saving to file 2019-02-21 21:58:36.568285: iter 13238028 (p=64), loss 5.567595 ---- anstwry by such Vacarciuse Amdiavion, or other Sestected, and the Congress shall may leibtry days by Contict Biltian convice Vith. No case, dupa such Penisdatizens prsed the Bildsent of thein be cindent for sitt in Cases of President and Vice President, or altice any Office of either House shall be held in the Bilas, except prohicies and Consuls; to be senict compected in this Conments of Congress. The executive atther during the right of the United States, shall choole the Office of Rewofity ---- Saving to file
char-rnn – Training Loss and Validation Loss
char-rnn – Training Loss and Validation Loss from MachineLearning
Lua Torch
I also experimented with torch-rnn which use Lua Torch. It works OK but nothing beyond what I see with the lstm version above. I only tried it breifly and haven’t formed any solid conclustions.
Lua Torch torch-rnn 2 layer 1024 dimensions
https://github.com/jcjohnson/torch-rnn
st keming the Immedince shall
have Power of Not
shall be not
lations for each
shall any
State by the Judigaany state not provided by Casssimate and Repund and Jurtice of the Sequicled in the Unanimed as excleding recrisal of its Consent of the
Mevole shall then the Vice-President, and of the President shall be make Raycesorveny or the right noveranded.
E thas Deleste, by Odfect to the nomes of any Qerfon and ciry of the State
becredo nugr on Condeling and firmine who
haviny this Constitution, but no derso- hivin, Regulation of Vice-Une Tneasor
this BitFzinst entseived.
he fect Coof Presidences, nhish shall be agSent of the Treaso shall gave to behave to the States nor and devermay of the United States; Monor subrected, nor and during the Leecther Year
d aftee the Adjupreit, but in a Memualif or public Ministersss atcerrind ad any Piffost the States connicted to Them thind
ponted by the United States.
S. Pemsud for the
chosen thes shall be a particied and Hays. Wh labth the narge of the Senate, law, ablone Indianty for a dwoun the Eves Motors of liozen Deardors and Elestions and ass ow the Legislatures
shall nake at semoun shall not be require the sunes as ivaly, age unters; and necons al
witn from Oate Members, and accuration of time of titimes, inlarconcancrading one properdyy of the United States, or in which meat
male, in property, sian to the Person having anm notine
Immortizer of having the President.
th onothert commors and Consent, shall apr in this Conviction
may shall, Ligizen aplice—
B.
Smation C
qulication, the first Manger To
theresimant of a pripersonr
Thithit subject dot chimles Tnemeriting the several States, shall be shall be equal States, or in any other Election,
compensation, without the several States; the receita diforme, but nother shall detmanation shall not excerain their Vecessary sexzect juty, or puflis indey
they shall be neach or number in mate been courtion or execuin s co-venty shall not be consugheraty of the Scatem at shall h
min-char-lstm-mod-2.py
# Minimal character-based language model learning with an LSTM architecture. # # Overall code structure based on Andrej Karpathy's min-char-rnn model: # https://gist.github.com/karpathy/d4dee566867f8291f086 # # But the architecture is modified to be LSTM rather than vanilla RNN. # The companion blog post is: # https://eli.thegreenplace.net/2018/minimal-character-based-lstm-implementation/ # # Tested with Python 3.6 # # Eli Bendersky [http://eli.thegreenplace.net] # BSD License per original (@karpathy) from __future__ import print_function import numpy as np import sys import datetime # Make it possible to provide input file as a command-line argument; input.txt # is still the default. if len(sys.argv) > 1: filename = sys.argv[1] else: filename = 'input.txt' with open(filename, 'r') as f: data = f.read() # All unique characters / entities in the data set. chars = list(set(data)) data_size = len(data) V = vocab_size = len(chars) print('data has %d characters, %d unique.' % (data_size, vocab_size)) # Each character in the vocabulary gets a unique integer index assigned, in the # half-open interval [0:N). These indices are useful to create one-hot encoded # vectors that represent characters in numerical computations. char_to_ix = {ch:i for i, ch in enumerate(chars)} ix_to_char = {i:ch for i, ch in enumerate(chars)} print('char_to_ix', char_to_ix) print('ix_to_char', ix_to_char) # Hyperparameters. # Size of hidden state vectors; applies to h and c. H = hidden_size = 100 seq_length = 16 # number of steps to unroll the LSTM for learning_rate = 0.1 # The input x is concatenated with state h, and the joined vector is used to # feed into most blocks within the LSTM cell. The combined height of the column # vector is HV. HV = H + V # Stop when processed this much data MAX_DATA = 1000000 # Model parameters/weights -- these are shared among all steps. Weights # initialized randomly; biases initialized to 0. # Inputs are characters one-hot encoded in a vocab-sized vector. # Dimensions: H = hidden_size, V = vocab_size, HV = hidden_size + vocab_size Wf = np.random.randn(H, HV) * 0.01 bf = np.zeros((H, 1)) Wi = np.random.randn(H, HV) * 0.01 bi = np.zeros((H, 1)) Wcc = np.random.randn(H, HV) * 0.01 bcc = np.zeros((H, 1)) Wo = np.random.randn(H, HV) * 0.01 bo = np.zeros((H, 1)) Wy = np.random.randn(V, H) * 0.01 by = np.zeros((V, 1)) def sigmoid(z): """Computes sigmoid function. z: array of input values. Returns array of outputs, sigmoid(z). """ # Note: this version of sigmoid tries to avoid overflows in the computation # of e^(-z), by using an alternative formulation when z is negative, to get # 0. e^z / (1+e^z) is equivalent to the definition of sigmoid, but we won't # get e^(-z) to overflow when z is very negative. # Since both the x and y arguments to np.where are evaluated by Python, we # may still get overflow warnings for large z elements; therefore we ignore # warnings during this computation. with np.errstate(over='ignore', invalid='ignore'): return np.where(z >= 0, 1 / (1 + np.exp(-z)), np.exp(z) / (1 + np.exp(z))) def lossFun(inputs, targets, hprev, cprev): """Runs forward and backward passes through the RNN. TODO: keep me updated! inputs, targets: Lists of integers. For some i, inputs[i] is the input character (encoded as an index into the ix_to_char map) and targets[i] is the corresponding next character in the training data (similarly encoded). hprev: Hx1 array of initial hidden state cprev: Hx1 array of initial hidden state returns: loss, gradients on model parameters, and last hidden states """ # Caches that keep values computed in the forward pass at each time step, to # be reused in the backward pass. xs, xhs, ys, ps, hs, cs, fgs, igs, ccs, ogs = ( {}, {}, {}, {}, {}, {}, {}, {}, {}, {}) # Initial incoming states. hs[-1] = np.copy(hprev) cs[-1] = np.copy(cprev) loss = 0 # Forward pass for t in range(len(inputs)): # Input at time step t is xs[t]. Prepare a one-hot encoded vector of # shape (V, 1). inputs[t] is the index where the 1 goes. xs[t] = np.zeros((V, 1)) xs[t][inputs[t]] = 1 # hprev and xs[t] are column vector; stack them together into a "taller" # column vector - first the elements of x, then h. xhs[t] = np.vstack((xs[t], hs[t-1])) # Gates f, i and o. fgs[t] = sigmoid(np.dot(Wf, xhs[t]) + bf) igs[t] = sigmoid(np.dot(Wi, xhs[t]) + bi) ogs[t] = sigmoid(np.dot(Wo, xhs[t]) + bo) # Candidate cc. ccs[t] = np.tanh(np.dot(Wcc, xhs[t]) + bcc) # This step's h and c. cs[t] = fgs[t] * cs[t-1] + igs[t] * ccs[t] hs[t] = np.tanh(cs[t]) * ogs[t] # Softmax for output. ys[t] = np.dot(Wy, hs[t]) + by ps[t] = np.exp(ys[t]) / np.sum(np.exp(ys[t])) # Cross-entropy loss. loss += -np.log(ps[t][targets[t], 0]) # Initialize gradients of all weights/biases to 0. dWf = np.zeros_like(Wf) dbf = np.zeros_like(bf) dWi = np.zeros_like(Wi) dbi = np.zeros_like(bi) dWcc = np.zeros_like(Wcc) dbcc = np.zeros_like(bcc) dWo = np.zeros_like(Wo) dbo = np.zeros_like(bo) dWy = np.zeros_like(Wy) dby = np.zeros_like(by) # Incoming gradients for h and c; for backwards loop step these represent # dh[t] and dc[t]; we do truncated BPTT, so assume they are 0 initially. dhnext = np.zeros_like(hs[0]) dcnext = np.zeros_like(cs[0]) # The backwards pass iterates over the input sequence backwards. for t in reversed(range(len(inputs))): # Backprop through the gradients of loss and softmax. dy = np.copy(ps[t]) dy[targets[t]] -= 1 # Compute gradients for the Wy and by parameters. dWy += np.dot(dy, hs[t].T) dby += dy # Backprop through the fully-connected layer (Wy, by) to h. Also add up # the incoming gradient for h from the next cell. dh = np.dot(Wy.T, dy) + dhnext # Backprop through multiplication with output gate; here "dtanh" means # the gradient at the output of tanh. dctanh = ogs[t] * dh # Backprop through the tanh function; since cs[t] branches in two # directions we add dcnext too. dc = dctanh * (1 - np.tanh(cs[t]) ** 2) + dcnext # Backprop through multiplication with the tanh; here "dhogs" means # the gradient at the output of the sigmoid of the output gate. Then # backprop through the sigmoid itself (ogs[t] is the sigmoid output). dhogs = dh * np.tanh(cs[t]) dho = dhogs * ogs[t] * (1 - ogs[t]) # Compute gradients for the output gate parameters. dWo += np.dot(dho, xhs[t].T) dbo += dho # Backprop dho to the xh input. dxh_from_o = np.dot(Wo.T, dho) # Backprop through the forget gate: sigmoid and elementwise mul. dhf = cs[t-1] * dc * fgs[t] * (1 - fgs[t]) dWf += np.dot(dhf, xhs[t].T) dbf += dhf dxh_from_f = np.dot(Wf.T, dhf) # Backprop through the input gate: sigmoid and elementwise mul. dhi = ccs[t] * dc * igs[t] * (1 - igs[t]) dWi += np.dot(dhi, xhs[t].T) dbi += dhi dxh_from_i = np.dot(Wi.T, dhi) dhcc = igs[t] * dc * (1 - ccs[t] ** 2) dWcc += np.dot(dhcc, xhs[t].T) dbcc += dhcc dxh_from_cc = np.dot(Wcc.T, dhcc) # Combine all contributions to dxh, and extract the gradient for the # h part to propagate backwards as dhnext. dxh = dxh_from_o + dxh_from_f + dxh_from_i + dxh_from_cc dhnext = dxh[V:, :] # dcnext from dc and the forget gate. dcnext = fgs[t] * dc # Gradient clipping to the range [-5, 5]. for dparam in [dWf, dbf, dWi, dbi, dWcc, dbcc, dWo, dbo, dWy, dby]: np.clip(dparam, -5, 5, out=dparam) return (loss, dWf, dbf, dWi, dbi, dWcc, dbcc, dWo, dbo, dWy, dby, hs[len(inputs)-1], cs[len(inputs)-1]) def sample(h, c, seed_ix, n): """Sample a sequence of integers from the model. Runs the LSTM in forward mode for n steps; seed_ix is the seed letter for the first time step, h and c are the memory state. Returns a sequence of letters produced by the model (indices). """ x = np.zeros((V, 1)) x[seed_ix] = 1 ixes = [] for t in range(n): # Run the forward pass only. xh = np.vstack((x, h)) fg = sigmoid(np.dot(Wf, xh) + bf) ig = sigmoid(np.dot(Wi, xh) + bi) og = sigmoid(np.dot(Wo, xh) + bo) cc = np.tanh(np.dot(Wcc, xh) + bcc) c = fg * c + ig * cc h = np.tanh(c) * og y = np.dot(Wy, h) + by p = np.exp(y) / np.sum(np.exp(y)) # Sample from the distribution produced by softmax. #ix = np.random.choice(range(V), p=p.ravel()) # IX HACK ix = p.argmax() x = np.zeros((V, 1)) x[ix] = 1 ixes.append(ix) return ixes def gradCheck(inputs, targets, hprev, cprev): global Wf, Wi, bf, bi, Wcc, bcc, Wo, bo, Wy, by num_checks, delta = 10, 1e-5 (_, dWf, dbf, dWi, dbi, dWcc, dbcc, dWo, dbo, dWy, dby, _, _) = lossFun(inputs, targets, hprev, cprev) for param, dparam, name in zip( [Wf, bf, Wi, bi, Wcc, bcc, Wo, bo, Wy, by], [dWf, dbf, dWi, dbi, dWcc, dbcc, dWo, dbo, dWy, dby], ['Wf', 'bf', 'Wi', 'bi', 'Wcc', 'bcc', 'Wo', 'bo', 'Wy', 'by']): assert dparam.shape == param.shape print(name) for i in range(num_checks): ri = np.random.randint(0, param.size) old_val = param.flat[ri] param.flat[ri] = old_val + delta numloss0 = lossFun(inputs, targets, hprev, cprev)[0] param.flat[ri] = old_val - delta numloss1 = lossFun(inputs, targets, hprev, cprev)[0] param.flat[ri] = old_val # reset grad_analytic = dparam.flat[ri] grad_numerical = (numloss0 - numloss1) / (2 * delta) if grad_numerical + grad_analytic == 0: rel_error = 0 else: rel_error = (abs(grad_analytic - grad_numerical) / abs(grad_numerical + grad_analytic)) print('%s, %s => %e' % (grad_numerical, grad_analytic, rel_error)) def basicGradCheck(): inputs = [char_to_ix[ch] for ch in data[:seq_length]] targets = [char_to_ix[ch] for ch in data[1:seq_length+1]] hprev = np.random.randn(H, 1) cprev = np.random.randn(H, 1) gradCheck(inputs, targets, hprev, cprev) # Uncomment this to run gradient checking instead of training #basicGradCheck() #sys.exit() # n is the iteration counter; p is the input sequence pointer, at the beginning # of each step it points at the sequence in the input that will be used for # training this iteration. n, p = 0, 0 # Memory variables for Adagrad. mWf = np.zeros_like(Wf) mbf = np.zeros_like(bf) mWi = np.zeros_like(Wi) mbi = np.zeros_like(bi) mWcc = np.zeros_like(Wcc) mbcc = np.zeros_like(bcc) mWo = np.zeros_like(Wo) mbo = np.zeros_like(bo) mWy = np.zeros_like(Wy) mby = np.zeros_like(by) smooth_loss = -np.log(1.0/V) * seq_length best_loss = smooth_loss # Save the initial loss so that printing and saving occur at 1/2 of it and 1/10 of it. start_loss = smooth_loss output_filename = "lstm-output.txt" print("\nStart Loss:",start_loss) while p < MAX_DATA: # Prepare inputs (we're sweeping from left to right in steps seq_length long) if p+seq_length+1 >= len(data) or n == 0: # Reset RNN memory hprev = np.zeros((H, 1)) cprev = np.zeros((H, 1)) p = 0 # go from start of data # In each step we unroll the RNN for seq_length cells, and present it with # seq_length inputs and seq_length target outputs to learn. inputs = [char_to_ix[ch] for ch in data[p:p+seq_length]] targets = [char_to_ix[ch] for ch in data[p+1:p+seq_length+1]] # Sample from the model now and then. # if n % 1000 == 0: # sample_ix = sample(hprev, cprev, inputs[0], 200) # txt = ''.join(ix_to_char[ix] for ix in sample_ix) # print('----\n %s \n----' % (txt,)) # Forward seq_length characters through the RNN and fetch gradient. (loss, dWf, dbf, dWi, dbi, dWcc, dbcc, dWo, dbo, dWy, dby, hprev, cprev) = lossFun(inputs, targets, hprev, cprev) smooth_loss = smooth_loss * 0.999 + loss * 0.001 # if n % 200 == 0: # print('iter %d (p=%d), loss %f' % (n, p, smooth_loss)) # Sample from the model now and then. if smooth_loss > (start_loss/4): if n % 1000 == 0: print('%s: iter %d (p=%d), loss %f' % (datetime.datetime.now(),n, p, smooth_loss)) elif smooth_loss < best_loss: print('%s: iter %d (p=%d), loss %f' % (datetime.datetime.now(),n, p, smooth_loss)) best_loss = smooth_loss sample_ix = sample(hprev, cprev, inputs[0], 500) txt = ''.join(ix_to_char[ix] for ix in sample_ix) print('----\n %s \n----' % (txt,)) if smooth_loss < (start_loss/6): print("\nSaving to file\n") with open(output_filename,'a') as file_object: file_object.write(txt) file_object.write("\n") # Perform parameter update with Adagrad. for param, dparam, mem in zip( [Wf, bf, Wi, bi, Wcc, bcc, Wo, bo, Wy, by], [dWf, dbf, dWi, dbi, dWcc, dbcc, dWo, dbo, dWy, dby], [mWf, mbf, mWi, mbi, mWcc, mbcc, mWo, mbo, mWy, mby]): mem += dparam * dparam param += -learning_rate * dparam / np.sqrt(mem + 1e-8) p += seq_length n += 1
GPT-2 the Next Level in Text Generation for now at least
If you love WordPress you are really going to like this post 🙂
I have played around with OpenAI’s GPT-2 a bit and it is a fun text generator. It does a strikingly good job at generating fairly OK text. With a little touch up it one could create something sensible and readable.
Seeded with “Welcome to WordPress!” (I’m editing in WordPress and this was the first thing that came to mind) below is what OpenAI’s GPT-2 machine learning text generator came up with on the first shot. This has not been edited and GPT-2 seems to spell all words 100% and has fair grammar and sentence structure. Even though it can make fair paragraphs, it can wander a bit off topic at times but, is generally coherent. I have to admit being a bit blown away when I first started playing with it a bit and this is only using the 117M model version available on Github.
So, here’s the part where we start…
Welcome to WordPress!
Model prompt >>> Welcome to WordPress!
======================================== SAMPLE 1 ========================================
There are over 10,000 websites. It’s hard to count them all! And, it really is.
Let’s start with a quick summary of a few websites – WordPress, WordPress Plus, Hosted Blogger, WordPress, blog, etc.:
This is a list that lets you go from list to list and even from list to list. When you click on my name you can see I have 5 pages with 5,000+ blog posts.
It’s very easy to find and read a list on Twitter.
When you visit the Website, you are being asked to navigate through several pages of websites. You can also go to our Website navigation.
Now, let’s go for a little more fun: I hope that you have enjoyed this website and find the posts of other visitors that are looking to help you. It’s been one of those times, like now since the late ’80s, when I was doing it, that people would tell me I was dumb, that I didn’t know how to read a book. “I’d never read a book!” And that would be the beginning.
Now, I know when I read a book, I don’t look like a dumb person. No.
To be honest, I’m used to looking pretty stupid for being dumb. I don’t always have friends in their twenties or thirties that I would have found interesting. And I don’t take myself very seriously when things are looking good.
And I always have friends just as I am, and I don’t do good writing, and, in fact, when I’m not writing, I have friends I think are actually intelligent, but they are totally out of their heads. They are not stupid, so there’s just something about me that I would like to be called an intelligent genius. And they are just out of their brains.
I always go through my twenties and thirties thinking I’m smarter, and I’m going to give them crap and they’re probably right. I go through my twenties and thirties thinking I’m smarter and they’re just not going to.
I see all the people I’m reading these days thinking I’m smart and smart in my twenties and thirties, and I think, “My God? It’s only been a month since I have read a book.” I just think I’m getting the wrong look at it.
For Variety Let’s Go Try Again
This time around it output’s what looks like the intro to a tutorial on building a site, with some clunky HTML at the bottom. Notice the emoticon! I stole a few lines from this output and already wove them in above for fun. If one was to take the text below and hand edit it, it could be used to kick start a tutorial. It could break any writers block that you might have and get the ball rolling, see the example right after this text dump.
If you love WordPress you are really going to like this post 🙂
How Do I get started making WordPress?
In case you didn’t know WordPress is actually not quite that interesting after all. Even if you’re not trying to go the Web with a web browser.
But in order to succeed, WordPress needs you to be familiar with the various parts of it and if that’s all, you’re going to need some background info!
We’re actually all interested in WordPress on a lot of levels.
So, here’s the part where we start…
Creating a website
For WordPress, you’re going to be using the web for a couple of things.
The first thing you’ll want to do…
Create websites
So, you’ve probably read how the web can be an intimidating tool for beginners.
And so, we want to take you through what it really is.
Our site is a very basic web page.
So, how do we define a site and what do we do with it?
Well, it starts with making an appearance.
It’s called an email address
A website addresses are very powerful because it tells us the number of page views and the total number of views for an email.
Let’s start by getting you to get a feeling of how well this page works.
So what’s the deal with a website?
Let’s take a little detour
Now that you’ve got that impression about the website and get to your first point, we’ll start to explain more about how it functions.
How a website works?
Let’s first get you started with a simple HTML page .
We’ll start with defining our website at a basic level. Let’s go ahead, for the sake of simplicity we’ll take all of the components from the HTML below:
<a href=”https://www.wp.com/v3/wp/”>
<div class=”example-wrapper”>
</div>
<script type=”text/javascript”>
//
“example”
</script>
“http://the.example.com/?page=example.svg”
</a>
<page>
<img src=”https://www.wp.com/v3/wp/”>
</page>
</body>
OK lets make an intro to a WordPress tutorial out of some of the text above to see how it can help prime the pump of writing….
If you love WordPress you are really going to like this post 🙂
You might be wondering, how do I get started making a WordPress site? You’ve probably read how WordPress can be an intimidating tool for beginners. But, in order to succeed, you need to be familiar with the various parts of WordPress. You’re going to need some background info!
So what’s the deal with a website? Let’s start by getting a feeling of how building a page works by looking at how webpages work in the first place. We will take a little detour and get you started with a simple HTML page.
…it is entirely possible to get recursive and keep feeding the model text as you work along in the tutorial to create more ideas to propel the creative process forward. I might go into this further in the future and produce an example. But for I post a few cuts from model produced text below to show off the concept.
How do I get started with WordPress?
Once you have your free, easy to use WordPress site up and running for your WordPress account, you can find some tips and tricks to get started with the site you want to build your own plugin and set up in your WordPress application.
..I liked the line “How do I get started with WordPress?” so I fed that into the model and next thing you know I get something that could be a start to the next section of a tutorial…
Model prompt >>> How do I get started with WordPress?
======================================== SAMPLE 1 ========================================
Step 1 – Create your site
Once you have your site, get a copy of the plugin. I use WP Engine as my plugin manager. Once you are installed, you should see a page with WordPress: Setup – Configuration for your content page. After you have done that, click Create a new page for your newly created page. You should see the page with WordPress: Setup – Your site. Click Next to see the configuration section. In the next step, you will create the page as if your site was created with WordPress.
Step 2 – Update your site
Update your site in the WordPress dashboard. If it is installed from the local system of your WordPress installation, your WordPress will be updated. You can click Next to see updates for your site as they were made.
Step 3 – Set up your site
Set up your site by creating a WordPress account, signing in to the WordPress account, setting up your website with WordPress, etc.
Step 4 – Creating your website
Go to the Settings page and click Create Website. You can now create a new page under your WordPress profile. Select your new URL. In this section, you can check if this should work. If not, then you will need to click on the Advanced Button to make an update. Once you have checked if your site has been updated, click Continue. To finish, select Update Site and make a new change to your WordPress site.
Step 5 – Register
Once you have registered with WordPress, sign up for the My Online Account Program, which allows WordPress websites to be easily accessed from any web browser. Register your account with your web hosting provider (AWS) and you should see the instructions below.
Register a domain name
To begin, click on the Registration Check button. If it is still not there, then you will need to click on the “New Username” option or click on the Search bar that appears.
Click on the Search button in one of your applications. It will take you to the section on registration.
Select your domain name. Click OK to confirm that you are registered, it will pop in.
In both the Name and Contact fields below, click Add domain to Register and click the Registration Button, check Yes or OK to confirm that you should see a confirmation page.
Once you have checked in on your domain name, the web browser will ask you to enter your password. Next, follow these steps to change your existing
… almost the end for now.
Finally, How about a 3rd Try
Now the model goes way off topic. My guess is that there is random seeded of the Weights and Biases in the model and they must have been randomized in a way that caused the model to veer off topic right from the start.
<|endoftext|>A few weeks ago, I published an article detailing the first round of the 2016 American College Football Championship. The article was titled “Top 10 Players in Division I College Football,” and it’s still a long walk from having the best-of-the-class selection process of any college in college football. It’s an interesting concept, as it’s a way into the future. However, a lot of people may still think the same thing I’m saying, and I should think twice.
After seeing the rankings at my own site, I decided to share a few details on the 2017 football draft. The Top 10 prospects in Division I, along with a few other players, are included so that this post will highlight what makes the best players in college football.
The top 11 prospects in 2017
I’m making it sound as if our top class could be considered the top 5 in college football now. That’s not really so. I’m sure, we’ll be seeing much of the top 10 players in this Class of 2017 in 2016. The Top 10 players in Division I were ranked by the following: The number of career touchdowns and receiving yards the top 10 plays a season. If you are a member of the College Football Playoff, and you’re a member of Football Bowl Subdivision, I am going to rank you by the following. You are no slouch, but that is, if you rank first in the Big Ten or NFC Division, you might not have the Big Ten/CSN, unless that person, Jim Irsay, is looking at you.
If you are a member of the NCAA, and you’re going to be ranked second or third nationally in each conference, you might not have the highest ranking player in one conference, but maybe a couple of the higher rankings are worth your time and attention. These rankings are based off of two different ways of looking at players going into their careers as Division I college football prospects:
The Football Bowl Subdivision
My current ranking of teams is based on just two different ways:
• Based on how many points the top team is allowed to gain in division I.
• Based on how many points a team is allowed to lose in division I
This is also really well thought out and makes me wonder what the best option (or worse) for the college football players I know in the future may be.
I’m going to list my team’s results in alphabetical order, and I’d like to get
Resources
https://www.lmspulse.com/2019/open-source-artificial-neural-network-gpt/
https://lambdalabs.com/blog/run-openais-new-gpt-2-text-generator-code-with-your-gpu/
Siraj Ravel does a good job explain the technology behind OpenAi’s GPT-2 Text Generator

AlphaGo: Machine Learning and the game Go
This post is basically a list of good resources on AlphaGo and the game Go. There are many fine tutorials out there on the Internet that I have read through to understand more about machine learning and about how AlphaGo functions. I have collected what are in my opinion some of the best out there and published them in this post.
Additionally there is (as of June 2018) an open source version of AlphaGoZero (The zero means it started from zero, as in there was no priming with data from human played games, it is programmed with the rules to Go and just plays against itself repeatedly) called LeelaZero which was built by following the paper published by DeepMind that covers the research and development of AlphaGoZero. It is a formidable player indeed, I can’t even get one point against the monster. As an experiment, I played it against GnuGo to see how GnuGo would fair. It still gets beat by LeelaZero at a slower rate than I do but, is able to score some points against LeelaZero on occasion.
Alpha Go how and why it works
The post by Tim Wheeler is hands down one of the clearest explanations I have seen. Tim Wheeler not only does a great job with this post, he has many other quality posts on his site http://tim.hibal.org
tim.hibal.org/blog/alpha-zero-how-and-why-it-works/
While you are looking at Tim’s post consider viewing the Alpha Go Cheatsheet as well, keep them both open and flip between them, a great way to learn.
hi res AlphaGo Cheatsheet
https://applied-data.science/static/main/res/alpha_go_zero_cheat_sheet.png
Other resources
One Diagram AlphaGoZero
https://medium.com/applied-data-science/alphago-zero-explained-in-one-diagram-365f5abf67e0
The Wikipedia article on Monte Carlo Tree Search is worth a skim if you are not already familiar with Monte Carlo Tree Search which is used in game playing code, both machine learning driven game algorithms and what I would call pre-machine learning types. Previous to machine learning it was successful mostly for games that have a lower branching factor such as Chess. It is also used in GnuGo in a mode that plays on a smaller than standard board (9×9 and smaller). It is probably limited to a small board by the branching factor which gets huge as the board size increases. The number of board configurations is 3^n^2, n being intersections. A 9×9 board has 10^38 and a 19×19 10^170 legal positions according to a Wikipedia article that I read.
Background
For a good background and a brief history of machine learning, deep reinforcement learning in particular. Well worth the read…
Andrej Karpathy Deep Reinforcement Learning: Pong from Pixels
Hands on Exercise
There is an article on Medium that is worth a read, Teach a machine to learn Connect4 strategy through self-play and deep learning
Plus it lets you follow along and build the code to get a nice hands on experience.
LeelaZero: Basically an open source Alpha Go Zero and uses a JAVA GUI (Lizzie) to play it
LeelaZero, the Go engine is an easy to download and compile program, at least on Linux where I had it up and running in about 5 minutes. It uses a companion interface Lizzie written in Java for it’s GUI. LeelaZero is interesting and fun to try out. The pondering mode is cool. You hit the space bar and it ponders and shows the next moves probabilities of winning and depths of search. You can see from the 1.7%, it is beating me pretty bad after 70 moves as it is almost certain to win.
Hovering the mouse pointer over a specific move shows projections of the next moves for both players labeled with numbers up to it’s maximum forward game play estimates.
Released Code for LeelaZero
https://github.com/featurecat/lizzie/releases/tag/0.6
https://github.com/leela-zero/leela-zero
Main LeelaZero Page
An interesting discussion on LeelaZero
https://lifein19x19.com/forum/viewtopic.php?f=18&t=15631
GnuGo in EMACS
GnuGo Can be played within Emacs, which is handy. This is what I did when I played GNUGo against LeelaZero. I forced LeelaZero to play black so it went first and then mirrored it’s move into the GnuGo board and GnuGo’s move back to the Lizzle/LeelaZero board. When I looked at the projects code it looks like development stopped around 2009. At the time it was a fairly good computer Go game but since then others have outpaced it’s strength. From what I recall it is in the 900 elo range for strength.
If you have Emacs installed the GUI version and GnuGo installed, then with Emacs open pressing Alt-X and entering gnugo in the Emacs command buffer will open GnuGo within Emacs. The benefits of this is that you can use the mouse or up and down arrows to play instead of entering coordinates at the command line.
www.gnu.org/software/gnugo/gnugo_3.html#SEC27
General Go Resources
https://en.wikipedia.org/wiki/Book:Go:_The_Board_Game
https://en.m.wikipedia.org/wiki/Computer_Go
Getting CGI and Perl scripts up and running on Minimal Ubuntu
I was trying, again to get this up and running. I have a piece of code notestack-example.cgi that uses Perl and the Perl Module for CGI. I had this working after fiddling with it the first time I flashed the SD card that I set up for a Pine 64 that was set up with minimal Ubuntu Xenial.
The problem is I wrote down only sketchy instructions and had to re-figure it out. After flashing another card, the first one had a slow moving corruption that would cause the machine to halt after a while, I got more clear with the process.
I have posted it here for myself, if I get stuck again and for anyone else who might need to know the process, if they get stuck. It is a rough outline. I copied what commands I issued from the history and added comments and some test code that I had on a RaspberryPi which has been running the notestack-example.cgi among other items for years so that was my baseline.
Outline getting CGI and Perl running for Apache
In this outline it is assumed that Apache2 is installed and configured.
Optional: To make it easier to get to the cgi directory from your home, create a symlink in the user home directory to be able to move into the cgi folder easier.
ln -s /usr/lib/cgi-bin cgi
Enable CGI support for Apache…
sudo a2enmod cgi
modify /etc/apache2/sites-enabled/000-default.conf
Putting in the code that enables cgi in the Apache config file for sites, this was take from the Raspberrypi and added into /etc/apache2/sites-enabled/000-default.conf
it was put right above the </VirtualHost> line.
——————————————————
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory “/usr/lib/cgi-bin”>
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
——————————————————
Test with a simple BASH CGI script
Use the following code as printenv.cgi to test basic CGI with a bash script.
in the /usr/lib/cgi-bin directory.
——————————————————
#!/bin/bash -f
echo “Content-type: text/html”
echo “”
echo “<PRE>”
env || printenv
echo “</PRE>”
exit 0
——————————————————
test with…
which needs to be 755 (+x) permissions. This file is from the RPI, was used years ago to test it out.
sudo nano printenv.cgi
sudo chmod +x printenv.cgi
/printenv.cgi
If all is well this will also be accessible from the web…
curl http://localhost/cgi-bin/printenv.cgi
curl is installed in the minimal build.
If you are using this on your own intranet OK, if this machine is accessible from the web get rid of printenv.cgi so the whole world can’t see the output if it gets found.
Test Perl
Test Perl scripts, normally Perl is installed even in the minimal Ubuntu build. It’s
presence can be tested for by using ‘which perl‘.
Use the following code as perl-test.cgi
in the /usr/lib/cgi-bin directory.
——————————————————
#!/usr/bin/perl
print “Content-type: text/html\n\n”;
print “Hello CGI\n”;
EOF
——————————————————
sudo nano perl-test.cgi
sudo chmod 755 perl-test.cgi
./perl-test.cgi
Does it work via Apache?
curl http://localhost/cgi-bin/perl-test.cgi
Perl CGI Module
Get Perl scripts (Any Perl code that uses CGI.pm in it) running and web accessible, ones that require the CGI Perl Module…
Got ERROR #1,missing CGI.pm, followed by #2 complained about a missing Util.pm, see below.
Got this error when the Perl Module was missing got a similar error after installing PM, complaint about missing CGI/Util.pm
ERROR 1 and 2
Can’t locate CGI.pm in @INC (you may need to install the CGI module) (@INC contains: /etc/perl /usr/local/lib/aarch64-linux-gnu/perl/5.22.1 /usr/local/share/$
BEGIN failed–compilation aborted at ./notestack-example.cgi line 36.
Grabbed the CGI.pm and Util.pm from my Raspberry Pi by searching for them….
sudo find / -name CGI.pm
sudo find / -name Util.pm
and copying using rcp to/tmp on the board I was setting up, a Pine 64 in this case.
rcp /usr/share/perl/5.14.2/CGI.pm ubuntu@192.168.1.31:/tmp
rcp /usr/share/perl/5.14.2/CGI/Util.pm ubuntu@192.168.1.31:/tmp
The code I was trying to run, the goal of all this work was a script named notestack-example.cgi.
sudo cp /tmp/CGI.pm /etc/perl
./notestack-example.cgi <— Got ERROR #1
sudo cp /tmp/Util.pm /etc/perl/
./notestack-example.cgi <— Got ERROR #2
sudo mkdir /etc/perl/CGI
sudo mv /etc/perl/Util.pm /etc/perl/CGI
Final error ERROR 3
Can’t use ‘defined(@array)’ (Maybe you should just omit the defined()?) at /etc/perl/CGI.pm line 528.
Compilation failed in require at ./notestack-example.cgi line 36.
BEGIN failed–compilation aborted at ./notestack-example.cgi line 36.
This one requires removing defined as this is old and not compatible with the current version of Perl.
Just removed the defined on line 528…
ubuntu@pine64:~$ diff /etc/perl/CGI.pm /tmp/CGI.pm
528c528
< if (@QUERY_PARAM && !$initializer) {
—
> if (defined(@QUERY_PARAM) && !defined($initializer)) {
Learned about this trick about removing the ‘defined‘ from…
https://github.com/shenlab-sinai/diffreps/issues/6
https://rt.cpan.org/Public/Bug/Display.html?id=79917
New York and Pennsylvania Heavy Rain and Flood Events July and August 2018
In July and August 2018 the area that I live went from quite dry to drenched in a matter of weeks. It was a close call for me, many folks in the surrounding areas were affected by the floods. A few people that I spoke to stated that the flooding was worse in 2018 than the previous times of river flooding in 2011 and 2006. This flood event was mostly a small stream and creek flooding event and not a main stem river flood event. The flooding came on hard and fast as the rains seemed to train over the area repeatedly. The outlook for September still shows some above average precipitation but, thankfully we have had a tame Hurricane season so far.
NWS Summary of Rain Events for July and August 2018
The National Weather Service out of Binghamton did a nice summary of the rain events and posted it on their site.
https://www.weather.gov/bgm/pastFloodJulyAugust2018
Aerial View of the Flooding near where I live
Most Starred Python Projects on Github
I have been working through the Python Crash Course book by Eric Matthes. I got to Chapter 17, Working With API’s and ran the example code python_repos_updated.py that generates an SVG graph of the most starred Github Python projects. The thing that stands out to me is the amount of machine learning related resources that show up on this hot list. The interactive graph is generated by using Pygal which works well and is easy to use.
Interactive SVG Graph of Most Starred Github Python Projects
Out of curiosity I looked at the most starred C projects on Github as well with a simple modification of the code.
Interactive SVG Graph of the Most Starred Github C Projects
Python Crash Course
The book has been a good resource to develop programming skills in Python, my background is in C primarily and this book was an excellent starting point to officially learn Python. What I mean by that, is that I have been using Python by modding other peoples code when I need some piece of code to use for some application. For a few years I was learning it that way on an as needed basis (plus using the Internet to look up things that I might get suck on) which works to a point. When I started to get into machine learning a bit deeper, I could see that having a more formal introduction to Python would be helpful. Having a book that goes through the process formally helped to quickly build skills in my opinion. In a matter of a few months I have gone through a decent amount of the book and have been able to branch off some of the examples and create free standing code that was interesting to learn from.
Cloning Linux Mint Setups
Recently I swapped in an SSD to be the new primary drive on my media center PC which was running Linux Mint 18.0 on the spinning SATA drive.
This post is basically a brief documentation of the basic steps involved in cloning or upgrading/cloning Linux Mint. Most likely this works fine for Ubuntu as well as Debian as they share a common ancestry. There are most likely limits to this scheme. I imagine things would break badly trying to do this across 17.3 and 18 for example. The base on those is a different version of Ubuntu, 14.04 vs 16.04. I might try to do a clone when the next whole number version of Mint comes along. Just pop in a drive that I don’t care about, or do it on a VM, such as Virtualbox for an experiment.
Plans
The plan is to relieve some of the storage duties of the spinning drive which was filling up. Plus a speed increase as the SSD can move data 4x faster than the spinning drive but more importantly with no moving parts the access time is minute in comparison the the spinning drive. Applications open much faster, boot time is cut by 75%, etc. If the machine needs to use swap it won’t grind down to a halt as well with a fast disk. This machine is a bit older, SATA II, but a Solid State Drive (SSD) still makes a big difference.
The idea is to clone over the home folder but exclude large data such as the ~/Music folder and leave that on the old drive and mount the drive as additional storage and use a symlink to it.


Goal
The goal of this post’s example is to do an upgrade to Linux Mint 18.3 from 18, clone over my user settings and reinstall all programs. Over the past year and a half that the machine has been in use there have been quite a few programs that have been installed on this machine. Many of them run from the command line or are libraries related to some of the machine learning code that gets run in the background on the machine. Needless to say it would be very hard to remember them and a lot of little things would be broken.
Step 1: Install Linux Mint from USB Stick or DVD
This step is pretty basic and is covered elsewhere on the web…
But needless to say you want to create a user that has the same name and User ID (UID) and Group ID (GID) as on the drive that you will be cloning from.
Step 2: Login on the new machine/drive setup kill your home directory and rsync the old one over
Mount the old drive, doing this from the GUI folder is a fine way to do it. Make note of where it mounts. You can always execute df from the command line to find where it mounted as well
It sounds crazy but, it does work. Login, open a terminal and execute…
rm -rf /home/yourusername
Everything is in memory that the OS needs right now to get through the next step, so nothing will crash and this will give you a blank slate to work with.
Next rsync over your home folder from the old drive ( /dev/sda in my case) making sure that you use the archive option. Using the v and h options as well is helpful as well to produce a lot of output in case you have to trace through a problem.
-v : verbose
-a : archive mode, archive mode allows copying files recursively and it also preserves symbolic links, file permissions, user & group ownerships and timestamps
# -h : human-readable, output numbers in a human-readable format
Example:
For me it went something like this…
rsync -avh /media/erick/B0B807B9-E4FC-499E-81AD-CDD246817F16/home/erick /home/
Next log out and then back in. Almost like magic everything should look familiar. The wallpaper on the desktop should look like whatever it was on the old setup, fonts and other desktop sizing customizations should be there. Open the browser and it should be like you left it in the old setup. It is almost like you hibernated the old setup and woke it up after teleporting it’s soul into the new drive.
But, wait the software needs attention
Step 3: Bring over the software too, sort of…
More like apt-get install it over is closer to the truth. I tried following a post on how to do this (https://askubuntu.com/questions/25633/how-to-migrate-user-settings-and-data-to-new-machine) but, what was described in it did not lead to success. The suggestion was the following…
oldmachine$ sudo dpkg --get-selections > installedsoftware
newmachine$ sudo dpkg --set-selections < installedsoftware
newmachine$ sudo apt-get --show-upgraded dselect-upgrade
It didn’t work but, it at least did the collection part. So I wound up using the first part…
oldmachine$ sudo dpkg --get-selections > installedsoftware
…and then brute forced an install by doing some grep,rev,cut,rev again on the input file. Which basically flips every line in the file and removes the word “install” which is now at the beginning and backwards then flips it back over line by line.
The next line with the awk command prepends sudo apt-get install to the front of each line and saves the output to reinstall-software.sh
installedsoftware-to-apt-get-install.sh
#!/bin/bash cat installedsoftware | grep "install" | rev | cut -c 12- | rev > cleaned-installed-software awk '{printf "sudo apt-get install "$0"\n"}' cleaned-installed-software > reinstall-software.sh
Run the reinstall-software.sh script and it will do just what it says, install all of the software that was on the old setup. I believe there is an option for apt-get to preanswer Yes when it comes up and asks you the yes or no question about installing. I left it off so that I could review all the larger sized software being loaded. A few times I hit no by accident so had to re-run the script, no big deal.
Reboot is best now to avoid side-effects
Before going much further a reboot is probably in order as so much has changed on the machine.
For me, during the software install process, I was presented with a question about picking LightDM or another X- windows manager. I picked LightDM because I think that is what I had been using. After I was all done, I put the machine in suspend and it had a bit of trouble coming out of it, having a temporary error related to the X-windows manager. A blue screen came up and had a message about removing a temporary file. Just rebooting the machine cleared this up as the /tmp directory is flushed. Apparently this was something that was set before the upgrade, clone and software install process and did not get unset. Other than that I have seen no side effects from the process of upgrade, clone, software install.
Other Items
If you had files configured outside of the home directory such as /etc/hosts, you will obviously have to copy that over. Also, if you have any /etc/cron.hourly,weekly,monthlies that you put on the old machine. Also, it pays to do a dump of crontab’s using crontab -l > crontab-dump.txt on the old setup so they can be reconfigured to the same settings.
Cloning old to new box
This entire process can be used to clone one computer setup to another, old box to new one for example. Which brings us to…
Final Thoughts: Twin Machines
It is entirely possible to keep two machines in sync using the methods outlined above. I have not tried this but I am tempted to test it out at least. What I am thinking of is a laptop and desktop for instance. The desktop with it’s ability to hold multiple drives with ease works nice here It has one drive with the same OS as the “twin” laptop and is setup as multi OS boot. The steps above are executed, cloning the laptop setup and data to the desktop. It is entirely possible to keep cloning the home folder contents back and forth between the two to keep them sync’d. Even the software can be kept in sync using the method used above to re-install it.
It is possible to do this directly between them, both on at the same time. Or, through a server where they both get backed up to. The only caveat is overwriting and deletions. Such as care when using the –delete option with rsync. There is a potential for a race condition of sorts if settings and files get changed and then clobbered by a sync operation. If I were to try this I would start with a one direction sync. One device is the master and the other the slave. Deletions and settings changes get cloned from master to slave automatically only.
Raspberry Pi WiFi via USB device
Setting WiFi up via the command line on Raspberry Pi, using a USB Wireless Adapter
These are notes on how to setup WiFi on the Raspberry Pi. The R-Pi is a model 2 running Raspbian 4.1.19+.
In my case and in the example that follows, the Raspberry Pi is connected to an Ethernet network, static IP at 192.168.1.17. This is the address that I am logging in via SSH to get to the command line to configure the USB WiFi. Adapter.
USB WiFi Adapters
Two USB Wifi’s were tried a Belkin N300 and an Edimax EW7811Un. Both use the Realtek RTL8192CU chip and work well with the R-pi. Initial testing was with the Belkin and the output from this device is used in this post for the command line examples.
NOTE: Originally the adapters were tried by plugging them into a powered USB hub which plugged into the R-pi. This allows for hot-plugging. If a device is hot-plugged directly into the R-Pi it will force a reboot, at least on the one that I have (R-Pi Model 2B). This is probably due to an inrush current that pulls down the power bus momentarily, I am guessing. The powered USB hub isolates the R-Pi from the devices connected to it as far as power is concerned and things will hot plug fine using it. I did realize later on that when I plugged the USB WiFi adapter directly into the R-Pi, I got more stable behavior with it. As in less strange dropouts of the WiFi from the network. It maintains a network connection better for me at least, plugged in directly.
Initial Testing
The first steps involve checking to see that the adapter is detected, registered and the correct device driver is loaded. They are just confirmation that all is well. They can be skipped and then ran later if problems arise and troubleshooting is needed.
Plug in USB WiFi adapter and run a lsusb and dmesg…
lsusb
erick@raspberrypi ~ $ lsusb
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 004: ID 2101:8500 ActionStar
Bus 001 Device 005: ID 2101:8501 ActionStar
Bus 001 Device 006: ID 154b:005b PNY
Bus 001 Device 008: ID 050d:2103 Belkin Components F7D2102 802.11n N300 Micro Wireless Adapter v3000 [Realtek RTL8192CU]
Bus 001 Device 007: ID 174c:1153 ASMedia Technology Inc.
The device shows up fine using lsusb. Now on to dmesg to see if the correct driver loaded…
[156238.694964] usb 1-1.3.3: new high-speed USB device number 8 using dwc_otg
[156238.797146] usb 1-1.3.3: New USB device found, idVendor=050d, idProduct=2103
[156238.797188] usb 1-1.3.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[156238.797207] usb 1-1.3.3: Product: Belkin Wireless Adapter
[156238.797225] usb 1-1.3.3: Manufacturer: Realtek
[156238.797242] usb 1-1.3.3: SerialNumber: 00e04c000001
[156239.201673] usbcore: registered new interface driver rtl8192cu
Kernel driver rtl8192cu is loaded, all should be well with the adapter!
lsmod
The following lsmod was run and it confirms the kernel module is loaded for the 8192cu driver. It is just added confirmation that all is well.
erick@raspberrypi ~ $ lsmod
Module Size Used by
xt_state 1434 1
ipt_MASQUERADE 1220 1
nf_nat_masquerade_ipv4 2814 1 ipt_MASQUERADE
iptable_nat 2120 1
nf_nat_ipv4 6162 1 iptable_nat
nf_nat 17132 2 nf_nat_ipv4,nf_nat_masquerade_ipv4
8192cu 556175 0
nfsd 263815 11
nf_conntrack_ipv4 14388 3
nf_defrag_ipv4 1766 1 nf_conntrack_ipv4
xt_conntrack 3420 1
nf_conntrack 95316 6 nf_nat,xt_state,nf_nat_ipv4,xt_conntrack,nf_nat_masquerade_ipv4,nf_conntrack_ipv4
iptable_filter 1698 1
ip_tables 12362 2 iptable_filter,iptable_nat
x_tables 18590 5 ip_tables,ipt_MASQUERADE,xt_state,xt_conntrack,iptable_filter
i2c_dev 6386 4
snd_bcm2835 22502 0
snd_pcm 92861 1 snd_bcm2835
snd_seq 58152 0
snd_seq_device 5142 1 snd_seq
snd_timer 22156 2 snd_pcm,snd_seq
snd 67534 5 snd_bcm2835,snd_timer,snd_pcm,snd_seq,snd_seq_device
sg 20575 0
i2c_bcm2708 5988 0
bcm2835_gpiomem 3703 0
bcm2835_rng 2207 0
uio_pdrv_genirq 3526 0
uio 10078 1 uio_pdrv_genirq
Setup the WiFi Connection
In this example this is a WPA type of security. I know the SSID and password and just put them into the wpa_supplicant configuration file. If you need to see what WiFi nodes are available on the network consider using the scan …
( IF Needed )
sudo iwlist wlan0 scan
Check /etc/network/interfaces
Check to see that the section exists in the file that will allow the USB apapter to hot plug and also the wpa-roam line that points to the wpa_supplicant.conf file where the SSID and password will be stored in the next step.
allow-hotplug wlan0 iface wlan0 inet manual wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf iface default inet dhcp
…any changes to the interfaces file will require a reboot or a restart of networking to take effect, via….
sudo service networking restart
If you are running the R-Pi headless it will disconnect from SSH and will require a re-login. If a mistake is made in the interfaces file, it might not come back and require connecting a keyboard and monitor to reconnect. The good news about having both a running eth0 and wlan0 is that if you make a mistake in only one of them it will be possible to connect via the other one. Less chances of being totally locked out by a small typo in the interfaces file. Sometimes a restart of network services will cause a non-recoverable dropout which requires a reboot to get an SSH connection going again.
Config wpa_supplicant
sudo nano /etc/wpa_supplicant/wpa_supplicant.conf
Go to the bottom of the file and add the following type of entry, putting in the correct SSID and pwd:
network={ ssid="SprintHotspot2.4-example" psk="thepassword" }
Save and Exit
Then execute the follow to apply the new configuration….
wpa_cli -i wlan0 reconfigure
TEST IT:
ifconfig wlan0
Results show that the interface is up and and running
erick@raspberrypi ~/Music/music-test $ ifconfig wlan0
wlan0 Link encap:Ethernet HWaddr 74:df:e0:e0:0e:e0
inet addr:192.168.128.46 Bcast:192.168.128.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:4023854 errors:0 dropped:1664207 overruns:0 frame:0
TX packets:2955774 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3003299485 (2.7 GiB) TX bytes:1956045437 (1.8 GiB)
It should be working at this stage. Trying to reach the net using something like ping google.com should give good results. If not more troubleshooting is required. I had to do the next step to get it to reach the net on the wireless network as it was trying to use the Ethernet connection to the router to get out, set as the default gateway, which was not hooked up to the web at all. Just a router at 192.168.1.1 and no WAN port connection.
Additional Step
The following bit may or may not apply for everyone. But, I am adding here as it was not obvious at the moment I got WiFi up. I had to think on it a bit! Basically a default route has to exist that takes it to a gateway to the Internet.
IN ORDER TO GET PI OUT ON INTERNET NEEDED TO DO A
sudo route add default gw 192.168.128.1 wlan0
As there was no route out and it must pick eth0 by priority! Needs a route to the Sprint Box that I am connected to the net on the 192.168.128.0 network.
THE ABOVE WOULD HAVE TO HAPPEN ON EVERY REBOOT OR NETWORK REFRESH! Or just get rid of default gateway on ETH0 and it might just pick up the gateway on the wlan0 all of the time! If both are dhcp the eth0 gateway will always be treated as preferred, so going static will get rid of it as I was planning on using this R-pi as a bridge from LAN to WLAN! This required editing /etc/network/interfaces to remove the 192.168.1.1 router as a gateway. The router was reconfigured by turning off DHCP on it, effectively making it an access point for WiFi. Essentially it becomes another path to the Internet along with the WiFi hotspot.
erick@raspberrypi ~ $ route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
192.168.128.0 0.0.0.0 255.255.255.0 U 0 0 0 wlan0
erick@raspberrypi ~ $ sudo route add default gw 192.168.128.1 wlan0
erick@raspberrypi ~ $ route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.128.1 0.0.0.0 UG 0 0 0 wlan0
0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
192.168.128.0 0.0.0.0 255.255.255.0 U 0 0 0 wlan0
SHOWS UP IN /etc/resolv.conf as well….
erick@raspberrypi ~ $ cat /etc/resolv.conf domain router search router nameserver 192.168.128.1
ip show route as well…
erick@raspberrypi ~ $ ip route show default via 192.168.128.1 dev wlan0 default via 192.168.1.1 dev eth0 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.17 192.168.128.0/24 dev wlan0 proto kernel scope link src 192.168.128.46
/etc/network/interfaces
The following /etc/network/interfaces file was edited to make the wlan0 connection which connected to the Internet work for the R-Pi.
Note the eth0 connection is setup static on the 192.168.1.0 wired network. The wlan0 connection is set for dhcp on the 192.168.128.0. The default gateway at 192.168.1.1 ( the router ) is commented out to allow the default to fall on the 192.168.128.1 WiFi router, which is a ZTE WiFi hotspot, basically a repeater from 4G LTE cell to WiFi.
Note the wpa-roam points to the wpa_supplicant file that has the SSID and password entered earlier in this post to get the WiFi going.
erick@raspberrypi ~/Music/music-test $ sudo cat /etc/network/interfaces [sudo] password for erick: auto lo iface lo inet loopback #iface eth0 inet dhcp iface eth0 inet static address 192.168.1.17 netmask 255.255.255.0 network 192.168.1.0 broadcast 192.168.1.255 # Remove gateway to see if it fails-over to wlan0 gateway on 192.168.128.1 12242017 # gateway 192.168.1.1 # nameservers dns-nameservers 8.8.8.8 8.8.4.4 allow-hotplug wlan0 iface wlan0 inet manual wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf iface default inet dhcp
ALL UP AND RUNNING OK
Running ip a shows all interfaces. Note that the R-pi is connected to wlan0 on the 192.168.128.46 address and eth0 is connected at 192.168.1.17, both networks are now available.
erick@raspberrypi ~ $ ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether b8:2a:eb:2a:a4:2a brd ff:ff:ff:ff:ff:ff inet 192.168.1.17/24 brd 192.168.1.255 scope global eth0 valid_lft forever preferred_lft forever 3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000 link/ether 08:8a:3c:ba:83:8a brd ff:ff:ff:ff:ff:ff inet 192.168.128.46/24 brd 192.168.128.255 scope global wlan0 valid_lft forever preferred_lft forever
The connection to the WiFi node can be confirmed via iwconfig wlan0…
erick@raspberrypi ~ $ iwconfig wlan0 IEEE 802.11bg ESSID:"SprintHotspot2.4-example" Nickname:"<WIFI@REALTEK>" Mode:Managed Frequency:2.452 GHz Access Point: 34:3A:87:3A:BA:3A Bit Rate:54 Mb/s Sensitivity:0/0 Retry:off RTS thr:off Fragment thr:off Power Management:off Link Quality=100/100 Signal level=63/100 Noise level=0/100 Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0 Tx excessive retries:0 Invalid misc:0 Missed beacon:0 lo no wireless extensions. eth0 no wireless extensions.