AWS人工智能主题学习月:深度学习入门笔记

目录

一、深度学习入门课程的学习重点

二、简单介绍一下深度学习和神经网络

1.深度学习

2.神经网络

3.深度学习储备知识拓展

三、深度学习生产生活实际案例

四、深度学习的框架介绍

总结


深度学习是机器学习中的一种方法,它利用多层神经网络来学习数据的特征表示。近年来,深度学习在许多领域取得了巨大的成功,包括计算机视觉、语音识别、自然语言处理等。

深度学习使用多层神经网络来解决各种问题。神经网络由输入层、隐藏层和输出层组成,每层都有多个神经元。输入层接收输入数据,隐藏层对数据进行处理,输出层生成预测结果。每个神经元都有一些权重和偏差,它们都是模型的参数。深度学习的核心思想是让模型自动学习这些参数,从而解决问题。

深度学习的优势在于它可以处理大量的数据和高维度的特征。它在计算机视觉、自然语言处理等领域有着广泛的应用。

我的博客里也有我自己深度学习的学习记录,Pytorch、RNN、yolov5等都有涉及,也欢迎大家去交流学习,最后也感谢亚马逊云科技提供的深度学习入门课程,让我进一步了解了深度学习,同时也拥有更深层次的体会。


一、深度学习入门课程的学习重点

AWS人工智能主题学习月:深度学习入门笔记_第1张图片

翻译一下就是

1.什么是深度学习?
2.理解一些深度学习的概念。
3.亚马逊深度学习资源。
4.使用案例。

二、简单介绍一下深度学习和神经网络

1.深度学习

深度学习算法是学习数据表示的更广泛的机器学习领域的一个子集,而机器学习本身是人工智能的一个子集。深度学习使用多层非线性处理单元进行特征提取和转换,每个连续层都使用前一层的输出作为输入。

早在上个世纪50年代就有许多种深度学习算法的研究,当时研究者们开始探索神经网络的概念。1960年,Frank Rosenblatt提出了“感知器”,这是一种基于神经网络的机器学习模型,它可以用来识别特定的模式。1970年,Paul Werbos提出了反向传播算法,这是一种用于训练神经网络的算法,它可以让神经网络更好地拟合数据。1980年,John Hopfield提出了Hopfield网络,这是一种可以解决优化问题的神经网络模型。
1990年,Yann LeCun提出了卷积神经网络(CNN),这是一种用于图像分类的神经网络模型,它可以提取图像中的特征。2006年,Geoffrey Hinton提出了深度置信网络(DBN),这是一种可以解决复杂问题的深度学习模型。2012年,Alex Krizhevsky等人提出了AlexNet,这是一种用于图像分类的深度学习模型,它在ImageNet比赛中取得了巨大的成功。
自2012年以来,深度学习技术发展迅速,出现了许多新的模型,如残差网络(ResNet)、注意力机制(Attention Mechanism)、生成对抗网络(GAN)等。深度学习技术已经被广泛应用于计算机视觉、自然语言处理、语音识别等领域,取得了巨大的成功。

同时,随着科技进步和数据的膨胀,GPU逐渐成为了通用的计算工具。这使得神经网络得以进步。GPU的出现和训练时间的缩短成为了神经网络和深度学习的支柱。08年以后,神经网络成为深度学习的主流方法。

AWS人工智能主题学习月:深度学习入门笔记_第2张图片 ANN神经网络

不同于传统的机器学习,深度学习侧重基于原始特征的端到端学习。后者使用多层神经网络来进行机器学习的方法。每一层负责分析数据中的其他复杂特征。这些多层神经网络被称为深度神经网络,因此这种方法被称为深度学习。深度学习可以用来解决许多机器学习问题,包括图像分类、语音识别和自然语言处理等。

2.神经网络

 接下来简单介绍一下神经网络。(以下代码为构建CNN网络和RNN网络为样例)

import torch.nn.functional as F
 
