When you read the Keras code, you will come across various matrix operations. It is very difficult to read without knowing the contents of these operations. This time, I will share the code that I read, because I confirmed the matrix operations that often appear in Keras based on actual examples.
Even though Keras, the environment I confirmed this time is an old version of the era when it was a part of tensorflow. However, I don't think matrix operations are much different than they are now.
The source code of this article assumes the following imports. Please copy and paste it if you want it to work.
import numpy as np
import warnings
import os
warnings.simplefilter('ignore')
import tensorflow as tf
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.layers import Dense, Input, Dropout, BatchNormalization
The confirmation method is as follows, assuming that the processing in Keras can be imagined.
Create a Keras model to perform operations
Confirm the calculation contents by giving input to the predict method of the model and outputting the result.
concat Concatenate the list of tensors along the specified axis.
input1 = Input(shape=(2,))
input2 = Input(shape=(2,))
output = tf.concat(axis=1, values=[input1, input2])
model = Model(inputs=[input1, input2], outputs=[output])
print(model.summary())
print(model.predict(x=[np.array([[10, 20], [20, 30]]), np.array([[20, 5], [30, 2]])]))
[[10. 20. 20. 5.]
[20. 30. 30. 2.]]
stack Stack the list of rank R tensors into rank R + 1 tensors. The big difference from concat is that it is not connected as it is, but it is connected after adding one axis, and it is possible to retrieve the information before connection even after connection.
# stack
input1 = Input(shape=(2,))
input2 = Input(shape=(2,))
output = tf.stack(axis=1, values=[input1, input2])
model = Model(inputs=[input1, input2], outputs=[output])
print(model.summary())
print(model.predict(x=[np.array([[10, 20], [20, 30]]), np.array([[20, 5], [30, 2]])]))
[[[10. 20.]
[20. 5.]]
[[20. 30.]
[30. 2.]]]
expand_dims Add a dimension of size 1 with the subscript "axis".
input1 = Input(shape=(1,))
output = tf.expand_dims(input1, axis=1)
model = Model(inputs=[input1], outputs=[output])
print(model.summary())
print(model.predict(x=[np.array([[10], [20], [30]])]))
[[[10.]]
[[20.]]
[[30.]]]
squeeze The opposite of expand_dims, excluding one dimension with the subscript "axis" from the tensor.
input1 = Input(shape=(1,1,))
output = tf.squeeze(input1, axis=1)
model = Model(inputs=[input1], outputs=[output])
print(model.summary())
print(model.predict(x=[np.array([[[10]], [[20]], [[30]]])]))
[[10.]
[20.]
[30.]]
reduce_max Calculate the maximum value of an element across the dimensions of the tensor.
The following is a 3x2 matrix calculated in 0, 1 and 2 dimensions. It is interesting that in 0 dimension, the result is broadcast as it is, in 1 dimension, the result is exactly the same, and in 2 dimension, the order is reduced.
input1 = Input(shape=(1,2))
output = tf.reduce_max(input1, axis=0)
model = Model(inputs=[input1], outputs=[output])
print(model.summary())
print(model.predict(x=[np.array([[[10, 20]], [[20, 5]], [[30, 4]]])]))
input1 = Input(shape=(1,2))
output = tf.reduce_max(input1, axis=1)
model = Model(inputs=[input1], outputs=[output])
print(model.summary())
print(model.predict(x=[np.array([[[10, 20]], [[20, 5]], [[30, 4]]])]))
input1 = Input(shape=(1,2))
output = tf.reduce_max(input1, axis=2)
model = Model(inputs=[input1], outputs=[output])
print(model.summary())
print(model.predict(x=[np.array([[[10, 20]], [[20, 5]], [[30, 4]]])]))
[[30. 20.]
[30. 20.]
[30. 20.]]
[[10. 20.]
[20. 5.]
[30. 4.]]
[[20.]
[20.]
[30.]]
reduce_sum Calculate the sum of the elements of the entire dimension of the tensor. Similarly, I tried to calculate the source in 0 dimension, 1 dimension, and 2 dimensions for a 3x2 matrix. The idea is the same as reduce_max.
input1 = Input(shape=(1,2))
output = tf.reduce_sum(input1, axis=0)
model = Model(inputs=[input1], outputs=[output])
print(model.summary())
print(model.predict(x=[np.array([[[10, 20]], [[20, 5]], [[30, 4]]])]))
input1 = Input(shape=(1,2))
output = tf.reduce_sum(input1, axis=1)
model = Model(inputs=[input1], outputs=[output])
print(model.summary())
print(model.predict(x=[np.array([[[10, 20]], [[20, 5]], [[30, 4]]])]))
input1 = Input(shape=(1,2))
output = tf.reduce_sum(input1, axis=2)
model = Model(inputs=[input1], outputs=[output])
print(model.summary())
print(model.predict(x=[np.array([[[10, 20]], [[20, 5]], [[30, 4]]])]))
[[60. 29.]
[60. 29.]
[60. 29.]]
[[10. 20.]
[20. 5.]
[30. 4.]]
[[30.]
[25.]
[34.]]
matmul Abbreviation for "Multiplies matrix", multiplying matrix a by matrix b to generate a * b. It is often used for fully connected layers.
The following is an example in which a 1x1 matrix is generated as a result of calculating the 1x2 and 2x1 matrices.
input1 = Input(shape=(2,))
input2 = Input(shape=(2,1))
output = tf.matmul(input1, input2)
model = Model(inputs=[input1, input2], outputs=[output])
print(model.summary())
print(model.predict(x=[np.array([[10, 20]]), np.array([[[1], [2]]])]))
[[[50.]]]
slice For the tensor, specify the start position and extraction size, and extract a part of the tensor.
input1 = Input(shape=(4,))
input1_reshape = tf.reshape(input1, [4])
input2 = Input(shape=(1), dtype=tf.int32)
input2_reshape = tf.reshape(input2, [1])
input3 = Input(shape=(1), dtype=tf.int32)
input3_reshape = tf.reshape(input3, [1])
output = tf.slice(input1_reshape, input2_reshape, input3_reshape)
model = Model(inputs=[input1, input2, input3], outputs=[output])
print(model.summary())
print(model.predict(x=[np.array([[1, 8, 3, 4]]), np.array([[1]]), np.array([[1]])]))
[8.]
gather Specify the index for the tensor and get the element of the index.
For the list [1,8,3,4], a matrix with the 0th and 3rd items taken out and the 1st and 2nd items taken out is returned. If the input shape is not fixed, an error will occur, so reshape is forcibly performed.
input1 = Input(shape=(4,))
input1_reshape = tf.reshape(input1, [4])
input2 = Input(shape=(2,2), dtype=tf.int32)
output = tf.gather(input1_reshape, input2)
model = Model(inputs=[input1, input2], outputs=[output])
print(model.summary())
print(model.predict(x=[np.array([[1, 8, 3, 4]]), np.array([[[0, 3],[1, 2]]])]))
[[[1. 4.]
[8. 3.]]]
――This time, only some operations are posted, but I hope that your reading comprehension will have improved a little. ――Even if you give it to the input of the Keras model and let it calculate, it was not easy due to an error such as the number of dimensions of the matrix does not match, but it was quite difficult, but it was very useful for understanding the matrix. --In particular, it is important to match the value of the input shape argument with the shape of the matrix given to predcit. ――This sample is also the minimum code for creating and predicting Models that take multiple inputs in Keras, so I think it will be useful when creating complex models in the future.
Recommended Posts