added ml experiments / projects
parent
169d99a82f
commit
5a33b132a8
@ -0,0 +1,102 @@
|
|||||||
|
import cv2
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from sklearn.cluster import KMeans
|
||||||
|
from os import listdir
|
||||||
|
import imageio
|
||||||
|
|
||||||
|
from PIL import Image, ImageDraw
|
||||||
|
|
||||||
|
def list_files(directory, extension):
|
||||||
|
return (f for f in listdir(directory) if f.endswith('.jpg') or f.endswith('.png'))
|
||||||
|
|
||||||
|
def find_histogram(clt):
|
||||||
|
"""
|
||||||
|
create a histogram with k clusters
|
||||||
|
:param: clt
|
||||||
|
:return:hist
|
||||||
|
"""
|
||||||
|
numLabels = np.arange(0, len(np.unique(clt.labels_)) + 1)
|
||||||
|
(hist, _) = np.histogram(clt.labels_, bins=numLabels)
|
||||||
|
|
||||||
|
hist = hist.astype("float")
|
||||||
|
hist /= hist.sum()
|
||||||
|
|
||||||
|
return hist
|
||||||
|
def plot_colors2(hist, centroids):
|
||||||
|
bar = np.zeros((50, 300, 3), dtype="uint8")
|
||||||
|
startX = 0
|
||||||
|
|
||||||
|
for (percent, color) in zip(hist, centroids):
|
||||||
|
# plot the relative percentage of each cluster
|
||||||
|
endX = startX + (percent * 300)
|
||||||
|
cv2.rectangle(bar, (int(startX), 0), (int(endX), 50),
|
||||||
|
color.astype("uint8").tolist(), -1)
|
||||||
|
startX = endX
|
||||||
|
|
||||||
|
# return the bar chart
|
||||||
|
return bar
|
||||||
|
|
||||||
|
|
||||||
|
def generateColorImage(img_input):
|
||||||
|
img = cv2.imread("images/"+img_input)
|
||||||
|
|
||||||
|
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
|
||||||
|
img_old = img
|
||||||
|
|
||||||
|
height=img.shape[0]
|
||||||
|
width=img.shape[1]
|
||||||
|
|
||||||
|
img = img.reshape((img.shape[0] * img.shape[1],3)) #represent as row*column,channel number
|
||||||
|
clt = KMeans(n_clusters=3) #cluster number
|
||||||
|
clt.fit(img)
|
||||||
|
|
||||||
|
hist = find_histogram(clt)
|
||||||
|
|
||||||
|
#print(hist, clt.cluster_centers_)
|
||||||
|
|
||||||
|
# size of image
|
||||||
|
canvas = (width, height)
|
||||||
|
|
||||||
|
# scale ration
|
||||||
|
scale = 1
|
||||||
|
thumb = canvas[0]/scale, canvas[1]/scale
|
||||||
|
|
||||||
|
# rectangles (width, height, left position, top position)
|
||||||
|
#print(width*hist[0])
|
||||||
|
frames = [(0, 0, 115, height), (width*hist[0], height, width*hist[0]+width,2), (100, 205, 120,200)]
|
||||||
|
|
||||||
|
# init canvas
|
||||||
|
im = Image.new('RGB', canvas, (255, 255, 255))
|
||||||
|
draw = ImageDraw.Draw(im)
|
||||||
|
|
||||||
|
draw.rectangle([0, 0, width*hist[0], height], fill=(int(clt.cluster_centers_[0][0]), int(clt.cluster_centers_[0][1]), int(clt.cluster_centers_[0][2])))
|
||||||
|
draw.rectangle([width*hist[0], 0, width*hist[0]+width*hist[1], height], fill=(int(clt.cluster_centers_[1][0]),int(clt.cluster_centers_[1][1]),int(clt.cluster_centers_[1][2])))
|
||||||
|
draw.rectangle([width*hist[0]+width*hist[1], 0, width*hist[0]+width*hist[1]+width*hist[2], height], fill=(int(clt.cluster_centers_[2][0]),int(clt.cluster_centers_[2][1]),int(clt.cluster_centers_[2][2])))
|
||||||
|
|
||||||
|
# make thumbnail
|
||||||
|
im.thumbnail(thumb)
|
||||||
|
|
||||||
|
# save image
|
||||||
|
im.save("output/"+img_input)
|
||||||
|
|
||||||
|
# images = []
|
||||||
|
# images.append(imageio.imread("images/"+img_input))
|
||||||
|
# images.append(imageio.imread("img/"+img_input))
|
||||||
|
# imageio.mimsave('gifs/'+img_input+".gif", images)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
directory = 'images'
|
||||||
|
files = list_files(directory, "jpg")
|
||||||
|
for f in files:
|
||||||
|
print(f)
|
||||||
|
generateColorImage(f)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#bar = plot_colors2(hist, clt.cluster_centers_)
|
||||||
|
|
||||||
|
#plt.axis("off")
|
||||||
|
#plt.imshow(bar)
|
||||||
|
#plt.show()
|
@ -0,0 +1,58 @@
|
|||||||
|
|
||||||
|
# Part 3 - Making new predictions
|
||||||
|
import numpy as np
|
||||||
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
|
from keras.preprocessing import image
|
||||||
|
from keras.models import model_from_yaml
|
||||||
|
from keras.preprocessing.image import ImageDataGenerator
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('images', nargs="*", help="images to classify")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# load YAML and create model
|
||||||
|
yaml_file = open('model.yaml', 'r')
|
||||||
|
loaded_model_yaml = yaml_file.read()
|
||||||
|
yaml_file.close()
|
||||||
|
classifier = model_from_yaml(loaded_model_yaml)
|
||||||
|
# load weights into new model
|
||||||
|
classifier.load_weights("model.h5")
|
||||||
|
print("Loaded model from disk")
|
||||||
|
|
||||||
|
|
||||||
|
for f in args.images:
|
||||||
|
from keras.preprocessing import image
|
||||||
|
test_image = image.load_img(f, target_size = (64, 64))
|
||||||
|
test_image = image.img_to_array(test_image)
|
||||||
|
test_image = np.expand_dims(test_image, axis = 0)
|
||||||
|
result = classifier.predict(test_image)
|
||||||
|
print(result)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#WHAT ARE YOUR CLASSES?
|
||||||
|
if result[0][0] == 1:
|
||||||
|
prediction = 'rect'
|
||||||
|
else:
|
||||||
|
prediction = 'circle'
|
||||||
|
|
||||||
|
print("PREDICTION: {}".format(prediction))
|
||||||
|
|
||||||
|
|
||||||
|
#WRITE RESULT TO IMAGE
|
||||||
|
image = Image.open(f)
|
||||||
|
width, height = image.size
|
||||||
|
size = (width, height+100)
|
||||||
|
layer = Image.new('RGB', size, (255,255,255))
|
||||||
|
layer.paste(image, (0,0))
|
||||||
|
|
||||||
|
draw = ImageDraw.Draw(layer)
|
||||||
|
font = ImageFont.truetype('Roboto-Regular.ttf', size=45)
|
||||||
|
(x, y) = (50, height+20)
|
||||||
|
message = prediction
|
||||||
|
color = 'rgb(0, 0, 0)' # black color
|
||||||
|
draw.text((x, y), message, fill=color, font=font)
|
||||||
|
|
||||||
|
|
||||||
|
layer.save("{}.predicted.png".format(f))
|
@ -0,0 +1,11 @@
|
|||||||
|
h5py==2.8.0
|
||||||
|
Keras==2.2.4
|
||||||
|
Keras-Applications==1.0.6
|
||||||
|
Keras-Preprocessing==1.0.5
|
||||||
|
numpy==1.15.2
|
||||||
|
Pillow==5.3.0
|
||||||
|
protobuf==3.6.1
|
||||||
|
PyYAML==3.13
|
||||||
|
scipy==1.1.0
|
||||||
|
six==1.11.0
|
||||||
|
tensorflow==1.0.0
|
@ -0,0 +1,78 @@
|
|||||||
|
# Convolutional Neural Network
|
||||||
|
|
||||||
|
# Installing Theano
|
||||||
|
# pip install --upgrade --no-deps git+git://github.com/Theano/Theano.git
|
||||||
|
|
||||||
|
# Installing Tensorflow
|
||||||
|
# pip install tensorflow
|
||||||
|
|
||||||
|
# Installing Keras
|
||||||
|
# pip install --upgrade keras
|
||||||
|
|
||||||
|
# Part 1 - Building the CNN
|
||||||
|
|
||||||
|
# Importing the Keras libraries and packages
|
||||||
|
|
||||||
|
from keras.models import Sequential
|
||||||
|
from keras.layers import Conv2D
|
||||||
|
from keras.layers import MaxPooling2D
|
||||||
|
from keras.layers import Flatten
|
||||||
|
from keras.layers import Dense
|
||||||
|
|
||||||
|
# Initialising the CNN
|
||||||
|
classifier = Sequential()
|
||||||
|
# Step 1 - Convolution
|
||||||
|
classifier.add(Conv2D(32, (3, 3), input_shape = (64, 64, 3), activation = 'relu'))
|
||||||
|
|
||||||
|
# Step 2 - Pooling
|
||||||
|
classifier.add(MaxPooling2D(pool_size = (2, 2)))
|
||||||
|
|
||||||
|
# Adding a second convolutional layer
|
||||||
|
classifier.add(Conv2D(32, (3, 3), activation = 'relu'))
|
||||||
|
classifier.add(MaxPooling2D(pool_size = (2, 2)))
|
||||||
|
|
||||||
|
# Step 3 - Flattening
|
||||||
|
classifier.add(Flatten())
|
||||||
|
|
||||||
|
# Step 4 - Full connection
|
||||||
|
classifier.add(Dense(units = 128, activation = 'relu'))
|
||||||
|
classifier.add(Dense(units = 1, activation = 'sigmoid'))
|
||||||
|
|
||||||
|
# Compiling the CNN
|
||||||
|
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
|
||||||
|
|
||||||
|
# Part 2 - Fitting the CNN to the images
|
||||||
|
|
||||||
|
from keras.preprocessing.image import ImageDataGenerator
|
||||||
|
|
||||||
|
train_datagen = ImageDataGenerator(rescale = 1./255,
|
||||||
|
shear_range = 0.2,
|
||||||
|
zoom_range = 0.2,
|
||||||
|
horizontal_flip = True)
|
||||||
|
|
||||||
|
test_datagen = ImageDataGenerator(rescale = 1./255)
|
||||||
|
|
||||||
|
training_set = train_datagen.flow_from_directory('dataset/training_set',
|
||||||
|
target_size = (64, 64),
|
||||||
|
batch_size = 32,
|
||||||
|
class_mode = 'binary')
|
||||||
|
|
||||||
|
test_set = test_datagen.flow_from_directory('dataset/test_set',
|
||||||
|
target_size = (64, 64),
|
||||||
|
batch_size = 32,
|
||||||
|
class_mode = 'binary')
|
||||||
|
|
||||||
|
classifier.fit_generator(training_set,
|
||||||
|
steps_per_epoch = 500,
|
||||||
|
epochs = 1,
|
||||||
|
validation_data = test_set,
|
||||||
|
validation_steps = 100)
|
||||||
|
|
||||||
|
|
||||||
|
# serialize model to YAML
|
||||||
|
model_yaml = classifier.to_yaml()
|
||||||
|
with open("model.yaml", "w") as yaml_file:
|
||||||
|
yaml_file.write(model_yaml)
|
||||||
|
# serialize weights to HDF5
|
||||||
|
classifier.save_weights("model.h5")
|
||||||
|
print("Saved model to disk")
|
@ -0,0 +1,162 @@
|
|||||||
|
class NeuralNetwork
|
||||||
|
{
|
||||||
|
constructor(numInputs, numOutputs, numHiddenLayers, numNeuronsPerHiddenLayer)
|
||||||
|
{
|
||||||
|
|
||||||
|
this.numInputs = numInputs;
|
||||||
|
this.numOutputs = numOutputs;
|
||||||
|
this.numHiddenLayers = numHiddenLayers;
|
||||||
|
this.numNeuronsPerHiddenLayer = numNeuronsPerHiddenLayer;
|
||||||
|
|
||||||
|
this.bias = 0.0;
|
||||||
|
this.activationResponse = 1.0;
|
||||||
|
this.neuronLayers = [];
|
||||||
|
|
||||||
|
this.createNetwork();
|
||||||
|
}
|
||||||
|
|
||||||
|
createNetwork()
|
||||||
|
{
|
||||||
|
|
||||||
|
//create the layers of the network
|
||||||
|
if (this.numHiddenLayers > 0)
|
||||||
|
{
|
||||||
|
//create first hidden layer
|
||||||
|
var firstHiddenLayer = new NeuronLayer(this.numNeuronsPerHiddenLayer, this.numInputs);
|
||||||
|
this.neuronLayers.push(firstHiddenLayer);
|
||||||
|
|
||||||
|
for (var i=0; i<this.numHiddenLayers-1; ++i)
|
||||||
|
{
|
||||||
|
var newHiddenLayer = new NeuronLayer(this.numNeuronsPerHiddenLayer, this.numNeuronsPerHiddenLayer);
|
||||||
|
this.neuronLayers.push(newHiddenLayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
//create output layer
|
||||||
|
var outputLayer = new NeuronLayer(this.numOutputs, this.numNeuronsPerHiddenLayer);
|
||||||
|
this.neuronLayers.push(outputLayer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//create output layer
|
||||||
|
var outputLayer = new NeuronLayer(this.numOutputs, this.numInputs);
|
||||||
|
this.neuronLayers.push(outputLayer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
update(inputs)
|
||||||
|
{
|
||||||
|
|
||||||
|
var outputs = [];
|
||||||
|
|
||||||
|
var cWeight = 0;
|
||||||
|
|
||||||
|
// If the number of inputs supplied is incorrect...
|
||||||
|
if (inputs.length!=this.numInputs)
|
||||||
|
{
|
||||||
|
return outputs; // Return empty outputs
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop through all layers
|
||||||
|
var inputLayer = true;
|
||||||
|
for (var i=0; i < this.numHiddenLayers + 1; ++i)
|
||||||
|
{
|
||||||
|
var neuronLayer = this.neuronLayers[i];
|
||||||
|
|
||||||
|
if (!inputLayer)
|
||||||
|
{
|
||||||
|
inputs = [];
|
||||||
|
inputs = inputs.concat(outputs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inputLayer = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
outputs = [];
|
||||||
|
|
||||||
|
cWeight = 0;
|
||||||
|
|
||||||
|
// For each neuron sum the (inputs * corresponding weights).
|
||||||
|
// Throw the total at our sigmoid function to get the output.
|
||||||
|
for (var j=0; j < neuronLayer.neurons.length; ++j)
|
||||||
|
{
|
||||||
|
var neuron = neuronLayer.neurons[j];
|
||||||
|
|
||||||
|
var totalInput = 0;
|
||||||
|
|
||||||
|
// For each weight...
|
||||||
|
for (var k=0; k < neuron.numInputs ; ++k) // -1 ???
|
||||||
|
{
|
||||||
|
// Multiply it with the input.
|
||||||
|
totalInput += neuron.weights[k] *
|
||||||
|
inputs[cWeight];
|
||||||
|
console.log("cweight "+cWeight);
|
||||||
|
console.log("neuron weight "+neuron.weights[k]);
|
||||||
|
console.log("input: "+inputs[cWeight]);
|
||||||
|
console.log("total input "+totalInput);
|
||||||
|
|
||||||
|
|
||||||
|
cWeight++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add in the bias (final weight)
|
||||||
|
// totalInput += neuron.weights[neuron.weights.length-1] * this.bias;
|
||||||
|
|
||||||
|
// We can store the outputs from each layer as we generate them.
|
||||||
|
// The combined activation is first filtered through the sigmoid function
|
||||||
|
outputs.push(this.sigmoid(totalInput, this.activationResponse));
|
||||||
|
|
||||||
|
cWeight = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return outputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
sigmoid(totalInput, activationResponse)
|
||||||
|
{
|
||||||
|
return ( 1 / ( 1 + Math.exp(-totalInput / activationResponse)));
|
||||||
|
}
|
||||||
|
|
||||||
|
getWeights()
|
||||||
|
{
|
||||||
|
var weights = [];
|
||||||
|
|
||||||
|
//for each layer
|
||||||
|
for (var i=0; i<this.numHiddenLayers + 1; ++i)
|
||||||
|
{
|
||||||
|
|
||||||
|
//for each neuron
|
||||||
|
for (var j=0; j<this.neuronLayers[i].neurons.length; ++j)
|
||||||
|
{
|
||||||
|
//for each weight
|
||||||
|
for (var k=0; k<this.neuronLayers[i].neurons[j].numInputs; ++k)
|
||||||
|
{
|
||||||
|
weights.push(this.neuronLayers[i].neurons[j].weights[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return weights;
|
||||||
|
}
|
||||||
|
|
||||||
|
setWeights(weights)
|
||||||
|
{
|
||||||
|
var cWeight = 0;
|
||||||
|
|
||||||
|
//for each layer
|
||||||
|
for (var i=0; i<this.numHiddenLayers + 1; ++i)
|
||||||
|
{
|
||||||
|
|
||||||
|
//for each neuron
|
||||||
|
for (var j=0; j<this.neuronLayers[i].neurons.length; ++j)
|
||||||
|
{
|
||||||
|
//for each weight
|
||||||
|
for (var k=0; k<this.neuronLayers[i].neurons[j].numInputs; ++k)
|
||||||
|
{
|
||||||
|
this.neuronLayers[i].neurons[j].weights[k] = weights[cWeight++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
class Neuron
|
||||||
|
{
|
||||||
|
constructor(numInputs)
|
||||||
|
{
|
||||||
|
this.weights = [];
|
||||||
|
this.numInputs = numInputs;
|
||||||
|
|
||||||
|
for (var i=0; i<numInputs+1; ++i)
|
||||||
|
{
|
||||||
|
var newWeight = -1 + (Math.random()*2);
|
||||||
|
//var newWeight = 1;
|
||||||
|
this.weights.push(newWeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
class NeuronLayer
|
||||||
|
{
|
||||||
|
constructor(numNeuronsPerHiddenLayer, numInputs)
|
||||||
|
{
|
||||||
|
this.neurons = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < numNeuronsPerHiddenLayer; ++i)
|
||||||
|
{
|
||||||
|
var newNeuron = new Neuron(numInputs);
|
||||||
|
|
||||||
|
this.neurons.push(newNeuron);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,225 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script src="NeuralNetwork.js"></script>
|
||||||
|
<script src="Neuron.js"></script>
|
||||||
|
<script src="NeuronLayer.js"></script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body{
|
||||||
|
padding:0;
|
||||||
|
margin:0;
|
||||||
|
overflow:hidden;
|
||||||
|
font-family:Helvetica;
|
||||||
|
font-size:10px;
|
||||||
|
}
|
||||||
|
input{
|
||||||
|
padding:0;
|
||||||
|
}
|
||||||
|
p{
|
||||||
|
padding:0;
|
||||||
|
margin:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#input{
|
||||||
|
position:absolute;
|
||||||
|
top:100px;
|
||||||
|
left:10px;
|
||||||
|
}
|
||||||
|
#first_layer{
|
||||||
|
position:absolute;
|
||||||
|
top: 100px;
|
||||||
|
left: 200px;
|
||||||
|
}
|
||||||
|
#second_layer{
|
||||||
|
position:absolute;
|
||||||
|
top: 100px;
|
||||||
|
left: 400px;
|
||||||
|
}
|
||||||
|
#output{
|
||||||
|
position:absolute;
|
||||||
|
top: 100px;
|
||||||
|
left: 600px;
|
||||||
|
}
|
||||||
|
#network_container{
|
||||||
|
position:absolute;
|
||||||
|
top: 100px;
|
||||||
|
left: 600px;
|
||||||
|
margin-left:-400px;
|
||||||
|
margin-top:-250px;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<canvas id="myCanvas" width="100%" height="100%"></canvas>
|
||||||
|
<div id="network_container">
|
||||||
|
<div id="input">
|
||||||
|
|
||||||
|
|
||||||
|
<input type="range" min="0" max="100" value="1" class="i0" id="i0">
|
||||||
|
<p id="i0_output"></p>
|
||||||
|
<input type="range" min="0" max="100" value="10" class="i1" id="i1">
|
||||||
|
<p id="i1_output"></p>
|
||||||
|
</div>
|
||||||
|
<div id = "first_layer">
|
||||||
|
<input type="range" min="-400" max="400" value="10" class="w0" id="w0">
|
||||||
|
<p id="w0_output"></p>
|
||||||
|
<input type="range" min="-400" max="400" value="10" class="w1" id="w1">
|
||||||
|
<p id="w1_output"></p><br><br>
|
||||||
|
<input type="range" min="-400" max="400" value="10" class="w2" id="w2">
|
||||||
|
<p id="w2_output"></p>
|
||||||
|
<input type="range" min="-400" max="400" value="10" class="w3" id="w3">
|
||||||
|
<p id="w3_output"></p><br><br>
|
||||||
|
<input type="range" min="-400" max="400" value="10" class="w4" id="w4">
|
||||||
|
<p id="w4_output"></p>
|
||||||
|
<input type="range" min="-400" max="400" value="10" class="w5" id="w5">
|
||||||
|
<p id="w5_output"></p>
|
||||||
|
</div>
|
||||||
|
<div id = "second_layer">
|
||||||
|
<input type="range" min="-400" max="400" value="10" class="w6" id="w6">
|
||||||
|
<p id="w6_output"></p>
|
||||||
|
<input type="range" min="-400" max="400" value="10" class="w7" id="w7">
|
||||||
|
<p id="w7_output"></p>
|
||||||
|
<input type="range" min="-400" max="400" value="10" class="w8" id="w8">
|
||||||
|
<p id="w8_output"></p><br><br>
|
||||||
|
<input type="range" min="-400" max="400" value="10" class="w9" id="w9">
|
||||||
|
<p id="w9_output"></p>
|
||||||
|
<input type="range" min="-400" max="400" value="10" class="w10" id="w10">
|
||||||
|
<p id="w10_output"></p>
|
||||||
|
<input type="range" min="-400" max="400" value="10" class="w11" id="w11">
|
||||||
|
<p id="w11_output"></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="output">
|
||||||
|
<input id="clickMe" type="button" value="update network" onclick="update();" />
|
||||||
|
<input id="random" type="button" value="random network" onclick="random();" />
|
||||||
|
|
||||||
|
<p id="network_output"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
var numInputs = 2;
|
||||||
|
var numOutputs = 2;
|
||||||
|
var numHiddenLayers = 1;
|
||||||
|
var numNeuronsPerHiddenLayer = 3;
|
||||||
|
|
||||||
|
var slider = [];
|
||||||
|
var output = [];
|
||||||
|
|
||||||
|
var neuralNetwork = new NeuralNetwork(numInputs, numOutputs, numHiddenLayers, numNeuronsPerHiddenLayer);
|
||||||
|
|
||||||
|
|
||||||
|
var input0 = document.getElementById("i0")
|
||||||
|
var input_display0 = document.getElementById("i0_output")
|
||||||
|
input_display0.innerHTML = input0.value/100;
|
||||||
|
input0.oninput = function() {
|
||||||
|
input_display0.innerHTML = this.value/100;
|
||||||
|
}
|
||||||
|
var input1 = document.getElementById("i1")
|
||||||
|
var input_display1 = document.getElementById("i1_output")
|
||||||
|
input_display1.innerHTML = input1.value/100;
|
||||||
|
input1.oninput = function() {
|
||||||
|
input_display1.innerHTML = this.value/100;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//slider
|
||||||
|
for (var i = 0; i<12; i++){
|
||||||
|
slider.push(document.getElementById("w"+i));
|
||||||
|
output.push(document.getElementById("w"+i+"_output"));
|
||||||
|
output[i].innerHTML = slider[i].value/100;
|
||||||
|
slider[i].oninput = function() {
|
||||||
|
output[slider.indexOf(this)].innerHTML = this.value/100;
|
||||||
|
|
||||||
|
updateCanvas()
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('mousemove', function(e) {
|
||||||
|
console.log("move")
|
||||||
|
var x = e.clientX / window.innerWidth;
|
||||||
|
var y = e.clientY / window.innerHeight;
|
||||||
|
input0.value=x*100;
|
||||||
|
input1.value=y*100;
|
||||||
|
input_display0.innerHTML = x;
|
||||||
|
input_display1.innerHTML = y;
|
||||||
|
update([x,y])
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
//CANVAS STUFF
|
||||||
|
var c = document.getElementById("myCanvas");
|
||||||
|
var ctx = c.getContext("2d");
|
||||||
|
ctx.canvas.width = window.innerWidth;
|
||||||
|
ctx.canvas.height = window.innerHeight;
|
||||||
|
var stepsize = 50;
|
||||||
|
for(var x = 0; x < window.innerWidth; x = x+stepsize){
|
||||||
|
for(var y = 0; y < window.innerHeight; y = y+stepsize){
|
||||||
|
var outputs = neuralNetwork.update([x/window.innerWidth,y/window.innerHeight]);
|
||||||
|
ctx.fillStyle = 'hsl(' + 360 * outputs[0] + ', 50%,'+outputs[1]*100 +'%)';
|
||||||
|
//ctx.fillStyle= "rgb(255,20,255);"
|
||||||
|
console.log(outputs[1]*255)
|
||||||
|
ctx.fillRect(x,y,stepsize,stepsize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function updateCanvas(){
|
||||||
|
|
||||||
|
var stepsize = 50;
|
||||||
|
for(var x = 0; x < window.innerWidth; x = x+stepsize){
|
||||||
|
for(var y = 0; y < window.innerHeight; y = y+stepsize){
|
||||||
|
var outputs = neuralNetwork.update([x/window.innerWidth,y/window.innerHeight]);
|
||||||
|
ctx.fillStyle = 'hsl(' + 360 * outputs[0] + ', 90%,'+outputs[1]*100+'%)';
|
||||||
|
//ctx.fillStyle= "rgb(255,20,255);"
|
||||||
|
console.log(outputs[1]*255)
|
||||||
|
ctx.fillRect(x,y,stepsize,stepsize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function update(inputs){
|
||||||
|
|
||||||
|
|
||||||
|
var weights = neuralNetwork.getWeights();
|
||||||
|
var newWeights = [];
|
||||||
|
for (var i=0; i < weights.length; i++) {
|
||||||
|
newWeights.push(slider[i].value/100);
|
||||||
|
//newWeights.push(1);
|
||||||
|
}
|
||||||
|
neuralNetwork.setWeights(newWeights);
|
||||||
|
|
||||||
|
|
||||||
|
//var inputs = [input0.value/100, input1.value/100];
|
||||||
|
var outputs = neuralNetwork.update(inputs);
|
||||||
|
// console.log(neuralNetwork.getWeights());
|
||||||
|
var output_display = document.getElementById("network_output")
|
||||||
|
output_display.innerHTML = "<br> "+outputs[0] + "<br><br> "+outputs [1];
|
||||||
|
|
||||||
|
document.getElementById('network_container').style.left=outputs[0]*window.innerWidth;
|
||||||
|
document.getElementById('network_container').style.top=outputs[1]*window.innerHeight;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
random()
|
||||||
|
function random(inputs){
|
||||||
|
|
||||||
|
for (var i = 0; i<slider.length; i++){
|
||||||
|
|
||||||
|
slider[i].value = Math.random()*800-400;
|
||||||
|
output[slider.indexOf(slider[i])].innerHTML = slider[i].value/100;
|
||||||
|
}
|
||||||
|
updateCanvas();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,198 @@
|
|||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>neural network art</title>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=320, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="description" content="ōtoro.net">
|
||||||
|
<meta name="author" content="hardmaru">
|
||||||
|
|
||||||
|
|
||||||
|
<!-- extra styles -->
|
||||||
|
<style>
|
||||||
|
head {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
padding: 10px;
|
||||||
|
font-family: Courier, "Helvetica Neue",Helvetica,Arial,sans-serif;
|
||||||
|
font-weight: 100;
|
||||||
|
font-size: 0.6em;
|
||||||
|
}
|
||||||
|
textarea {
|
||||||
|
padding: 5;
|
||||||
|
font-family: Courier, "Helvetica Neue",Helvetica,Arial,sans-serif;
|
||||||
|
font-weight: 100;
|
||||||
|
font-size: 0.5em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="p5Container">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- jQuery -->
|
||||||
|
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
|
||||||
|
|
||||||
|
<script src="lib/p5.min.js"></script>
|
||||||
|
|
||||||
|
<script src="lib/recurrent.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// neural network random art generator
|
||||||
|
|
||||||
|
// settings
|
||||||
|
|
||||||
|
// actual size of generated image
|
||||||
|
var sizeh = 300;
|
||||||
|
var sizew = 300;
|
||||||
|
var sizeImage = sizeh*sizew;
|
||||||
|
|
||||||
|
var nH, nW, nImage;
|
||||||
|
var mask;
|
||||||
|
|
||||||
|
// settings of nnet:
|
||||||
|
var networkSize = 8;
|
||||||
|
var nHidden = 10;
|
||||||
|
var nOut = 3; // r, g, b layers
|
||||||
|
|
||||||
|
// support variables:
|
||||||
|
var img;
|
||||||
|
var img2;
|
||||||
|
var G = new R.Graph(false);
|
||||||
|
|
||||||
|
var initModel = function() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var model = [];
|
||||||
|
var i;
|
||||||
|
|
||||||
|
var randomSize = 1.0;
|
||||||
|
|
||||||
|
// define the model below:
|
||||||
|
model.w_in = R.RandMat(networkSize, 3, 0, randomSize); // x, y, and bias
|
||||||
|
|
||||||
|
// model['w_0'] = R.RandMat(networkSize, networkSize, 0, randomSize);
|
||||||
|
|
||||||
|
for (i = 0; i < nHidden; i++) {
|
||||||
|
model['w_'+i] = R.RandMat(networkSize, networkSize, 0, randomSize);
|
||||||
|
}
|
||||||
|
model.w_out = R.RandMat(nOut, networkSize, 0, randomSize); // output layer
|
||||||
|
|
||||||
|
console.log(model)
|
||||||
|
|
||||||
|
return model;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var forwardNetwork = function(G, model, x_, y_) {
|
||||||
|
// x_, y_ is a normal javascript float, will be converted to a mat object below
|
||||||
|
// G is a graph to amend ops to
|
||||||
|
var x = new R.Mat(3, 1); // input
|
||||||
|
var i;
|
||||||
|
x.set(0, 0, x_);
|
||||||
|
x.set(1, 0, y_);
|
||||||
|
x.set(2, 0, 1.0); // bias.
|
||||||
|
var out;
|
||||||
|
out = G.tanh(G.mul(model.w_in, x));
|
||||||
|
for (i = 0; i < nHidden; i++) {
|
||||||
|
out = G.tanh(G.mul(model['w_'+i], out));
|
||||||
|
}
|
||||||
|
out = G.sigmoid(G.mul(model.w_out, out));
|
||||||
|
console.log(out)
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
|
||||||
|
function getColorAt(model, x, y) {
|
||||||
|
// function that returns a color given coordintes (x, y)
|
||||||
|
// (x, y) are scaled to -0.5 -> 0.5 for image recognition later
|
||||||
|
// but it can be behond the +/- 0.5 for generation above and beyond
|
||||||
|
// recognition limits
|
||||||
|
var r, g, b;
|
||||||
|
var out = forwardNetwork(G, model, x, y);
|
||||||
|
|
||||||
|
r = out.w[0]*255.0;
|
||||||
|
g = out.w[1]*255.0;
|
||||||
|
b = out.w[2]*255.0;
|
||||||
|
|
||||||
|
return color(r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
function genImage(img, model) {
|
||||||
|
var i, j, m, n;
|
||||||
|
img.loadPixels();
|
||||||
|
for (i = 0, m=img.width; i < m; i++) {
|
||||||
|
for (j = 0, n=img.height; j < n; j++) {
|
||||||
|
img.set(i, j, getColorAt(model, i/sizeh-0.5,j/sizew-0.5));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
img.updatePixels();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setup() {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
var myCanvas;
|
||||||
|
|
||||||
|
myCanvas = createCanvas(windowWidth,windowHeight);
|
||||||
|
|
||||||
|
myCanvas.parent('p5Container');
|
||||||
|
|
||||||
|
nW = Math.max(Math.floor(windowWidth/sizew), 1);
|
||||||
|
nH = Math.max(Math.floor(windowHeight/sizeh), 1);
|
||||||
|
nImage = nH*nW;
|
||||||
|
mask = R.zeros(nImage);
|
||||||
|
|
||||||
|
//img.resize(320*1.0, 320*1.0);
|
||||||
|
//img.save('genart.png','png');
|
||||||
|
//noLoop();
|
||||||
|
img = createImage(sizeh, sizew);
|
||||||
|
|
||||||
|
frameRate(30);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRandomLocation() {
|
||||||
|
var i, result=0, r;
|
||||||
|
for (i=0;i<nImage;i++) {
|
||||||
|
result += mask[i];
|
||||||
|
}
|
||||||
|
if (result === nImage) {
|
||||||
|
mask = R.zeros(nImage);
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
r = R.randi(0, nImage);
|
||||||
|
} while (mask[r] !== 0);
|
||||||
|
mask[r] = 1;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
function displayImage(n) {
|
||||||
|
var row = Math.floor(n/nW);
|
||||||
|
var col = n % nW;
|
||||||
|
image(img, col*sizew, row*sizeh);
|
||||||
|
}
|
||||||
|
|
||||||
|
function draw() {
|
||||||
|
|
||||||
|
model = initModel();
|
||||||
|
genImage(img, model);
|
||||||
|
displayImage(getRandomLocation());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue