@Rubix
Люблю кодить, разрабатываю проекты в разных сферах

Как исправить проблему Keras?

Есть самая простая модель Keras. Нужно выдать последнюю цифру из массива:
import numpy as np
import matplotlib.pyplot as plt
from tensorflow import keras
from tensorflow.keras.layers import Dense

c = np.array([
    [1, 1, 1],
    [1, 1, 0],
    [1, 0, 1],
    [1, 0, 0],
    [0, 1, 1],
    [0, 1, 0],
    [0, 0, 1],
    [0, 0, 0]
])
f = np.array([1, 0, 1, 0, 1, 0, 1, 0])

model = keras.Sequential()
model.add(Dense(units=1, activation='linear'))

model.compile(loss='mean_squared_error', optimizer=keras.optimizers.Adam(0.1))

history = model.fit(c, f, epochs=500, verbose=0)

print(model.predict([1, 0, 1]), model.get_weights())

plt.plot(history.history['loss'])
plt.grid(True)
plt.show()

...запускаю, но пишет ошибку:
Traceback (most recent call last):
  File "C:\Users\Rubix\*\*.py", line 28, in <module>
    print(model.predict([1, 1, 1]), model.get_weights())
  File "C:\Users\Rubix\AppData\Local\Programs\Python\Python37\lib\site-packages\
tensorflow\python\keras\engine\training.py", line 1692, in predict
    tmp_batch_outputs = self.predict_function(iterator)
  File "C:\Users\Rubix\AppData\Local\Programs\Python\Python37\lib\site-packages\
tensorflow\python\eager\def_function.py", line 867, in __call__
    result = self._call(*args, **kwds)
  File "C:\Users\Rubix\AppData\Local\Programs\Python\Python37\lib\site-packages\
tensorflow\python\eager\def_function.py", line 911, in _call
    self._initialize(args, kwds, add_initializers_to=initializers)
  File "C:\Users\Rubix\AppData\Local\Programs\Python\Python37\lib\site-packages\
tensorflow\python\eager\def_function.py", line 749, in _initialize
    *args, **kwds))
  File "C:\Users\Rubix\AppData\Local\Programs\Python\Python37\lib\site-packages\
tensorflow\python\eager\function.py", line 3045, in _get_concrete_function_inter
nal_garbage_collected
    graph_function, _ = self._maybe_define_function(args, kwargs)
  File "C:\Users\Rubix\AppData\Local\Programs\Python\Python37\lib\site-packages\
tensorflow\python\eager\function.py", line 3439, in _maybe_define_function
    graph_function = self._create_graph_function(args, kwargs)
  File "C:\Users\Rubix\AppData\Local\Programs\Python\Python37\lib\site-packages\
tensorflow\python\eager\function.py", line 3284, in _create_graph_function
    capture_by_value=self._capture_by_value),
  File "C:\Users\Rubix\AppData\Local\Programs\Python\Python37\lib\site-packages\
tensorflow\python\framework\func_graph.py", line 998, in func_graph_from_py_func

    func_outputs = python_func(*func_args, **func_kwargs)
  File "C:\Users\Rubix\AppData\Local\Programs\Python\Python37\lib\site-packages\
tensorflow\python\eager\def_function.py", line 657, in wrapped_fn
    out = weak_wrapped_fn().__wrapped__(*args, **kwds)
  File "C:\Users\Rubix\AppData\Local\Programs\Python\Python37\lib\site-packages\
tensorflow\python\framework\func_graph.py", line 985, in wrapper
    raise e.ag_error_metadata.to_exception(e)
ValueError: in user code:

    C:\Users\Rubix\AppData\Local\Programs\Python\Python37\lib\site-packages\tens
orflow\python\keras\engine\training.py:1537 predict_function  *
        return step_function(self, iterator)
    C:\Users\Rubix\AppData\Local\Programs\Python\Python37\lib\site-packages\tens
orflow\python\keras\engine\training.py:1527 step_function  **
        outputs = model.distribute_strategy.run(run_step, args=(data,))
    C:\Users\Rubix\AppData\Local\Programs\Python\Python37\lib\site-packages\tens
orflow\python\distribute\distribute_lib.py:1280 run
        return self._extended.call_for_each_replica(fn, args=args, kwargs=kwargs
)
    C:\Users\Rubix\AppData\Local\Programs\Python\Python37\lib\site-packages\tens
