InvalidArgumentError: Input to reshape is a tensor with * values, but the requested shape has * [[{

记录一个在使用tensorflow把数据存储为tfr文件,之后在从tfr文件中读取时遇到的问题。

问题是:

InvalidArgumentError: Input to reshape is a tensor with 2944256 values, but the requested shape has 1472128 [[{{node Reshape_1}}]] [Op:IteratorGetNext]

这里面我做了一个reshape操作,它的意思是,我的tensor一共有2944256个value,但是我reshape后的tensor只有1472128个值,正好少了一半的数据没了。

出现这个问题的代码是这样的:

  1. 首先,我要把dncVectarget这两个ndarray类型的多维数组,存为example中的值。

问题就出在target,我们只看target,target是我用随机矩阵,随机生成的,代码为:

 target = np.random.rand(1,896,1643)

整个写入过程都是没问题的。

seqLength = 131072
def data_generate(path):
  #写入
  with tf.io.TFRecordWriter(path) as writer:

    #生成255个example
    for i in range(5):
      dna = randomSeq(seqLength)#dna序列
      dnaVec = one_hot_encode(dna)#131072,4的矩阵
      dnaVec = np.expand_dims(dnaVec,axis=0)#1,131072,4的矩阵

      target = np.random.rand(1,896,1643)
      
      #转成字节
      dnaVec = dnaVec.tobytes()
      target = target.tobytes()

      feature = {
      #序列使用的是tf.train.BytesList类型
        'sequence':tf.train.Feature(bytes_list=tf.train.BytesList(value=[dnaVec])),
        'target':tf.train.Feature(bytes_list=tf.train.BytesList(value=[target]))
    }
      example = tf.train.Example(features=tf.train.Features(feature=feature))
      writer.write(example.SerializeToString())

我们先看下np.random.rand()生成的矩阵:
在这里插入图片描述
这没问题,然后看下a的元素类型

>>> a.dtype
dtype('float64')
>>>

矩阵的内部元素的类型是float64

接着是读取tfr文件:

def parse_example(example_string):
  #解析之后得到的example
  example = tf.io.parse_single_example(example_string,feature_description)
  #example['sequence']还是字节流的形式,重新转为数字向量
  sequence = tf.io.decode_raw(example['sequence'], tf.float32)
  sequence = tf.reshape(sequence,(1,seqLength,4))  #形状需要重塑,不然就是一个长向量

  target = tf.io.decode_raw(example['target'], tf.float32)
  target = tf.reshape(target,(1,896,1643))
  
  #把整个字典返回
  return {
      'sequence':sequence,
      'target': target
  }

关键是这句代码:

  target = tf.io.decode_raw(example['target'], tf.float32)
tf.io.decode_raw(
    input_bytes, out_type, little_endian=True, fixed_length=None, name=None
)

tf.io.decode_raw()将输入张量的原始字节转换成数字张量。
输入的是字节序列,然后把这些字节解码为 out_type 指定格式的数字。
原始数据是什么格式这里解析必须是什么格式,要不然会出现形状的不对应问题!

这里指定的是tf.float32,但是之前随机生成矩阵中的元素类型是float64,这就是问题所在。为什么会这样我也不清楚,但是只要把 target = tf.io.decode_raw(example['target'], tf.float32)改为tf.float64,就不会出现这个问题了。

或者提前把矩阵内元素的类型做一下变换,

target = target.astype(np.float32)

后面代码就不需要改变了。

拿出一个example
在这里插入图片描述

总之,问题应该就是矩阵元素的类型变换出错了。

### 批量大小(Batch Size)不设置为1时可能出现的错误 当批量大小(batch size)在训练和测试阶段不一致时,可能会遇到维度不匹配等问题。例如,在LSTM网络中,如果初始化状态`init_state = lstm_cell.zero_state(batch_size, dtype=tf.float32)`中的`batch_size`被固定为某个数值(如32),而在实际操作过程中传入的数据数量少于该值(比如只有11条记录)[^2],则会发生形状(shape)上的冲突。 这种情况下通常会出现如下类型的异常信息:“InvalidArgumentError: Input to reshape is a tensor with X values, but the requested shape has Y”,这是因为框架尝试将输入张量转换成与预设批次大小相适应的形式失败所致。 ### 解决方案 为了应对上述情况带来的挑战,可以采取以下几种方法之一: #### 方法一:动态设定批尺寸 允许模型接受可变长度的批次作为输入,而不是硬编码特定的`batch_size`值。对于RNN类架构而言,这意味着要修改代码逻辑以支持不同规模的小批量数据处理。具体实现方式取决于所使用的深度学习库;某些高级API可能已经内置了对此特性的支持。 #### 方法二:填充至指定批尺寸 另一种策略是在准备每一批次之前先对其进行适当扩充或裁剪,使其达到预期的数量。这可以通过向现有样本集中添加虚拟项来完成——这些额外元素不会影响最终结果的有效性,因为它们会在后续计算环节被忽略掉。不过需要注意的是,这种方法可能导致资源浪费以及潜在的时间延迟增加。 #### 方法三:单独配置推理期参数 考虑到训练集往往较大且稳定不变的特点,建议保持原有较大的`batch_size`用于优化过程;而对于验证/测试集,则可以根据实际情况灵活调整此超参直至找到最佳平衡点。这样做不仅有助于提升整体效率,还能有效规避因两者间差异引发的各种兼容性难题[^3]。 ```python import tensorflow as tf # 假定lstm_cell已定义好 def get_initial_state(batch_sz): return lstm_cell.zero_state(batch_sz, dtype=tf.float32) # 训练模式下使用固定的较大batch_size train_batch_size = 32 initial_state_train = get_initial_state(train_batch_size) # 测试模式可根据具体情况改变batch_size test_data_count = 11 # 实际待测样本数 if test_data_count != train_batch_size: initial_state_test = get_initial_state(test_data_count) else: initial_state_test = initial_state_train ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值