class Network_bn(nn.Module):
    def __init__(self):
        super(Network_bn, self).__init__()
       
        self.conv1 = nn.Conv2d(in_channels=3, out_channels=12, kernel_size=5, stride=1, padding=0)
        self.bn1 = nn.BatchNorm2d(12)
        self.conv2 = nn.Conv2d(in_channels=12, out_channels=12, kernel_size=5, stride=1, padding=0)
        self.bn2 = nn.BatchNorm2d(12)
        self.pool = nn.MaxPool2d(2,2)
        self.conv4 = nn.Conv2d(in_channels=12, out_channels=24, kernel_size=5, stride=1, padding=0)
        self.bn4 = nn.BatchNorm2d(24)
        self.conv5 = nn.Conv2d(in_channels=24, out_channels=24, kernel_size=5, stride=1, padding=0)
        self.bn5 = nn.BatchNorm2d(24)
        self.fc1 = nn.Linear(24*50*50, len(classeNames))
 
    def forward(self, x):
        x = F.relu(self.bn1(self.conv1(x)))      
        x = F.relu(self.bn2(self.conv2(x)))     
        x = self.pool(x)                        
        x = F.relu(self.bn4(self.conv4(x)))     
        x = F.relu(self.bn5(self.conv5(x)))  
        x = self.pool(x)                        
        x = x.view(-1, 24*50*50)
        x = self.fc1(x)
 
        return x
 
device = "cuda" if torch.cuda.is_available() else "cpu"
print("Using {} device".format(device))
 
model = Network_bn().to(device)
print(model)

import tensorflow
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense,LSTM,SimpleRNN
 