orflow\python\distribute\distribute_lib.py:2820 call_for_each_replica
        return self._call_for_each_replica(fn, args, kwargs)
    C:\Users\Rubix\AppData\Local\Programs\Python\Python37\lib\site-packages\tens
orflow\python\distribute\distribute_lib.py:3588 _call_for_each_replica
        return fn(*args, **kwargs)
    C:\Users\Rubix\AppData\Local\Programs\Python\Python37\lib\site-packages\tens
orflow\python\keras\engine\training.py:1520 run_step  **
        outputs = model.predict_step(data)
    C:\Users\Rubix\AppData\Local\Programs\Python\Python37\lib\site-packages\tens
orflow\python\keras\engine\training.py:1493 predict_step
        return self(x, training=False)
    C:\Users\Rubix\AppData\Local\Programs\Python\Python37\lib\site-packages\tens
orflow\python\keras\engine\base_layer.py:1013 __call__
        input_spec.assert_input_compatibility(self.input_spec, inputs, self.name
)
    C:\Users\Rubix\AppData\Local\Programs\Python\Python37\lib\site-packages\tens
orflow\python\keras\engine\input_spec.py:259 assert_input_compatibility
        ' but received input with shape ' + display_shape(x.shape))

    ValueError: Input 0 of layer sequential is incompatible with the layer: expe
cted axis -1 of input shape to have value 3 but received input with shape (None,
 1)


Process returned 1 (0x1)        execution time : 5.596 s

Как решить эту проблему?
  • Вопрос задан
  • 52 просмотра
Решения вопроса 1
@Rubix Автор вопроса
Люблю кодить, разрабатываю проекты в разных сферах
import numpy as np
import matplotlib.pyplot as plt
from tensorflow import keras
from tensorflow.keras.layers import Dense

c = np.array([
    [1, 1, 1],
    [1, 1, 0],
    [1, 0, 1],
    [1, 0, 0],
    [0, 1, 1],
    [0, 1, 0],
    [0, 0, 1],
    [0, 0, 0]
])
f = np.array([1, 0, 1, 0, 1, 0, 1, 0])

model = keras.Sequential()
model.add(Dense(units=1, activation='sigmoid'))

model.compile(loss='mean_squared_error', optimizer=keras.optimizers.Adam(0.1))

history = model.fit(c, f, epochs=500, verbose=0)

#      model.predict([1, 0, 1]) #было
print(model.predict([[1, 0, 1]])) #стало

print(model.get_weights())

plt.plot(history.history['loss'])
plt.grid(True)
plt.show()

Мы просто передаём не массив, а один массив с массивами данных, подобными при обучении (можно передать одну попытку, но главное - передать ее в массиве). То есть, керас может предсказать сразу несколько попыток и записать их в выходной массив, а потом уже им можно как-то манипулировать. То есть, если массив с данными при обучении содержит массивы из трёх элементов (один такой массив данных: [5, 21, 13], например), то после обучения, мы должны передавать массив с массивами из трёх элементов: model.predict([[a, b ,c], [a, b, c], [a, b, c]]); здесь на выходе мы получим массив с предсказаниями попыток, которые мы дали в predict: [d, d, d]; смотря от формы выхода, могут быть разные выходные данные. Если на выходе два нейрона: [[d, e], [d, e], [d, e]]; то будет выдаваться массив с массивами из двух элементов. Далее, если мы передаём не массив, а некое одно значение (при обучении мы использовали тоже одно значение): [5, 1, 16], то у нас на выходе выйдет тоже массив с предсказаниями: [d, d, d]. Опять же, тип выхода зависит от количества нейронов на выходе. Вывод: в predict нужно передавать массив из попыток, которые мы хотим предсказать, даже если она одна. А на выходе мы получим массив с предсказанным попытками.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
adugin
@adugin Куратор тега Python
1) Задать input shape. Сейчас вход сети неизвестен.
2) В принципе функции активации вам не нужны, т.к. вы получите просто одну матрицу, домножая на которую входную матрицу и получите искомое число. Более того, можно даже не обучать сеть, а вручную установить ей очевидные веса:

for i, vector in enumerate(c):
    assert c[i] @ [0, 0, 1] == c[i, -1]
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы