百度 AI Studio——《高层API助你快速上手深度学习》课程学习1

2023-11-09

百度 AI Studio——《高层API助你快速上手深度学习》课程学习1

该系列文章系个人读书笔记及总结性内容,任何组织和个人不得转载进行商业活动!

相关链接:

  • 飞桨:飞桨开源框架(PaddlePaddle)是一个易用、高效、灵活、可扩展的深度学习框架。
  • 百度 AI Studio——课程链接

课程介绍

零基础解锁深度学习神器高层 API ,七天时间助你掌握CV、NLP领域最火模型及应用。

课程大纲

Day 1(2月3日)

  • 主题:走进深度学习与高层API
  • 作业:客观题

Day 2(2月4日)

  • 主题:CV案例_基于resnet的十二生肖分类
  • 作业:客观题与模型实现

Day 3(2月5日)

  • 主题:CV案例_人脸关键点检测
  • 作业:客观题与模型实现

Day 4(2月6日)

  • 主题:NLP案例_利用情感分析选择年夜饭
  • 作业:客观题与模型实现

Day 5(2月7日)

  • 主题:NLP案例_让计算机为你写对联
  • 作业:客观题与模型实现

Day 6(2月8日)

  • 主题:玩转开源社区与模型部署
  • 作业:客观题与模型部署
  • 赛题发布:训练你自己的大型CV模型

Day 7(2月10日)

  • 作业讲评、小春晚颁奖、预拜年

课节1:解决深度学习任务的必备知识和工具

课程目录:

  • 什么是深度学习
  • 深度学习数学基础
  • Python基础
  • Notebook基础操作
  • PaddlePaddle快速入门
  • 选修:Debug基础教学

什么是深度学习

一、深度学习的发展历程

1.图灵测试:

把一个人和一台计算机分别放在两个隔离的房间中,房间外的一个人同时询问人和计算机相同的问题,如果房间外的人无法分别哪个是人,哪个是计算机,就能够说明计算机具有人工智能。

2.医学上发现,人的视觉系统处理信息是分级的;

从视网膜(Retina)出发,经过低级的V1区提取边缘特征,到V2区的基本形状或目标的局部,再到高层的整个目标(如判定为一张人脸),以及到更高层的PFC(前额叶皮层)进行分类判断等。也就是说高层的特征是低层特征的组合,从低层到高层的特征表达越来越抽象和概念化,也即越来越能表现语义或者意图。

边缘特征 —–> 基本形状和目标的局部特征——>整个目标 这个过程其实和我们的常识是相吻合的,因为复杂的图形,往往就是由一些基本结构组合而成的。同时我们还可以看出:大脑是一个深度架构,认知过程也是深度的。

3.Deep Learning的出现

低层次特征 - - - - (组合) - - ->抽象的高层特征;

  • 深度学习,恰恰就是通过组合低层特征形成更加抽象的高层特征(或属性类别)。
  • 例如,在计算机视觉领域,深度学习算法从原始图像去学习得到一个低层次表达,然后在这些低层次表达的基础上,通过线性或者非线性组合,来获得一个高层次的表达。
二、机器学习

机器学习:

是实现人工智能的一种手段,也是目前被认为比较有效的实现人工智能的手段,目前在业界使用机器学习比较突出的领域很多,例如:计算机视觉、自然语言处理、推荐系统等等。(如高速上的ETC的车牌识别,今日头条的新闻推荐)

简单来说,机器学习就是通过算法,使得机器能从大量历史数据中学习规律,从而对新的样本做智能识别或对未来做预测。

人工智能是计算机科学的一个分支,研究计算机中智能行为的仿真。

我们有四个不同层次的AI,让我们来解释前两个:

  • 弱人工智能,也被称为狭义人工智能,是一种为特定的任务而设计和训练的人工智能系统。弱人工智能的形式之一是虚拟个人助理,比如苹果公司的Siri。
  • 强人工智能,又称人工通用智能,是一种具有人类普遍认知能力的人工智能系统。当计算机遇到不熟悉的任务时,它具有足够的智能去寻找解决方案。

机器学习是指计算机使用大数据集而不是硬编码规则来学习的能力。

机器学习允许计算机自己学习。这种学习方式利用了现代计算机的处理能力,可以轻松地处理大型数据集。

基本上,机器学习是人工智能的一个子集;更为具体地说,它只是一种实现AI的技术,一种训练算法的模型,这种算法使得计算机能够学习如何做出决策。

从某种意义上来说,机器学习程序根据计算机所接触的数据来进行自我调整。

监督式学习vs非监督式学习:

监督式学习需要使用有输入和预期输出标记的数据集。

如果人工智能产生的输出结果是错误的,它将重新调整自己的计算。这个过程将在数据集上不断迭代地完成,直到AI不再出错。

非监督式学习是利用既不分类也不标记的信息进行机器学习,并允许算法在没有指导的情况下对这些信息进行操作。

当你使用非监督式学习训练人工智能时,你可以让人工智能对数据进行逻辑分类。这里机器的任务是根据相似性、模式和差异性对未排序的信息进行分组,而不需要事先对数据进行处理。

非监督式学习的一个例子是亚马逊等电子商务网站的行为预测AI。

它将创建自己输入数据的分类,帮助亚马逊识别哪种用户最有可能购买不同的产品(交叉销售策略)。 另一个例子是,程序可以任意地使用以下两种算法中的一种来完成男孩女孩的图像分类任务。一种算法被称为“聚类”,它根据诸如头发长度、下巴大小、眼睛位置等特征将相似的对象分到同一个组。另一种算法被称为“相关”,它根据自己发现的相似性创建if/then规则。换句话说,它确定了图像之间的公共模式,并相应地对它们进行分类。【?】

三、深度学习如何工作

深度学习是一种机器学习方法 , 它允许我们训练人工智能来预测输出,给定一组输入(指传入或传出计算机的信息)。监督学习和非监督学习都可以用来训练人工智能。

