mnist multi_layer

本文介绍了一种使用TensorFlow实现的手写数字识别系统。该系统通过构建一个多层卷积神经网络来处理MNIST数据集,并详细展示了从数据加载到模型训练及评估的全过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import tensorflow as tf
import tensorflow.examples.tutorials.mnist.input_data as input_data
#定义变量
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): 
  return tf.nn.conv2d(x,W,strides=[1,1,1,1],padding='SAME')
#定义池化操作
def max_pool_2x2(x): 
  return tf.nn.max_pool(x,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
#load dataset
mnist=input_data.read_data_sets("MNIST_data/",one_hot=True)
#定义输入图片变量x
x=tf.placeholder(tf.float32,[None,784])
#定义label变量y_
y_=tf.placeholder("float",[None,10])
x_image=tf.reshape(x,[-1,28,28,1])
#the first layer
W_conv1 = weight_variable([5,5,1,32])b_conv1 = bias_variable([32])
h_conv1 = tf.nn.relu(conv2d(x_image,W_conv1)+b_conv1)
h_pool1 = max_pool_2x2(h_conv1)
#the second layer
W_conv2 = weight_variable([5,5,32,64])
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1,W_conv2)+b_conv2)
h_pool2 = max_pool_2x2(h_conv2)
#the first full connection layer
W_fc1 = weight_variable([7*7*64,1024])
b_fc1 = bias_variable([1024])
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)
#dropout
keep_prob = tf.placeholder("float")
h_fc1_drop = tf.nn.dropout(h_fc1,keep_prob)
#the second full connection layer
W_fc2 = weight_variable([1024,10])
b_fc2 = bias_variable([10])
y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop,W_fc2)+b_fc2)
#compute loss
cross_entropy=-tf.reduce_sum(y_*tf.log(y_conv))
train_step=tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
correct_prediction=tf.equal(tf.argmax(y_conv,1),tf.argmax(y_,1))
accuracy=tf.reduce_mean(tf.cast(correct_prediction,"float"))
#初始化变量
init=tf.initialize_all_variables()
sess=tf.InteractiveSession()sess.run(init)
#迭代20000次,每100次,输出一次accuracy,batch=50
for i in range(20000): 
batch=mnist.train.next_batch(50) 
  if i%100 == 0: 
    train_accuracy = accuracy.eval(feed_dict={ x:batch[0],y_:batch[1],keep_prob: 1.0}) 
    print "step %d ,training accuracy %g"%(i,train_accuracy) 
  train_step.run(feed_dict={x:batch[0],y_:batch[1],keep_prob:0.5})#训练时keep_prob=0.5,测试时keep_prob=1.0#输出在测试集上的准确率
print "test accuracy %g" %accuracy.eval(feed_dict={x:mnist.test.images,y_:mnist.test.labels,keep_prob:0.5})

