深度学习_07_5_随机梯度下降_手写数字问题实战(层)&TensorBoard可视化

本文介绍了使用TensorFlow进行FashionMNIST手写数字识别的深度学习模型构建,包括多层神经网络的设计、Adam优化器的应用以及损失函数的计算。同时,详细阐述了如何利用TensorBoard进行训练过程的可视化,包括损失曲线和图像数据的展示,展示了TensorBoard在模型监控和调试中的重要作用。

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

07_5_随机梯度下降_手写数字问题实战(层)&TensorBoard可视化

FashionMNIST实战(手写数字问题实战(层))

FashionMNIST

大小、类型和MNIST一样,只是图片内容是帽子、鞋子……10种。

黑白,28*28

代码实现

import  os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
#可以和之前的41_前向传播_forward.py一一对应(使用手写和keras)

import tensorflow as tf
#keras新建层
from tensorflow import keras
#datasets用于数据集的管理;layers用于Dense层;optimizers优化器;Sequential容器;metrics测试的度量器
from tensorflow.keras import datasets, layers, optimizers, Sequential, metrics

#预处理函数
def preprocess(x,y):
    #转换成Tensor,并且灰度值转换到0~1范围
    # x = tf.convert_to_tensor(x,dtype=tf.float32) /255.
    # y = tf.convert_to_tensor(y,dtype=tf.int32)

    #因为from_tensor_slices函数会自动转换成Tensor,在这里不需要转化
    #直接分别利用cast转化到float32和int32就ok
    x = tf.cast(x,dtype=tf.float32) /255.
    y = tf.cast(y,dtype=tf.int32)
    return x,y

(x,y),(x_test,y_test) = datasets.fashion_mnist.load_data()
print(x.shape,y.shape)

batchsz = 128
#构造数据集
db = tf.data.Dataset.from_tensor_slices((x,y))
#对数据集做预处理
#传入函数,对每一个(x,y)都进行处理
#.shuffle
#.batch,这里数据集比较小,因此batchsz设置大一些
db = db.map(preprocess).shuffle(10000).batch(batchsz)

#对test部分做同样处理
db_test = tf.data.Dataset.from_tensor_slices((x_test,y_test))
#对测试集来说,测试样本,因此不需要shuffle
db_test = db_test.map(preprocess).batch(batchsz)

#看样本,iter为迭代器,next去下个batch样本
db_iter = iter(db)
sample = next(db_iter)
#batch: (128, 28, 28) (128,)
print('batch:', sample[0].shape,sample[1].shape)

#到此数据已经准备完毕!!

#新建网络
#Sequential是容器,把每个层都传给容器后,它就是网络了
#一层相当于之前的->
# => [b,256] + [b,256] => [b,256]
#             h1 = x @ w1 + b1
#             # 非线性转化
#             h1 = tf.nn.relu(h1)

model = Sequential([
    #relu为激活函数
    #这里不需要写输入维度,因为TensorFlow会自动推算
    layers.Dense(256,activation=tf.nn.relu), # [b,784] -> [b,256]
    layers.Dense(128,activation=tf.nn.relu), # [b,256] -> [b,128]
    layers.Dense(64,activation=tf.nn.relu), # [b,128] -> [b,64]
    layers.Dense(32,activation=tf.nn.relu), # [b,64] -> [b,32]
    #最后一层一般不需要激活函数
    layers.Dense(10), # [b,32] -> [b,10] , 330 = 32*10(w)+10(b)
    #中间层的设置是随便取的,一般是从大到小降维的概念,因为对图片数据来说,输入的维度远远大于类型的维度
])
#首先喂一个输入来构建权值
model.build(input_shape=[None,28*28])
#打印网络结构
model.summary()
# Model: "sequential"
# _________________________________________________________________
# Layer (type)                 Output Shape              Param #
# =================================================================
# dense (Dense)                multiple                  200960
# _________________________________________________________________
# dense_1 (Dense)              multiple                  32896
# _________________________________________________________________
# dense_2 (Dense)              multiple                  8256
# _________________________________________________________________
# dense_3 (Dense)              multiple                  2080
# _________________________________________________________________
# dense_4 (Dense)              multiple                  330
# =================================================================
# Total params: 244,522
# Trainable params: 244,522
# Non-trainable params: 0
# _________________________________________________________________
#总参数量24万,每个链接是4字节的float,大约是100万字节/1000≈100K