神经网络:
神经网络是一组粗略模仿人类大脑,用于模式识别的算法。神经网络这个术语来源于这些系统架构设计背后的灵感,这些系统是用于模拟生物大脑自身神经网络的基本结构,以便计算机能够执行特定的任务。

“预测公交票价”:
神经元之间的每个连接都有一个权重。这个权重表示输入值的重要性。模型所做的就是学习每个元素对价格的贡献有多少。这些“贡献”是模型中的权重。一个特征的权重越高,说明该特征比其他特征更为重要。

每个神经元都有一个激活函数。最后一层神经元的激活函数主要是一个传递输出结果的函数。(激活函数的作用远不止于此

对于我们的公交票价模型,我们必须找到过去票价的历史数据;一旦我们遍历了整个数据集,就有可能创建一个函数来衡量AI输出与实际输出(历史数据)之间的差异。这个函数叫做成本函数。即成本函数是一个衡量模型准确率的指标,衡量依据为此模型估计X与Y间关系的能力。

模型训练的目标是使成本函数等于零,即当AI的输出结果与数据集的输出结果一致时(成本函数等于0)。

梯度下降算法:

梯度下降法是一种求函数最小值的方法。在这种情况下,目标是取得成本函数的最小值。 它通过每次数据集迭代之后优化模型的权重来训练模型。通过计算某一权重集下代价函数的梯度,可以看出最小值的梯度方向。

为了降低成本函数值,多次遍历数据集非常重要。这就是为什么需要大量计算能力的原因。

四、第一个例子

PaddlePaddle学习:

  • 安装、基本命令和操作;
  • MNIST数据集,手写数字分类;(这是深度学习的“Hello world!”)

Step1:MNIST数据集准备

  • 定义读取MNIST数据集的train_reader和test_reader,指定一个Batch的大小为128,也就是一次训练或验证128张图像。
  • paddle.dataset.mnist.train()或test()接口已经为我们对图片进行了灰度处理、归一化、居中处理等处理。
import numpy as np
import paddle as paddle
import paddle.fluid as fluid
from PIL import Image
import matplotlib.pyplot as plt
import os

# 训练集
train_reader = paddle.batch(paddle.reader.shuffle(paddle.dataset.mnist.train(), buf_size=512), batch_size=128)
# 测试集
test_reader = paddle.batch(paddle.dataset.mnist.test(), batch_size=128)

# 测试
temp_reader = paddle.batch(paddle.dataset.mnist.train(), batch_size=1)
temp_data = next(temp_reader())
print(temp_data)

Step2:配置网络

  • 三层感知器:输入层-》第一层-》第二层-》输出层;
  • 输出层的激活函数是Softmax,所以最后的输出层相当于一个分类器;
  • 这里输入数据的形状是[1,28,28]
# 定义多层感知器
def multilayer_perception(input):
    hidden1 = fluid.layers.fc(input=input, size=100, act='relu')
    hidden2 = fluid.layers.fc(input=hidden1, size=100, act='relu')
    prediction = fluid.layers.fc(input=hidden2, size=10, act='softmax')
    return prediction
# 定义输入层
image = fluid.layers.data(name='image', shape=[1,28,28], dtype='float32')
label = fluid.layers.data(name='label',  shape=[1], dtype='int64')

# 使用网络来获取分类器
model = multilayer_perception(image)

# 定义损失函数:使用交叉熵损失函数(多用于分类问题)描述真实样本标签和预测概率之间的差值
cost = fluid.layers.cross_entropy(input=model, label=label)
# 均值
avg_cost = fluid.layers.mean(cost)
# 准确度函数
acc = fluid.layers.accuracy(input=model, label=label)

# 优化方法:使用Adam优化方法,指定学习率为0.001
optimizer = fluid.optimizer.AdamOptimizer(learning_rate=0.001)
opts = optimizer.minimize(avg_cost)

Step3+4:训练模型 和 评估模型

# 定义一个使用CPU的解析器
place = fluid.CPUPlace()
exe = fluid.Executor(place)

# 进行参数初始化
exe.run(fluid.default_startup_program())

# 定义输入数据维度
feeder = fluid.DataFeeder(place=place, feed_list = [image, label])

# 训练模型和测试
#  训练5个Pass,之前定义的求准确率的函数,可以在训练的时候让它输出当前的准确率
#  计算准确率的原理很简单,就是把训练是预测的结果和真实的值比较,求出准确率。
#  每一个Pass训练结束之后,再进行一次测试,使用测试集进行测试,并求出当前的Cost和准确率的平均值。

# 遍历train_reader
for pass_id in range(5):
    # 开始训练 
    for batch_id, data in enumerate(train_reader()):
        train_cost, train_acc = exe.run(program=fluid.default_main_program(),# 运行主程序
        feed=feeder.feed(data),# 给模型喂入数据
        fetch_list=[acg_cost,acc] # 反馈 误差 准确率
        )

        # 每100个batch打印一次信息 误差 准确率
        if batch_id % 100 == 0:
            print('Pass:%d, Batch:%d, Cost:%0.5f, Accuracy:%0.5f' % (pass_id, batch_id, train_cost[0], train_acc[0]))
    # 进行测试
    test_accs = []
    test_costs = []

    # 每训练一轮 进行一次测试
    for batch_id, data in enumerate(test_reader()):
        test_cost, test_acc = exe.run(program=fluid.default_main_program(),
        feed=feeder.feed(data),
        fetch_list = [acg_cost, acc])

        # 保存每个batch的准确率和误差
        test_accs.append(test_acc[0])
        test_costs.append(test_cost[0])

    # 求测试结果的平均值
    test_cost = (sum(test_costs) / len(test_costs)) # 每轮的平均误差
    test_acc = (sum(test_accs) / len(test_accs))

    print('Test:%d, Cost:%0.5f, Accuracy:%0.5f' % (pass_id, test_cost, test_acc))

    # 保存模型
    model_save_dir = "./model/hand.inference.model"

    if not os.path.exists(model_save_dir):
        os.makedirs(model_save_dir)
    print('save models to %s' % (model_save_dir))

    fluid.io.save_inference_mode(model_save_dir,
        ['image'],# 推理(inference)需要 feed 的数据
        [model],# 保存推理(inference)结果的 Variables
        exe) # executor 保存 inference model

# log(part)
Pass:0, Batch:0, Cost:2.70130, Accuracy:0.05469
Pass:0, Batch:100, Cost:0.44905, Accuracy:0.84375
Pass:0, Batch:200, Cost:0.20944, Accuracy:0.93750
Pass:0, Batch:300, Cost:0.37832, Accuracy:0.85938
Pass:0, Batch:400, Cost:0.21634, Accuracy:0.93750
Test:0, Cost:0.22907, Accuracy:0.92880
save models to /home/aistudio/data/hand.inference.model
Pass:1, Batch:0, Cost:0.30485, Accuracy:0.91406
Pass:1, Batch:100, Cost:0.20843, Accuracy:0.95312
Pass:1, Batch:200, Cost:0.12292, Accuracy:0.96875
Pass:1, Batch:300, Cost:0.12543, Accuracy:0.95312
Pass:1, Batch:400, Cost:0.08486, Accuracy:0.97656
Test:1, Cost:0.15316, Accuracy:0.95095
save models to /home/aistudio/data/hand.inference.model

Step5:模型预测

  • 在预测之前,要对图像进行预处理,处理方式要跟训练的时候一样。
  • 首先进行灰度化,
  • 然后压缩图像大小为28*28,
  • 接着将图像转换成一维向量,
  • 最后再对一维向量进行归一化处理。
# 对图片进行预处理
def load_image(file):
    im = Image.open(file).convert('L')
    im = im.resize((28,28), Image.ANTIALIAS)
    im = np.array(im).reshape(1,1,28,28).astype(np.float32)
    im = im/255.0 * 2.0 - 1.0
    return im

def show_image(file):
    img = Image.open(file) # 例: ./test/6.png
    plt.imshow(img) # 绘制
    plt.show() # 显示

# 确定环境
place = fluid.CPUPlace()
infer_exe = fluid.Executor(place)
inference_scope = fluid.core.Scope()

with fluid.scope_guard(inference_scope):
    # 加载模型
    。。。。。。

# 进行预测

好吧,课程更新了,Step1——Step5,forgetted,重来!!!

Step1:准备数据

  • 使用飞桨内置数据集 paddle.vision.datasets.MNIST 定义MNIST数据集的 train_dataset 和 test_dataset。
  • 使用 Normalize 接口对图片进行归一化;
import paddle
from paddle.vision.transforms import Normalize

transform = Normalize(mean=[127.5],std=[127.5], data_format='CHW')

# 加载数据集 使用transform对数据集做归一化
train_dataset = paddle.vision.datasets.MNIST(mode='train', transform=transform)
test_dataset = paddle.vision.datasets.MNIST(mode='test', transform=transform)

取一条数据,观察一下数据集

import numpy as np
import matplotlib.pyplot as plt

train_data0, train_label_0 = train_dataset[0][0], train_dataset[0][1]
train_data0 = train_data0.reshape([28, 28]) # 1,28,28 => 28,28

plt.figure(figsize=(2,2))
plt.imshow(train_data0, cmap=plt.cm.binary)
print(str(train_label_0))

Step2:配置网络

  • 三层感知器,输入层–>>隐层–>>隐层–>>输出层。
  • 输出层的激活函数是Softmax,所以最后的输出层相当于一个分类器;
class MultilayerPerceptron(paddle.nn.Layer):
    # in_features表示有多少输入
    def __init__(self, in_features):
        super(MultilayerPerceptron, self).__init__()
        # 打平
        self.flatten = paddle.nn.Flatten()

        # 全连接层
        self.linear1 = paddle.nn.Linear(in_features=in_features, out_features = 100)
        self.linear2 = paddle.nn.Linear(in_features=100, out_features = 100)
        self.linear3 = paddle.nn.Linear(in_features=100, out_features = 10)

        # ReLU激活函数
        self.act1 = paddle.nn.ReLU()
        self.act2 = paddle.nn.ReLU()

    def forward(self, x):
        x = self.flatten(x)
        x = self.linear1(x)
        x = self.act1(x)
        x = self.linear2(x)
        x = self.act2(x)
        x = self.linear3(x)
        return x

# 使用paddle.Model 封装 MultilayerPerceptron网络
model = paddle.Model(MultilayerPerceptron(in_features=784))
# 使用model.summary 打印模型结构
model.summary((-1,1,28,28))


# 配置模型
model.prepare(paddle.optimizer.Adam(parameters=model.parameters()), # 使用Adam算法进行优化
    paddle.nn.CrossEntropyLoss(), # 使用CrossEntroyLoss计算损失
    paddle.metric.Accuracy()) # 使用Accuracy计算精度

Step3:模型训练

  • 使用飞桨高层API,可以很快的完成模型训练的部分,只需要在 prepare 配置好模型训练的相关算法后,调用 fit 接口,指定训练的数据集,训练的轮数以及数据的batch_size,就可以完成模型的训练
model.fit(train_dataset,
    epochs=5, # 设置训练轮数
    batch_size=64,
    verbose=1) # 设置日志打印格式

Step4:模型评估

  • 使用飞桨高层API完成模型评估也非常的简单,只需要调用 evaluate 接口并传入验证集即可;
model.evaluate(test_dataset, verbose=1)

Step5:模型预测

  • 使用飞桨高层API完成模型预测也非常的简单,只需要调用 predict 接口并传入测试集即可。
results = model.predict(test_dataset)

# 获取概率最大的label
lab = np.argsort(results[0])                               

讨论时间:为什么教程中的手写数据及分类问题 的输出层,没有设置softmax激活函数,CrossEntropyLoss中也没有?
目前在继续增强CrossEntropyLoss这个API,增加with_softmax参数,会把增加softmax由默认行为变成可控行为
如果是回归问题,不会用CrossEntropyLoss
所以用了CrossEntropyLoss对应的就是分类问题;

五、总结

下一节,准备必要的数学知识;

深度学习数学基础

数学基础知识:

高等数学:

  • 导数
  • 左导数、右导数
  • 函数可导性与连续性之间的关系
    • 函数可为微,则可导【微分?】
    • 可导一定连续,连续不一定可导
  • 平面曲线的切线和法线
  • 导数 四则运算
  • 基本导数和微分表
  • 复合函数,反函数,隐函数以及参数方程所确定的函数的微分法
  • 常用高阶导数公式
  • 微分中值定理,泰勒公式
    • 费马定理
    • 罗尔定理
    • 拉格朗日中值定理
    • 柯西中值定理
  • 洛必达法则
  • 泰勒公式
  • 函数单调性的判断
  • 渐近线的求法
  • 函数凹凸性的判断
    • 凹凸性的判别定理
    • 拐点的判别定理1
    • 拐点的判别定理2
  • 弧微分
  • 曲率
  • 曲率半径

线性代数

  • 行列式按行(列)展开定理
  • 矩阵的线性运算
    • 矩阵的加法
    • 矩阵的数乘
    • 矩阵的乘法
    • 转置、逆矩阵
  • 。。。

概率论和梳理统计

  • 常见分布
    • 0-1分布
    • 二项分布
    • Poisson分布
    • 均匀分布U(a,b)
    • 正态分布:N(μ,σ2)
    • 指数分布
    • 几何分布
    • 超几何分布
  • 随机变量的数字特征
    • 数学期望(离散型、连续型)
    • 方差
    • 标准差
    • 离散型
    • 连续型
  • 。。。

Python基础

第一节 Python基础关键字和语法

Python使用灵活,第三方支持也多;而且所有的深度学习框架一般都有一个Python版的接口;

IPython Notebook号称 “编码器的实验室笔记本” - 允许用户在单个基于浏览器的页面中交叉显示/执行数据,代码和说明文本,而不是在单独的文件中;

  • python中的主要基本数据类型是数字(整数和浮点数),布尔值和字符串
  • help(func)
  • dir(module)
  • 有四种不同的数字类型:普通整数,长整数,浮点数和复数。另外,布尔值是普通整数的子类型。
  • if、True、False、and、or、not、else、elif
  • 列表、切片、最大值-最小值-长度-总和(min(z), max(z), len(z), sum(z));
  • 对列表中对象出现次数进行统计
random_list = [4, 1, 5, 4, 10, 4]
random_list.count(4)
# 3
  • list.index(value)
  • list.sort()/sorted()
  • append(value)/pop(index)
  • 合并列表:list.extend([4,5]) 或 直接使用 “+”;
  • 在列表指定位置前插入对象:list.insert(index,value)
第二节 Python中常见的数据结构

字典:

  • 访问:dic['key']
  • 更新:直接赋值、dic.update({key,val,key1:val1})del dic['key']
  • dic.get('key')dic.get('key',defaultVal)
  • dic.pop('key'):删除的同时并返回;
  • 遍历:dic.keys()dic.values()for key in dicfor key, value in dic.items()

元组:

  • 元组是一种序列,就像列表一样。元组和列表之间的区别在于,与列表(可变)不同,元组不能更改(不可变)。 元组使用括号,而列表使用方括号。
  • 切分操作返回包含所请求项的新元组。切分很适合在元组中获取值的子集。(切片区间 左闭右开)
  • tuple.index(val) 返回索引
  • tuple.count(val) 返回计数
  • for item in tuple
  • 枚举元组:for index, item in enumerate(tuple)
  • 一些元组可以用作字典键(特别是包含不可变值的元组,如字符串,数字和其他元组)。列表永远不能用作字典键,因为列表不是不可变的
  • 集合(set)用一对大括号表示:元组可以是集合中的值,但列表不行;
第三节 Python中的for循环
  • for in
  • enumerate
  • stringSequence.split('')
  • continue语句将转到循环的下一次迭代
  • break语句将完全打断循环
  • 整数从1到50:range(1,51)
第四节 Python中的while循环
candidates = list(range(0, 5))
candidates


while len(candidates) > 0: 
    first = candidates[0]
    candidates.remove(first)
    print(candidates)

第五节 Python中的函数

文档字符串:

def greet(name):
	"""This function greets to
	the person passed in as
	parameter"""
	print("Hello, " + name + ". Good morning!")

print(greet.__doc__)
  • 变量的范围是程序中识别变量的部分。函数内定义的参数和变量在外部不可见。因此,它们具有局部范围。
  • 变量的生命周期是变量在存储器中退出的时间段。函数内部变量的生命周期与函数执行的时间一样长。

一旦我们从函数返回它们就会被销毁。因此,函数不记得先前调用的变量值:

def my_func():
	x = 10
	print("Value inside function:",x)

x = 20
my_func()
print("Value outside function:",x)

# ('Value inside function:', 10)
# ('Value outside function:', 20)

  • 函数外部的变量从内部可见。它们具有全局范围。
  • 我们可以从函数内部读取这些值,但不能更改(写入)它们。为了修改函数外部变量的值,必须使用关键字global将它们声明为全局变量。
# 函数参数 带默认值
#   在此函数中,参数名称没有默认值,在调用期间是必需的(必需)
#   一旦我们有一个默认参数,它右边的所有参数也必须有默认值。
def greet(name, msg = "Good morning!"):

# Python任意参数
#   我们事先并不知道将传递给函数的参数数量
#   Python允许我们通过具有任意数量参数的函数调用来处理这种情况。
#   在函数定义中,我们在参数名称前使用星号(*)来表示这种参数
def greet(*names):
   """This function greets all
   the person in the names tuple."""
   # names is a tuple with arguments
   for name in names:
       print("Hello",name)


# Python函数: 在列表中移除重复对象
def remove_duplicates(duplicate): 
    uniques = [] 
    for num in duplicate: 
        if num not in uniques: 
            uniques.append(num) 
    return(uniques)
      
duplicate = [2, 4, 10, 20, 5, 2, 20, 4] 
print(remove_duplicates(duplicate)) 

第六节 Python中的面向对象编程

面向对象编程(OOP):

  • 是一种编程范例,它提供了一种结构化程序的方法,以便将属性和行为捆绑到单个对象中。
  • 另一种常见的编程范例是函数式编程,其构造类似于顺序执行的程序,因为它以函数和代码块的形式提供一组执行步骤,这些步骤一步步执行以完成任务。
  • 关键的一点是,对象是面向对象编程范例的核心,不仅在函数编程中表示数据,而且在程序的整体结构中也是如此。

注意:由于Python是一种多范式编程语言(也就是说面向对象或者函数式编程都是可以的),您可以选择最适合手头问题的范例,在一个程序中混合使用不同的范例,和/或随着程序的发展从一种范例切换到另一种范例。

Python中的类:

  • 一个类只提供结构 - 它是应该如何定义某个东西的蓝图,但它实际上并不提供任何真实的内容.
  • 可以将"类"视为"某事物的定义".

Python对象(实例):

  • 实例是具有实际值的类的副本,字面上是属于特定类的对象。
class Dog(object):
    # 类属性(类方法也可以通过实例进行调用)
    species = 'mammal'

    # 初始化方法
    def __init__(self, name, age):
        super(Dog,self).__init__()
        # 属性
        self.name = name
        self.age = age

    # 实例方法
    def speak(self, sound):
        return sound

a = Dog('Mikey', 6)

父类与子类:

  • isinstance()函数用于确定实例是否也是某个父类的实例
  • Is jim an instance of Dog()
  • print(isinstance(jim, Dog))
第七节让我们来做个小测验吧!

常规测验

  • 将字母转换成小写字母
  • 反转字符串中的单词
  • 排列组合
  • 阶乘
  • 整型转罗马数字
  • 盛水最多的容器
  • 矩阵置零
  • 文件操作

高难度联系

  • 猜数字
  • FizzBuzz
  • 猜数字的AI
  • 整点报时
  • 敏感词审查
  • 文字毛线游戏
  • 词频统计
  • Markdown转化器
  • 邮件轰炸机
  • 用邮件控制电脑

Notebook基础操作

本次课程基于AI Studio平台进行,请各位同学先熟悉下Notebook基本操作:

  • 本系统的Notebook支持多文件编辑, 支持.py, .json, .txt, .log等格式的在线编辑, 支持部分图片类型文件的在线预览.
  • 上传文件的体积是30MB. 如果需要引用更大体积的文件, 请使用数据集功能.
  • 用户也可以使用命令, !cat <<newfile > newfile.py 在项目空间内直接创建文件, 之后双击进行编辑. 如下图所示:
  • 可以用自己的ipynb文件取代当前默认的Notebook(前提是格式合法)

Notebook中使用Shell命令:

  • 通过在Shell命令前添加! (感叹号), 就可以执行部分Shell命令. 包括诸如 !pip install这样的命令. 不过, !apt-get这种可能引发用户进一步操作的命令是不支持的.
# 查看当前挂载的数据集目录
!ls /home/aistudio/data/

#显示当前路径
!pwd

# 使用pip来安装自己需要的package (但不支持apt-get)
!pip install jupyterthemes

# 查看当前环境中安装的package
!pip list --format=columns

# 如果需要进行持久化安装, 需要使用持久化路径
!mkdir /home/aistudio/external-libraries
!pip install beautifulsoup4 -t /home/aistudio/external-libraries
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可:
import sys
sys.path.append('/home/aistudio/external-libraries')

# 使用git命令来同步代码 (暂时需要Paddle 1.4.1以上)
%cd work/
## 可以用gitee,速度会快一些
!git clone https://github.com/PaddlePaddle/Paddle.git  #Paddle官方模型

Python代码执行与调试

Notebook执行Python代码的原理和传统IDE略有不同.

  • 传统IDE, 当点击Run按钮时, 编译器/解释器开始构建一个进程. 用户通过单步执行/设置断点进行代码调试和变量监控. 当代码出错, 或用户点击Stop按钮时, 进程被杀死, 资源回收.
  • 而Notebook, 一旦启动, 就是开始创建一个"进程"(kernel). 每一个Cell, 都是一个天然的断点. 当代码出错, 或用户点击Stop按钮时, "进程"通常也不会被杀死.
  • 因此如果代码陷入死循环等情况, 需要用户手动关闭并重启该"进程".
  • 此外, Notebook的Cell是可以随意颠倒顺序来执行的. 这点和传统IDE有很大不同.
  • 作为前端的Notebook, 与后端的进程(kernel), 建立有一个Session. 未来本平台将支持terminal功能. 也就可以同时支持多个Session来控制kernel.
变量监控

本平台自带"变量监控"和"运行历史". 方便用户了解当前代码运行状态.

Magic命令

Magic命令是Notebook的高级用法了. 可以运行一些特殊的指令. Magic 命令的前面带有一个或两个百分号(% 或 %%),分别代表行 Magic 命令和单元格 Magic 命令。行 Magic 命令仅应用于编写 Magic 命令时所在的行,而单元格 Magic 命令应用于整个单元格。

#显示全部可用的Magic命令
%lsmagic

#使用Magic命令来统计运行时长
import random
%%timeit
prize = 0 
for i in range(100):
    roll = random.randint(1, 6)
    if roll%2 == 0:
        prize += roll
    else:
        prize -= 1

# 直接嵌入可视化内容, 例如%matplotlib inline:
%matplotlib inline
%config InlineBackend.figure_format = 'retina'

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0,1,300)
for w in range(2,6,2):
    plt.plot(x, np.sin(np.pi*x)*np.sin(2*w*np.pi*x))

