Tuesday, 29 October 2019

Why Unsupervised Learning & Reinforcement Learning are More Important than Supervised Learning

Supervised Learning (SL):
  • Requires some training data
  • This learning method only knows what learnt
Unsupervised Learning (UL, check data using formula), and Reinforcement Learning (RL, check data using environment):
  • Don't require data
  • Generate data and test themselves --> Some creativity!
However, the optimal method in reality is combining SL with both UL & RL to make IL: Incremental Learning.

Friday, 25 October 2019

Nginx Redirect: Return and Rewrite

Nginx redirect all using location+return:

server {
  listen ...;
  server_name ...;
  
  location ~* ^/(.*)$ {
    return 307 https://some.domain/$1;
  }
}

Nginx redirect all using rewrite:

server {
  listen ...;
  server_name ...;

  rewrite ^/(.*)$ https://some.domain/$1 redirect;
}

Nginx as proxy (to port 9999 for example):

server {
  listen ...;
  server_name ...;

  location / {
    proxy_pass http://localhost:9999;
  }
}

Thursday, 24 October 2019

TensorFlow: Load Model to Continue Training

TensorFlow low-level model based on tf.Module is easy to save just as Keras model but low-level model is hard to continue training after loading back as custom functions must be created to assign weight values. The following is an example to save/load Keras model to continue training.

Source code:
%tensorflow_version 2.x
%reset -f

#libs
import tensorflow as tf;
from tensorflow.keras.layers import *;

#constants
BSIZE = 4;

#model
class model(tf.keras.Model):
  def __init__(this):
    super().__init__();
    this.W1 = tf.Variable(tf.random.uniform([2,20], -1,1));
    this.B1 = tf.Variable(tf.random.uniform([  20], -1,1));

    this.W2 = tf.Variable(tf.random.uniform([20,1], -1,1));
    this.B2 = tf.Variable(tf.random.uniform([   1], -1,1));

  #@tf.function(input_signature=[tf.TensorSpec([BSIZE,2])])
  def call(this,Inp):
    H1  = tf.nn.leaky_relu(tf.matmul(Inp,this.W1) + this.B1);
    Out = tf.sigmoid(tf.matmul(H1,this.W2) + this.B2);
    return Out;

#data
X = tf.convert_to_tensor([[0,0],[0,1],[1,0],[1,1]], tf.float32);
Y = tf.convert_to_tensor([[0],  [1],  [1],  [0]  ], tf.float32);

#train
Model = model();

#hard to resume training with this low-level training procedure:
'''
Loss  = tf.losses.MeanSquaredError();
Optim = tf.optimizers.SGD(1e-1);
Steps = 100;

for I in range(Steps):
  if I%(Steps/10)==0:
    Out = Model(X);
    Lv  = Loss(Y,Out);
    print("Loss:",Lv.numpy());

  with tf.GradientTape() as T:
    Out = Model(X);
    Lv  = Loss(Y,Out);

  Grads = T.gradient(Lv, Model.trainable_variables);
  Optim.apply_gradients(zip(Grads, Model.trainable_variables));

Out = Model(X);
Lv  = Loss(Y,Out);
print("Loss:",Lv.numpy(),"(Last)");
'''

#easier to resume training with keras
Model.compile(loss=tf.losses.MeanSquaredError(), optimizer=tf.optimizers.SGD(1e-1));
Model.fit(X,Y, batch_size=4, epochs=10, verbose=0);
print("Test:");
print(Model.predict(X, batch_size=4, verbose=0));

#save
print("\nSaving model...");
tf.keras.models.save_model(Model,"/tmp/models/test");

#load
print("\nLoading model to train more...");
M = tf.keras.models.load_model("/tmp/models/test");
print(M.predict(X, batch_size=4, verbose=0));

#continue training
M.fit(X,Y, batch_size=4, epochs=5000, verbose=0);
print("\nTest:");
print(M.predict(X, batch_size=4, verbose=0));
#eof

Wednesday, 23 October 2019

3D Plotting with Numpy


Source code:
%tensorflow_version 2.x
%reset -f

#core
import math;

#libs
import numpy      as np;
import tensorflow as tf;
from tensorflow.keras.layers import *;

import matplotlib.pyplot as pp;
from mpl_toolkits import mplot3d;

#plot
pp.figure(figsize=[10,10]);
pp3d = pp.axes(projection="3d",elev=45,azim=20);
X    = np.linspace(-10,10, 50);
Y    = np.linspace(-10,10, 50);
X,Y  = np.meshgrid(X,Y);
Z    = np.sin(X/math.pi/2)*np.cos(Y/math.pi/2)*(X-Y);

