【完全多线程的输入通道】MNIST图像分类

使用TensorFlow进行多线程MNIST数据输入与模型训练
该博客介绍了如何利用TensorFlow实现多线程的输入通道,结合MNIST数据集,从数据写入TFRecord文件,到数据加载、预处理,再到模型训练。通过创建QueueRunner和使用TFRecordReader,实现了数据的高效读取。最后,建立了一个简单的softmax分类模型并进行了训练。
部署运行你感兴趣的模型镜像

完全多线程的输入通道应用——MNIST手写数字图像分类

  简介

       在本节我们将所有要介绍的内容放在一个 MNIST 图像的应用示例中,从数据写入到 TensorFlow 高效的文件格式,通过数据加载和预处理,到模型的训练。我们都用队列和多线程功能来实现这一点,并且依照这样的方式引入了一些更有用的组件来读取和处理 TensorFlow 中的数据。
       

  项目设计

       首先我们把 MNIST 数据写入TFRecord 中,使用之前的代码,此处不再过多赘述。详细内容可以参考这篇博客

	# Download data to save_dir
	data_sets = mnist.read_data_sets(save_dir, dtype=tf.uint8, reshape=False, validation_size=1000)
	
	data_splits = ["train", "test", "validation"]
	for d in range(len(data_splits)):
	    print("saving" + data_splits[d])
	    data_set = data_sets[d]
	
	    filename = os.path.join(save_dir, data_splits[d] + '.tfrecords')
	    writer = tf.python_io.TFRecordWriter(filename)
	
	    for index in range(data_set.images.shape[0]):
	        image = data_set.images[index].tostring()
	        example = tf.train.Example(features=tf.train.Features(feature={
	            'height' : tf.train.Feature(int64_list=tf.train.Int64List(value=[data_set.images.shape[1]])),
	            'width' : tf.train.Feature(int64_list=tf.train.Int64List(value=[data_set.images.shape[2]])),
	            'depth' : tf.train.Feature(int64_list=tf.train.Int64List(value=[data_set.images.shape[3]])),
	            'label' : tf.train.Feature(int64_list=tf.train.Int64List(value=[int(data_set.labels[index])])),
	            'image_raw' : tf.train.Feature(bytes_list=tf.train.BytesList(value=[image]))
	        }))
	
	        writer.write(example.SerializeToString())
	    writer.close()

       
       使用 string_input_producer() 在幕后创建一个 QueueRunner , 将文件名子字符串输出到我们输入通道的队列中,这个文件名队列将被多个多线程共享

	filename = os.path.join(save_dir, "train.tfrecords")
	filename_queue = tf.train.string_input_producer([filename], num_epochs=10)

       
       接着使用 TFReacordReader()从队列中读取文件,TFReacordReader()会以文件名队列为参数,按照文件名从 filename_queue 中出队
       TFReacordReader()内部实现使用计算图的状态来跟踪将要被读取的 TFRecord 的位置,一块块地从磁盘的输入数据中加载

	reader = tf.TFRecordReader()
	_, serialized_example = reader.read(filename_queue)

       
       返回一个 dict,解析数据并映射功能键到 Tensor 和 SparseTensor

	features = tf.parse_single_example(
	    serialized_example,
	    features={
	        'image_raw': tf.FixedLenFeature([], tf.string),
	        'label': tf.FixedLenFeature([], tf.int64)
	    })

       
       解码原始字节字符串数据,进行基本的预处理,将像素值转换为浮点数,然后将图像实例进行重新排序,并通过 tf.train.shuffle_batch()
       将其收集到 batch_size 批处理中,内部使用 RandomShuffleQueue 并累计示例,直到它包含 batch_size + min_sfter_dequeue个元素

	image = tf.decode_raw(features['image_raw'], tf.uint8)
	image.set_shape([784])
	image = tf.cast(image, tf.float32) * (1. / 255) - 0.5
	label = tf.cast(features['label'], tf.int32)
	
	# 随机采集一批数据
	images_batch, labels_batch = tf.train.shuffle_batch(
	    [image, label], batch_size=16,
	    capacity=200, min_after_dequeue=100)

       
       定义一个简单的 softmax 分类模型

	W = tf.get_variable("W", [28*28, 10])
	y_pred = tf.matmul(images_batch, W)
	loss = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y_pred, labels=labels_batch)
	
	loss_mean = tf.reduce_mean(loss)
	
	train_op = tf.train.AdamOptimizer().minimize(loss)
	
	config = tf.ConfigProto()
	config.gpu_options.allow_growth = True
	
	sess = tf.Session(config=config)
	init = tf.global_variables_initializer()
	sess.run(init)
	init = tf.local_variables_initializer()
	sess.run(init)

       
       创建线程,进行训练

	coord = tf.train.Coordinator()
	threads = tf.train.start_queue_runners(sess=sess, coord=coord)
	print(threads)
	
	try:
	    step = 0
	    while not coord.should_stop() and step < 500:
	        step += 1
	        sess.run([train_op])
	        if step % 50 == 0:
	            loss_mean_val = sess.run(loss_mean)
	            print('step %d : %f' % (step, loss_mean_val))
	except tf.errors.OutOfRangeError:
	    print('Done training for %d epochs, %d steps.' % (NUM_EPOCHS, step))
	finally:
	    coord.request_stop()
	
	coord.join(threads)
	sess.close()

       

  完整代码

	from __future__ import print_function
	import os
	import tensorflow as tf
	from tensorflow.contrib.learn.python.learn.datasets import mnist
	import numpy as np
	
	save_dir = 'c:/tmp/data'
	NUM_EPOCHS = 500
	
	# # Download data to save_dir
	# data_sets = mnist.read_data_sets(save_dir, dtype=tf.uint8, reshape=False, validation_size=1000)
	#
	# data_splits = ["train", "test", "validation"]
	# for d in range(len(data_splits)):
	#     print("saving" + data_splits[d])
	#     data_set = data_sets[d]
	#
	#     filename = os.path.join(save_dir, data_splits[d] + '.tfrecords')
	#     writer = tf.python_io.TFRecordWriter(filename)
	#
	#     for index in range(data_set.images.shape[0]):
	#         image = data_set.images[index].tostring()
	#         example = tf.train.Example(features=tf.train.Features(feature={
	#             'height' : tf.train.Feature(int64_list=tf.train.Int64List(value=[data_set.images.shape[1]])),
	#             'width' : tf.train.Feature(int64_list=tf.train.Int64List(value=[data_set.images.shape[2]])),
	#             'depth' : tf.train.Feature(int64_list=tf.train.Int64List(value=[data_set.images.shape[3]])),
	#             'label' : tf.train.Feature(int64_list=tf.train.Int64List(value=[int(data_set.labels[index])])),
	#             'image_raw' : tf.train.Feature(bytes_list=tf.train.BytesList(value=[image]))
	#         }))
	#
	#         writer.write(example.SerializeToString())
	#     writer.close()
	
	filename = os.path.join(save_dir, "train.tfrecords")
	# 在幕后创建一个QueueRunner, 将文件名子字符串输出到我们输入通道的队列中
	# 这个文件名队列将被多个多线程共享
	filename_queue = tf.train.string_input_producer([filename], num_epochs=10)
	
	# 接着使用 TFReacordReader()从队列中读取文件,TFReacordReader()会以文件名队列为参数,按照文件名从 filename_queue 中出队。
	# TFReacordReader()内部实现使用计算图的状态来跟踪将要被读取的 TFRecord 的位置,一块块地从磁盘的输入数据中加载
	reader = tf.TFRecordReader()
	_, serialized_example = reader.read(filename_queue)
	
	# 返回一个 dict,解析数据并映射功能键到 Tensor 和 SparseTensor
	features = tf.parse_single_example(
	    serialized_example,
	    features={
	        'image_raw': tf.FixedLenFeature([], tf.string),
	        'label': tf.FixedLenFeature([], tf.int64)
	    })
	
	# 解码原始字节字符串数据,进行基本的预处理,将像素值转换为浮点数,然后将图像实例进行重新排序,并通过 tf.train.shuffle_batch()
	# 将其收集到 batch_size 批处理中,内部使用 RandomShuffleQueue 并累计示例,直到它包含 batch_size + min_sfter_dequeue个元素
	image = tf.decode_raw(features['image_raw'], tf.uint8)
	image.set_shape([784])
	image = tf.cast(image, tf.float32) * (1. / 255) - 0.5
	label = tf.cast(features['label'], tf.int32)
	
	# 随机采集一批数据
	images_batch, labels_batch = tf.train.shuffle_batch(
	    [image, label], batch_size=16,
	    capacity=200, min_after_dequeue=100)
	
	# 定义简单的 softmax 分类模型
	W = tf.get_variable("W", [28*28, 10])
	y_pred = tf.matmul(images_batch, W)
	loss = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y_pred, labels=labels_batch)
	
	loss_mean = tf.reduce_mean(loss)
	
	train_op = tf.train.AdamOptimizer().minimize(loss)
	
	config = tf.ConfigProto()
	config.gpu_options.allow_growth = True
	
	sess = tf.Session(config=config)
	init = tf.global_variables_initializer()
	sess.run(init)
	init = tf.local_variables_initializer()
	sess.run(init)
	
	coord = tf.train.Coordinator()
	threads = tf.train.start_queue_runners(sess=sess, coord=coord)
	print(threads)
	
	try:
	    step = 0
	    while not coord.should_stop() and step < 500:
	        step += 1
	        sess.run([train_op])
	        if step % 50 == 0:
	            loss_mean_val = sess.run(loss_mean)
	            print('step %d : %f' % (step, loss_mean_val))
	except tf.errors.OutOfRangeError:
	    print('Done training for %d epochs, %d steps.' % (NUM_EPOCHS, step))
	finally:
	    coord.request_stop()
	
	coord.join(threads)
	sess.close()

       

       本文示例参考《TensorFlow学习指南——深度学习系统构建详解》第八章第四节。

       
       欢迎各位大佬交流讨论!

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