# 这里需要注意的是, 当前技术架构局限, 一个Cell里面只能输出一张图片. 如果输出多张图片, 可能会有显示异常的问题


# %env:设置环境变量
# 使用该命令, 可以在不必重启Kernel的情况下管理notebook的环境变量
%env OMP_NUM_THREADS=4

# %run: 运行python代码
%run /home/aistudio/work/SampleOfRun.py
# or
!python /home/aistudio/work/SampleOfRun.py


# %%writefile and %pycat: 导出cell内容/显示外部脚本的内容
#   %%writefile magic可以把cell的内容保存到外部文件里。 
#   而%pycat则可把外部文件展示在Cell中
%%writefile SaveToPythonCode.py

from math import sqrt
for i in range(2,10):
    flag=1
    k=int(sqrt(i))
    for j in range(2,k+1):
        if i%j==0:
            flag=0
        break
        if(flag):
            print(i)
# 因为没有指定路径, 所以文件被保存到了根目录下. 但至少it works.

%pycat /home/aistudio/work/SaveToPythonCode.py

关于快速查看某个对象/方法/接口的用法

在要查询的对象前输入?或??并执行即可. 单问号是普通信息, 双问号是详细信息.

前提: 该对象方法已经被正确导入(import)

import paddle
?paddle.nn.Conv3D