#pp3d.plot_wireframe(X,Y,Z);
pp3d.plot_surface(X,Y,Z, cmap="coolwarm");
#eof

Monday, 21 October 2019

ReLU as a Function of Single Infinite Domain


In machine learning, ReLU = max(0,x); this leads to a function with 2 domains:
  • f = 0 for x<0
  • f = x for x>=0
However, ReLU can be expressed as a function in infinite domain:

ReLU = f(x) = [ abs(x) + x ] / 2

ML Activation Functions and Their Uses

Linear Activation (both negative and positive to infinity):

Tanh Activation (limited negative, limited positive):

Sigmoid Activation (no negative, limited positive):

ReLU (no negative, positive to infinity):

Softplus aka Smooth ReLU (rectifier, smooth value transition):

Basically, depends on what output values should be and an activation function is selected:
  • Identity activation: No negative limit, no positive limit.
  • Tanh: Limited negative, limited positive.
  • Sigmoid: No negative, limited positive.
  • ReLU: No negative, limited positive.
  • Etc.
Any custom function can be used as activation function, for example, a function similar to Tanh:

f(x) = [ sign(x)*(abs(x) - ln(cosh(x))) ] / 0.7

Softsign is a sigmoid-like activation function that utilise sign(x) and abs(x) too:

softsign(x) = x / (abs(x)+1)

Friday, 18 October 2019

Python 3D Plotting with matplotlib

The following is a plot of a sample function f(x,y) = sin(x)*cos(y)*(x-y).

Source code:
%reset -f

#core
import math;

#libs
import numpy             as np;
import matplotlib.pyplot as pp;

from mpl_toolkits import mplot3d;

#function to plot
Pi = math.pi;
f  = lambda x,y: math.sin(x/Pi/2)*math.cos(y/Pi/2)*(x-y);

#make data
Len = 50;
X   = np.linspace(-10,10, Len);
Y   = np.linspace(-10,10, Len);
X,Y = np.meshgrid(X,Y);
Z   = [];

for I in range(Len):
  Z += [[]];
  for J in range(Len):
    Z[I] += [f(X[I][J],Y[I][J])]; #any function of x,y  

#plot
pp.figure(figsize=[10,10]);
pp3d = pp.axes(projection="3d", elev=50, azim=70);

pp3d.set_title("Function z = f(x,y)");
pp3d.set_xlabel("x values");
pp3d.set_ylabel("y values");
pp3d.set_zlabel("z values");
pp3d.plot_wireframe(X,Y,np.array(Z));
#pp3d.plot_surface(X,Y,np.array(Z), cmap="coolwarm");
#eof

The 4 Factors of Machine Learning

The 4 factors of machine learning:


1) Are there training data?
2) Should training data be generated, all or more?
3) Are there formula to check output?
4) Should output be checked in virtual(bot)/real(robot) environment?

For Supervised Learning (SL):
1) Yes
2) No
3) No
4) No

For Unsupervised Learning (UL):
1) No
2) Yes
3) Yes
4) No

For Reinforcement Learning (RL):
1) No
2) Yes
3) No
4) Yes

Summary:

With training data --> Supervised Learning
No training data, generate them, then:
  • Check output using formula --> Unsupervised Learning
  • Check output using environment --> Reinforcement Learning
Any of the 3 above with more data added to train --> Incremental Learning.

Thursday, 17 October 2019

TensorFlow: Draw Loss Landscape of Single Neuron that Learns OR

Single neuron with bias, sigmoid activation, 2 inputs, data from OR true table. Loss landscape plot:

Source code:
%tensorflow_version 2.x
%reset -f

#libs
import tensorflow        as tf;
import numpy             as np;
import matplotlib.pyplot as pp;

from mpl_toolkits import mplot3d;

#constants
BSIZE = 4;

#model
class model(tf.Module):
  def __init__(this):
    super().__init__();
    this.W = tf.Variable(tf.random.uniform([2,1], -1,1));
    this.B = tf.Variable(tf.random.uniform([  1], -1,1));

  @tf.function(input_signature=[tf.TensorSpec([BSIZE,2])])
  def __call__(this,Inp):
    return tf.sigmoid(tf.matmul(Inp,this.W) + this.B);

  def ff(this,Inp):
    Out = tf.sigmoid(tf.matmul(Inp,this.W) + this.B);
    return Out;

#data
X = tf.convert_to_tensor([[0,0],[0,1],[1,0],[1,1]], tf.float32);
Y = tf.convert_to_tensor([[0],  [1],  [1],  [1]  ], tf.float32);