#创建优化器
#实质上作用是 w = w - lr*grad
optimizer = optimizers.Adam(lr=1e-3)

def main():
    for epoch in range(30):
        for step,(x,y) in enumerate(db):
            # x: [b,28,28]
            # y: [b]
            # x: [b,28,28] => [b,784]
            x = tf.reshape(x,[-1,28*28])

            #保存梯度信息
            with tf.GradientTape() as tape:
                #使用model(),前向传播;输入x,x[b,28*28],经过model后会得到[b,10]
                logits = model(x)
                y_onehot = tf.one_hot(y,depth=10)
                #MSE返回[b],reduce_mean返回loss均值(标量),相当于以前的loss = tf.square(y_onehot - out)和loss = tf.reduce_mean(loss)...
                loss_mse = tf.reduce_mean(tf.losses.MSE(y_onehot,logits))
                #上下两种皆可,它们是两种误差计算方法
                loss_ce = tf.losses.categorical_crossentropy(y_onehot,logits,from_logits=True)
                #获得标量,loss是针对instance做的,所以需要求均值
                loss_ce = tf.reduce_mean(loss_ce)

            #trainable_variables为要更新的参数,相当于之前的grads = tape.gradient(loss, [w1, b1, w2, b2, w3, b3])...
            #这里使用categorical_crossentropy误差计算,这里也可以填loss_mse,结果大同小异
            grads = tape.gradient(loss_ce,model.trainable_variables)
            #zip是把2个元素,梯度在前,参数在后,进行w = w - lr*grad原地更新。相当于之前的w1.assign_sub(lr * grads[0])...
            optimizer.apply_gradients(zip(grads,model.trainable_variables))

            if step % 100 == 0:
                print(epoch,step,'loss:',float(loss_ce),float(loss_mse))


        #test测试
        total_correct = 0
        total_num = 0
        for x,y in db_test:
            # x: [b,28,28]
            # y: [b]
            # x: [b,28,28] => [b,784]
            x = tf.reshape(x,[-1,28*28])

            #这里不需要求梯度,因此也不需要GradientTape
            #输出是[b,10]
            logits = model(x)
            #得到输出后,对测试来讲,只需要求出概率最大的值所在的索引
            # logits => prob,[b,10]。使用softmax,把原来实数范围的值转换到0~1的范围,而且保证概率和为1
            prob = tf.nn.softmax(logits,axis=1)
            # [b,10] => [b]
            pred = tf.argmax(prob,axis=1)
            #为了能和y比较,从64转成32
            pred = tf.cast(pred,dtype=tf.int32)
            #比较
            #pred:[b],已经argmax过
            #y不变: [b]
            correct = tf.equal(pred,y)
            #correct: [b], True: equal, False: not equal;cast bool转换成int;reduce_sum求和;
            correct = tf.reduce_sum(tf.cast(correct,dtype=tf.int32))

            #加correct的数量,int用来转换成numpy
            total_correct += int(correct)
            #加batch数量
            total_num += x.shape[0]

        #一个epoch打印一次正确率
        acc = total_correct / total_num
        print(epoch,'test acc:',acc)

#一次epoch就能到0.84的原因,第一、网络变深了;第二、之前用的是w = w - lr*grad,现在用更好的优化器Adam,训练起来快很多
#和之前张量相比(代码41课)
#   要创建很多Tensor,要额外的管理,
#   forward也不需要从输出到输入,直接使用model()搞定
#   所有的参数trainable_variables,不需要一个个寻找

if __name__ == "__main__":
    main()

TensorBoard可视化

Tensor Flow(引言)

可视化图中的数据,并用曲线的方式展示。

在这里插入图片描述

  • TensorBoard

    主要TensorFlow

  • Visdom

    主要pytorch

TensorBoard

  • Installation
  • Curves (loss/acc的监听)
  • Image Visualization (图片的可视化)

Installation

pip install tensorboard(默认已经安装)

Principle(工作原理)

  • Listen logdir (监听目录)
  • build summary instance (新建summary instance)
  • fed data into summary instance (喂数据给summary instance)

CPU会将一些更新的数据(比如loss)写入Disk,比如logs目录。有一个listener监听器,监听logs目录,只要目录有变化,就会把数据更新web。

在这里插入图片描述

Step1.run listener

(tfEnvi) D:\tfCCode\79_可视化>tensorboard --logdir logs
2021-03-21 14:00:33.287413: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cudart64_101.dll
Serving TensorBoard on localhost; to expose to the network, use a proxy or pass --bind_all
TensorBoard 2.3.0 at http://localhost:6006/ (Press CTRL+C to quit)

