tensor.get_shape()用法解析

本文详细解析了TensorFlow中tensor.get_shape()函数的使用方法,通过实例展示了如何获取张量维度,以及如何利用该函数在卷积神经网络中自动计算特征数量,实现卷积层到全连接层的转换。
部署运行你感兴趣的模型镜像

今天介绍tensor.get_shape()的用法

tensor.get_shape()
返回张量的维度,用一个元组来表示。
例如:

x=tf.constant([[[1,1,1],[2,2,2],[3,3,3],[4,4,4]],
			  [[1,1,1],[2,2,2],[3,3,3],[4,4,4]],
			  [[1,1,1],[2,2,2],[3,3,3],[4,4,4]]])
#容易看出,这是一个三维的张量(tensor)
x.get_shape()
x.get_shape()[1:]
x.get_shape()[1:].num_elements()

以上三个用法分别是什么意思呢?
第一个返回:(3,4,3)
用张量来说的话就是三个四行三列的张量,分别依次对应3,4,3
第二个返回(4,3)
就是切片操作,从第一个元素开始往后全部取来。
注意切片[a:b] 中,包含a而不包含b的元素。
第三个返回12
即:(4,3)中的元素个数,也就是12。

有什么用呢?再卷积神经网络中,用此种方法可以在卷积层拉伸为全连接层时,免于人工计算应该拉成多长。

features=last_conv_layer.get_shape()[1:].num_elements()
#第一个维度是数据的个数(batch_size组)
result =last_conv_layer.reshape([-1,features])
#拉伸成全连接层,-1是不知道有多少组数据的意思。

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

TensorFlow-v2.15

TensorFlow-v2.15

TensorFlow

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