model = Sequential()
model.add(SimpleRNN(200, input_shape= (13,1), activation='relu'))
model.add(Dense(100, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.summary()

 神经网络是一种人工智能技术,它模仿人脑的神经元网络来处理信息。 神经网络由输入层、隐藏层和输出层组成,每层由许多神经元组成。 神经元之间通过权重相连,神经网络通过学习调整权重来处理输入信息并生成输出结果。神经网络是一个简单可训练的数学单元的集合,可以共同学习复杂的函数。

AWS人工智能主题学习月:深度学习入门笔记_第3张图片

神经网络由三种层组成,分别是一个输入层、一些隐藏层和一个输出层。人工神经网络的基本单元是人工神经元(又称为节点),其有数个输入通道,一个神经元在处理阶段将这些输入相加,并得到一个可以展开到多个人工神经元的输出。

AWS人工智能主题学习月:深度学习入门笔记_第4张图片

 如下面这个示例,输入值乘以权重即可得到加权值。节点将偏移矢量添加到总和中,称为偏差,用于基于先前的成功或失败预测来调整总和以生成更准确的预测。对输入进行加权,然后求和并加上适当偏差。如果前面的步骤得到的最终值达到或超过确定的激活阈值,则神经元激活。这就是所谓的神经元激活,这是提供输出之前的最后一步 。

AWS人工智能主题学习月:深度学习入门笔记_第5张图片

 前馈神经网络是不在神经元之间形成循环的任何神经网络,这意味着数据从一个输入移动到输出而没有向后循环。还有另一种类型的神经网络是向后循环的,称为循环神经网络。

循环神经网络的主要价值在于处理序列信息,像文本、语言和手写内容等,比如要把下一个单词或字母之前的单词或字母计算在内,则预测该单词或字母的能力会大大提高。

AWS人工智能主题学习月:深度学习入门笔记_第6张图片

 最后,可以总结到,神经网络是一种模拟人脑的计算模型,它可以用来解决复杂的问题,比如识别图像、语音识别、自然语言处理等。它的重要性在于它可以模拟人类的大脑,从而解决复杂的问题,而不需要人工编程。神经网络也可以用来提高机器学习的性能,从而更好地解决实际问题。

3.深度学习储备知识拓展

 这里稍微拓展一下深度学习的计算知识,常用到的有卷积层的计算:⭐
输入图片矩阵I 大小:w×w                       

卷积核K:k×k

步长S:s

填充大小(padding):p

AWS人工智能主题学习月:深度学习入门笔记_第7张图片

 当卷积函数中padding='same'时,会动态调整p 值,确保o=w ,即保证输入与输出一致。例如:输入是 28*28*1 输出也为 28*28*1 。

步长为1,卷积核为3*3,padding='same'的卷积情况如下:

AWS人工智能主题学习月:深度学习入门笔记_第8张图片

 池化层的计算:

torch.nn.MaxPool2d()函数原型:

torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)

 关键参数说明:
●kernel_size:最大的窗口大小
●stride:窗口的步幅,默认值为kernel_size
●padding:填充值,默认为0
●dilation:控制窗口中元素步幅的参数,默认为1

池化层计算公式:
●Input:(N, C, Hin, Win) or (C, Hin, Win)
●Output:(N, C, Hout, Wout) or (C, Hout, Wout)

 

例子: 

import torch
import torch.nn as nn

m = nn.MaxPool2d(2)
input_x = torch.randn(3, 32, 32)
print("输入数据input_x.shape:",input_x.shape)
output = m(input_x)
print("输出数据output.shape:",output.shape)

输入数据input_x.shape: torch.Size([3, 32, 32])
输出数据output.shape: torch.Size([3, 16, 16])

三、深度学习生产生活实际案例

深度学习在许多领域都有广泛的应用,其中包括:
1. 语音识别:深度学习技术可以用于语音识别,从而实现语音转文本的功能。
2. 自然语言处理:深度学习技术可以用于自然语言处理,从而实现自然语言理解和自然语言生成的功能。
3. 图像识别:深度学习技术可以用于图像识别,从而实现图像分类、目标检测和图像分割的功能。

通过yolov5实现的数字识别

4. 计算机视觉:深度学习技术可以用于计算机视觉,从而实现视觉识别、视觉定位和视觉分析的功能。
5. 机器人:深度学习技术可以用于机器人,从而实现机器人的自主导航、自主学习和自主控制的功能。
6. 推荐系统:深度学习技术可以用于推荐系统,从而实现基于用户的个性化推荐的功能

AWS人工智能主题学习月:深度学习入门笔记_第9张图片

 亚马逊云科技也提供了三种深度学习api接口供我们实践学习。

AWS人工智能主题学习月:深度学习入门笔记_第10张图片

四、深度学习的框架介绍

一些框架允许我们定义模型,然后对其进行大规模训练。

这里自荐一下我自己~首先对比一下两种常见的深度学习框架。

  • TensorFlow:TensorFlow是一个使用数据流图进行数值计算的开源软件库。它由谷歌大脑团队开发,供谷歌内部使用,并根据Apache 2.0开源许可证发布。TensorFlow用于各种任务,包括机器学习、深度学习、自然语言处理、图像识别等。它的设计是灵活和可扩展的,允许开发人员构建和部署自定义模型和算法。相对简单,模块封装比较好,容易上手,对新手比较友好。在工业界最重要的是模型落地,目前国内的大部分企业支持TensorFlow模型在线部署,不支持Pytorch。
  • PyTorch:PyTorch是一个开源的Python机器学习库,用于自然语言处理,计算机视觉和深度学习应用。它提供了一个灵活的编程环境,可以轻松地实现和调试模型,并且可以使用GPU加速。前沿算法多为PyTorch版本,如果是你在校学生,建议学这个。相对于TensorFlow,Pytorch在易用性上更有优势,更加方便调试。

我写的一些文章,用到了pytorch搭建的cnn神经网络,这里放一个链接供大家参考学习。深度学习Week8-咖啡豆识别(Pytorch)_牛大了2022的博客-CSDN博客 这是它的源码,详细可以去读读这篇文章。

import torch
import torch.nn as nn
import torchvision.transforms as transforms
import torchvision
from torchvision import transforms, datasets

import os, PIL, pathlib

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

print(device)



data_dir = './49-data/'
data_dir = pathlib.Path(data_dir)

data_paths = list(data_dir.glob('*'))
classeNames = [str(path).split("\\")[1] for path in data_paths]
print(classeNames)

# 关于transforms.Compose的更多介绍可以参考:https://blog.csdn.net/qq_38251616/article/details/124878863
train_transforms = transforms.Compose([
    transforms.Resize([224, 224]),  # 将输入图片resize成统一尺寸
    # transforms.RandomHorizontalFlip(), # 随机水平翻转
    transforms.ToTensor(),          # 将PIL Image或numpy.ndarray转换为tensor,并归一化到[0,1]之间
    transforms.Normalize(           # 标准化处理-->转换为标准正太分布(高斯分布),使模型更容易收敛
        mean=[0.485, 0.456, 0.406],
        std=[0.229, 0.224, 0.225])  # 其中 mean=[0.485,0.456,0.406]与std=[0.229,0.224,0.225] 从数据集中随机抽样计算得到的。
])

test_transform = transforms.Compose([
    transforms.Resize([224, 224]),  # 将输入图片resize成统一尺寸
    transforms.ToTensor(),          # 将PIL Image或numpy.ndarray转换为tensor,并归一化到[0,1]之间
    transforms.Normalize(           # 标准化处理-->转换为标准正太分布(高斯分布),使模型更容易收敛
        mean=[0.485, 0.456, 0.406],
        std=[0.229, 0.224, 0.225])  # 其中 mean=[0.485,0.456,0.406]与std=[0.229,0.224,0.225] 从数据集中随机抽样计算得到的。
])

total_data = datasets.ImageFolder("./49-data/",transform=train_transforms)
print(total_data.class_to_idx)

train_size = int(0.8 * len(total_data))
test_size  = len(total_data) - train_size
train_dataset, test_dataset = torch.utils.data.random_split(total_data, [train_size, test_size])

batch_size = 4 
train_dl = torch.utils.data.DataLoader(train_dataset,
                                           batch_size=batch_size,
                                           shuffle=True,
                                           num_workers=0)
test_dl = torch.utils.data.DataLoader(test_dataset,
                                          batch_size=batch_size,
                                          shuffle=True,
                                          num_workers=0)
for X, y in test_dl:
    print("Shape of X [N, C, H, W]: ", X.shape)
    print("Shape of y: ", y.shape, y.dtype)
    break

from torchvision.models import vgg16

device = "cuda" if torch.cuda.is_available() else "cpu"
print("Using {} device".format(device))

# 加载预训练模型,并且对模型进行微调
model = vgg16(pretrained=True).to(device)  # 加载预训练的vgg16模型

for param in model.parameters():
    param.requires_grad = False  # 冻结模型的参数,这样子在训练的时候只训练最后一层的参数

# 修改classifier模块的第6层(即:(6): Linear(in_features=4096, out_features=2, bias=True))
# 注意查看我们下方打印出来的模型
model.classifier = nn.Sequential(
            # 14
            nn.Linear(25088, 1024),
            nn.BatchNorm1d(1024),
            # nn.ReLU(True),
            nn.Dropout(0.4),
            # 15
            nn.Linear(1024, 128),
            nn.BatchNorm1d(128),
            # nn.ReLU(True),
            nn.Dropout(0.4),
            # 16
            nn.Linear(128, len(classeNames)),
            nn.Softmax()
        )
model.to(device)
print(model)

import torchsummary as summary
summary.summary(model, (3, 224, 224))


# 训练循环
def train(dataloader, model, loss_fn, optimizer):
    size = len(dataloader.dataset)  # 训练集的大小
    num_batches = len(dataloader)  # 批次数目, (size/batch_size,向上取整)

    train_loss, train_acc = 0, 0  # 初始化训练损失和正确率

    for X, y in dataloader:  # 获取图片及其标签
        X, y = X.to(device), y.to(device)

        # 计算预测误差
        pred = model(X)  # 网络输出
        loss = loss_fn(pred, y)  # 计算网络输出和真实值之间的差距,targets为真实值,计算二者差值即为损失

        # 反向传播
        optimizer.zero_grad()  # grad属性归零
        loss.backward()  # 反向传播
        optimizer.step()  # 每一步自动更新

        # 记录acc与loss
        train_acc += (pred.argmax(1) == y).type(torch.float).sum().item()
        train_loss += loss.item()

    train_acc /= size
    train_loss /= num_batches

    return train_acc, train_loss


def test(dataloader, model, loss_fn):
    size = len(dataloader.dataset)  # 测试集的大小
    num_batches = len(dataloader)  # 批次数目
    test_loss, test_acc = 0, 0

    # 当不进行训练时,停止梯度更新,节省计算内存消耗
    with torch.no_grad():
        for imgs, target in dataloader:
            imgs, target = imgs.to(device), target.to(device)

            # 计算loss
            target_pred = model(imgs)
            loss = loss_fn(target_pred, target)

            test_loss += loss.item()
            test_acc += (target_pred.argmax(1) == target).type(torch.float).sum().item()

    test_acc /= size
    test_loss /= num_batches

    return test_acc, test_loss

import torch, gc

gc.collect()
torch.cuda.empty_cache()


import copy


learn_rate = 1e-4 # 初始学习率
lambda1 = lambda epoch: 0.92 ** (epoch // 10)
optimizer = torch.optim.Adam(model.parameters(), lr=learn_rate)
scheduler = torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda=lambda1)

loss_fn    = nn.CrossEntropyLoss() # 创建损失函数

epochs = 40

train_loss = []
train_acc = []
test_loss = []
test_acc = []

best_acc = 0  # 设置一个最佳准确率,作为最佳模型的判别指标

for epoch in range(epochs):
    # 更新学习率(使用自定义学习率时使用)
    # adjust_learning_rate(optimizer, epoch, learn_rate)

    model.train()
    epoch_train_acc, epoch_train_loss = train(train_dl, model, loss_fn, optimizer)
    # scheduler.step() # 更新学习率(调用官方动态学习率接口时使用)

    model.eval()
    epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)

    # 保存最佳模型到 best_model
    if epoch_test_acc > best_acc:
        best_acc = epoch_test_acc
        best_model = copy.deepcopy(model)

    train_acc.append(epoch_train_acc)
    train_loss.append(epoch_train_loss)
    test_acc.append(epoch_test_acc)
    test_loss.append(epoch_test_loss)

    # 获取当前的学习率
    lr = optimizer.state_dict()['param_groups'][0]['lr']

    template = ('Epoch:{:2d}, Train_acc:{:.1f}%, Train_loss:{:.3f}, Test_acc:{:.1f}%, Test_loss:{:.3f}, Lr:{:.2E}')
    print(template.format(epoch + 1, epoch_train_acc * 100, epoch_train_loss,
                          epoch_test_acc * 100, epoch_test_loss, lr))

