Tensorflow中的reshape、set_shape的区别!!!

本文深入探讨了TensorFlow中reshape与set_shape的区别,解释了它们在更新tensor形状和创建新tensor上的不同用途。同时,文章还解析了staticshape与dynamicshape的概念,以及get_shape()与tf.shape()的使用场景。
部署运行你感兴趣的模型镜像

Tensorflow中的reshape、set_shape的区别!!!

讨论reshape与set_shape的区别之前,我们首先需要知道dynamic shape和static shape的区别:

Tensorflow在构建图的时候,tensor的shape被称为static(inferred);而在实际运行中,常常出现图中tensor的具体维数不确定而用placeholder代替的情况,因此static shape未必是已知的。tensor在训练过程中的实际维数被称为dynamic shape,而dynamic shape是一定的。

import tensorflow as tf
x1 = tf.placeholder(tf.int32)
print(x1.get_shape())
 
sess = tf.Session()
print(sess.run(tf.shape(x1), feed_dict={x1:[0,1,2,3]}))
print(sess.run(tf.shape(x1), feed_dict={x1:[[0,1],[2,3]]}))

结果为:

unknown 
[4] 
[2,2]

第一个结果代表构建图时x1的shape,此时它是未知的,尽管在Session中运行了以后给出了[0,1,2,3]的传入值,但无法改变图中的x1的static shape。而后面的print也可以看到,随着传入值的不同,x1的dynamic shape是会变化的。

get_shape()方法和tf.shape()的区别,get_shape()是tensor的方法,返回一个tuple,而tf.shape()则返回一个tensor。第三行的unknown直接代表了x1的shape数组,假如我们这里用:

print(tf.shape(x1))

shape返回值是一个tensor,而get_shape返回的是一个tuple.因此,我们在获取x1的shape的时候,要用tf.shape方法,让指针指向一个tensor,不然使用get_shape()指针就会指向一个tuple从而报错。

下面说下set_shape()和reshape()的区别。其实从官方说明中可以看出,这两个主要是适用场合的区别,前者用于更新图中某个tensor的shape,而后者则往往用于动态地创建一个新的tensor。

一个set_shape的典型用法如下:

import tensorflow as tf
x1 = tf.placeholder(tf.int32)
x1.set_shape([22])
print(x1.get_shape())
 
sess = tf.Session()
#print(sess.run(tf.shape(x1), feed_dict={x1:[0,1,2,3]}))
print(sess.run(tf.shape(x1), feed_dict={x1:[[0,1],[2,3]]}))
(2,2) 
[2,2]

这代表了图中最开始没有shape的x1在使用了set_shape后,它的图中的信息已经改变了,如果取消掉注释就会报错,因为我们传入了和图不符合的参数。

reshape的典型用法则是这样:

import tensorflow as tf
x1 = tf.placeholder(tf.int32)
x2 = tf.reshape(x1, [2,2])
print(x1.get_shape())
 
sess = tf.Session()
print(sess.run(tf.shape(x2), feed_dict={x1:[0,1,2,3]}))
print(sess.run(tf.shape(x2), feed_dict={x1:[[0,1],[2,3]]}))
(2,2) 
[2,2] 
[2,2]

即它并不是想改变图,而只是想创造一个新的tensor以供我们使用。

但是reshape能否和set_shape有着相同的用法,即用来改变图?我们试着修改上面的代码:

import tensorflow as tf
x1 = tf.placeholder(tf.int32)
x1 = tf.reshape(x1, [2,2]) # use tf.reshape()
print(tf.shape(x1))
 
sess = tf.Session()
#print(sess.run(tf.shape(x1), feed_dict={x1:[0,1,2,3]}))
print(sess.run(tf.shape(x1), feed_dict={x1:[[0,1],[2,3]]}))

经测试,reshape后x1的shape也发生了变化,注释不取消仍然会有报错现象。

那么set_shape和reshape的用法是否完全一样呢?还是有一定差别的。

reshape可以改变原有tensor的shape,而set_shape只能更新信息没办法直接改变值,可以参考下面的程序:

import tensorflow as tf
x1 = tf.Variable([[0, 1], [2, 3]])
print(x1.get_shape())
 
x1 = tf.reshape(x1, [4, 1]) # if we use x1.set_shape([4, 1]),the program cannot run
print(x1.get_shape())

最后总结一下,reshape应用场合比较广泛,当我们需要创建新的tensor或者动态地改变原有tensor的shape的时候可以使用;而当我们只是想更新图中某个tensor的shape或者补充某个tensor的shape信息可以使用set_shape来进行更新。

您可能感兴趣的与本文相关的镜像

TensorFlow-v2.15

TensorFlow-v2.15

TensorFlow

TensorFlow 是由Google Brain 团队开发的开源机器学习框架,广泛应用于深度学习研究和生产环境。 它提供了一个灵活的平台,用于构建和训练各种机器学习模型

bool OVVoiceRecognizer::init(const std::string& model_path, const FeatureParams& params) { try { // 1. 保存特征参数 feature_params_ = params; // 2. 初始化特征提取器(PCM→mel特征) if (!feature_extractor_.init(params)) { std::cerr << "Feature extractor init failed" << std::endl; return false; } // 3. 初始化解码器(Whisper tokenizer) if (!tokenizer_.init("models/tokenizer.model")) { // 需提前准备tokenizer模型 std::cerr << "Tokenizer init failed" << std::endl; return false; } // 4. 加载OpenVINO模型(.xml路径) std::string bin_path = model_path.substr(0, model_path.find_last_of('.')) + ".bin"; auto model = core_.read_model(model_path, bin_path); // 5. 配置输入形状([1, n_mel_channels, feature_length]) auto input_port = model->input(); ov::Shape input_shape = {1, params.n_mel_channels, params.feature_length}; input_port.set_shape(input_shape); // 6. 编译模型(指定设备:"CPU"或"GPU") compiled_model_ = core_.compile_model(model, "CPU"); infer_request_ = compiled_model_.create_infer_request(); is_initialized_ = true; return true; } catch (const std::exception& e) { std::cerr << "OV init failed: " << e.what() << std::endl; return false; } } 报错: E:\projects\VoCasst\VAServiceWin\va_core\openvino\ov_voice_recognizer.cpp:29: error: 'class ov::Output<ov::Node>' has no member named 'set_shape'; did you mean 'get_shape'? E:/projects/VoCasst/VAServiceWin/va_core/openvino/ov_voice_recognizer.cpp:29:20: error: 'class ov::Output<ov::Node>' has no member named 'set_shape'; did you mean 'get_shape'? 29 | input_port.set_shape(input_shape); | ^~~~~~~~~ | get_shape
最新发布
10-21
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值