深度学习理论与应用

作业1:数字手写体识别,网络模型训练、识别准确率

import paddle as pdl
import numpy as np
import cv2 as cv
from tqdm import tqdm
import paddle.vision.transforms as T
transform = T.Normalize(mean = [127.5], std = [127.5]) 
#对minst数据集中图像进行归一化处理,均值和标准差设置为127.5目的把像素值缩放到[-1,1]范围内。
training_set = pdl.vision.datasets.MNIST(mode = 'train', transform = transform)
#创建一个Mnist数据集模型,模式为训练集,transform为预处理操作方式
testing_set = pdl.vision.datasets.MNIST(mode = 'test', transform = transform)
#创建一个Mnist数据集模型,模式为测试集,transform为预处理操作方式
print('Num of training set: {}, num of testing set: {}'.format(len(training_set), len(testing_set)))
#输出训练集和测试集的样本数量
import matplotlib.pyplot as plt
plt.figure()#先绘制个大图像
plt.imshow(training_set[0][0][0], cmap = plt.cm.binary)
#training_set[0]获取训练集中的第一个样本,包含图像和标签的元组
#training_set[0][0]从第一个样本中获取图像部分,表示图像张量
#training_set[0][0][0]从图像张量中获取图像的像素值,表示图像像素的张量
#调用imshow函数将训练集样本以二进制颜色映射,将灰度值映射到黑白颜色
plt.show()#调用show函数显示图像
net1 = pdl.nn.Sequential(
    pdl.nn.Flatten(), pdl.nn.Linear(784, 100), pdl.nn.ReLU(),
    pdl.nn.Linear(100, 100), pdl.nn.ReLU(),
    pdl.nn.Linear(100, 10), pdl.nn.Softmax()
)
#使用paddle.nn.Sequential定义了一个神经网络模型MLP,包括三个线性层和两个激活函数
#Flatten()函数是将多维数据扁平化为一维数据,具体作用:将mnist数据集图像28*28转为一维784的
#pdl.nn.Linear()第一个全连接层,784个输入特征和100个输出特征
#pdl.nn.ReLU()激活函数,用于引入非线性。它在正数输入时返回该输入,而在负数输入时返回零。
#pdl.nn.Linear()第二个全连接层,输入100个特征输出100个特征
#pdl.nn.ReLU()第二个激活函数,引入非线性
#pdl.nn.Linear()第三个全连接层,输入100特征,输出10个特征:0-9
# convolution neural network model net2
#构建全连接神经网络模型,构建卷积神经网络模型,
#全连接也叫多层感知机,特点后一层神经元与所有前一层神经元相连接。
#卷积神经网络主要通过卷积层和池化层来提取高度抽象特征
#激活函数,学习非线性关系
net2 = pdl.nn.Sequential(
    pdl.nn.Conv2D(1, 6, (5, 5)), pdl.nn.MaxPool2D(kernel_size = 2),
    pdl.nn.Conv2D(6, 16, (5, 5)), pdl.nn.MaxPool2D(kernel_size = 2),
    pdl.nn.Flatten(), pdl.nn.Linear(256, 120),
    pdl.nn.Linear(120, 60),
    pdl.nn.Linear(60, 10),
    pdl.nn.Softmax()
)
#定义了一个卷积神经网络
#第一个卷积层单通道,6个卷积核大小为5的卷积层,最大池化层为2
#第二个卷积层6通道,16个卷积核大小为5的卷积层,最大池化层为2
#扁平化维数后进行全连接层输入特征256[4*4*16]通过卷积和池化后计算得来的
#全连接层第二层输入特征数120,输出60
#第三层全连接层输入特征60,输出10
#最后通过softmax函数,将原始输出转换为概率分布。
model1 = pdl.Model(net1, inputs=[pdl.static.InputSpec(shape=[-1, 28, 28], dtype='float32', name='image')])
#使用pdl.model创建模型对象,在model函数中包括指定神经网络模型net1,输入规格[形状数据名称]
model2 = pdl.Model(net2, inputs=[pdl.static.InputSpec(shape=[-1, 28, 28], dtype='float32', name='image')])
#使用model函数创建第二个模型对象,包括指定卷积神经网络net2,输入规格[形状数据名称]
model1.summary((1, 784))
#这将打印出模型每一层的输出形状和参数数量。

model2.summary((1, 1, 28, 28))
#批次中包含的样本数量为1,通道数为1,维度为28*28

model1.prepare(pdl.optimizer.Adam(learning_rate = 0.001,
parameters = net1.parameters()),
pdl.nn.CrossEntropyLoss(),
pdl.metric.Accuracy())
#通过调用prepare()方法为模型指定优化器Adam,参数,损失函数,准确率