# 保存最佳模型到文件中
PATH = './best_model.pth'  # 保存的参数文件名
torch.save(model.state_dict(), PATH)

print('Done')

import matplotlib.pyplot as plt
#隐藏警告
import warnings
warnings.filterwarnings("ignore")               #忽略警告信息
plt.rcParams['font.sans-serif']    = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False      # 用来正常显示负号
plt.rcParams['figure.dpi']         = 100        #分辨率

epochs_range = range(epochs)

plt.figure(figsize=(12, 3))
plt.subplot(1, 2, 1)

plt.plot(epochs_range, train_acc, label='Training Accuracy')
plt.plot(epochs_range, test_acc, label='Test Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')

plt.subplot(1, 2, 2)
plt.plot(epochs_range, train_loss, label='Training Loss')
plt.plot(epochs_range, test_loss, label='Test Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()

from PIL import Image

classes = list(total_data.class_to_idx)


from PIL import Image

classes = list(total_data.class_to_idx)


def predict_one_image(image_path, model, transform, classes):
    test_img = Image.open(image_path).convert('RGB')
    plt.imshow(test_img)  # 展示预测的图片

    test_img = transform(test_img)
    img = test_img.to(device).unsqueeze(0)

    model.eval()
    output = model(img)

    _, pred = torch.max(output, 1)
    pred_class = classes[pred]
    print(f'预测结果是:{pred_class}')

# 预测训练集中的某张照片
predict_one_image(image_path='./49-data/Green/green (9).png',
                  model=model,
                  transform=train_transforms,
                  classes=classes)

系统地学完只后,不仅会对深度学习有一定的理解与认识,也可以更进一步去深入地学习更多常用的模型,比如yolov5模型。

yolov5结构示意图   yolov5结构示意图

当然也可以用亚马逊的资源构建自定义模型,Deep Learning AMI,种类非常多。当然需要破费一下。

AWS人工智能主题学习月:深度学习入门笔记_第11张图片

深度学习常用GPU进行训练数据,并选择CPU进行学习预测或推断。这两者都可为您提供一个稳定、安全且高性能的执行环境。最后用生成的模型运行自己的程序。

同时,运行的时候也会涉及到优化器的选择,优化器是一种算法,它在模型优化过程中,动态地调整梯度的大小和方向,使模型能够收敛到更好的位置,或者用更快的速度进行收敛。

以梯度下降法 (Gradient Descent)举例:

我们可以把模型的参数空间想象成是一个曲面,曲面的高度是整体上模型预测值与真实值的误差。我们的目的就是找到整个曲面的最低点,这样我们其实就找到了模型参数的最优点。梯度下降法是最基本的优化算法之一,它让参数朝着梯度下降最大的方向去变化。

 假设模型参数为 θ,损失函数为 J(θ) ,损失函数 J(θ) 关于参数 θ 的偏导数,也就是梯度为 ▽θJ(θ) ,学习率为 α ,则使用梯度下降法更新参数的公式为:

AWS人工智能主题学习月:深度学习入门笔记_第12张图片

 梯度下降算法中,沿着梯度的方向不断减小模型参数,从而最小化损失函数。基本策略可以理解为”在你目光所及的范围内,不断寻找最陡最快的路径下山

AWS人工智能主题学习月:深度学习入门笔记_第13张图片

 算法缺点:
●训练速度慢:每走一步都要计算调整下一步的方向,下山的速度变慢。在应用于大型数据集中,每输入一个样本都要更新一次参数,且每次迭代都要遍历所有的样本。会使得训练过程及其缓慢,需要花费很长时间才能得到收敛解。
●容易陷入局部最优解:由于是在有限视距内寻找下山的方向。当陷入平坦的洼地,会误以为到达了山地的最低点,从而不会继续往下走。

 真正在使用时,主要是经过改进的以下三类方法,区别在于每次参数更新时计算的样本数据量不同:
●批量梯度下降法(BGD, Batch Gradient Descent)
●随机梯度下降法(SGD, Stochastic Gradient Descent)
●小批量梯度下降法(Mini-batch Gradient Descent)

更多优化器欢迎看我的文章,咱们一同交流。

最后,可以选择亚马逊云科技提供的收费架构,会极大方便训练的流程。但我建议小白还是一点一点先打好基础,从入门的pytorch架构入手,尝试自己搭建一个深度学习模型。
最后感谢亚马逊云科技AI团队的Dan Mbanga教授的授课。

总结

随着人工智能的蓬勃发展,行业对技术人员的要求越来越高了。其中本篇的深度学习便是人工智能领域的重要部分,深度学习的重要性在于它可以解决复杂的问题,比如计算机视觉、自然语言处理、语音识别等,这些问题在传统机器学习方法中很难解决。作为一名大学生,能很早地接触到有趣的人工智能课程我感到非常幸运。最后再次感谢亚马逊云科技平台提供的学习资料,深入浅出地介绍了深度学习,希望亚马逊云科技以后能提供更加优质的免费课程~

师傅领进门,修行靠个人。如果你是对人工智能与深度学习十分感兴趣的小白,我十分推荐这门课。
AWS人工智能主题学习月:深度学习入门笔记_第14张图片
最后希望大家点点关注点点赞,我的主页有许多有关深度学习的文章,希望我们一同进步。

你可能感兴趣的:(Python深度学习,深度学习,人工智能)