Я хочу запрограммировать нейронную сеть, и я использую для нее библиотеку Keras. Один набор данных делится на случайное число подмножеств (1-100). Не используемые подмножества установлены на ноль. Одно подмножество состоит из двоичных входных значений 2 * 4 + 1. Архитектура должна выглядеть так (веса всех подмножеств должны быть разделены):
. InA1(4) InB1(4) _
. \ / \
. FCNA FCNB |
. \ / |
. Concatinate |
. | \ 100x (InA2, InB2, InC2, InA3, ...)
. FCN /
.InC(1) | |
. \ / |
. \ / _/
. Concatinate
. |
. FCN
. |
. Out(1)
Я просмотрел ряд руководств и примеров, но я не нашел подходящего метода для реализации этой сети. Вот что я пробовал до сих пор:
from keras import *
# define arrays for training set input
InA = []
InB = []
InC = []
for i in range(100):
InA.append( Input(shape=4,), dtype='int32') )
InB.append( Input(shape=4,), dtype='int32') )
InC.append( Input(shape=1,), dtype='int32') )
NetA = Sequential()
NetA.add(Dense(4, input_shape(4,), activation="relu"))
NetA.add(Dense(3, activation="relu"))
NetB = Sequential()
NetB.add(Dense(4, input_shape(4,), activation="relu"))
NetB.add(Dense(3, activation="relu"))
NetMergeAB = Sequential()
NetMergeAB.add(Dense(1, input_shape=(3,2), activation="relu"))
# merging all subsample networks of InA, InB
MergeList = []
for i in range(100):
NetConcat = Concatenate()( [NetA(InA[i]), NetB(InB[i])] )
MergedNode = NetMergeAB(NetConcat)
MergeList.append(MergedNode)
MergeList.append(InC[i])
# merging also InC
FullConcat = Concatenate()(MergeList)
# put in fully connected net
ConcatNet = Sequential()
ConcatNet.add(Dense(10, input_shape(2, 100), activation="relu"))
ConcatNet.add(Dense(6, activation="relu"))
ConcatNet.add(Dense(4, activation="relu"))
ConcatNet.add(Dense(1, activation="relu"))
Output = ConcatNet(FullConcat)
Проблема в том, что либо я получаю ошибку "без тензора", либо вообще не работает. У кого-то есть идея, как правильно это решить?
Используя код из ответа автора вопроса:
ActInA = Input(shape=(4,), dtype='int32')
ActInB = Input(shape=(4,), dtype='int32')
ActInC = Input(shape=(1,), dtype='int32')
NetA = Dense(4, activation="relu")(ActInA)
NetA = Dense(3, activation="relu")(NetA)
NetB = Dense(4, activation="relu")(ActInB)
NetB = Dense(3, activation="relu")(NetB)
NetAB = concatenate([NetA, NetB])
NetAB = Dense(1, activation="relu")(NetAB)
Теперь мы построим модель для этого подмножества сети:
mymodel = Model([ActInA, ActInB], NetAB)
Теперь важная часть от keras doc:
Все модели вызываются, как и слои
это означает, что вы можете сделать что-то вроде этого:
for i in range(100):
NetMergeABC.append(mymodel([ActInA_array[i], ActInB_array[i]]))
Поскольку вы повторно используете слои, весы будут совместно использоваться.
Вы можете легко получить эту сетевую архитектуру с помощью функционального API и не использовать Sequential
вообще:
InA, InB, InC = [Input(shape=(4,), dtype='int32') for _ in range(3)]
netA = Dense(4, activation="relu")(InA)
netA = Dense(3, activation="relu")(netA)
netB = Dense(4, activation="relu")(InB)
netB = Dense(3, activation="relu")(netB)
netMergeAB = concatenate([netA, netB])
netMergeAB = Dense(1, activation="relu")(netMergeAB)
fullConcat = concatenate([netMergeAB, InC])
out = Dense(10, activation="relu")(fullConcat)
out = Dense(6, activation="relu")(out)
out = Dense(4, activation="relu")(out)
out = Dense(1, activation="relu")(out)
model = Model([InA, InB, InC], out)
Возможно, вам придется немного приспособить его, но общая идея должна быть ясной.
Хорошо, сама сеть работает. Теперь у меня есть еще одна проблема: я не могу соответствовать модели из-за формата ввода данных обучения.
С:
X = [[0], [0], [0], [0], [0], [0]]
Y = 10
myModel.fit(X, Y, epochs=1, batch_size=1)
Я получаю следующую ошибку:
AttributeError: объект 'list' не имеет атрибута 'ndim'
С:
X = numpy.array([[0], [0], [0], [0], [0], [0]])
Y = 10
myModel.fit(X, Y, epochs=1, batch_size=1)
Я получаю следующую ошибку:
"ValueError: ошибка при проверке ввода модели: список массивов Numpy, которые вы передаете своей модели, - это не размер ожидаемой модели. Ожидается, что вы увидите 6 массивов, но вместо этого получился следующий список из 1 массива: [массив ([[0], [0], [0], [0], [0], [0]])]... "
Во-первых, я не понимаю, почему, или если нужны массивы Numpy. И, во-вторых, почему его бросает этот повод? Я прошел 6 массивов?!
Я изменил свой код, и я надеюсь, что теперь станет ясно:
NetMergeABC = []
for i in range(100):
ActInA = Input(shape=(4,), dtype='int32')
ActInB = Input(shape=(4,), dtype='int32')
ActInC = Input(shape=(1,), dtype='int32')
NetA = Dense(4, activation="relu")(ActInA)
NetA = Dense(3, activation="relu")(NetA)
NetB = Dense(4, activation="relu")(ActInB)
NetB = Dense(3, activation="relu")(NetB)
NetAB = concatenate([NetA, NetB])
NetAB = Dense(1, activation="relu")(NetAB)
NetMergeABC.append(NetAB)
NetMergeABC.append(ActInC)
NetABC = concatenate(NetMergeABC)
NetABC = Dense(10, activation="relu")(NetABC)
NetABC = Dense(6, activation="relu")(NetABC)
NetABC = Dense(4, activation="relu")(NetABC)
NetABC = Dense(1, activation="relu")(NetABC)
Теперь проблема заключается в том, что (я думаю) весы общего доступа NetA/B/C 1-100.