В настоящее время я пытаюсь реализовать слой свопаута в кератах (как в: http://papers.nips.cc/paper/6205-swapout-learning-an-ensemble-of-deep-architectures.pdf). Если я правильно понял концепцию, то, например, просто получается вывод нормального плотного слоя. Таким образом, случайным образом выбирается междувыдача 0, x, F (x) и x + F (x), где x - это ввод, а F (x) - нормальный вывод, который будет производить слой.
Поэтому я попытался использовать плотныйслой в качестве основы и просто отредактируйте метод call следующим образом (все остальное точно так же, как в плотном слое):
def call(self, inputs):
output = K.dot(inputs, self.kernel)
if self.use_bias:
output = K.bias_add(output, self.bias, data_format='channels_last')
#--------- edited -----------
theta1 = np.random.randint(2, size=(1, 256))
theta2 = np.random.randint(2, size=(1, 256))
theta1 = theta1.astype(np.float32)
theta2 = theta2.astype(np.float32)
output = tf.add(tf.multiply(theta1, inputs), tf.multiply(theta2, output))
# -----------------------------------
if self.activation is not None:
output = self.activation(output)
return output
Так что я просто вычисляю результат, как в статье Y = Theta1* input + Theta2 * output, где * - поэлементное умножение. Форма вывода остается такой же, как и без этого вычисления, но когда я пытаюсь запустить его в следующей модели:
import tensorflow as tf
from keras.models import Sequential
from keras.layers import Dense, Flatten
from swapout import Swapout
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
model = Sequential()
model.add(Flatten(input_shape = (28,28)))
model.add(Swapout(256, activation='relu'))
model.add(Dense(10, activation='softmax'))
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.fit(x_train, y_train, epochs=5)
res = model.evaluate(x_test, y_test, verbose=2)
Хотя я получаю следующую ошибку:
2019-12-21 22:59:31.924209: W tensorflow/core/common_runtime/base_collective_executor.cc:216] BaseCollectiveExecutor::StartAbort Invalid argument: Incompatible shapes: [32,784] vs. [1,256]
[[{{node swapout_1/Mul}}]]
Traceback (most recent call last):
File "/home/andreas/studium/semester9/vertiefungs/neural.py", line 294, in <module>
runSingleMnistExperimant()
File "/home/andreas/studium/semester9/vertiefungs/neural.py", line 220, in runSingleMnistExperimant
model.fit(x_train, y_train, epochs=5)
File "/home/andreas/studium/my_tensorflow/venv/lib/python3.6/site-packages/keras/engine/training.py", line 1239, in fit
validation_freq=validation_freq)
File "/home/andreas/studium/my_tensorflow/venv/lib/python3.6/site-packages/keras/engine/training_arrays.py", line 196, in fit_loop
outs = fit_function(ins_batch)
File "/home/andreas/studium/my_tensorflow/venv/lib/python3.6/site-packages/tensorflow_core/python/keras/backend.py", line 3740, in __call__
outputs = self._graph_fn(*converted_inputs)
File "/home/andreas/studium/my_tensorflow/venv/lib/python3.6/site-packages/tensorflow_core/python/eager/function.py", line 1081, in __call__
return self._call_impl(args, kwargs)
File "/home/andreas/studium/my_tensorflow/venv/lib/python3.6/site-packages/tensorflow_core/python/eager/function.py", line 1121, in _call_impl
return self._call_flat(args, self.captured_inputs, cancellation_manager)
File "/home/andreas/studium/my_tensorflow/venv/lib/python3.6/site-packages/tensorflow_core/python/eager/function.py", line 1224, in _call_flat
ctx, args, cancellation_manager=cancellation_manager)
File "/home/andreas/studium/my_tensorflow/venv/lib/python3.6/site-packages/tensorflow_core/python/eager/function.py", line 511, in call
ctx=ctx)
File "/home/andreas/studium/my_tensorflow/venv/lib/python3.6/site-packages/tensorflow_core/python/eager/execute.py", line 67, in quick_execute
six.raise_from(core._status_to_exception(e.code, message), None)
File "<string>", line 3, in raise_from
tensorflow.python.framework.errors_impl.InvalidArgumentError: Incompatible shapes: [32,784] vs. [1,256]
[[node swapout_1/Mul (defined at /my_tensorflow/venv/lib/python3.6/site-packages/tensorflow_core/python/framework/ops.py:1751) ]] [Op:__inference_keras_scratch_graph_761]
Function call stack:
keras_scratch_graph
Что я делаю неправильно в вычислениях? И есть ли лучший / более простой способ получить слой свопаута? Я очень новичок в Keras и tenorflow;)
Большое спасибо за помощь!
Обновление: Я только что решил проблему. Проблема заключалась в форме входных данных (None, 784). Конечно, это не может быть умножено поэлементно на вектор (1, 256). Также мне пришлось умножить одно из полученных слагаемых в сложении на матрицу, которая приводит их к одной и той же форме ... Я выбрал заполнение нулями.
Вот решение:
def call(self, inputs):
output = K.dot(inputs, self.kernel)
if self.use_bias:
output = K.bias_add(output, self.bias, data_format='channels_last')
inputLength = K.int_shape(inputs)[-1]
outputLength = K.int_shape(output)[-1]
theta1 = np.random.randint(2, size=(1,inputLength))
theta2 = np.random.randint(2, size=(1,outputLength))
theta1 = theta1.astype(np.float32)
theta2 = theta2.astype(np.float32)
zeroPadding = getZeroPaddingMatrix(inputLength, outputLength)
output = tf.add(tf.matmul(tf.multiply(theta1, inputs), zeroPadding), tf.multiply(theta2, output))
if self.activation is not None:
output = s
return output
Матрица заполнения нулями вычисляется следующим образом:
def getZeroPaddingMatrix(inputLength, outputLength):
zeroPadding = np.identity(inputLength)
if(outputLength > inputLength):
zeros = np.zeros((inputLength, outputLength-inputLength))
zeroPadding = np.concatenate((zeroPadding, zeros), axis=1)
elif(outputLength < inputLength):
zeroPadding = zeroPadding[:,(inputLength-outputLength) :]
return zeroPadding.astype(np.float32)
Осталось только добавить параметры для изменения theta1 и theta2.