可以使用帮助为 Keras SimpleRNN 正确格式化数据
Could use help formatting data correctly for a Keras SimpleRNN
我在将数据转换为适合 simpleRNN 的正确格式时遇到了一些困难,或者我在正确定义模型方面遇到了困难。我希望有人能发现问题?
我正在尝试class对长度为 278 的向量列表 X
进行化验,其中包含从长度为 9026 的字典 vocab
中选择的整数值作为属于到 class 0 或 1。这是我的输入数据的示例:
X=[[1,822,773,54,51,...],[2,3,1,41,3,...],[121,17,311,4,12,...],...]
y=[0,1,1,...]
例如 np.array(X).shape=(1000,278)
和 len(y)=1000
我的模型是:
model.add(L.InputLayer([None],dtype='int32'))
model.add(L.Embedding(input_dim=len(vocab)+1,\
output_dim=64,\
input_length=278))
model.add(L.SimpleRNN(64,return_sequences=True))
model.add(L.TimeDistributed(L.Dense(1,activation='softmax')))
model.compile(optimizer='adam',\
loss='categorical_crossentropy',\
metrics=['accuracy']
)
print(model.summary())
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
embedding_8 (Embedding) (None, 278, 64) 577728
_________________________________________________________________
simple_rnn_7 (SimpleRNN) (None, 278, 64) 8256
_________________________________________________________________
time_distributed_7 (TimeDist (None, 278, 1) 65
=================================================================
Total params: 586,049
Trainable params: 586,049
Non-trainable params: 0
_________________________________________________________________
None
我准备如下:
X=np.array(X)
y=keras.utils.to_categorical(y)
frac=0.3
random_state=42
X_train,X_tmp,y_train,y_tmp = \
train_test_split(X,y,test_size=frac,random_state=random_state,\
stratify=y)
train=(X_train,y_train)
test=(X_tmp,y_tmp)
当我运行模特时:
model.fit(train[0],train[1],verbose=0,\
batch_size=batch_size,\
epochs=epochs,validation_data=test)
我收到以下错误:
ValueError: Error when checking target: expected time_distributed_1
to have 3 dimensions, but got array with shape (5450, 2)
如果我将输入数据更改为
train=(X_train,y_train[:,:,np.newaxis])
test=(X_tmp,y_tmp[:,:,np.newaxis])
和 运行 模型,我得到这个错误:
ValueError: Error when checking target: expected time_distributed_1
to have shape (278, 2) but got array with shape (2, 1)
好吧,很明显我有问题,因为我的最终致密层正在寻找形状 278 而不是 2。所以我尝试了这个模型但没有明确定义 input_length:
model.add(L.InputLayer([None],dtype='int32'))
model.add(L.Embedding(input_dim=len(vocab)+1,\
output_dim=64))
model.add(L.SimpleRNN(64,return_sequences=True))
model.add(L.TimeDistributed(L.Dense(1,activation='softmax')))
model.compile(optimizer='adam',\
loss='categorical_crossentropy',\
metrics=['accuracy']
)
print(model.summary())
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
embedding_10 (Embedding) (None, None, 64) 577728
_________________________________________________________________
simple_rnn_9 (SimpleRNN) (None, None, 64) 8256
_________________________________________________________________
time_distributed_9 (TimeDist (None, None, 2) 130
=================================================================
Total params: 586,114
Trainable params: 586,114
Non-trainable params: 0
当我 运行 模型时,我得到
ValueError: Error when checking target: expected time_distributed_9
to have shape (None, 2) but got array with shape (2, 1)
我很困惑。谁能帮我诊断一下?
为什么要使用 TimeDistributed
?你根本不需要那个。对于每个长度为 278 的向量,您只想预测一个介于 0 和 1 之间的数字。因此最后一层的输出形状应该是 (None,1)
。删除 SimpleRNN
层的 return_sequences
参数,因为 well.You 也不需要它。像这样:
model.add(L.SimpleRNN(64))
model.add(L.Dense(1,activation='sigmoid'))
此外,你应该使用'sigmoid'
作为激活函数,使最后一层输出一个介于0和1之间的值。并将'categorical_crossentropy'
更改为'binary_crossentropy'
。您也不需要将 y
转换为分类。它已经是 zeros 和 ones 了,没关系(只需将其转换为 numpy 数组);记住,你在这里做二分类。
另外,使用第一个模型。您的第二个模型没有意义,因为您提到所有输入向量的长度都相同(即 278)。
最后一点:删除 InputLayer
。这是多余的。您已经在嵌入层中设置了输入形状。
我在将数据转换为适合 simpleRNN 的正确格式时遇到了一些困难,或者我在正确定义模型方面遇到了困难。我希望有人能发现问题?
我正在尝试class对长度为 278 的向量列表 X
进行化验,其中包含从长度为 9026 的字典 vocab
中选择的整数值作为属于到 class 0 或 1。这是我的输入数据的示例:
X=[[1,822,773,54,51,...],[2,3,1,41,3,...],[121,17,311,4,12,...],...]
y=[0,1,1,...]
例如 np.array(X).shape=(1000,278)
和 len(y)=1000
我的模型是:
model.add(L.InputLayer([None],dtype='int32'))
model.add(L.Embedding(input_dim=len(vocab)+1,\
output_dim=64,\
input_length=278))
model.add(L.SimpleRNN(64,return_sequences=True))
model.add(L.TimeDistributed(L.Dense(1,activation='softmax')))
model.compile(optimizer='adam',\
loss='categorical_crossentropy',\
metrics=['accuracy']
)
print(model.summary())
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
embedding_8 (Embedding) (None, 278, 64) 577728
_________________________________________________________________
simple_rnn_7 (SimpleRNN) (None, 278, 64) 8256
_________________________________________________________________
time_distributed_7 (TimeDist (None, 278, 1) 65
=================================================================
Total params: 586,049
Trainable params: 586,049
Non-trainable params: 0
_________________________________________________________________
None
我准备如下:
X=np.array(X)
y=keras.utils.to_categorical(y)
frac=0.3
random_state=42
X_train,X_tmp,y_train,y_tmp = \
train_test_split(X,y,test_size=frac,random_state=random_state,\
stratify=y)
train=(X_train,y_train)
test=(X_tmp,y_tmp)
当我运行模特时:
model.fit(train[0],train[1],verbose=0,\
batch_size=batch_size,\
epochs=epochs,validation_data=test)
我收到以下错误:
ValueError: Error when checking target: expected time_distributed_1
to have 3 dimensions, but got array with shape (5450, 2)
如果我将输入数据更改为
train=(X_train,y_train[:,:,np.newaxis])
test=(X_tmp,y_tmp[:,:,np.newaxis])
和 运行 模型,我得到这个错误:
ValueError: Error when checking target: expected time_distributed_1
to have shape (278, 2) but got array with shape (2, 1)
好吧,很明显我有问题,因为我的最终致密层正在寻找形状 278 而不是 2。所以我尝试了这个模型但没有明确定义 input_length:
model.add(L.InputLayer([None],dtype='int32'))
model.add(L.Embedding(input_dim=len(vocab)+1,\
output_dim=64))
model.add(L.SimpleRNN(64,return_sequences=True))
model.add(L.TimeDistributed(L.Dense(1,activation='softmax')))
model.compile(optimizer='adam',\
loss='categorical_crossentropy',\
metrics=['accuracy']
)
print(model.summary())
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
embedding_10 (Embedding) (None, None, 64) 577728
_________________________________________________________________
simple_rnn_9 (SimpleRNN) (None, None, 64) 8256
_________________________________________________________________
time_distributed_9 (TimeDist (None, None, 2) 130
=================================================================
Total params: 586,114
Trainable params: 586,114
Non-trainable params: 0
当我 运行 模型时,我得到
ValueError: Error when checking target: expected time_distributed_9
to have shape (None, 2) but got array with shape (2, 1)
我很困惑。谁能帮我诊断一下?
为什么要使用 TimeDistributed
?你根本不需要那个。对于每个长度为 278 的向量,您只想预测一个介于 0 和 1 之间的数字。因此最后一层的输出形状应该是 (None,1)
。删除 SimpleRNN
层的 return_sequences
参数,因为 well.You 也不需要它。像这样:
model.add(L.SimpleRNN(64))
model.add(L.Dense(1,activation='sigmoid'))
此外,你应该使用'sigmoid'
作为激活函数,使最后一层输出一个介于0和1之间的值。并将'categorical_crossentropy'
更改为'binary_crossentropy'
。您也不需要将 y
转换为分类。它已经是 zeros 和 ones 了,没关系(只需将其转换为 numpy 数组);记住,你在这里做二分类。
另外,使用第一个模型。您的第二个模型没有意义,因为您提到所有输入向量的长度都相同(即 278)。
最后一点:删除 InputLayer
。这是多余的。您已经在嵌入层中设置了输入形状。