Hello everybody
A while ago try to make a neural network with PHP, I tried to verify what I was doing. However, it is slow and the system is not very good because there is no such thing as a sophisticated calculation method that has been verified and practiced in various places at present. So, this time, I will try Imadoki's machine learning mechanism using a framework called Keras.
Keras
Keras is a neural network library that runs on TensorFlow and is written in Python. From the feeling of using it, I thought that I could write a network by intuition. When I wrote TensorFlow raw, it was troublesome to set various parameters, but That area has also become easier to do.
Keras on Docker
Oh, there is, after all, the image with Keras https://hub.docker.com/r/gw000/keras/
Now you can try Keras without polluting your environment.
The problem setting is the donut type classification problem that I did before.
{f(x, y) = \left\{
\begin{array}{1}
1, (1 < x^2 + y^2 < 4)\\
0, ( \rm{otherwise} )
\end{array}
\right.
}
Now that you've decided what you want to do, let's start implementing
First, make it from the learning mechanism.
learn.py
from keras.models import Sequential
from keras.layers import Dense, Activation
import numpy as np
import random
import math
def double_circle():
x = random.uniform(-2, 2)
y = random.uniform(-2, 2)
sample = (x,y)
norm = math.sqrt(x * x + y * y)
if norm > 1 and norm < 2:
label = 1
else:
label = 0
return (sample, label)
# Model Definition
model = Sequential()
model.add(Dense(32, input_dim=2))
model.add(Dense(64, activation='relu'))
model.add(Dense(32, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy'])
data = []
labels = []
for num in range(1024):
(sample, label) = double_circle()
data.append(sample)
labels.append(label)
model.fit(np.array(data), np.array(labels), nb_epoch=100, batch_size=32)
model.save('/srv/model/double_circle')
The function double_circle
is used to pick random coordinates and return a label that determines if the point is inside a donut shape.
Then, add the coordinates and label pairs to the list.
Next, we will create a model, and Keras will form a model with the image of stacking each layer of the neural network.
model.add(Dense(32, input_dim=2))
model.add(Dense(64, activation='relu'))
For example, here we define the first and second layers.
Since the input dimension of the first layer is unknown, it is clearly stated. Since the coordinate point is the input this time, enter ʻinput_dim = 2. Since the first argument of the first layer is the output dimension, the second layer does not need an input dimension. In addition, ʻactivation ='relu'
is set in the activation function of the second layer (if there is no setting, it is output as it is).
You can stack layers as you like like this.
$ docker run --rm -v `pwd`:/srv/ gw000/keras python learn.py
Let's run Keras's Docker container and let it learn. It took about 5 seconds on my Mac. A model file has been created in the model directory.
Let's see how well the generated model works.
use.py
from keras.models import load_model
import numpy as np
model = load_model('/srv/ai/model/double_circle')
def check(x):
data = np.array([x])
pred = model.predict(np.array([x]))
#print pred
if pred > 0.5:
return 1
else:
return 0
for y in range(20):
labels = []
for x in range(20):
data = [(x-10.0)/5, (10.0-y)/5]
labels.append(check(data))
print labels
Keras just loads the model and it recreates the network you learned with learn. This script uses the loaded model to determine if the $ -2 <x <2 $, $ -2 <y <2 $ range is in the specified area in 0.1 increments. When you run this one, it looks like this.
$ docker run --rm -v `pwd`:/srv/ gw000/keras python use.py
[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0]
[0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0]
[0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0]
[0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0]
[0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1]
[0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1]
[0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0]
[0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0]
[0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0]
[0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0]
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]
The round shape has emerged, so I don't think it's going well.
Let's take a little more detail. Now let's take data points in 0.02 increments. This time I will try to spit out the coordinate points that are judged to be included in the area in CSV format
to_csv.py
from keras.models import load_model
import numpy as np
model = load_model('/srv/model/double_circle')
def check(x):
data = np.array([x])
pred = model.predict(np.array([x]))
#print pred
if pred > 0.5:
return 1
else:
return 0
for y in range(100):
for x in range(100):
data = [(x-50.0)/20, (50.0-y)/20]
if check(data) == 1:
print "%f,%f" % (data[0],data[1])
So, as usual, it will be processed by docker.
docker run --rm -v `pwd`:/srv/ gw000/keras python to_csv.py > result.csv
Let's plot the result.csv that came out. Well, it might be something like this
For the time being, to get started with Keras, I tried to realize the one I made with PHP before. It's easier to understand than TensorFlow when building networks and layers.
This time it is like this.