model2.prepare(pdl.optimizer.Adam(learning_rate = 0.001,
parameters = net2.parameters()),
pdl.nn.CrossEntropyLoss(),
pdl.metric.Accuracy())
#调用prepare()方法为模型指定优化器,参数,损失函数,准确率
model1.fit(training_set, testing_set, epochs = 10, batch_size = 128, verbose = 1)
#对神经网络模型进行训练,有测试集、训练集、训练轮次,每批次训练样本个数
result1 = model1.evaluate(testing_set, verbose = 1)
#计算模型评估性能指标
model2.fit(training_set, testing_set, epochs = 10, batch_size = 128, verbose = 1)
#对神经网络模型进行训练,有测试集、训练集、训练轮次,每批次训练样本个数
result2 = model2.evaluate(testing_set, verbose = 1)
#计算模型评估性能指标
print(result1, result2)
model1.save('finetuning/mnist_NN')
#保存经过训练的模型参数,保存在指定路径
model2.save('finetuning/mnist_LeNet')
predict1 = model1.predict(testing_set)
#对神经网络模型测试集进行预测
predict2 = model2.predict(testing_set)
def show_img(img, predict):
    plt.figure()
    plt.title('predict: {}'.format(predict))
    plt.imshow(img.reshape([28,28]), cmap=plt.cm.binary)
    plt.show()
#定义一个显示图像的函数,先绘制大图像,创建标题,标题中包含预测结果,显示图像为28*28
import random
indexs = random.randint(0, 2000) * np.array(range(1, 6))
#在数据集中随机选择一些样本,数组中的每个元素都是一个随机整数乘以1到5之间的一个数字当做索引
print(indexs)
#打印索引
for idx in indexs:
    show_img(testing_set[idx][0], 'NN:{},CNN:{}|Truth:{}'.format(np.argmax(predict1[0][idx]), np.argmax(predict2[0][idx]), testing_set[idx][1][0]))
#从测试集中随机选择一些图像,使用训练好的神经网络模型对这些图像进行预测,并可视化

model1.load('finetuning/mnist_NN')
model2.load('finetuning/mnist_LeNet')
#加载模型的参数与结构
import os
import PIL
import matplotlib.pyplot as plt
number = 10
dir_path = r"dig10"
#表示一个文件夹(目录)的路径
files = os.listdir(dir_path)
# print(files)
for idx in range(number):
    if('0'<=files[idx][0]<='9'):
        image_path = dir_path + '/' + files[idx]
        image = PIL.Image.open(image_path)
        # plt.imshow(image)
        # plt.show()
        image = image.convert("L")
        image = image.resize((28, 28), PIL.Image.ANTIALIAS)
        image = np.array(image).reshape(1, 1, 28, 28).astype(np.float32)
        image = 255 - image #反相操作!非常重要!
        image = image / 255.0 * 2.0 - 1.0
        pred1 = model1.predict_batch(image)
        pred2 = model2.predict_batch(image)
        # show_img(image,'NN:{}, LeNet-5:{}'.format(np.argmax(pred1), np.argmax(pred2)))
        print("神经网络预测数字为:{}".format(np.argmax(pred1)),end=",")
        print("卷积神经网络预测数字为:{}".format(np.argmax(pred2)))
        print("实际数字为:{}".format(files[idx].split(".")[0]))
#for循环,判断文件开头是否为数字文件,然后构建图像的完整路径
#打开图像进行预处理,包括灰度化,缩放28*28,转换numpy数组,反相操作,归一化
#使用神经网络模型和卷积神经网络模型进行预测
#加载外部数字图像,将其转换为模型可接受的格式,然后使用训练好的模型进行预测,并输出预测结果和实际标签。

代码在飞浆跑的出来

总结:

该代码是基于两个模型多层感知机MLP和卷积神经网络应用在mnist数据集上,通过预处理,模型训练与评估、保存与加载从测试集中随机选择样本去预测,最后使用没有经过训练和测试的mnist数据集进行预测并输出结果。

真的再会

第一次作业:

构建神经网络模型(MLP)进行手写数字体识别

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from sklearn import datasets
from sklearn.model_selection import train_test_split

# 使用load_digits函数加载数据集,
digits = datasets.load_digits()
X = digits.data #是一个包含数组特征的一维数组,数组中包含像素值,像素值构成图像特征
#数组为一维,长度为64位(8*8)
y = digits.target #y为对象digits的具体值

# 使用train_test_split函数把数据集digits划分为图像特征和数值的训练集、测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=4, test_size=0.1)

