测开准备-Day03python基础+深度学习

测开准备-Day03python基础+深度学习 上次的基础在这测开准备-python基础Day01-CSDN博客就是python基础语法基本数据类型等的介绍。条件控制if-else演示a1 while a7: if(a%20): print(a,id even) else: print(a,is odd) a1代码运行结果1 is odd 2 id even 3 is odd 4 id even 5 is odd 6 id even注意1、每个条件后面要使用冒号 :表示接下来是满足条件后要执行的语句块。2、使用缩进来划分语句块相同缩进数的语句在一起组成一个语句块。3、在 Python 中没有 switch...case 语句但在 Python3.10 版本添加了 match...case功能也类似。if-elif演示num7 guess-1 while guess ! num: guess int(input(请输入数字)) if guess num: print(恭喜你猜对了) elif guess num: print(你猜的数字太大了) else: print(你猜的数字太小了)代码运行结果请输入数字5 你猜的数字太小了 请输入数字6 你猜的数字太小了 请输入数字7 恭喜你猜对了if嵌套if 表达式1:语句if 表达式2:语句elif 表达式3:语句else:语句elif 表达式4:语句else:语句numint(input(输入一个数字)) if num%20: if num%30: print(该数字是偶数且能被3整除) else: print(该数字是偶数但不能被3整除) else: print(该数字是奇数)循环语句while循环a1 while a10: print(a) a2代码运行结果1 3 5 7 9同样需要注意冒号和缩进。另外在 Python 中没有 do..while 循环。while 1无限循环while 循环使用 else 语句如果 while 后面的条件语句为 false 时则执行 else 的语句块。while expr: statement(s) else: additional_statement(s)count0 while count 5: print(count,小于5) count1 else: print(count,大于等于5)代码运行结果0 小于5 1 小于5 2 小于5 3 小于5 4 小于5 5 大于等于5for循环Python for 循环可以遍历任何可迭代对象如一个列表或者一个字符串。for variable in sequence: statements else: statementssites[baidu,gooole,sina,163,yahoo] for site in sites: print(site) print(-*30) for i in sites[0]: print(i)代码运行结果baidu gooole sina 163 yahoo ------------------------------ b a i d ufor...else在 Python 中for...else 语句用于在循环结束后执行一段代码。for item in iterable: # 循环主体 else: # 循环结束后执行的代码for x in range(6): print(x) else: print(Finally finished!)代码运行结果0 1 2 3 4 5 Finally finished!break 语句用于跳出当前循环体不会执行 else 子句sites [Baidu, Google,Runoob,Taobao] for site in sites: if site Runoob: print(菜鸟教程!) break print(循环数据 site) else: print(没有循环数据!) print(完成循环!)代码运行结果循环数据 Baidu 循环数据 Google 菜鸟教程! 完成循环!break语句可以跳出 for 和 while 的循环体。如果你从 for 或 while 循环中终止任何对应的循环 else 块将不执行。continue语句被用来告诉 Python 跳过当前循环块中的剩余语句然后继续进行下一轮循环。range()函数如果需要遍历数字序列可以使用该函数他会生成数列for i in range(5): ... print(i) ... 0 1 2 3 4for i in range(5,9) : print(i) 5 6 7 8 也可以使 range() 以指定数字开始并指定不同的增量(甚至可以是负数有时这也叫做步长):for i in range(0, 10, 3) : print(i) 0 3 6 9 end 关键字关键字end可以用于将结果输出到同一行或者在输出的末尾添加不同的字符函数函数是组织好的可重复使用的用来实现单一或相关联功能的代码段。函数能提高应用的模块性和代码的重复利用率。你已经知道Python提供了许多内建函数比如print()。但你也可以自己创建函数这被叫做用户自定义函数。规则定义函数的规则函数代码块以def关键词开头后接函数标识符名称和圆括号()。任何传入参数和自变量必须放在圆括号中间圆括号之间可以用于定义参数。函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。函数内容以冒号 : 起始并且缩进。return [表达式]结束函数选择性地返回一个值给调用方不带表达式的 return 相当于返回 None。函数调用的方法def max(a, b): if a b: return a else: return b a 4 b 5 print(max(a, b))参数传递在 python 中类型属于对象对象有不同类型的区分变量是没有类型的a[1,2,3]aRunoob以上代码中[1,2,3]是 List 类型Runoob是 String 类型而变量 a 是没有类型它仅仅是一个对象的引用一个指针可以是指向 List 类型对象也可以是指向 String 类型对象。可更改(mutable)与不可更改(immutable)对象在 python 中strings, tuples, 和 numbers 是不可更改的对象而 list,dict 等则是可以修改的对象。不可变类型变量赋值a5后再赋值a10这里实际是新生成一个 int 值对象 10再让 a 指向它而 5 被丢弃不是改变 a 的值相当于新生成了 a。可变类型变量赋值la[1,2,3,4]后再赋值la[2]5则是将 list la 的第三个元素值更改本身la没有动只是其内部的一部分值被修改了。python 函数的参数传递不可变类型类似 C 的值传递如整数、字符串、元组。如 fun(a)传递的只是 a 的值没有影响 a 对象本身。如果在 fun(a) 内部修改 a 的值则是新生成一个 a 的对象。可变类型类似 C 的引用传递如 列表字典。如 fun(la)则是将 la 真正的传过去修改后 fun 外部的 la 也会受影响python 中一切都是对象严格意义我们不能说值传递还是引用传递我们应该说传不可变对象和传可变对象。python 传不可变对象实例def change(a): print(id(a)) # 指向的是同一个对象 a10 print(id(a)) # 一个新对象 a1 print(id(a)) change(a)代码运行结果4379369136 4379369136 4379369424传可变对象实例# 可写函数说明 def changeme( mylist ): 修改传入的列表 mylist.append([1,2,3,4]) print (函数内取值: , mylist) return # 调用changeme函数 mylist [10,20,30] changeme( mylist ) print (函数外取值: , mylist)代码运行结果函数内取值: [10, 20, 30, [1, 2, 3, 4]] 函数外取值: [10, 20, 30, [1, 2, 3, 4]]参数以下是调用函数时可使用的正式参数类型必需参数关键字参数默认参数不定长参数必需参数必需参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。调用 printme() 函数你必须传入一个参数不然会出现语法错误关键字参数关键字参数和函数调用关系紧密函数调用使用关键字参数来确定传入的参数值。使用关键字参数允许函数调用时参数的顺序与声明时不一致因为 Python 解释器能够用参数名匹配参数值。默认参数调用函数时如果没有传递参数则会使用默认参数。以下实例中如果没有传入 age 参数则使用默认值。不定长参数你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数和上述 2 种参数不同声明时不会命名。匿名函数Python 使用 lambda 来创建匿名函数。所谓匿名意即不再使用def语句这样标准的形式定义一个函数。lambda 只是一个表达式函数体比def简单很多。lambda 的主体是一个表达式而不是一个代码块。仅仅能在 lambda 表达式中封装有限的逻辑进去。lambda 函数拥有自己的命名空间且不能访问自己参数列表之外或全局命名空间里的参数。虽然 lambda 函数看起来只能写一行却不等同于 C 或 C 的内联函数内联函数的目的是调用小函数时不占用栈内存从而减少函数调用的开销提高代码的执行速度。语法lambda [arg1 [,arg2,.....argn]]:expression冒号之前是参数冒号之后是表达式x lambda a : a 10 print(x(5))代码运行结果15设置两个参数# 可写函数说明 sum lambda arg1, arg2: arg1 arg2 # 调用sum函数 print (相加后的值为 : , sum( 10, 20 )) print (相加后的值为 : , sum( 20, 20 ))代码运行结果相加后的值为 : 30 相加后的值为 : 40拆解说明lambda x: x是一个简单的匿名函数作用是直接返回传入的参数 x这里没有做任何额外计算只是原样返回元素。map(...)会遍历numbers列表把每个元素1、3、6依次传给lambda x: x函数执行后返回原元素最终生成一个包含原元素的迭代器。tuple(...)把这个迭代器转换为元组因此最终结果是(1, 3, 6)。线性神经网络线性回归的简洁实现在过去的几年里出于对深度学习强烈的兴趣 许多公司、学者和业余爱好者开发了各种成熟的开源框架。 这些框架可以自动化基于梯度的学习算法中重复性的工作。实际上由于数据迭代器、损失函数、优化器和神经网络层很常用 现代深度学习库也为我们实现了这些组件。#生成数据集 import numpy as np import torch from torch.utils import data from d2l import torch as d2l true_w torch.tensor([2, -3.4]) true_b 4.2 features, labels d2l.synthetic_data(true_w, true_b, 1000) #读取数据集 我们可以调用框架中现有的API来读取数据。 我们将features和labels作为API的参数传递并通过数据迭代器指定batch_size。 此外布尔值is_train表示是否希望数据迭代器对象在每个迭代周期内打乱数据。 def load_array(data_arrays, batch_size, is_trainTrue): #save 构造一个PyTorch数据迭代器 dataset data.TensorDataset(*data_arrays) return data.DataLoader(dataset, batch_size, shuffleis_train) batch_size 10 data_iter load_array((features, labels), batch_size) #构造模型 对于标准深度学习模型我们可以使用框架的预定义好的层。这使我们只需关注使用哪些层来构造模型而不必关注层的实现细节。 我们首先定义一个模型变量net它是一个Sequential类的实例。 Sequential类将多个层串联在一起。 当给定输入数据时Sequential实例将数据传入到第一层 然后将第一层的输出作为第二层的输入以此类推。 在下面的例子中我们的模型只包含一个层因此实际上不需要Sequential。 但是由于以后几乎所有的模型都是多层的在这里使用Sequential会让你熟悉“标准的流水线”。 回顾单层网络架构 这一单层被称为全连接层fully-connected layer 因为它的每一个输入都通过矩阵-向量乘法得到它的每个输出。 在PyTorch中全连接层在Linear类中定义。 值得注意的是我们将两个参数传递到nn.Linear中。 第一个指定输入特征形状即2第二个指定输出特征形状输出特征形状为单个标量因此为1。 # nn是神经网络的缩写 from torch import nn net nn.Sequential(nn.Linear(2, 1)) #初始化模型参数 在使用net之前我们需要初始化模型参数。 如在线性回归模型中的权重和偏置。 深度学习框架通常有预定义的方法来初始化参数。 在这里我们指定每个权重参数应该从均值为0、标准差为0.01的正态分布中随机采样 偏置参数将初始化为零。 net[0].weight.data.normal_(0, 0.01) net[0].bias.data.fill_(0) #定义损失函数 计算均方误差使用的是MSELoss类也称为平方L2范数。 默认情况下它返回所有样本损失的平均值。 loss nn.MSELoss() #定义优化算法 小批量随机梯度下降算法是一种优化神经网络的标准工具 PyTorch在optim模块中实现了该算法的许多变种。 当我们实例化一个SGD实例时我们要指定优化的参数 可通过net.parameters()从我们的模型中获得以及优化算法所需的超参数字典。 小批量随机梯度下降只需要设置lr值这里设置为0.03。 trainer torch.optim.SGD(net.parameters(), lr0.03) #训练模型 在每个迭代周期里我们将完整遍历一次数据集train_data 不停地从中获取一个小批量的输入和相应的标签。 对于每一个小批量我们会进行以下步骤: 通过调用net(X)生成预测并计算损失l前向传播。 通过进行反向传播来计算梯度。 通过调用优化器来更新模型参数。 num_epochs 3 for epoch in range(num_epochs): for X, y in data_iter: l loss(net(X) ,y) trainer.zero_grad() l.backward() trainer.step() l loss(net(features), labels) print(fepoch {epoch 1}, loss {l:f}) w net[0].weight.data print(w的估计误差, true_w - w.reshape(true_w.shape)) b net[0].bias.data print(b的估计误差, true_b - b)代码输出结果epoch 1, loss 0.000200 epoch 2, loss 0.000094 epoch 3, loss 0.000094 w的估计误差 tensor([0.0002, 0.0002]) b的估计误差 tensor([0.0006])