利用tensorflow做lstm,遇到一个奇怪的问题,只是显示输入格式不对,但是 换个batch_size就可以了,思来想去可能是tensorflow1.0的bug,写一下解决方案
解决方案1:
直接采用
steps_per_epoch
参数,将原来的代码
AE.fit(x_train, x_train, epochs=params['epochs_pre'],
batch_size=batch_size,
shuffle=False,
verbose = 0
)
改为
AE.fit(x_train, x_train, epochs=params['epochs_pre'],
steps_per_epoch =len(x_train)//(params['batch_size']*params['epochs_pre']),
shuffle=False,
verbose = 0
)
这个地方注意:①在model.fit()函数中设置了batch_size就不可以设置step_per_epoch了
②keras 中 fit_generator参数steps_per_epoch已经改变含义了,目前的含义是一个epoch分成多少个batch_size。旧版的含义是一个epoch的样本数目。因为我采用的是tensorflow1.0,所以用的还是旧版的定义。
解决方案2:
第一个解决方案在我用numpy数组定义输入数据时可以使用,但是我写成从文件中读取后就不行了,很无奈,找了很多方法,有说用tensorflow中去除不足一个batch的数据的tensorflow函数,参考:https://blog.csdn.net/qq_36076233/article/details/81063127
dataset = dataset.apply(tf.contrib.data.batch_and_drop_remainder(3)) #每个batch3个数据,不足3个舍弃
的,但是好像跟我的数据格式不太一样,我是直接读取.csv文件,这个好像是迭代器,搞了半天也没弄明白咋用=_=
查了一些资料又有说,参考:https://www.javaroad.cn/questions/108699
-
设置
batch_size
时,训练数据将被分割为此大小的批次(请参阅L184) . -
当您设置
steps_per_epoch
时,如果训练输入不是框架原生张量(这是最常见的情况),整个训练集将被一次性送入网络(参见L152),这就是为什么你得到了记忆错误 .
因此,基于实现,我建议仅在通过框架本机张量(即第一个维度为批量大小的TensorFlow张量)进行馈送时使用参数 steps_per_epoch
,这确实是一个要求 . 为此,需要将 model.fit
中的参数 x
和 y
设置为 None
.
这个的,我也没搞明白=_=
最后,我用了最直白的方法,直接遍历数组,把不能整除batch_size的剩余数据直接删掉,写了个函数,方便调用一下:
def remove(x,y,batch_size):
if len(x) / batch_size != 0:
index = []
for step, batch in enumerate(Data.DataLoader(dataset=x, batch_size=batch_size, shuffle=False)):
if len(batch) != batch_size:
for i in range(len(batch)):
index.append(step * batch_size + i)
x = np.delete(x, index, axis=0)
y = np.delete(y, index, axis=0)
print('x.shape is desized!', x.shape)
return x,y
x,y就是不能被batch_size整除的数据,通过把不能被整除的索引记录下来并删除对应元素,最后返回一个能够被整除的数组,方法虽然很笨,但是终于能用了