21个项目玩转深度学习

21个项目玩转深度学习
一、MNIST机器学习入门1.1查看变量形状大小import tensorflow as tf #使用内置数据集、张量运算、独热编码 API import numpy as np #把 Tensor 张量转为标准 numpy 数组 # 1. 加载 MNIST 数据自动下载/缓存 (x_train, y_train), (x_test, y_test) tf.keras.datasets.mnist.load_data() # 2. 手动拆分训练集 → 训练 验证 x_val x_train[55000:] #55000取到末尾 y_val y_train[55000:] x_train x_train[:55000] #取到55000 y_train y_train[:55000] # 3. 展平图片28×28 → 784并归一化到 0~1 x_train x_train.reshape(-1, 784) / 255.0 x_val x_val.reshape(-1, 784) / 255.0 x_test x_test.reshape(-1, 784) / 255.0 # 4. one-hot 编码标签 y_train tf.one_hot(y_train, depth10).numpy()#训练 y_val tf.one_hot(y_val, depth10).numpy()#验证 y_test tf.one_hot(y_test, depth10).numpy()#测试 # 5. 打印数据形状 print(x_train.shape) # (55000, 784) print(y_train.shape) # (55000, 10) print(x_val.shape) # (5000, 784) print(y_val.shape) # (5000, 10) print(x_test.shape) # (10000, 784) print(y_test.shape) # (10000, 10) # 6. 打印第0张图片和标签 print(x_train[0, :]) print(y_train[0, :])为什么要用独热编码直接用数字作为标签神经网络会误以为这是回归数值而非分类标签训练完全跑偏。比如实际数值5按数值预测预测为4比3的差距小但实际图像处理预测为3或者4其实误差都一样使用hot -one可以使其平等举例考场十个题型题型 0~ 题型 9阅卷时平等独热答错任意一道题扣分一致认真均衡学习所有题型不平等原始数字答错题 9 扣 9 分、答错题 0 只扣 1 分学生会只玩命练题型 0、1完全放弃 7、8、9最终偏科严重。实验1.MNIST数据集保存为图片代码import ssl ssl._create_default_https_context ssl._create_unverified_context #Python 内置安全套接字模块用于 HTTPS 网络请求的证书加密校验 #我用的是独立 Conda 虚拟环境dl_21project这个环境自带一套独立的 CA 根证书文件不和 Windows 系统证书共用此操作关闭ssl证书验证 #更新打开Anaconda Prompt #输入conda activate dl_21project #pip install --upgrade certifi import tensorflow as tf #TensorFlow 内置高级高阶 API封装了极简的数据集加载、网络搭建、训练接口适合快速原型开发 from PIL import Image#图像处理库 import os # 1. 自动创建文件夹 save_dir MNIST_data/raw/ os.makedirs(save_dir, exist_okTrue)#递归创建多级文件夹 # 2. 加载 MNIST 数据集 (x_train, y_train), (x_test, y_test) tf.keras.datasets.mnist.load_data() # 3. 保存前 20 张图片 for i in range(20): img Image.fromarray(x_train[i])#将 numpy 像素数组转为 PIL 图像对象 filename os.path.join(save_dir, fmnist_train_{i}.jpg) #把「文件夹路径」和「文件名」拼在一起生成一个合法的、可直接用于保存文件的完整路径。 img.save(filename)#将图像对象写入本地磁盘 print(真实 MNIST 图片已保存到:, os.path.abspath(save_dir))#将相对路径转换为系统绝对物理路径生成效果打印前20张的标签import tensorflow as tf import numpy as np (x_train, y_train), (x_test, y_test) tf.keras.datasets.mnist.load_data() # 转为one-hot y_train_onehot tf.one_hot(y_train, depth10).numpy() for i in range(20): one_hot_label y_train_onehot[i] label np.argmax(one_hot_label)#数组中最大值元素对应的下标索引 print(mnist_train_%d.jpg label: %d % (i, label))1.2Softmax函数将各种输入的“打分”输出为概率。Softmax回归手写数字识别import tensorflow as tf # 加载数据并预处理 (x_train, y_train), (x_test, y_test) tf.keras.datasets.mnist.load_data() x_train x_train.reshape(-1, 784) / 255.0 x_test x_test.reshape(-1, 784) / 255.0 y_train tf.one_hot(y_train, depth10) y_test tf.one_hot(y_test, depth10) # 构建 Softmax 模型 model tf.keras.Sequential([ tf.keras.layers.Dense(10, activationsoftmax, input_shape(784,)) ]) # 编译模型SGD 优化器 交叉熵损失 model.compile(optimizertf.keras.optimizers.SGD(0.01), #优化器:SGD0.01学习率每次参数更新的步长 losscategorical_crossentropy,#损失函数多分类交叉熵 metrics[accuracy])#评估指标准确率 # 训练 model.fit(x_train, y_train, batch_size100, epochs1000//(60000//100)) # 约17个epoch等价1000步 # 评估 test_loss, test_acc model.evaluate(x_test, y_test) print(test_acc) # 结果接近原代码的 0.9185运行两层卷积网络分类输入 → 卷积 1ReLU 池化 → 卷积 2ReLU 池化 → 展平 → 全连接 1Dropout → 全连接 2 输出 logits → 交叉熵损失 Adam 优化。# coding: utf-8 import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data #卷积核、全连接层权重初始化 def weight_variable(shape): initial tf.truncated_normal(shape, stddev0.1) return tf.Variable(initial)#用于反向传播更新 #每层卷积、全连接偏置初始化 def bias_variable(shape): initial tf.constant(0.1, shapeshape)#0.1避免 ReLU 激活后输出全 0 return tf.Variable(initial) #二维卷积运算封装:提取图像边缘、纹理、轮廓局部特征 def conv2d(x, W): return tf.nn.conv2d(x, W, strides[1, 1, 1, 1], paddingSAME)#特征图权重步长等宽填充 #最大池化压缩特征、降低计算量、防止过拟合保留区域最强特征 def max_pool_2x2(x): return tf.nn.max_pool(x, ksize[1, 2, 2, 1], strides[1, 2, 2, 1], paddingSAME) if __name__ __main__: # 读入数据 mnist input_data.read_data_sets(MNIST_data/, one_hotTrue) # x为训练图像的占位符、y_为训练图像标签的占位符 x tf.placeholder(tf.float32, [None, 784]) y_ tf.placeholder(tf.float32, [None, 10]) # 将单张图片从784维向量重新还原为28x28的矩阵图片 x_image tf.reshape(x, [-1, 28, 28, 1]) # 第一层卷积层 W_conv1 weight_variable([5, 5, 1, 32])#卷积核尺寸5×5输入通道 1灰度输出 32 个卷积核 b_conv1 bias_variable([32])#输出 32 张特征图 h_conv1 tf.nn.relu(conv2d(x_image, W_conv1) b_conv1)#tf.nn.relu非线性激活 h_pool1 max_pool_2x2(h_conv1)#经过 2×2 池化输出尺寸从28×28 → 14×14通道数保持 32 # 第二层卷积层 W_conv2 weight_variable([5, 5, 32, 64])#输入通道 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)#池化后缩小为7×7 # 全连接层输出为1024维的向量 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) # 使用Dropoutkeep_prob是一个占位符训练时为0.5测试时为1 keep_prob tf.placeholder(tf.float32)#Dropout保留概率占位符防止过拟合 h_fc1_drop tf.nn.dropout(h_fc1, keep_prob) # 输出层全连接把1024维的向量转换成10维对应10个类别 W_fc2 weight_variable([1024, 10]) b_fc2 bias_variable([10]) y_conv tf.matmul(h_fc1_drop, W_fc2) b_fc2 # 我们不采用先Softmax再计算交叉熵的方法而是直接用tf.nn.softmax_cross_entropy_with_logits直接计算内部自动完成 Softmax 交叉熵计算 cross_entropy tf.reduce_mean( tf.nn.softmax_cross_entropy_with_logits(labelsy_, logitsy_conv)) # 同样定义train_step train_step tf.train.AdamOptimizer(1e-4).minimize(cross_entropy) # 定义测试的准确率 correct_prediction tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_, 1)) #按行取最大值下标把 10 维概率 / 独热向量转为数字 0~9 #对比预测与真实标签 accuracy tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) # 创建Session和变量初始化 sess tf.InteractiveSession() sess.run(tf.global_variables_initializer()) # 训练20000步 for i in range(20000): batch mnist.train.next_batch(50) # 每100步报告一次在验证集上的准确度 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})#更新参数 # 训练结束后报告在测试集上的准确度 print(test accuracy %g % accuracy.eval(feed_dict{ x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))疑问1.weight_variable (shape)权重初始化对比全 0 初始化、卷积不能全 0 初始化的原因全0初始化用于单层线性Softmx一层输出权重应当随即更新如果全为0失去训练意义应当用截断正态分布2.bias_variable (shape)偏置初始化后输出不能全为0ReLU 神经元死亡神经元在训练中永久输出 0无论输入什么数据梯度始终为 0参数再也无法更新3.占位符 tf.placeholder 是什么F2不载涉及占位符4.tf.reduce_mean 函数含义交叉熵5.. 会话初始化给全部可训练变量分配内存、执行初始值填充比如权重 W、偏置 b仅定义了初始化规则随机正态、常数 0.1)6.补充基础知识TensorFlow1 基础语法\Python 数值基础\深度学习基础理论(网络设计)