在这里插入图片描述

Step2.build summary

在代码中进行,新建summary,这个是接口,具体不需要关心

tf.summary.create_file_writer(log_dir) #log_dir为监听路径

在这里插入图片描述

Step3.fed scalar(喂标量数据)

tf.summary.scalar(...)

step默认是x轴,float()是将Tensor格式转换为np或具体数值格式。

名字为loss,数值更新为float(loss)

在这里插入图片描述

Step3.fed single Image(喂图片数据)

tf.summary.image(...)

[1,28,28,1]:1张图片,28*28,1个通道

step随便

在这里插入图片描述

结果:

在这里插入图片描述

Step3.fed multi-images(喂多张图片)

tf.summary.image(...)

reshape,图片集转化成[b,28,28,1]

在这里插入图片描述

结果:

不太美观。

在这里插入图片描述

自己设计:

image_grid():[16,28,28]组合成1张图片

在这里插入图片描述

效果:

在这里插入图片描述

代码实现

import  os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import datasets, layers, optimizers, Sequential, metrics
import datetime
from matplotlib import pyplot as plt
import io

#预处理函数
def preprocess(x,y):
    x = tf.cast(x,dtype=tf.float32) /255.
    y = tf.cast(y,dtype=tf.int32)
    return x,y

#把多张图片拼接成1张图片,plot_to_image和image_grid
def plot_to_image(figure):
    """Converts the matplorlib plot specified by 'figure' to a PNG image and
    returns it. The supplied figure is closed and inaccessible after this call."""
    #Save the plot to a PNG in memory
    buf = io.BytesIO()
    plt.savefig(buf,format='png')
    # Closing the figure prevents it from being displayed directly inside
    # the notebook.
    plt.close(figure)
    buf.seek(0)
    #Convert PNG buffer to TF image
    image = tf.image.decode_png(buf.getvalue(),channels=4)
    # Add the batch dimension
    image = tf.expand_dims(image,0)
    return image

def image_grid(images):
    """Return a 5*5 grid of the MNIST images as a matplotlib figure."""
    #Create a figure to contain the plot.
    figure = plt.figure(figsize=(10,10))
    for i in range(25):
        #Start next subplot
        plt.subplot(5,5,i+1,title='name')
        plt.xticks([])
        plt.yticks([])
        plt.grid(False)
        plt.imshow(images[i],cmap=plt.cm.binary)

    return figure

(x,y),(x_test,y_test) = datasets.fashion_mnist.load_data()
batchsz = 128
#构造数据集
db = tf.data.Dataset.from_tensor_slices((x,y))
#对数据集做预处理
db = db.map(preprocess).shuffle(60000).batch(batchsz).repeat(10)

#对test部分做同样处理
db_test = tf.data.Dataset.from_tensor_slices((x_test,y_test))
db_test = db_test.map(preprocess).batch(batchsz,drop_remainder=True)

#新建网络
model = Sequential([
    layers.Dense(256,activation=tf.nn.relu), # [b,784] -> [b,256]
    layers.Dense(128,activation=tf.nn.relu), # [b,256] -> [b,128]
    layers.Dense(64,activation=tf.nn.relu), # [b,128] -> [b,64]
    layers.Dense(32,activation=tf.nn.relu), # [b,64] -> [b,32]
    layers.Dense(10), # [b,32] -> [b,10] , 330 = 32*10(w)+10(b)
])
#首先喂一个输入来构建权值
model.build(input_shape=[None,28*28])
#打印网络结构
model.summary()

#创建优化器
optimizer = optimizers.Adam(lr=0.01)

####创建writer(summary)
current_time = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
log_dir = 'logs/' + current_time
summary_writter = tf.summary.create_file_writer(log_dir)

#get x from (x,y)
sample_img = next(iter(db))[0]
#get first image instance
sample_img = sample_img[0]
sample_img = tf.reshape(sample_img,[1,28,28,1])
with summary_writter.as_default():
    tf.summary.image("Training sample:", sample_img,step=0)