import tensorrt as trt import numpy as np import time import pycuda.driver as cuda import pycuda.autoinit # 自定义INT8校准器类 class MyCalibrator(trt.IInt8EntropyCalibrator2): def __init__(self, batch_size=1, input_shape=(1, 3, 224, 224), cache_file="calibration.cache"): trt.IInt8EntropyCalibrator2.__init__(self) self.batch_size = batch_size self.input_shape = input_shape self.cache_file = cache_file # 生成随机校准数据(实际应用中应使用真实数据集) self.data = np.random.randn(100, *input_shape).astype(np.float32) self.current_index = 0 # 分配设备内存 self.device_input = cuda.mem_alloc(self.data.nbytes * self.batch_size) def get_batch_size(self): return self.batch_size def get_batch(self, names): if self.current_index + self.batch_size > len(self.data): return None batch = self.data[self.current_index:self.current_index+self.batch_size] self.current_index += self.batch_size # 将数据复制到设备 cuda.memcpy_htod(self.device_input, batch.tobytes()) return [int(self.device_input)] def read_calibration_cache(self): # 如果存在缓存,跳校准 try: with open(self.cache_file, "rb") as f: return f.read() except FileNotFoundError: return None def write_calibration_cache(self, cache): with open(self.cache_file, "wb") as f: f.write(cache) # 创建简单网络(使用 add_pooling_nd 替代 add_pooling) def create_network(): logger = trt.Logger(trt.Logger.WARNING) builder = trt.Builder(logger) network = builder.create_network(1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)) # 定义输入 input_tensor = network.add_input("input", trt.DataType.FLOAT, (1, 3, 224, 224)) # 添加卷积层(模拟ResNet-18第一层) conv1 = network.add_convolution_nd( input=input_tensor, num_output_maps=64, kernel_shape=(7, 7), kernel=np.random.randn(64, 3, 7, 7).astype(np.float32).ravel(), bias=np.random.randn(64).astype(np.float32) ) # 设置步长和填充(直接赋值属性) conv1.stride_nd = [2, 2] conv1.padding_nd = [3, 3] # 添加池化层(使用 add_pooling_nd) window_shape = trt.Dims([3, 3]) # 修改:使用 trt.Dims pool1 = network.add_pooling_nd( input=conv1.get_output(0), type=trt.PoolingType.MAX, window_size=window_shape ) pool1.stride_nd = [2, 2] # 设置池化步长 # 展平输出为二维张量(N, C*H*W) flatten = network.add_shuffle(pool1.get_output(0)) output_shape = (1, 64 * 56 * 56) # 假设输入是 (1, 64, 56, 56) flatten.reshape_dims = tuple(output_shape) # 定义权重和偏置 kernel = np.random.randn(1000, 64 * 56 * 56).astype(np.float32).ravel() bias = np.random.randn(1000).astype(np.float32) # 添加常量张量作为权重和偏置 w = network.add_constant((1000, 64 * 56 * 56), kernel) b = network.add_constant((1000,), bias) # 矩阵乘法:[input] @ [weights.T] + [bias] matmul = network.add_matrix_multiply(flatten.get_output(0), trt.MatrixOperation.NONE, w.get_output(0), trt.MatrixOperation.TRANSPOSE) bias_add = network.add_elementwise(matmul.get_output(0), b.get_output(0), trt.ElementWiseOperation.SUM) # 标记输出 bias_add.get_output(0).name = "output" network.mark_output(bias_add.get_output(0)) return builder, network, logger # 主测试函数 def int8_perf_test(): # 创建网络 builder, network, logger = create_network() # 配置INT8量化 config = builder.create_builder_config() config.set_flag(trt.BuilderFlag.INT8) config.set_memory_pool_limit(trt.MemoryPoolType.WORKSPACE, 1 << 30) # 1GB工作空间 # 创建校准器并设置给配置 calib = MyCalibrator(batch_size=1, input_shape=(1, 3, 224, 224), cache_file="calibration.cache") config.int8_calibrator = calib # ✅ 正确方式:直接赋值属性 # 构建引擎(新API) engine = builder.build_engine(network, config) if not engine: print("Engine构建失败!") return # 创建执行上下文 context = engine.create_execution_context() # 准备输入输出缓冲区 input_shape = (1, 3, 224, 224) output_shape = (1, 1000) host_input = np.random.randn(*input_shape).astype(np.float32) host_output = np.empty(output_shape, dtype=np.float32) # 分配设备内存 d_input = cuda.mem_alloc(host_input.nbytes) d_output = cuda.mem_alloc(host_output.nbytes) bindings = [int(d_input), int(d_output)] # 创建CUDA流 stream = cuda.Stream() # 预热 for _ in range(5): cuda.memcpy_htod_async(d_input, host_input, stream) context.execute_async_v2(bindings=bindings, stream_handle=stream.handle) cuda.memcpy_dtoh_async(host_output, d_output, stream) stream.synchronize() # 正式测试 start = time.time() for _ in range(100): cuda.memcpy_htod_async(d_input, host_input, stream) context.execute_async_v2(bindings=bindings, stream_handle=stream.handle) cuda.memcpy_dtoh_async(host_output, d_output, stream) stream.synchronize() total_time = time.time() - start # 计算INT8 TOPS(基于ResNet-18的3.9G MACs) # 注意:INT8操作数 = MACs × 2(乘加各算一次操作) ops = 3.9e9 * 2 # ResNet-18的INT8操作数 tops = (ops * 100) / (total_time * 1e12) # 100次推理 print(f"INT8 TOPS: {tops:.2f} TOPS") # 清理资源 del context del engine if __name__ == "__main__": int8_perf_test() 报错 jp@jp-Super-Server:~/test$ python3 TensorRT_int8.py /home/jp/test/TensorRT_int8.py:113: DeprecationWarning: Use Deprecated in TensorRT 10.1. Superseded by explicit quantization. instead. config.int8_calibrator = calib # ✅ 正确方式:直接赋值属性 Traceback (most recent call last): File "/home/jp/test/TensorRT_int8.py", line 166, in <module> int8_perf_test() File "/home/jp/test/TensorRT_int8.py", line 116, in int8_perf_test engine = builder.build_engine(network, config) AttributeError: 'tensorrt_bindings.tensorrt.Builder' object has no attribute 'build_engine' 给出修改后的完整代码
06-18
def get_label(self, img_path, labelme_json_path, img_size): # h, w 是图片的宽高 mask_array = np.zeros([self.num_classes, h, w, 1], dtype=np.uint8) with open(labelme_json_path, "r") as f: json_data = json.load(f) shapes = json_data["shapes"] for shape in shapes: category = shape["label"] # 获取类别的索引 category_idx = self.category_types.index(category) points = shape["points"] points_array = np.array(points, dtype=np.int32) temp = mask_array[category_idx, ...] # 获取出mask_array对应的类别层 # 将标注的坐标点连接成一个区域,并将区域内的值填为255 mask_array[category_idx, ...] = cv2.fillPoly(temp, [points_array], 255) # 可以将每一层的输出来看mask图 # 交换维度 mask_array = np.transpose(mask_array, (1, 2, 0, 3)).squeeze(axis=-1) # 将mask转为tensor mask_tensor = ut.i2t(mask_array, False) return mask_tensor import torch import os import numpy as np from torch.utils.data import Dataset from utils_func import seg_utils as ut import cv2 from torchvision.transforms.functional import rotate as tensor_rotate from torchvision.transforms.functional import vflip, hflip from torchvision.transforms.functional import adjust_brightness import random import base64 import json import os import os.path as osp device = torch.device("cuda" if torch.cuda.is_available() else "cpu") class train_data(Dataset): def __init__(self, image_folder, img_size, category_types): self.image_folder = image_folder self.img_size = img_size self.category_types = category_types self.num_classes = len(category_types) self.data_list = self.generate_mask() # print(self.data_list) self.img_and_mask = [] for idx, data in enumerate(self.data_list): img_tensor, mask_tensor = self.get_image_and_label(data[0], data[1], self.img_size) self.img_and_mask.append([img_tensor, mask_tensor]) def __len__(self): return len(self.img_and_mask) def __getitem__(self, index): img_tensor = self.img_and_mask[index][0].to(device) mask_tensor = self.img_and_mask[index][1].to(device) # 如果有数据增强就在这里处理 return img_tensor, mask_tensor def data_augment(self, img_tensor, mask_tensor, aug_flag): if aug_flag[0] == 0: angel = random.choice(aug_flag[1]) img_tensor = tensor_rotate(img_tensor, int(angel)) mask_tensor = tensor_rotate(mask_tensor, int(angel)) elif aug_flag[0] == 1: factor = aug_flag[1] img_tensor = adjust_brightness(img_tensor, factor) elif aug_flag[0] == 2: flip_type = random.choice(aug_flag[1]) if flip_type == 1: img_tensor = vflip(img_tensor) mask_tensor = vflip(mask_tensor) else: img_tensor = hflip(img_tensor) mask_tensor = hflip(mask_tensor) return img_tensor, mask_tensor def generate_mask(self): data_lists = [] for file_name in os.listdir(self.image_folder): if file_name.endswith("json"): json_path = os.path.join(self.image_folder, file_name) img_path = osp.join(self.image_folder, "%s.jpg" % file_name.split(".")[0]) data_lists.append([img_path, json_path]) return data_lists def get_image_and_label(self, img_path, labelme_json_path, img_size): # print("==================================================") # print(img_path) # print("==================================================") img = ut.p2i(img_path) h, w = img.shape[:2] img = cv2.resize(img, (img_size[0], img_size[1])) # cv2.imwrite(r"C:\Users\HJ\Desktop\test\%s.jpg"%img_path.split(".")[0][-7:], img) img_tensor = ut.i2t(img) mask_array = np.zeros([self.num_classes, h, w, 1], dtype=np.uint8) with open(labelme_json_path, "r") as f: json_data = json.load(f) shapes = json_data["shapes"] for shape in shapes: category = shape["label"] category_idx = self.category_types.index(category) points = shape["points"] points_array = np.array(points, dtype=np.int32) temp = mask_array[category_idx, ...] mask_array[category_idx, ...] = cv2.fillPoly(temp, [points_array], 255) mask_array = np.transpose(mask_array, (1, 2, 0, 3)).squeeze(axis=-1) mask_array = cv2.resize(mask_array, (self.img_size[0], self.img_size[1])).astype(np.uint8) mask_tensor = ut.i2t(mask_array, False) return img_tensor, mask_tensor if __name__ == '__main__': img_folder = r"D:\finish_code\SegmentationProject\datasets\data2" img_size1 = [256, 512] category_types = ["background", "person", "car", "road"] t = train_data(img_folder, img_size1, category_types) t.__getitem__(1)
最新发布
07-25
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值