Click here for Keras lottery starting from nothing [http://qiita.com/Ishotihadus/items/6ecf5684c2cbaaa6a5ef)
Last time created a rough data set and trained it roughly.
The input is 5 dimensions and each element is greater than or equal to 0 and less than 1. The output is one-dimensional, -1 if the sum of the input elements is 2.5 or less, 1 if greater than 2.5. Do so-called "two-class classification".
The data set was created as follows. The output is 0 or 1 and then multiplied by 2 to -1 (it becomes -1 or 1).
data = np.random.rand(250,5)
labels = (np.sum(data, axis=1) > 2.5) * 2 - 1
The model was as follows. For the activation function, we used tanh, which has a range of -1 to 1, and for the loss, we used the hinge loss, which is good for the code.
model = Sequential([Dense(20, input_dim=5, activation='tanh'), Dense(1, activation='tanh')])
model.compile('adam', 'hinge', metrics=['accuracy'])
As mentioned in Part 1, the Sequential model simply puts arrows on each node of the current layer from all the nodes of the previous layer. It is an image that pulls. Sure, it still works as a neural network, but it's a bit uninteresting.
The Functional API solves this problem. You can do something quite complicated, such as putting in the output of two neural networks or sharing layers.
Let's create a neural network with the same shape as last time. Since it has the same shape, it seems meaningless to make it, but that is practice.
The Functional API is simply "you can mess up how you connect the arrows." In the Sequential model, it could only be done in the form of A → B → C. But with the Functional API
A ↘ C → D → E ↗ B
You will be able to do something like that. I won't do it this time.
First, the input layer.
from keras.layers import Input, Dense
from keras.models import Model
inputs = Input(shape=(5,))
This layer is named Input, but unfortunately there is no documentation.
shape
represents the dimension of the input.
The notation (5,)
feels like something you don't know about Python, but it's just a Tuple (like an array) with only the element 5. It looks like there are multiple elements because of the comma, but there is only one element. It's because it's indistinguishable from just a number without a comma, but I think it's really a shit notation. Python doesn't like this.
x = Dense(20, activation='tanh')(inputs)
A layer with 20 nodes and ʻinputs` inputs.
Dense means "dense", but I think it's dense in that sense because it pulls all the arrows from all the nodes in the previous layer to all the nodes in this layer.
predictions = Dense(1, activation='tanh')(x)
This is almost the same as the hidden layer. No explanation needed.
What does Functional mean?
If you look closely, you can see that Dense
is calling that instance as a function.
The documentation says that a function call to an instance of a layer will return a tensor.
In the first place, a neural network is roughly a tensor product (or a matrix product in a simpler way). Multiplying the input vector by a matrix, and then multiplying it by a matrix ... is the essence in the first place. Going through a single layer is roughly the same as running a single matrix. The image of multiplying the matrix (tensor) is compared with the function call.
When a function is called, the input tensor is transformed with the specified meaning and output as a tensor again. I think it's easy to understand if you capture it with that kind of image.
I'm not saying anything exactly, so that's it.
By the way, only the ʻInput` layer returns a tensor in the first place (so no function call is needed).
import numpy as np
from keras.layers import Input, Dense
from keras.models import Model
data = np.random.rand(250,5)
labels = (np.sum(data, axis=1) > 2.5) * 2 - 1
inputs = Input(shape=(5,))
x = Dense(20, activation='tanh')(inputs)
predictions = Dense(1, activation='tanh')(x)
model = Model(input=inputs, output=predictions)
model.compile('adam', 'hinge', metrics=['accuracy'])
model.fit(data, labels, nb_epoch=150, validation_split=0.2)
test = np.random.rand(200, 5)
predict = np.sign(model.predict(test).flatten())
real = (np.sum(test, axis=1) > 2.5) * 2 - 1
print(sum(predict == real) / 200.0)
Except for the writing method, it is exactly the same as Part 2, so I think that the accuracy will be almost the same.
Recommended Posts