def main():
    for step,(x,y) in enumerate(db):
        with tf.GradientTape() as tape:
            x = tf.reshape(x, [-1, 28 * 28])
            logits = model(x)
            y_onehot = tf.one_hot(y,depth=10)
            loss_ce = tf.losses.categorical_crossentropy(y_onehot,logits,from_logits=True)
            loss_ce = tf.reduce_mean(loss_ce)

        grads = tape.gradient(loss_ce,model.trainable_variables)
        optimizer.apply_gradients(zip(grads,model.trainable_variables))

        if step % 100 == 0:
            print(step,'loss:',float(loss_ce))
            ####喂loss数据
            with summary_writter.as_default():
                tf.summary.scalar('train-loss',float(loss_ce),step=step)

        # test测试
        if step % 500 == 0:
            total_correct = 0
            total_num = 0
            for x,y in db_test:
                x = tf.reshape(x,[-1,28*28])

                logits = model(x)
                prob = tf.nn.softmax(logits,axis=1)
                pred = tf.argmax(prob,axis=1)
                pred = tf.cast(pred,dtype=tf.int32)
                correct = tf.equal(pred,y)
                correct = tf.reduce_sum(tf.cast(correct,dtype=tf.int32))

                total_correct += int(correct)
                total_num += x.shape[0]

            acc = total_correct / total_num
            print(step, 'Evaluate Acc:', acc)
            #喂Acc
            #print(x,shape)
            val_images = x[:25]
            val_images = tf.reshape(val_images,[-1,28,28,1])
            with summary_writter.as_default():
                tf.summary.scalar('test-acc',float(acc),step=step)
                #喂图(一张一张)
                tf.summary.image("val-onebyone-images:",val_images,max_outputs=25,step=step)
                #喂图(一整张)
                val_images = tf.reshape(val_images,[-1,28,28])
                figure = image_grid(val_images)
                tf.summary.image('val-images:',plot_to_image(figure),step=step)

if __name__ == "__main__":
    main()

结果

在这里插入图片描述

在这里插入图片描述

