tensorflow笔记(十九)——错误集锦

错误及应对方案

1,问题:训练正常,预测和评估的时候报OOM:

  • 办法:减少预测和训练的batchsize,或者减少网络参数。参考:ResourceExhaustedError (see above for traceback): OOM when allocating tensor of shape [7744,512] #3393

2,问题:从dataset打印数据,报错OP_REQUIRES failed at example_parsing_ops.cc:144 : Invalid argument: Name: , Feature: label (data type: int64) is required but could not be found.

  • 原因:dataset解析问题,生成的.tfrecord数据中的key(键值)和你在代码中读取的 key 不匹配导致的。
  • 办法:检查dataset解析的feature_spec,保证正确。

3,问题:tfrecord以tf.io.VarLenFeature(tf.int64) 格式读入SparseTensor,转成to_dense后进行了筛选部分样本的操作(gather),然后用from_dense转回SparseTensor,训练过程中出现Invalid argument: Shapes of all inputs must match: values[0].shape = [13,16] != values[39].shape = [12,16]

  • 排查过程:
    从报错看,部分输入的shape不一致,这里的输入指的是特征,也就是说部分特征维度有问题,其中16是embedding长度,那么第一维应该就是batch_size,也就是说有部分特征少一个样本。
    说下背景:我从tfrecord读入sparse tensor特征,训练前我筛选其中的部分样本(tf.gather),因为SparseTensor不支持gather、shuffle等操作,所以我先需要把sparse转成dense,gather出部分样本后再转回SparseTensor查embedding。为啥gather之后要转回sparse?——因为我的特征基本是多值特征,有些样本一个特征的特征值有上百个,有的只有1个,那么某个特征从sparse转dense的时候,dense向量的长度取决于当前batch中特征值最多的那条样本的特征值个数,其余样本不足的补0,如果直接用这些dense tensor去embedding_lookup找embedding,多值特征再reduce_mean,就会出现那些特征值只有1-2个的样本,基本上约等于0对应的embedding的均值,显然是不合适的。
    测试发现,直接用原始的SparseTensor + tf.nn.embedding_lookup_sparse正常,用to_dense + tf.nn.embedding_lookup也可以,to_dense + gather + tf.nn.embedding_lookup,但是to_dense + gather + from_dense + tf.nn.embedding_lookup_sparse就报错了,说明问题在于从dense转回sparse tensor的过程中被吃了维度。
    打印报错的sparse tensor:
[[ 0  0] [ 1  0] [ 2  0] [ 3  0] [ 4  0] [ 5  0] [ 6  0] [ 7  0] [ 8  0] [ 9  0] [10  0] [11  0]], 
shape=(12, 2), dtype=int64), values=tf.Tensor([655914 655914 655914 655914 655914 655914 655914 
655914 655914 655914 655914 655914], shape=(12,), dtype=int64), 
dense_shape=tf.Tensor([13 20], shape=(2,), dtype=int64))

发现一个奇怪的现象,这个SparseTensor中,dense_shape的第一维度是13,但indices只有0-11这12行,也就是说,第13行没有非0的值。什么情况下会出现这个问题?经排查发现原始数据中,有一条样本的特征值就是0,sparse转dense倒无妨就是有一行都是0(其中有一个是真实值,其他是填充),但是在dense到sparse的转化中,全0行所有值都当作默认填充值了。而查看embedding_lookup_sparse函数我们发现,embedding的输出第一维不是由dense_shape的第一维决定的,而是由输入sparse tensor的indices的第一维度集合决定,这就导致经过embedding_lookup_sparse后有0值的那个特征被“吃”了一条样本,出现跟其他特征不匹配的情况。
为什么会有特征值为0的情况,经过排查,发现我们在样本构造的时候,会先对特征编码为index,本来没有从0编码,但是在构建编码的时候,有些特征值出现次数很少就没有编码,这类特征值给了默认值0,导致出现这个问题。

  • 解决方法:通过把默认值改成len(index_list)后解决。

4,问题:InternalError: Dst tensor is not initialized

  • 原因:GPU内存耗尽,挂在后台进程中的IPython内核。
  • 办法:如果有多卡,切换到有内存的卡运行,运行程序之前,执行 export CUDA_VISIBLE_DEVICES=n使只有设备n可见。

你可能感兴趣的:(tensorflow,tensorflow,深度学习,错误)