# 确保你的数据被适当地准备和转换与pytorch的神经网络模型兼容
X_train_tensor = torch.tensor(X_train, dtype=torch.float)
y_train_tensor = torch.tensor(y_train, dtype=torch.long)
X_test_tensor = torch.tensor(X_test, dtype=torch.float)
y_test_tensor = torch.tensor(y_test, dtype=torch.long)

# 定义神经网络模型
#在模型中定义一个函数,先调用模型module基类,然后对8*8图像进行全连接层操作
#构建神经网络模型的全连接层第一层,该层将输入维度64的特征映射到输出维度为120的特征
#构建全连接层第二层,该层将上层的输出维度为120的特征转为输入层映射到输出维度100的特征
#构建全连接层第三层,该层将输出输入维度为100的特征转为输出维度为10的特征,10代表分类问题数量
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(64, 120)  
        self.fc2 = nn.Linear(120, 100)
        self.fc3 = nn.Linear(100, 10)  
#定义一个前向传播函数
#通过relu函数将全连接第一层所有负数变为0,正数不变,这有助于引入非线性特征。
#x代表输入数据的张量,经过模型的各个层最终产生一个结果。
    def forward(self, x):
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

#把类net赋值给模型model
#创建了一个使用随机梯度下降的优化器,它将通过最小化损失函数来更新神经网络模型中的参数
#其中model.parameters函数中参数包括神经网络中的权重和偏置
model = Net()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)

#定义一个交叉熵损失函数,计算完损失后你可以通过反向传播和优化器来更新模型的参数,进行模型训练
criterion = nn.CrossEntropyLoss()

#开始训练模型
num_epochs = 5000
for epoch in range(num_epochs):
    #X_train_tensor怎么进入Net里面的? 
    outputs = model(X_train_tensor)

    # Compute the loss
    loss = criterion(outputs, y_train_tensor)

    # Backpropagation and optimization
    optimizer.zero_grad() #清零梯度,确保每个迭代步骤都是基于新的梯度计算的
    loss.backward() #计算损失函数相对于模型参数的梯度?
    optimizer.step() #参数更新

    if (epoch + 1) % 10 == 0:
        print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')
#每个训练周期(epoch)结束时输出训练过程中的损失值。
#评估模型准确率
with torch.no_grad():
    test_outputs = model(X_test_tensor)
    _, predicted = torch.max(test_outputs, 1)
    accuracy = (predicted == y_test_tensor).sum().item() / len(y_test_tensor)
    print(f'Test Accuracy: {accuracy * 100:.2f}%')

这个模型的结构可以总结为:

  1. 输入层:接收大小为64的特征。
  2. 隐含层1(全连接层 self.fc1):将输入特征映射到大小为120的特征。
  3. 隐含层2(全连接层 self.fc2):将上一层的输出映射到大小为100的特征。
  4. 输出层(全连接层 self.fc3):将上一层的输出映射到大小为10的特征,通常用于分类问题中的类别数量。

这种结构是一个典型的前馈神经网络(feedforward neural network),其中信息从输入层传递到输出层,每一层都通过权重矩阵的线性变换和激活函数来处理。在这个具体的例子中,nn.Linear 模块表示了全连接层,其中输入和输出的维度由参数指定。这种网络结构常见于多层感知机(MLP)等模型,用于解决各种任务,特别是分类问题。

两段代码没看懂:

1、Net类

2、训练模型循环语句

下次使用30个字概括一下

第一版:数据预处理之后,构建合适模型,建立全连接层,前向传播,创建梯度下降优化器,计算损失函数再训练模型评估模型准确率。

第二版:先把数据集中的数据预处理成网络模型好处理的类型,然后构建神经网络模型(MLP),输入层、隐藏层和输出层的维度都输入进模型中,进行全连接层的计算和激活函数输入的维度进行非线性转换。然后进行梯度优化和损失函数的参数更新最后对数据进行训练,评估。

第三版:

简单描述一下整个流程吧,周四要给我导汇报这个呢!

        第一个是看了文献,奶牛围产期行为识别,他的工作量第一个是1600多张日常奶牛行为照片使用ResNet深度残差网络模型进行识别,照片分为四类:走、卧、站立、反刍。第二个是100多个视频数据集分五类【行走、侧卧、回望】,使用two-stream双流模型进行识别。然后看了一些文献综述和论文关于奶牛、羊行为识别、动物发情检测等论文和综述。在这些论文和综述当中我总结了一些作者使用什么技术做了什么事这样一个东西。