<think>嗯,用户之前问过激光雷达的用途,现在转向了深度学习和机器学习的学习路径。这可能意味着他们对技术领域有广泛的兴趣,或者正在考虑进入数据科学或AI领域。我需要确定他们的背景,是学生、转行者还是有其他目的。 首先,用户提到“新手如何学习”,所以需要提供从基础开始的指导。可能他们的主要需求是找到系统化的学习路线,避免在学习过程中感到迷茫。应该包括资源推荐、学习方以及实践项目的重要性。 考虑到他们之前的问题关于激光雷达,可能对应用场景比较感兴趣,比如在自动驾驶或工业检测中的应用。所以在介绍学习路径时,可以结合这些实际应用案例,增强相关性。 需要区分机器学习和深度学习,虽然深度学习是机器学习的子领域,但初学者可能会混淆两者的学习顺序。应该建议先掌握机器学习基础,再过渡到深度学习,这样有助于建立扎实的理论基础。 用户可能没有明确说明是否有编程基础,但学习这两个领域通常需要Python和数学知识。因此,在回答中需要强调编程和数学的重要性,并提供相应的学习资源。 另外,实践是关键。新手可能会陷入理论学习的泥潭,而缺乏实际项目经验。建议他们通过Kaggle竞赛或开源项目来应用所学知识,同时培养解决问题的能力。 还要注意学习路径的阶段性,分步骤引导,避免信息过载。比如先学Python和数学,再学机器学习基础,接着是深度学习,最后是项目实战。同时,推荐社区和论坛,帮助他们解决学习中的问题,保持学习动力。 最后,可能用户担心学习难度大,需要鼓励他们保持耐心,持续实践,并参与社区交流。同时,提醒他们根据兴趣选择方向,比如计算机视觉、自然语言处理等,以保持学习的热情。</think>好的!对于深度学习和机器学习的新手,学习路径需要结合**理论基础、工具实践**和**项目经验**。以下是一个分阶段的系统化学习指南,结合中文资源和学习建议: --- ### **一、基础准备:数学 + 编程** #### 1. **数学基础** - **线性代数**:矩阵运算、向量空间(推荐《线性代数的本质》系列视频)。 - **概率与统计**:概率分布、贝叶斯定理、假设检验(可参考《统计学导论》)。 - **微积分**:导数、梯度、最优化(重点理解梯度下降原理)。 *🔍 工具辅助*:如果数学薄弱,可用工具库(如NumPy、SymPy)边实践边补基础。 #### 2. **编程能力** - **Python**:掌握基础语、数据结构(列表/字典/函数),推荐[廖雪峰Python教程](https://www.liaoxuefeng.com/wiki/1016959663602400)。 - **关键库**: - **NumPy**(数值计算)、**Pandas**(数据分析); - **Matplotlib/Seaborn**(数据可视化)。 *📌 目标*:能独立完成数据清洗、简单可视化分析。 --- ### **二、机器学习入门:理论与工具** #### 1. **经典算理解** - **监督学习**:线性回归、逻辑回归、决策树、SVM、随机森林。 - **无监督学习**:K-Means、PCA、聚类评估。 - **模型评估**:交叉验证、ROC曲线、混淆矩阵、过拟合与正则化。 *📚 推荐书籍*: - 《机器学习》(周志华,西瓜书)——理论扎实,适合反复读; - 《Hands-On Machine Learning》(Scikit-Learn版)——代码实践友好。 #### 2. **工具实战** - **Scikit-Learn**:从调用API开始,理解参数调优(如GridSearchCV)。 - **项目练习**: - Kaggle入门赛(如泰坦尼克生存预测、房价预测); - 使用UCI数据集(如鸢尾花分类、手写数字识别)。 --- ### **三、深度学习进阶:框架与模型** #### 1. **深度学习基础** - **核心概念**:神经网络结构、激活函数、反向传播、损失函数。 - **框架选择**: - **PyTorch**(灵活,适合研究)或 **TensorFlow/Keras**(工程部署友好)。 *🎥 推荐课程*: - 吴恩达《深度学习专项课》(Coursera,中文字幕); - 李沐《动手学深度学习》(B站免费视频+代码)。 #### 2. **经典模型实践** - **计算机视觉**:CNN(LeNet、ResNet)、目标检测(YOLO)。 - **自然语言处理**:RNN、LSTM、Transformer。 - **实战工具**: - PyTorch Lightning(简化训练流程); - Hugging Face(快速调用预训练模型)。 #### 3. **调试技巧** - 学习使用TensorBoard或Weights & Biases可视化训练过程; - 掌握过拟合解决方(数据增强、Dropout、早停)。 --- ### **四、项目实战:从模仿到创新** #### 1. **复现经典项目** - 图像分类:CIFAR-10数据集训练ResNet; - 文本生成:用LSTM生成唐诗或新闻标题; - 目标检测:用YOLOv5训练自定义数据集(如检测交通标志)。 #### 2. **参与竞赛** - **Kaggle**:从Featured竞赛中选择感兴趣的主题(如预测、图像分割); - **阿里天池/AI Studio**:国内平台,中文社区支持更友好。 #### 3. **开源贡献** - 在GitHub上复现论文代码(如搜索“PyTorch implementation of XXX”); - 参与开源项目(如Hugging Face模型库的文档优化或Bug修复)。 --- ### **五、持续提升:理论与工程结合** #### 1. **深入理论** - 阅读经典论文(如AlexNet、Transformer、BERT),配合代码实现; - 学习《深度学习》(花书)中的数学推导。 #### 2. **工程化能力** - 模型部署:学习ONNX、TensorRT或Flask/Django构建API; - 性能优化:掌握模型剪枝、量化、蒸馏等轻量化技术。 #### 3. **领域聚焦** - **CV方向**:学习OpenCV、MMDetection; - **NLP方向**:深入Hugging Face库、Prompt Engineering; - **强化学习**:从Gym环境到PPO算。 --- ### **六、学习资源推荐** #### 1. **中文社区** - **论坛**:知乎(关注李沐、邱锡鹏等大V)、优快云(入门教程多); - **公众号**:AI科技评论、机器之心。 #### 2. **免费课程** - B站:跟李沐学AI、莫烦Python; - 百度AI Studio:提供免费GPU算力。 #### 3. **书籍** - 《机器学习实战:基于Scikit-Learn、Keras和TensorFlow》 - 《Python深度学习(第2版)》 --- ### **七、避坑指南** 1. **不要盲目追新**:先掌握经典模型(如ResNet、BERT),再跟进前沿论文。 2. **代码 > 理论**:初期以跑通代码、理解流程为主,数学推导可逐步深入。 3. **学会提问**:遇到报错先查Stack Overflow、GitHub Issues,再向社区求助。 --- ### **总结** 新手学习的关键是**快速建立正反馈**: 1. 从工具(Python+框架)入手,先实现“能跑通代码”; 2. 通过项目理解理论(如反向传播),而非死磕公式; 3. 加入社群,避免闭门造车。保持耐心,半年可入门,1-2年能独立开发模型!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值