TensorFlow-v2.15

TensorFlow-v2.15

TensorFlow

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

<think>好的,我现在需要帮助用户找到关于使用PyTorch实现图像识别多分类的教程或代码示例。用户特别提到了“pytorch 多分类 图像识别 教程 实现 代码”这几个关键词,所以我要确保覆盖这些方面。 首先,我应该回顾用户提供的引用内容。引用[1]、[2]、[3]、[4]都提到了PyTorch在图像分类中的应用,其中引用[1]和[3]提到了数据准备的步骤,引用[2]讨论了ZFNet的结构,引用[4]则列出了多个不同的模型,如LSTM、GRU、LeNet5等。这些信息可以帮助用户了解不同的网络结构和实现方法。 接下来,我需要整理实现多分类图像识别的基本步骤。通常,这包括数据准备、模型搭建、训练流程和测试验证。用户可能需要一个结构化的指南,所以分步骤说明会比较清晰。 数据准备部分,引用[1]和[3]都提到了数据集的准备,比如使用ImageFolder加载数据,进行预处理和数据增强。需要详细说明如何组织数据集目录结构,以及应用哪些变换,比如调整大小、标准化等。同时,数据加载器的设置也很重要,比如批量大小和是否使用多线程加载。 模型搭建方面,用户可能对不同的网络结构感兴趣。引用[2]中的ZFNet和引用[4]中的LeNet5都是经典的CNN模型,可以作为示例。此外,还可以提到使用预训练模型进行迁移学习,比如ResNet,这在实践中非常常见。需要提供代码片段,展示如何定义模型结构,包括卷积层、激活函数、池化层和全连接层。 训练流程部分,需要包括损失函数(如交叉熵损失)、优化器(如Adam或SGD)、学习率调整以及训练循环。引用[1]和[3]可能涉及训练代码的结构,可以引用这些内容。同时,要强调训练过程中的关键步骤,如前向传播、损失计算、反向传播和参数更新。 测试和验证阶段,准确率计算和模型保存是重点。需要说明如何在测试集上评估模型性能,并保存训练好的模型以供后续使用。 用户可能需要更多的示例项目,引用中提到的花卉识别、自然风光分类、钢板缺陷检测等都可以作为应用案例。这些示例不仅展示了不同的数据集,还提供了完整的代码和配置教程,对用户很有帮助。 最后,生成的相关问题需要考虑用户可能遇到的后续疑问,比如数据增强方法、处理类别不平衡、提升准确率的技巧、迁移学习的应用以及部署模型的方法。这些问题可以帮助用户深入学习和解决问题。 需要确保回答结构清晰,分步骤讲解,并正确引用提供的资料。同时,检查LaTeX格式是否符合要求,数学表达式是否正确使用$...$或$$...$$,代码块使用正确的语法高亮,如Python的代码示例。</think>### PyTorch图像多分类实现指南 根据提供的参考资料,实现流程主要包含数据准备、模型搭建、训练验证三个核心环节。以下分步骤说明实现方法: #### 一、数据准备 1. 数据集目录结构需按类别划分: ``` dataset/ train/ class1/ class2/ test/ class1/ class2/ ``` 2. 使用$transforms.Compose$进行预处理: ```python transform = transforms.Compose([ transforms.Resize((224,224)), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]) ``` 3. 加载数据时使用$ImageFolder$: ```python train_dataset = datasets.ImageFolder(root='dataset/train', transform=transform) train_loader = DataLoader(dataset, batch_size=32, shuffle=True, num_workers=4) ``` [^3]中详细说明了数据准备流程 #### 二、模型搭建 1. CNN基础结构示例(LeNet5变体): ```python class CNN(nn.Module): def __init__(self, num_classes): super().__init__() self.features = nn.Sequential( nn.Conv2d(3, 6, 5), # 输入通道3,输出通道6 nn.ReLU(), nn.MaxPool2d(2), nn.Conv2d(6, 16, 5), nn.ReLU(), nn.MaxPool2d(2) ) self.classifier = nn.Sequential( nn.Linear(16*53*53, 120), # 根据输入尺寸调整 nn.ReLU(), nn.Linear(120, num_classes) ) ``` [^4]提供了多种网络结构实现 2. 使用预训练模型(迁移学习): ```python model = torchvision.models.resnet18(pretrained=True) num_ftrs = model.fc.in_features model.fc = nn.Linear(num_ftrs, num_classes) # 修改最后一层 ``` #### 三、训练流程 1. 设置损失函数与优化器: ```python criterion = nn.CrossEntropyLoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.001) scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=7, gamma=0.1) ``` 2. 训练循环关键代码: ```python for epoch in range(epochs): for inputs, labels in train_loader: outputs = model(inputs) loss = criterion(outputs, labels) optimizer.zero_grad() loss.backward() optimizer.step() scheduler.step() print(f'Epoch {epoch+1}/{epochs}, Loss: {loss.item():.4f}') ``` [^1]中的训练流程可作参考 #### 四、测试验证 1. 计算准确率: ```python correct = 0 total = 0 with torch.no_grad(): for data in test_loader: images, labels = data outputs = model(images) _, predicted = torch.max(outputs.data, 1) total += labels.size(0) correct += (predicted == labels).sum().item() print(f'Accuracy: {100 * correct / total:.2f}%') ``` 2. 模型保存与加载: ```python torch.save(model.state_dict(), 'model.pth') model.load_state_dict(torch.load('model.pth')) ``` #### 五、完整示例项目推荐 1. 花卉图像识别(ZFNet实现)[^2] 2. 自然风光场景分类[^3] 3. MNIST手写数字分类(含LSTM/GRU变体) 4. 钢板表面缺陷分类(工业应用场景) ```python # 完整训练框架示例 import torch from torchvision import transforms, datasets, models if __name__ == '__main__': # 数据加载 train_transform = transforms.Compose([...]) train_data = datasets.ImageFolder('path/to/data', transform=train_transform) train_loader = DataLoader(train_data, batch_size=32, shuffle=True) # 模型初始化 model = models.resnet18(pretrained=True) model.fc = nn.Linear(model.fc.in_features, len(train_data.classes)) # 训练配置 device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model = model.to(device) # 执行训练 for epoch in range(100): train_one_epoch(model, train_loader, device) ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值