作者沈维政团队利用三轴加速度传感器采集奶牛加速度数据,应用K-均值聚类算法对其行为特征进行分类,分析一天内奶牛各种行为特征所占时间比例,判断奶牛发情和身体异常等情况使用分类模型对奶牛行为识别,准确率90%以上。

刘艳秋采用递阶遗传算法对BP神经网络的结构和参数进行改进 。应用K-means-BP神经网络对母羊产前典型运动行为进行识别实现89%平均识别准确率。母羊典型运动行为包括:走动 、站立与趴卧次增多、用力刨地等。

田富洋团队三种传感器设计奶牛发情检测系统,采用 LVQ神经网络智能算法进行辨识和预测奶牛行为特征最终达到70%预测准度。

温长吉团队构建视觉词典法识别奶牛产前行为识别准确率达88.3%。构建视觉词典法具体步骤:利用 k-means 算法对初始特征量进行聚类,然后利用贪婪算法对近邻元视觉单词进行合并。做法:奶牛每类行为都可以通过视觉词典中的单词表示为一个视觉单词直方图,利用训练视频对最近邻分类器进行训练,训练结果用于对测试视频中母牛基本行为进行分类识别。

温长吉团队改进视觉词典法,来识别奶牛坡足行为,准确率100%。

张子儒提出融合颜色和纹理特征的背景减去法检测奶牛目标,该检测算法能将奶牛目标区域从背景中检测出来,构建了奶牛爬跨行为分类识别的 SVM 模型,对识别奶牛爬跨行为,平均识别准确率为 90.9%。

第二个做了一个手写数字体识别,用百度开发的深度学习框架paddle做了一个,然后用卷积神经网络做了一个,然后我介绍一下这两个进行手写数字体识别的关键步骤。全连接神经和卷积神经,然后把mnist数据集放模型里训练、评估、预测最后把数字图像放到模型里面预测。

收获1:了解到了一些神经网络算法、

收获2:通过看论文和综述知道了一些下学期可能遇到问题的技术:

掩膜技术:去除奶牛场无关背景;中值滤波算法去燥:降低椒盐噪声和高斯噪声;图像增强方法:灰度变换、直方图均衡化、同态滤波、Retinex;

作业2:卷积神经网络实战

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from sklearn import datasets
from sklearn.model_selection import train_test_split

# 加载手写数字数据集
digits = datasets.load_digits()
X = digits.data
y = digits.target

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=4, test_size=0.1)

# 确保数据被适当地准备和转换以适应 PyTorch 的神经网络模型
X_train_tensor = torch.tensor(X_train.reshape(-1, 1, 8, 8), dtype=torch.float)  # 调整输入形状
y_train_tensor = torch.tensor(y_train, dtype=torch.long)
X_test_tensor = torch.tensor(X_test.reshape(-1, 1, 8, 8), dtype=torch.float)  # 调整输入形状
y_test_tensor = torch.tensor(y_test, dtype=torch.long)

# 定义卷积神经网络模型
class CNNModel(nn.Module):
    def __init__(self):
        super(CNNModel, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, kernel_size=3, stride=1, padding=1)
        self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1)
        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
        self.fc1 = nn.Linear(64 * 2 * 2, 128)
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = x.view(-1, 64 * 2 * 2)  # 将卷积层的输出展平
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return x

# 创建卷积神经网络模型
cnn_model = CNNModel()

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(cnn_model.parameters(), lr=0.02)

# 开始训练模型
num_epochs = 1000
for epoch in range(num_epochs):
    # 前向传播
    outputs = cnn_model(X_train_tensor)

    # 计算损失
    loss = criterion(outputs, y_train_tensor)

    # 反向传播和优化
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if (epoch + 1) % 10 == 0:
        print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')

# 在测试集上评估模型准确率
with torch.no_grad():
    cnn_model.eval()
    test_outputs = cnn_model(X_test_tensor)
    _, predicted = torch.max(test_outputs, 1)
    accuracy = (predicted == y_test_tensor).sum().item() / len(y_test_tensor)
    print(f'Test Accuracy: {accuracy * 100:.2f}%')

准确率比MLP高,CNN准确率达到了98.89%

总结第一版:先进性8*8图像数据的预处理便于适应卷积神经网络对数据的操作然后构建卷积神经网络模型,把卷积层,池化层和全连接层的特征维度都写进去,其次对输入数据进行卷积激活池化操作,再对参数权重w和偏置b进行梯度优化和计算损失函数最后进行模型训练通过前向传播、计算损失、反向传播、梯度清零更新参数操作,lastly进行模型评估。

问题:反向传播原理不太懂

齐活再见!周六愉快

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值