-------- TEST CPU -------- Loading MNIST data from files... Load images from ./mnist_data/train-images-idx3-ubyte, number: 60000, data shape: (60000, 784) Load images from ./mnist_data/train-labels-idx1-ubyte, number: 60000, data shape: (60000, 1) Load images from ./mnist_data/t10k-images-idx3-ubyte, number: 10000, data shape: (10000, 784) Load images from ./mnist_data/t10k-labels-idx1-ubyte, number: 10000, data shape: (10000, 1) Building multi-layer perception model... Fully connected layer with input 784, output 100. Relu layer Fully connected layer with input 100, output 100. Relu layer Fully connected layer with input 100, output 10. Softmax loss layer. Initializing parameters of each layer in MLP... inferencing time: 1.480017 Accuracy in test set: 0.087400 -------- TEST DLP -------- Init success: creating mlp layer ... creating relu layer ... [2025-5-31 22:49:1] [CNNL] [Warning]:[cnnlSetActivationDescriptor] is deprecated and will be removed in the future release, please use [cnnlSetActivationDescriptor_v5] instead. creating mlp layer ... creating relu layer ... creating mlp layer ... creating relu layer ... softmax output_shape: [10000 1 10 Loading MNIST data from files... Load images from ./mnist_data/t10k-images-idx3-ubyte, number: 10000, data shape: (10000, 784) Load images from ./mnist_data/t10k-labels-idx1-ubyte, number: 10000, data shape: (10000, 1) Loading parameters from file /opt/code_chap_2_3/code_chap_2_3_student/exp_2_2_mnist_mlp_dlp/stu_upload/weight.npy w1 shape: (78400,) b1 shape: (100,) loading params for layer fc1 ... Segmentation fault (core dumped)
最新发布
06-01
<think>好的,我现在需要帮助用户解决在加载MNIST数据并初始化多层感知机模型时出现的段错误(SegmentationFault)问题,同时用户还提到了一个关于cnnlSetActivationDescriptor的警告。首先,我需要回忆一下段错误的常见原因,并结合用户的具体场景来分析可能的原因。根据用户提供的引用内容,段错误通常由缓冲区溢出、空指针引用、数组越界或错误的内存释放引起。用户的问题发生在加载数据和初始化模型阶段,可能涉及数据读取、内存分配或库函数调用的问题。首先考虑数据加载部分。MNIST数据集通常是图像文件,比如IDX格式,如果用户自己编写数据加载代码,可能在读取文件时出现缓冲区溢出或指针错误。例如,错误的内存分配大小,或者访问了未初始化的指针,导致写入越界,触发段错误。然后是模型初始化部分。用户提到使用ReLU和Softmax层的多层感知机,可能涉及到矩阵运算或激活函数的设置。那个cnnlSetActivationDescriptor的警告可能来自某个深度学习框架(比如CNNL库)的激活层描述符设置不正确,比如传入了无效参数或未正确初始化描述符,导致后续操作出错。 接下来需要分步骤排查:1.**检查数据加载代码**:确保读取MNIST文件时正确解析了文件头,分配了足够的内存,没有越界访问。例如,MNIST图像文件的头信息包含魔数和图像数量、尺寸等,如果解析错误,可能导致分配的内存不足,后续读取时溢出。 2. **验证指针和数组访问**:在数据加载和模型参数初始化过程中,所有指针都应正确初始化,数组访问不应超出分配的范围。使用调试工具如GDB跟踪程序崩溃的位置,确定是哪个函数或哪行代码导致的段错误。 3. **检查深度学习框架的API调用**:查看cnnlSetActivationDescriptor函数的文档,确认参数是否正确,比如激活类型、斜率等。错误的参数可能导致库内部访问非法内存地址,从而引发段错误。警告信息可能提示参数问题,需处理警告而非忽略。4.**内存管理问题**:确保在创建网络层时正确分配和释放内存。例如,如果在初始化层时未正确分配权重矩阵的内存,后续前向传播时访问会导致段错误。 5. **库的版本或兼容性**:如果使用的库(如CNNL)版本与系统或其他库不兼容,也可能导致运行时错误。检查库的安装是否正确,是否有依赖项缺失或版本冲突。 6. **使用工具排查**:建议用户使用Valgrind或AddressSanitizer检测内存错误,这些工具可以帮助发现内存泄漏、越界访问等问题。另外,用户可能在代码中混合使用了不同的内存分配方式,比如在C++中混用malloc和delete,导致未定义行为。或者,在多线程环境中未正确同步数据访问,导致竞争条件,进而引发内存错误。 总结可能的原因:数据加载时的内存处理错误、模型参数初始化时的无效指针、激活函数描述符配置不当、库函数调用错误或内存管理问题。需要逐一排查这些方面,结合调试工具和日志信息来定位问题根源。</think>### 分段错误(Segmentation Fault)的排查与解决步骤 在加载MNIST数据并初始化多层感知机(MLP)模型时,段错误通常与**内存越界访问**、**空指针引用**或**第三方库配置错误**相关。以下是具体排查方法: --- #### **1. 检查MNIST数据加载过程** MNIST数据集通常以二进制文件(如IDX格式)存储,若数据读取代码未正确处理文件头或缓冲区大小,可能导致段错误。 - **验证文件解析逻辑**: 确保读取文件头时正确解析了魔数(Magic Number)、图像数量、尺寸等信息。例如: ```python # 正确读取MNIST文件头的示例(Python) with open('train-images-idx3-ubyte', 'rb') as f: magic = int.from_bytes(f.read(4), byteorder='big') num_images = int.from_bytes(f.read(4), byteorder='big') rows = int.from_bytes(f.read(4), byteorder='big') cols = int.from_bytes(f.read(4), byteorder='big') data = f.read(rows * cols * num_images) # 确保分配足够内存 ``` 若`data`缓冲区大小不足,后续访问会触发段错误[^1][^3]。 - **使用调试工具定位问题**: 通过`GDB`或`Valgrind`检查数据加载代码的内存访问: ```bash valgrind --tool=memcheck --leak-check=yes ./your_program ``` 若输出显示`Invalid write`或`Address 0x0 is not stack'd`,说明存在越界或空指针问题[^3][^4]。 --- #### **2. 验证模型初始化代码** 多层感知机的初始化涉及权重矩阵分配和激活函数设置。若未正确分配内存或传递无效参数,可能触发段错误。 - **检查激活函数配置**: 用户提到的`cnnlSetActivationDescriptor`警告可能源于参数错误(如无效的`alpha`值或未支持的激活类型)。例如,在设置ReLU时需确保参数符合库的要求: ```c // 示例:正确设置ReLU描述符(假设使用CNNL库) cnnlActivationDescriptor_t relu_desc; cnnlCreateActivationDescriptor(&relu_desc); cnnlSetActivationDescriptor(relu_desc, CNNL_ACTIVATION_RELU, 0.0, 0.0); // 检查alpha值是否合法 ``` 若参数不合法(如`alpha`为负值),库可能访问非法内存地址[^3][^4]。 - **检查权重矩阵维度**: 确保输入层、隐藏层、输出层的维度匹配。例如: $$W_1 \in \mathbb{R}^{784 \times 256}, \quad W_2 \in \mathbb{R}^{256 \times 10}$$ 若维度错误(如矩阵乘法形状不匹配),可能导致越界访问[^1]。 --- #### **3. 排查第三方库依赖问题** 深度学习框架(如CNNL、CUDA)的版本冲突或安装错误也可能导致段错误。 - **验证库的兼容性**: 检查库版本是否与系统架构(如GPU驱动版本)匹配。例如,CUDA 11.x需与对应版本的cuDNN配合使用。 - **重新安装依赖项**: 若安装过程中部分文件损坏(如`.so`文件缺失),可能触发段错误。可尝试: ```bash # 清理并重新安装库(以CNNL为例) make clean ./configure make sudo make install ``` 引用[^2]中提到,文件校验(如`md5sum`)可避免因下载损坏导致的运行时错误。 --- #### **4. 代码审查与测试** - **隔离问题模块**: 先注释模型初始化代码,仅运行数据加载部分,确认段错误是否由数据读取引起。 - **逐步启用功能**: 若数据加载正常,逐步添加模型初始化代码,定位具体触发段错误的函数调用。 --- ### 总结 段错误的核心原因是**非法内存访问**,需通过以下步骤解决: 1. 使用`Valgrind`或`GDB`定位崩溃位置。 2. 检查数据加载代码的内存分配与文件解析逻辑。 3. 验证模型参数(如矩阵维度、激活函数描述符)。 4. 确保第三方库版本兼容且安装完整。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值