python - 批量大小 = 1 和可变时间步长误差的 LSTM
问题描述
大家好,我正在尝试使用 batch_size = 1 训练我的 LSTM 模型。输入是一个二维数组列表,每个数组都包含可变时间步长,因为每个音频都有不同的长度和固定数量的特征,所以列表的每个元素看起来像这样(Tx,Number_of 特征)。例如(随机):
X=[]
for i in range(0,420):
X.append(np.random.rand(np.random.randint(1,10),12))
y = np.random.rand(420)
y = to_categorical(Y,num_classes=5)
我尝试按如下方式传递输入:
def rnn(X,y):
model = Sequential()
model.add(LSTM(128, input_shape=(None, X[0].shape[1])))
model.add(Dense(32, activation='relu'))
model.add(Dense(5, activation='softmax'))
opt = tf.keras.optimizers.Adam(lr=1e-3, decay=1e-5)
model.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy'])
model.fit(X, y, epochs=3,batch_size=1,validation_split=0.3)
但是我收到以下错误:
File "C:\Users\mp95\PycharmProjects\Thesis\venv\lib\site-packages\tensorflow_core\python\keras\engine\training_utils.py", line 573, in standardize_input_data
'with shape ' + str(data_shape))
ValueError: Error when checking input: expected lstm_input to have 3 dimensions, but got array with shape (86, 12)
我认为我必须按如下方式重塑列表的每个元素(1,Tx,number_of_features),所以我这样做了:
def rnn(X,y):
for s,x in enumerate(X):
seq_len = x.shape[0]
X[s]=np.reshape(X[s],(1,seq_len,x.shape[1]))
model = Sequential()
model.add(LSTM(128, input_shape=(None, X[0].shape[2])))
model.add(Dense(32, activation='relu'))
model.add(Dense(5, activation='softmax'))
opt = tf.keras.optimizers.Adam(lr=1e-3, decay=1e-5)
model.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy'])
model.fit(X, y, epochs=3,batch_size=1,validation_split=0.3)
但我似乎无法让它发挥作用:
File "C:\Users\mp95\PycharmProjects\Thesis\venv\lib\site-packages\tensorflow_core\python\keras\engine\training_utils.py", line 744, in check_array_lengths
'and ' + str(list(set_y)[0]) + ' target samples.')
ValueError: Input arrays should have the same number of samples as target arrays. Found 1 input samples and 420 target samples.
如何以可变时间步长提供样本?我发现了一些类似的问题,但无法真正让它发挥作用。
编辑:添加了随机参数初始化以实现最小的可重复性,如评论中指出的那样
解决方案
您应该使用train_on_batch
而不是fit
.
fit
将尝试创建一个具有一致维度的 numpy 数组,这在您的情况下将是一个问题。
fit
您可以使用train_on_bacth
、predict_on_batch
和编写自己的自定义test_on_batch
。
def train_task(simple_conv, X, y_ohe, EPOCH, train_split=1.0):
# single zero padding for NULL datas
report_acc = 0.0
for epoch in range(EPOCH):
print(f'Training epoch {epoch} ...')
avg_loss = 0.0
avg_acc = 0.0
avg_mae = 0.0
for sample_i in tqdm(range(int(len(X)*train_split))):
[train_loss, acc, mae] = simple_conv.train_on_batch(X[sample_i].reshape(1,X[sample_i].shape[0], X[sample_i].shape[1]),
,
y_ohe[sample_i].reshape(1,5))
avg_loss += train_loss/(len(X)*train_split)
avg_acc += acc/(len(X)*train_split)
avg_mae += mae/(len(X)*train_split)
report_acc = avg_acc
print(f'f1: {avg_acc} mae: {avg_mae} loss: {avg_loss}')
#print('Running validation ...')
avg_loss = 0.0
avg_acc = 0.0
avg_mae = 0.0
return simple_conv, report_acc
这是一个做类似事情的仓库(也包括一篇论文):https ://github.com/zabir-nabil/activity-recognition-abc
推荐阅读
- python - 散景悬停工具显示过于拥挤,无法显示多条图表线
- javascript - 如何将用户从任何 url 重定向到另一个?
- swift - 在 Swift 中关闭 macOS 的模式表
- angular - Angular Rest Service 在创建实体时使用 Hal 根链接而不是属性
- javascript - 如何将文件路径放在 package.json 文件中
- javascript - gchjs-dom安装问题:安装jsaddle-dom内存不足
- ajax - 单击登录按钮时无法输入正确的页面
- c++ - 使用类的成员构造函数后出现分段错误
- firebase - 颤振位置距离有效值但返回 null
- flutter - 在 Flutter 应用程序中将文本编码到捕获的图像上