Skip to content

Commit

Permalink
Merge pull request #57 from SharathGa/reformat
Browse files Browse the repository at this point in the history
Format numpynet files
  • Loading branch information
Chronocook authored Oct 16, 2019
2 parents eca3a9f + 9573765 commit 7842028
Show file tree
Hide file tree
Showing 6 changed files with 386 additions and 247 deletions.
86 changes: 59 additions & 27 deletions examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@
"""


def make_checkerboard_training_set(num_points=0, noise=0.0, randomize=True,
x_min=0.0, x_max=1.0, y_min=0.0, y_max=1.0):
def make_checkerboard_training_set(
num_points=0, noise=0.0, randomize=True, x_min=0.0, x_max=1.0, y_min=0.0, y_max=1.0
):
"""
Makes a binary array like a checkerboard (to work on an xor like problem)
:param num_points: (int) The number of points you want in your training set
Expand Down Expand Up @@ -56,7 +57,9 @@ def make_checkerboard_training_set(num_points=0, noise=0.0, randomize=True,
coords.append(coord_point)
# Assign an xor boolean value to the coordinates
for coord_point in coords:
bool_point = np.array([np.round(coord_point[0]) % 2, np.round(coord_point[1]) % 2]).astype(bool)
bool_point = np.array(
[np.round(coord_point[0]) % 2, np.round(coord_point[1]) % 2]
).astype(bool)
bools.append(np.logical_xor(bool_point[0], bool_point[1]))
# If noisy then bit flip
if noise > 0.0:
Expand All @@ -73,7 +76,7 @@ def make_checkerboard_training_set(num_points=0, noise=0.0, randomize=True,
train_out = np.array([[bools[i]]])
else:
train_in = np.append(train_in, np.array([coord]), axis=0)
train_out = np.append(train_out, np.array([[bools[i]]]), axis=1)
train_out = np.append(train_out, np.array([[bools[i]]]), axis=1)

train_out = train_out.T
return train_in, train_out
Expand Down Expand Up @@ -105,12 +108,11 @@ def make_smiley_training_set(num_points=0, delta=0.05):
for coord_point in coords:
x = coord_point[0]
y = coord_point[1]
if (abs(x - 0.65) < delta) & (abs(y - 0.65) < (0.05+delta)):
if (abs(x - 0.65) < delta) & (abs(y - 0.65) < (0.05 + delta)):
bools.append(True)
elif (abs(x - 0.35) < delta) & (abs(y - 0.65) < (0.05+delta)):
elif (abs(x - 0.35) < delta) & (abs(y - 0.65) < (0.05 + delta)):
bools.append(True)
elif ((x > 0.2) & (x < 0.8) &
(abs(y - ((1.5 * (x - 0.5))**2 + 0.25)) < delta)):
elif (x > 0.2) & (x < 0.8) & (abs(y - ((1.5 * (x - 0.5)) ** 2 + 0.25)) < delta):
bools.append(True)
else:
bools.append(False)
Expand All @@ -125,7 +127,7 @@ def make_smiley_training_set(num_points=0, delta=0.05):
train_out = np.array([[bools[i]]])
else:
train_in = np.append(train_in, np.array([coord]), axis=0)
train_out = np.append(train_out, np.array([[bools[i]]]), axis=1)
train_out = np.append(train_out, np.array([[bools[i]]]), axis=1)

train_out = train_out.T
return train_in, train_out
Expand All @@ -139,36 +141,64 @@ def complete_a_picture(viz_client):
:param viz_client: An instance of NumpynetVizClient
"""
# Get a training set for a set of x-y coordinates, this one is part of a checkerboard pattern
x_min = 0.0; x_max = 2.0; y_min = 0; y_max = 1.0
train_in, train_out = make_checkerboard_training_set(num_points=1000, noise=0.00, randomize=True,
x_min=x_min, x_max=x_max, y_min=y_min, y_max=y_max)
x_min = 0.0
x_max = 2.0
y_min = 0
y_max = 1.0
train_in, train_out = make_checkerboard_training_set(
num_points=1000,
noise=0.00,
randomize=True,
x_min=x_min,
x_max=x_max,
y_min=y_min,
y_max=y_max,
)

# Plot he training set
viz_client.plot_2d_classes(train_in, train_out, title="Training data",
x_min=x_min, x_max=x_max,
y_min=y_min, y_max=y_max, delta=0.01)
viz_client.plot_2d_classes(
train_in,
train_out,
title="Training data",
x_min=x_min,
x_max=x_max,
y_min=y_min,
y_max=y_max,
delta=0.01,
)

training_size = train_in.shape[0]
batch_size = round(training_size / 3.0)
num_features = train_in.shape[1]

# Initialize a numpynet object
numpy_net = NumpyNet(num_features, batch_size,
num_hidden=5, hidden_sizes=[4, 8, 16, 8, 4],
activation=["tanh", "tanh", "tanh", "tanh", "tanh", "tanh"],
learning_rate=0.0001,
dropout_rate=None, weight_decay=None,
random_seed=1337)
numpy_net = NumpyNet(
num_features,
batch_size,
num_hidden=5,
hidden_sizes=[4, 8, 16, 8, 4],
activation=["tanh", "tanh", "tanh", "tanh", "tanh", "tanh"],
learning_rate=0.0001,
dropout_rate=None,
weight_decay=None,
random_seed=1337,
)
# Hook the object up to the viz client
numpy_net.set_viz_client(viz_client)

# A basic report of the net to the logs
numpy_net.report_model()

# Train the model!
numpy_net.train(train_in, train_out, epochs=10000,
visualize=True, visualize_percent=1, save_best="./numpynet_best_model.pickle",
debug_visualize=True)
numpy_net.train(
train_in,
train_out,
epochs=10000,
visualize=True,
visualize_percent=1,
save_best="./numpynet_best_model.pickle",
debug_visualize=True,
)

# A silly viz of the network architecture (if the net isn't too huge to make it muddled)
if max(numpy_net.layer_sizes) <= 16:
Expand All @@ -181,7 +211,7 @@ def plot_activations():
y = common.Activation(activation).function(x, deriv=False)
dy = common.Activation(activation).function(x, deriv=True)
viz_client.plot_func(x, y, title=activation)
viz_client.plot_func(x, dy, title="d_"+activation)
viz_client.plot_func(x, dy, title="d_" + activation)


# TODO write this!
Expand All @@ -199,10 +229,12 @@ def paint_a_picture():
def load_a_model(filename, viz_client):
my_net = NumpyNet.load(filename)
prediction_matrix, axis_x, axis_y = common.predict_2d_space(my_net, delta=0.002)
viz_client.plot_2d_prediction(prediction_matrix, axis_x, axis_y, title="Best Prediction")
viz_client.plot_2d_prediction(
prediction_matrix, axis_x, axis_y, title="Best Prediction"
)


if __name__ == '__main__':
if __name__ == "__main__":
"""
Main driver.
"""
Expand Down
3 changes: 2 additions & 1 deletion numpynet/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class Activation:
"""
A class to hold all of the activation functions, ensures all have derivatives
"""

function = None
available = ["tanh", "tanhpos", "sigmoid", "relu", "softplus", "leakyrelu"]

Expand Down Expand Up @@ -62,7 +63,7 @@ def _sigmoid(x, deriv=False):
if deriv:
return y * (1.0 - y)
return y

@staticmethod
def _softplus(x, deriv=False):
"""
Expand Down
52 changes: 32 additions & 20 deletions numpynet/loggit.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ class LogObject:
onConsole = None
onFile = None


def __init__(self, filePath=None, fileName=None, header=None, onConsole=True, onFile=True):
def __init__(
self, filePath=None, fileName=None, header=None, onConsole=True, onFile=True
):
"""
Initialize log object.
"""
Expand All @@ -48,10 +49,17 @@ def __init__(self, filePath=None, fileName=None, header=None, onConsole=True, on
self.header = header
self.onConsole = onConsole
self.onFile = onFile
self.startLog(filePath=self.filePath, fileName=self.fileName, header=self.header,
onConsole=self.onConsole, onFile=self.onFile)

def startLog(self, filePath=None, fileName=None, header=None, onConsole=True, onFile=True):
self.startLog(
filePath=self.filePath,
fileName=self.fileName,
header=self.header,
onConsole=self.onConsole,
onFile=self.onFile,
)

def startLog(
self, filePath=None, fileName=None, header=None, onConsole=True, onFile=True
):
"""
Initialize log file with optional path and optional file name.
Parameters:
Expand All @@ -71,10 +79,10 @@ def startLog(self, filePath=None, fileName=None, header=None, onConsole=True, on

# Create Global Logger
try:
self.out = logging.getLogger(str(__main__.__file__)+'_logger')
self.out = logging.getLogger(str(__main__.__file__) + "_logger")

except AttributeError:
self.out = logging.getLogger(str(__name__+'_logger'))
self.out = logging.getLogger(str(__name__ + "_logger"))

# Clear old handlers
self.out.handlers = []
Expand All @@ -83,7 +91,9 @@ def startLog(self, filePath=None, fileName=None, header=None, onConsole=True, on

# create formatter and add to handlers
if self.header is None:
formatter = logging.Formatter("%(asctime)s;%(levelname)s;%(funcName)20s();%(message)s")
formatter = logging.Formatter(
"%(asctime)s;%(levelname)s;%(funcName)20s();%(message)s"
)
elif self.header == "message_only":
formatter = logging.Formatter("%(message)s")
elif self.header == "simple":
Expand All @@ -106,7 +116,7 @@ def startLog(self, filePath=None, fileName=None, header=None, onConsole=True, on

if fileName is None:
# If not provided, the fileName is set to the top level file calling the global logger.
self.fileName = main_filename + '.log'
self.fileName = main_filename + ".log"
else:
self.fileName = fileName

Expand All @@ -121,10 +131,10 @@ def startLog(self, filePath=None, fileName=None, header=None, onConsole=True, on
else: # Something unexpected went wrong so reraise the exception.
raise
else: # No exception, so the file must have been created successfully.
with open(self.fileFullName, 'w') as file_obj:
file_obj.write(main_filename + ' Log File\n')
with open(self.fileFullName, "w") as file_obj:
file_obj.write(main_filename + " Log File\n")
else:
sys.exit('ERROR! Path specified not able to be written to!')
sys.exit("ERROR! Path specified not able to be written to!")

# create console and file handler and set level to debug
file_handle = logging.FileHandler(self.fileFullName)
Expand All @@ -144,23 +154,20 @@ def startLog(self, filePath=None, fileName=None, header=None, onConsole=True, on
standard_handle.setFormatter(formatter)
self.out.addHandler(standard_handle)


def stopLog(self):
"""
Release logging handlers.
"""
self.out.handlers = []


def setLevel(self,level_tag):
def setLevel(self, level_tag):
"""
Sets the logging level
levelStr (str) - a string describing the desired logging level
'INFO', 'DEBUG', 'WARNING', also 'NOTSET'
"""
self.out.setLevel(logging.getLevelName(level_tag))


def changeFileName(self, new_name, header=None, onConsole=True, onFile=True):
"""
Change the name of the log
Expand All @@ -177,16 +184,21 @@ def changeFileName(self, new_name, header=None, onConsole=True, onFile=True):
# Check if name is okay
# Copy old log to new name
new_path, new_filename = os.path.split(new_name)
if new_path == '':
if new_path == "":
new_path = self.filePath
new_full_filename = os.path.join(new_path, new_filename)
if os.access(new_path, os.W_OK):
self.out.handlers = [] # clear old handlers
if self.onFile:
copyfile(self.fileFullName, new_full_filename)
os.remove(self.fileFullName)
self.startLog(filePath=new_path, fileName=new_filename, header=header,
onConsole=onConsole, onFile=onFile)
self.startLog(
filePath=new_path,
fileName=new_filename,
header=header,
onConsole=onConsole,
onFile=onFile,
)
else:
log.out.warning("No permissions to write new log name")

Expand Down
Loading

0 comments on commit 7842028

Please sign in to comment.