cnn for mnist

本文介绍了一种使用TensorFlow实现的卷积神经网络(CNN)模型,该模型应用于MNIST手写数字识别任务中,并达到了97%的高精度。模型包含两个卷积层和两个全连接层,通过tf.reshape函数进行数据处理。
  
 

#代码可运行,准确率高达97%

#tensorflow实现的用cnn处理mnist数据集,2个卷积层,2个全连接层,注意tf.reshape(...)函数的用法

  
 """
 Please note, this code is only for python 3+. If you are using python 2+, please modify the code accordingly.
 """
 from __future__ import print_function
 import tensorflow as tf
 from tensorflow.examples.tutorials.mnist import input_data
 # number 1 to 10 data
 mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
  
 def compute_accuracy(v_xs, v_ys):
 global prediction
 y_pre = sess.run(prediction, feed_dict={xs: v_xs, keep_prob: 1})
 correct_prediction = tf.equal(tf.argmax(y_pre,1), tf.argmax(v_ys,1))
 accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
 result = sess.run(accuracy, feed_dict={xs: v_xs, ys: v_ys, keep_prob: 1})
 return result
  
 def weight_variable(shape):
 initial = tf.truncated_normal(shape, stddev=0.1)
 return tf.Variable(initial)
  
 def bias_variable(shape):
 initial = tf.constant(0.1, shape=shape)
 return tf.Variable(initial)
  
 def conv2d(x, W):
 # stride [1, x_movement, y_movement, 1]
 # Must have strides[0] = strides[3] = 1
 return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
  
 def max_pool_2x2(x):
 # stride [1, x_movement, y_movement, 1]
 return tf.nn.max_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')
  
 # define placeholder for inputs to network
 xs = tf.placeholder(tf.float32, [None, 784])/255. # 28x28
 ys = tf.placeholder(tf.float32, [None, 10])
 keep_prob = tf.placeholder(tf.float32)
 x_image = tf.reshape(xs, [-1, 28, 28, 1])
 # print(x_image.shape) # [n_samples, 28,28,1]
  
 ## conv1 layer ##
 W_conv1 = weight_variable([5,5, 1,32]) # patch 5x5, in size 1, out size 32
 b_conv1 = bias_variable([32])
 h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1) # output size 28x28x32
 h_pool1 = max_pool_2x2(h_conv1) # output size 14x14x32
  
 ## conv2 layer ##
 W_conv2 = weight_variable([5,5, 32, 64]) # patch 5x5, in size 32, out size 64
 b_conv2 = bias_variable([64])
 h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2) # output size 14x14x64
 h_pool2 = max_pool_2x2(h_conv2) # output size 7x7x64
  
 ## fc1 layer ##
 W_fc1 = weight_variable([7*7*64, 1024])
 b_fc1 = bias_variable([1024])
 # [n_samples, 7, 7, 64] ->> [n_samples, 7*7*64]
 h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
 h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
 h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
  
 ## fc2 layer ##
 W_fc2 = weight_variable([1024, 10])
 b_fc2 = bias_variable([10])
 prediction = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
  
  
 # the error between prediction and real data
 cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(prediction),
 reduction_indices=[1])) # loss
 train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
  
 sess = tf.Session()
 # important step
 # tf.initialize_all_variables() no long valid from
 # 2017-03-02 if using tensorflow >= 0.12
 if int((tf.__version__).split('.')[1]) < 12 and int((tf.__version__).split('.')[0]) < 1:
 init = tf.initialize_all_variables()
 else:
 init = tf.global_variables_initializer()
 sess.run(init)
  
 for i in range(1000):
 batch_xs, batch_ys = mnist.train.next_batch(100)
 sess.run(train_step, feed_dict={xs: batch_xs, ys: batch_ys, keep_prob: 0.5})
 if i % 50 == 0:
 print(compute_accuracy(
 mnist.test.images[:1000], mnist.test.labels[:1000]))