你可以通过修改内核选项ast_note_interactivity,使得Jupyter对独占一行的所有变量或者语句都自动显示,这样你就可以马上看到多个语句的运行结果了。

from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"

PaddlePaddle快速入门

源于产业实践的开源深度学习平台

PaddlePaddle基础命令

PaddlePaddle是百度开源的深度学习框架,类似的深度学习框架还有谷歌的Tensorflow、Facebook的Pytorch等,在入门深度学习时,学会并使用一门常见的框架,可以让学习效率大大提升。在PaddlePaddle中,计算的对象是张量;

import paddle

paddle.__version__ # 优选2.0+



# 定义两个张量
x1 = paddle.ones([2,2], dtype='int64')
x2 = paddle.ones([2,2], dtype='int64')

# 将两个张量求和
y1 = paddle.add(x1, x2)

# 查看结果
print(y1)

使用PaddlePaddle做线性回归

import paddle
import numpy as np

paddle.__version__

# 定义训练和测试数据
x_data = np.array([[1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
                   [2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
                   [3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
                   [4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
                   [5.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]).astype('float32')
y_data = np.array([[3.0], [5.0], [7.0], [9.0], [11.0]]).astype('float32')
test_data = np.array([[6.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]).astype('float32')

# 定义一个简单的线性网络,这个网络非常简单,结构是:[输入层] --> [隐层] --> [激活函数] --> [输出层]

# 定义一个简单的线性网络
net = paddle.nn.Sequential(
    paddle.nn.Linear(13, 100),
    paddle.nn.ReLU(),
    paddle.nn.Linear(100, 1)
)

# 接着是定义训练使用的优化方法,这里使用的是随机梯度下降优化方法。PaddlePaddle提供了大量的优化函数接口,除了本项目使用的随机梯度下降法(SGD),还有Momentum、Adagrad、Adagrad等等,读者可以更加自己项目的需求使用不同的优化方法。

# 定义优化方法
optimizer = paddle.optimizer.SGD(learning_rate=0.01, parameters=net.parameters())

# 因为本项目是一个线性回归任务,所以我们在训练的时候使用的是平方差损失函数。
#   因为paddle.nn.functional.square_error_cost求的是一个Batch的损失值,所以我们还要对他求一个平均值。
#   PaddlePaddle提供了很多的损失函数的接口,比如交叉熵损失函数paddle.nn.CrossEntropyLoss。

# 在训练过程中,我们可以看到输出的损失值在不断减小,证明我们的模型在不断收敛。
# 将numpy类型数据转换成tensor之后才能用于模型训练
inputs = paddle.to_tensor(x_data)
labels = paddle.to_tensor(y_data)

# 开始训练100个pass
for pass_id in range(10):
    out = net(inputs)
    loss = paddle.mean(paddle.nn.functional.square_error_cost(out, labels))

    loss.backward()
    optimizer.step()
    optimizer.clear_grad()

    print("Pass:%d, Cost:%0.5f" % (pass_id, loss))



# 开始预测
predict_inputs = paddle.to_tensor(test_data)
result = net(predict_inputs)

print("当x为6.0时,y为:%0.5f" % result)
Demo1:用PaddlePaddle做房价预测

uci-housing数据集介绍:

  • 数据集共506行,每行14列。前13列用来描述房屋的各种信息,最后一列为该类房屋价格中位数。
  • PaddlePaddle提供了读取uci_housing数据集的接口,paddle.text.datasets.UCIHousing

数据集加载:

  • PaddlePaddle中使用paddle.io.DataLoader来进行数据的加载操作,通过参数batch_size控制批次大小,shuffle控制是否打乱顺序。

# 导入基本的库
import os
import paddle
import numpy as np

BATCH_SIZE=20

train_dataset = paddle.text.datasets.UCIHousing(mode='train')
valid_dataset = paddle.text.datasets.UCIHousing(mode='test')

#用于训练的数据加载器,每次随机读取批次大小的数据,剩余不满足批大小的数据丢弃
train_loader = paddle.io.DataLoader(train_dataset, batch_size=BATCH_SIZE, shuffle=True, drop_last=True)

#用于测试的数据加载器,每次随机读取批次大小的数据
valid_loader = paddle.io.DataLoader(valid_dataset, batch_size=BATCH_SIZE, shuffle=True)

#用于打印,查看uci_housing数据
print(train_dataset[0])

# 定义网络
net = paddle.nn.Linear(13, 1)

# 定义损失函数
#   此处使用均方差损失函数。
#   square_error_cost(input,lable):接受输入预测值和目标值,并返回方差估计,即为(y-y_predict)的平方

# 定义优化函数
#   此处使用的是随机梯度下降。
optimizer = paddle.optimizer.SGD(learning_rate=0.001, parameters=net.parameters())

import matplotlib.pyplot as plt


# 定义绘制训练过程的损失值变化趋势的方法draw_train_process
iter = 0
iters = []
train_costs = []

def draw_train_process(iters, train_costs):
    title="training cost"
    plt.title(title, fontsize=24)
    plt.xlabel("iter", fontsize=14)
    plt.ylabel("cost", fontsize=14)
    plt.plot(iters, train_costs, color='red', label='training cost') 
    plt.grid()
    plt.show()

# 模型训练
EPOCH_NUM=50

#训练EPOCH_NUM轮
for pass_id in range(EPOCH_NUM):                                  
    # 开始训练并输出最后一个batch的损失值
    train_cost = 0

    #遍历train_reader迭代器
    for batch_id, data in enumerate(train_loader()):
        inputs = paddle.to_tensor(data[0])
        labels = paddle.to_tensor(data[1])
        out = net(inputs)
        train_loss = paddle.mean(paddle.nn.functional.square_error_cost(out, labels))
        train_loss.backward()
        optimizer.step()
        optimizer.clear_grad()

        #打印最后一个batch的损失值
        if batch_id % 40 == 0:
            print("Pass:%d, Cost:%0.5f" % (pass_id, train_loss))    
        
        iter = iter + BATCH_SIZE
        iters.append(iter)
        train_costs.append(train_loss.numpy()[0])
       
    # 开始测试并输出最后一个batch的损失值
    test_loss = 0

    #遍历test_reader迭代器
    for batch_id, data in enumerate(valid_loader()):               
        inputs = paddle.to_tensor(data[0])
        labels = paddle.to_tensor(data[1])
        out = net(inputs)
        test_loss = paddle.mean(paddle.nn.functional.square_error_cost(out, labels))
        
    #打印最后一个batch的损失值
    print('Test:%d, Cost:%0.5f' % (pass_id, test_loss))     
    
#保存模型
paddle.save(net.state_dict(), 'fit_a_line.pdparams')

draw_train_process(iters,train_costs)


#绘制真实值和预测值对比图
infer_results = []
groud_truths = []

def draw_infer_result(groud_truths, infer_results):
    title='Boston'
    plt.title(title, fontsize=24)
    x = np.arange(1,20) 
    y = x
    plt.plot(x, y)
    plt.xlabel('ground truth', fontsize=14)
    plt.ylabel('infer result', fontsize=14)
    plt.scatter(groud_truths, infer_results, color='green',label='training cost') 
    plt.grid()
    plt.show()

# 模型预测
import paddle
import numpy as np
import matplotlib.pyplot as plt


valid_dataset = paddle.text.UCIHousing(mode='test')
infer_loader = paddle.io.DataLoader(valid_dataset, batch_size=200)

infer_net = paddle.nn.Linear(13, 1)
param = paddle.load('fit_a_line.pdparams')
infer_net.set_dict(param)


data = next(infer_loader())
inputs = paddle.to_tensor(data[0])
results = infer_net(inputs)

for idx, item in enumerate(zip(results, data[1])):
    print("Index:%d, Infer Result: %.2f, Ground Truth: %.2f" % (idx, item[0], item[1]))
    infer_results.append(item[0].numpy()[0])
    groud_truths.append(item[1].numpy()[0])
    
draw_infer_result(groud_truths, infer_results)


高层API助你快速上手深度学习七日打卡营即将开始,你准备好了吗!

选修:Debug基础教学

pdb

Python自带一个调试器, 在Python 3.7之后甚至成为内置调试器. 这就是PDB.

Python附带了一个名为pdb的有用模块,它基本上是一个交互式源代码调试器:

import pdb
pdb.set_trace() # 这个表示添加断点

一旦开始运行, 会出现交互框:

  • 在这个输入框里敲入命令, 即可开始调试.
  • 通常这些命令都是一个字母, 因此毋庸担心.

具体命令:

  • 下一行:n
  • 打印变量:p,如p num1
  • 动态添加断点:b
    • 我们在运行程序之前使用了pdb.set_trace()来设置断点。
    • 我们通常希望在调试会话开始后在程序的特定位置添加断点。
  • 动态分配变量:var_b = 'something'
  • 退出:q,正在执行的程序被中止;
ipdb

还有一种更好的方式, 叫ipdb. 用法和PDB很相似. 不过返回的输出是彩色的:

  • ENTER (重复上次命令)
  • c (继续)
  • l (查找当前位于哪里)
  • s (进入子程序,如果当前有一个函数调用,那么 s 会进入被调用的函数体)
  • n(ext) 让程序运行下一行,如果当前语句有一个函数调用,用 n 是不会进入被调用的函数体中的
  • r (运行直到子程序结束)
  • !<python 命令>
  • h (帮助)
  • a(rgs) 打印当前函数的参数
  • j(ump) 让程序跳转到指定的行数
  • l(ist) 可以列出当前将要运行的代码块
  • p(rint) 最有用的命令之一,打印某个变量
  • q(uit) 退出调试
  • r(eturn) 继续执行,直到函数体返回

安装:

#如发现环境中未安装, 可以运行下方代码来安装ipdb
!pip install ipdb -i https://pypi.tuna.tsinghua.edu.cn/simple

作业

# conda创建本地虚拟环境:
conda create -n piddle python=3.7
source activate piddle

# 安装piddle:https://www.paddlepaddle.org.cn/install/quick?docurl=/documentation/docs/zh/2.0/install/pip/macos-pip.html
python -m pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple


# 测试
import paddle.fluid
paddle.fluid.install_check.run_check()

参考资料

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

百度 AI Studio——《高层API助你快速上手深度学习》课程学习1 的相关文章

随机推荐

  • 单片机定时器/计数器、中断和串口控制位

    一 定时器 计数器 1 定时器控制寄存器 TCON TCON TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 TF1 TF0 定时器 计数器中断请求标志位当定时器计数满溢出回零时 有硬件置位 并可申请中断 当CPU响应中断并
  • C语言:(含大量图解)你真的了解结构体吗?

    文章目录 结构体 结构体的定义 结构体大小计算 结构体的对齐规则 关于对齐规则的解释 为什么C语言要这样进行大小设定 平台移植原因 追求高性能 修改默认对齐数 结构体传参问题 结构体 结构体的定义 结构体是一些值的集合 这些值被称为成员变量
  • 【RPC】RPC的序列化方式

    序列化 网络传输的数据必须是二进制数据 但调用方请求的出入参数都是对象 对象是不能直接在网络中传输的 所以我们需要提前把它转成可传输的二进制 并且要求转换算法是可逆的 这个过程我们一般叫做 序列化 这时 服务提供方就可以正确地从二进制数据中
  • 小程序——wxml组件和wxss适配

    一 和以往代码区别 wxml html zhuiy css view div text文字 加入这个可以长按选中 否则不能复制 image img button button form form input input label labe
  • Leetcode1333.餐厅过滤器——使用stream流

    文章目录 引入 本题题解 后记 int Integer List的互相转化 引入 在上周周赛中 有这么一道题 1333 餐厅过滤器 给你一个餐馆信息数组 restaurants 其中 restaurants i idi ratingi ve
  • Java远程调试原理与运用

    Java远程调试的原理是两个VM之间通过debug协议进行通信 然后以达到远程调试的目的 两者之间可以通过socket进行通信 首先被debug程序的虚拟机在启动时要开启debug模式 启动debug监听程序 jdwp是Java Debug
  • c语言——链表——多项式相加

    例题详解 一个多项式可以表示为二元组序列 a1 e1 a2 e2 an en 其中ai表示第i项的系数 非零值 ei表示第i项的指数 编写函数建立多项式链表实现一个多项式的输入 按指数从高到低有序 返回链表的头指针 3 编写函数实现两个多项
  • 【Kaggle】关于Kaggle永久保存Output & 如何关闭页面后在Kaggle后台运行程序的问题

    其实在创建一个notebook的时候上面的说明的代码已经讲到了 需要创建一个new version才能永久保存Output结果 否则就是临时保存 关掉页面就会删除 This Python 3 environment comes with m
  • 2023mothercup妈妈杯数学建模挑战赛思路

    先占坑 本人于2019年开始接触数学建模 参加了大大小小几十场数学建模比赛 本次mothercup也会持续陪跑 为大家提供免费的文字思路和视频思路 后续还有代码和参考文章等 2023年Mathorcup数学建模竞赛A题 比赛开始后第一时间更
  • swift:使用cocoapods引入Alamofire

    1 打开终端 Terminal 安装cocoapods 回车运行 抛出如下的异常 上网查了一下 这是墙外的网站 我们墙内的访问不了 这时候我们就要更换cocoapods的来源 如果gem的版本太旧 就执行如下命令更新一下gem 以下是更新成
  • vue router-view使用详解

    这里写目录标题 一 介绍 二 使用方法 1 实现效果 2 代码 一 介绍 router view组件作为vue最核心的路由管理组件 在项目中作为路由管理经常被使用到 vue项目最核心的App vue文件中即是通过router view进行路
  • 设置Tomcat默认访问路径

    步骤 1 打开server xml 在的上一行添加内容格式如下
  • 电脑关机一段时间后不能网络唤醒WOL

    一直以来 想实现远程开机的功能 后来经过NAT 花生壳DDNS的设置 可以通过一台常年开机的主机 来控制其他机器的开关机 但新的问题来了 就是电脑关机一段时间后不能网络唤醒WOL 按照网上教程 关闭了网卡的环保选项 在主板里也设置了WOL相
  • UE4_C++访问蓝图里的变量

    有没有碰到这样的问题 之前的同事用 连连看 实现了项目的逻辑 后续你要维护推展项目的开发 但头疼的是 你是个coder not 连连看 玩家 这时候how to do it UE4 C 访问蓝图里的变量 c 获得BP的方式 在访问蓝图变量之
  • GTest基础学习-04-第3个单元测试-测试夹具test fixture

    这篇来学习一下Gtest中更高级一些的特性test fixture 测试夹具的基本上使用 什么的场景需要使用到测试夹具呢 测试夹具是哪个宏 这篇来学习这个主题 1 什么叫test fixture 什么是测试夹具 这个概念在任何xUnit系列
  • 工厂车间设备智能化管理系统软件

    工厂车间设备智能化管理系统软件 在面对疫情这样的严峻挑战下 制造业企业和工厂开始走向精细化和智能化的管理模式 如今有不少的工厂采用智能化的管理模式 统筹人事 客户 采购 订单 车间 物料 仓储 工艺等板块 而这样的一款智能工厂管理系统 应该
  • C++:这门语言优势在哪?命名空间以及缺省参数?

    文章目录 C 的优势 解决命名空间的问题 缺省参数 C 的优势 C 和C语言比起来有许多优势 这里我们先举一个例子 后续进行补充 解决命名空间的问题 首先看这样的代码 include
  • docker ubuntu 使用apt安装vim--报错Unable to locate package vim

    docker ubuntu 安装vim 报错Unable to locate package vim 前言 想修改从vulhub拉取运行的docker容器里的配置文件 使用vim时报错bash vim command not found 发
  • nest:[TypeOrmModule] Unable to connect to the database. Retrying

    有可能是刚开机的时候 mysql服务还没有开启导致的
  • 百度 AI Studio——《高层API助你快速上手深度学习》课程学习1

    百度 AI Studio 高层API助你快速上手深度学习 课程学习1 该系列文章系个人读书笔记及总结性内容 任何组织和个人不得转载进行商业活动 相关链接 飞桨 飞桨开源框架 PaddlePaddle 是一个易用 高效 灵活 可扩展的深度学习