#train
Model = model();
Loss  = tf.losses.MeanAbsoluteError();
Optim = tf.optimizers.SGD(1e-1);
Steps = 5000;
Xyz   = [];
#'''
for I in range(Steps):
  if I%(Steps/10)==0:
    Out       = Model(X);
    Lossvalue = Loss(Y,Out);
    print("Loss:",Lossvalue.numpy());
    Xyz += [[Model.W.numpy()[0],Model.W.numpy()[1],Lossvalue.numpy()]];

  with tf.GradientTape() as T:
    Out       = Model(X);
    Lossvalue = Loss(Y,Out);

  Grads = T.gradient(Lossvalue, Model.trainable_variables);
  Optim.apply_gradients(zip(Grads, Model.trainable_variables));

Out       = Model(X);
Lossvalue = Loss(Y,Out);
print("Loss:",Lossvalue.numpy(),"(Last)");
Xyz += [[Model.W.numpy()[0],Model.W.numpy()[1],Lossvalue.numpy()]];

print("\nWeights of optimum:");
W = tf.keras.backend.flatten(Model.W).numpy();
print(W);
#'''
#loss landscape
D  = 50;
P  = np.linspace(-10,10, D); #marker points
W1 = [];
W2 = [];
for I in range(D):
  W1 += [[]];
  W2 += [[]];  
  for J in range(D):
    W1[I] += [P[I]];
    W2[I] += [P[J]];

print("\nW1",W1);
print("W2",W2);
Z  = [];

for I in range(D):
  Zrow = [];
  for J in range(D):
    Model.W = tf.convert_to_tensor([[P[I]],[P[J]]], tf.float32);
    Out     = Model.ff(X);
    Lossval = Loss(Y,Out).numpy();
    Zrow   += [Lossval];

  Z += [Zrow];

print("Z:",Z);
Z = np.array(Z);

pp.figure(figsize=(8,8));
pp3d = pp.axes(projection="3d",elev=10,azim=10);
pp3d.text(0,0,0,"(0,0,0)");
pp3d.text(W[0],W[1],0,"Optimum");

pp3d.plot([0,10],[0,0],"-r");
pp3d.plot([0,0],[0,10],"-g");
pp3d.plot([0,0],[0,0],[0,1],"-b");
pp3d.plot([W[0]],[W[1]],[0],"yo");

pp3d.set_title("Loss Landscape");
pp3d.set_xlabel("Weight1");
pp3d.set_ylabel("Weight2");
pp3d.set_zlabel("Loss");
pp3d.plot_wireframe(W1,W2,Z, cmap="coolwarm");

#gradient descent curve
W1s = [];
W2s = [];
Ls  = [];
for I in range(len(Xyz)):
  W1s += [Xyz[I][0]];
  W2s += [Xyz[I][1]];
  Ls  += [Xyz[I][2]];  

pp3d.plot(W1s,W2s,Ls,"-ro");
#eof

Wednesday, 16 October 2019

TensorFlow: Single Neuron Linear Regression without Bias

Source code:
%tensorflow_version 2.x
%reset -f

#libs
import tensorflow as tf;

#constants
BSIZE = 1;

#model
class model(tf.Module):
  def __init__(this):
    super().__init__();
    this.W1 = tf.Variable(tf.random.uniform([2,1], -1,1));
  
  @tf.function(input_signature=[tf.TensorSpec([BSIZE,2])])
  def __call__(this,Inp):
    return tf.matmul(Inp,this.W1);

#data
X = tf.convert_to_tensor([[1,2]],tf.float32);
Y = tf.convert_to_tensor([[3  ]],tf.float32);

#train
Model = model();
Loss  = tf.losses.LogCosh();
Optim = tf.optimizers.SGD(1e-1);
Steps = 10;

for I in range(Steps):
  if I%(Steps/10)==0:
    Out       = Model(X);
    Lossvalue = Loss(Y,Out);
    print("Loss:",Lossvalue.numpy());

  with tf.GradientTape() as T:
    Out       = Model(X);
    Lossvalue = Loss(Y,Out);

  Grads = T.gradient(Lossvalue, Model.trainable_variables);
  Optim.apply_gradients(zip(Grads, Model.trainable_variables));

Out       = Model(X);
Lossvalue = Loss(Y,Out);
print("Loss:",Lossvalue.numpy(),"(Last)");

#test
print("\nTest:");
print(X.numpy()[0],"-->",Y.numpy()[0]);
print(Model(X).numpy()[0][0]);

print("\nDone.");
#eof