<think>嗯,用户想用CNN实现MNIST数据集的分类任务。首先,我需要回忆一下MNIST数据集的结构。MNIST是手写数字图片,28x28的灰度图,所以输入通道是1。分类任务需要输出10个类别,对应数字0到9。 接下来,用户可能需要一个简单的CNN结构。根据引用[1]和[2]的内容,PyTorch里搭建CNN通常包括卷积层、激活函数、池化层,最后接全连接层。比如,经典的LeNet结构可能适用,但可能需要调整层数。 然后,数据加载部分。用户需要知道如何用PyTorch的DataLoader加载MNIST数据集,设置batch size,转换数据为Tensor。引用[1]里的代码示例应该有用,比如使用torchvision.datasets.MNIST,设置transform为ToTensor(),然后用DataLoader分批次加载。 模型构建方面,应该包含卷积层和全连接层。比如,第一个卷积层用nn.Conv2d(1, 16, 3),输入通道1,输出16个特征图,3x3的核。接着ReLU激活,然后最大池化。第二个卷积层可能增加到32个特征图,池化后展平,再通过全连接层输出10个类别。 训练过程需要定义损失函数,比如交叉熵损失,优化器选Adam或者SGD。训练循环中,前向传播、计算损失、反向传播、优化参数。每个epoch后测试准确率,监控模型表现。 可能还需要考虑数据预处理,比如归一化,但引用[1]里用了ToTensor(),它会将像素值缩放到[0,1]。不过有时会进一步归一化到[-1,1]或者使用均值和标准差,但用户示例中没有提到,可能需要指出这一点作为优化点。 另外,引用[2]提到卷积层保留空间结构,相比全连接的优势,所以需要在解释CNN结构时强调这一点。用户可能想知道为什么用CNN而不是全连接网络,可以引用[2]的内容说明。 代码示例部分,要确保正确使用PyTorch的模块,比如定义继承nn.Module的类,正确设置各层的参数。还要注意展平操作,卷积层后的特征图尺寸变化,避免全连接层的输入尺寸错误。 测试阶段,用model.eval(),不计算梯度,用torch.no_grad()循环测试集,计算准确率。引用[1]中的测试代码可以作为参考。 最后,用户可能需要优化方法,比如学习率调整、数据增强、增加网络深度或使用Dropout,但这些可能作为相关问题提出。需要确保回答覆盖基本实现步骤,结构清晰,代码正确,并引用相关参考资料中的内容。</think>### CNN实现MNIST分类任务分步指南 #### 一、数据准备 1. 数据集加载 使用`torchvision`模块直接下载MNIST数据集,设置训练集和测试集的转换器: ```python import torchvision from torch.utils.data import DataLoader # 数据标准化(将像素值[0,1]转换为[-1,1]) transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,)) ]) trainset = torchvision.datasets.MNIST( root='./data', train=True, transform=transform, download=True ) testset = torchvision.datasets.MNIST( root='./data', train=False, transform=transform ) trainloader = DataLoader(trainset, batch_size=128, shuffle=True) testloader = DataLoader(testset, batch_size=128, shuffle=False) ``` *说明:`Normalize`操作可加速模型收敛[^1]* #### 二、CNN模型搭建 2. 网络结构设计 典型CNN结构包含卷积层、激活函数、池化层和全连接层: ```python import torch.nn as nn class CNN(nn.Module): def __init__(self): super(CNN, self).__init__() self.conv1 = nn.Conv2d(1, 16, 3) # 输入通道1,输出16通道,3x3卷积核 self.pool = nn.MaxPool2d(2, 2) # 2x2最大池化 self.conv2 = nn.Conv2d(16, 32, 3) self.fc1 = nn.Linear(32*5*5, 128) # 展平后维度计算 self.fc2 = nn.Linear(128, 10) def forward(self, x): x = self.pool(nn.functional.relu(self.conv1(x))) # 输出尺寸:(16,13,13) x = self.pool(nn.functional.relu(self.conv2(x))) # 输出尺寸:(32,5,5) x = x.view(-1, 32*5*5) # 展平操作 x = nn.functional.relu(self.fc1(x)) x = self.fc2(x) return x ``` *卷积层保留空间结构特性是CNN的关键优势[^2]* #### 三、模型训练 3. 训练配置 ```python import torch.optim as optim model = CNN() criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.001) for epoch in range(10): for images, labels in trainloader: outputs = model(images) loss = criterion(outputs, labels) optimizer.zero_grad() loss.backward() optimizer.step() print(f'Epoch [{epoch+1}/10], Loss: {loss.item():.4f}') ``` #### 四、性能评估 4. 测试准确率计算 ```python correct = 0 total = 0 with torch.no_grad(): for images, labels in testloader: outputs = model(images) _, predicted = torch.max(outputs.data, 1) total += labels.size(0) correct += (predicted == labels).sum().item() print(f'Test Accuracy: {100 * correct / total:.2f}%') ``` *典型结果可达98%+准确率[^1]*
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值