深度学习Python基础
写在前面:本篇为本书读书笔记的第一篇,书名:《深度学习原理与Pytorch实战》张伟振,清华大学出版社,属于本书第二章节。其他章节笔记后续会一并分享。笔者邮箱:pinecypressfxd@outlook.com欢迎学习讨论。
深度学习Python基础
- 深度学习三要素:模型、算力、数据。
- 常见的深度学习框架:Pytorch\TensorFlow\PaddlePaddle\Caffe\Theano\MXNet等。
- Pytorch的优势:
-
- 基于动态图
-
- GPU加速
-
- 分布式(e.g. Bert)
-
- 强大的生态系统
-
# 载入图像:
import cv2
image = cv2.imread(<ImageName>)
print(image)
三种错误和异常检测:assert, raise, try-catch.
# 错误和异常检测:
def vector_add(v1, v2):
# 抛出异常1
# if(len(v1)!=len(v2)):
# # 抛出异常
# raise Exception("length of v1 must equal to v2")
# 抛出异常2
assert len(v1)==len(v2), "length of v1 must equal to v2"
result = []
for i in range(len(v1)):
result.append(v1[i] + v2[i])
print('data')
return result
if __name__ == '__main__':
v1 = [1,2,3]
v2 = [1,2,3,4]
v3 = [1]
# 抛出异常3
try:
v3 = vector_add(v1, v2)# 该语句不执行
except Exception as e:
print("the vector length error, skip")
print(v3)
the vector length error, skip
[1]
文件/夹操作
1. 文件写入
# 1. 文件写入:
with open(R"test.txt","w") as f:
f.write("hello! world!")
hello! world!
hello! world!
2. 文件读取
# 2. 文件读取
file = open(R"test.txt")
for line in file:
print(line)
with open(R"test.txt", encoding = "UTF - 8") as f:
content = f.read()
print(content)
3. 文件夹操作
# 创建文件夹
import os
import sys
import argparse# python标准库argparse
# os.mkdir('data')
# 递归遍历目录
for root, dirs, files in os.walk('.'):
for file in files:
print(file)
# print(os.path.join(root,file))
# 查找关键字
def search(path: str, file_extension: str, keyword: str):
for root, dirs, files in os.walk(path):
for file in files:
if file.endswith(".py"):
with open(os.path.join(root, file), encoding = "UTF - 8") as f:
content = f.read()
if content.find("TODO")>0:
print(os.path.join(root, file))
os.system("notepad " + os.path.join(root, file))# 使用记事本打开
if __name__ == '__main__':
arg_parser = argparse.ArgumentParser()
arg_parser.add_argument("keyword", help = "关键词", type = str)
arg_parser.add_argument("-p","--path", help = "搜索路径", type = str, default = ".")
arg_parser.add_argument("-fe","-- file_extension", help = "文件后缀名", type = str, default = "")
args = arg_parser.parse_args()
search(args.path, args.file_extension, args.path)
# 执行该脚本时使用如下语句:
# python ***.py def -p . -fe .py
test.txt
./test.txt
config_sentinel
./.config/config_sentinel
.last_survey_prompt.yaml
./.config/.last_survey_prompt.yaml
active_config
./.config/active_config
gce
./.config/gce
.last_update_check.json
./.config/.last_update_check.json
default_configs.db
./.config/default_configs.db
.last_opt_in_prompt.yaml
./.config/.last_opt_in_prompt.yaml
config_default
./.config/configurations/config_default
01.15.02.819304.log
./.config/logs/2023.06.23/01.15.02.819304.log
01.13.40.960999.log
./.config/logs/2023.06.23/01.13.40.960999.log
01.15.03.520980.log
./.config/logs/2023.06.23/01.15.03.520980.log
01.14.30.259445.log
./.config/logs/2023.06.23/01.14.30.259445.log
01.14.06.378983.log
./.config/logs/2023.06.23/01.14.06.378983.log
01.14.37.930094.log
./.config/logs/2023.06.23/01.14.37.930094.log
anscombe.json
./sample_data/anscombe.json
README.md
./sample_data/README.md
mnist_test.csv
./sample_data/mnist_test.csv
mnist_train_small.csv
./sample_data/mnist_train_small.csv
california_housing_train.csv
./sample_data/california_housing_train.csv
california_housing_test.csv
./sample_data/california_housing_test.csv
#
import sys
print(sys.argv)
print(len(sys.argv))
['/usr/local/lib/python3.10/dist-packages/ipykernel_launcher.py', '-f', '/root/.local/share/jupyter/runtime/kernel-70479095-214d-4258-949c-b75b56f1fde7.json']
3
Python面向对象
在Python中,一切皆对象。
使用列表管理花名册
# 花名册:
string_list = ["ZhangShan", "LiSi", "WangWu", "ZhaoLiu"]
# 如何让列表内的人互相打招呼呢?
def greet1():
print("Hello!")
func = greet1
func()
Hello!
# 将函数名字作为对象存入列表用()进行调用
people_list = [["ZhangShan", 20, greet], ["LiSi",24,greet], ["WangWu",23,greet], ["ZhaoLiu",18,greet]]
def greet(index):
person = people_list[index]
print(person[0]+" is saying Hello to you!")
for index in range(len(people_list)):
person = people_list[index]
person[2](index)
ZhangShan is saying Hello to you!
LiSi is saying Hello to you!
WangWu is saying Hello to you!
ZhaoLiu is saying Hello to you!
使用class关键字声明类
上面我们使用列表完成了管理花名册的任务,但是手动管理过于繁琐,高级语言提供了类和对象的方式组织我们的代码。
要表示一个人,只需要定一个一个类,将人的属性定义为类的属性,将人能够做的事情定义为类的方法。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
print(self.name + " is saying hello to you!")
当我们使用“类名()”的方式创建并返回一个对象时,Python解释器会自动调用__init__(self)方法。使用.可以访问这个对象的成员。
person = Person("ZhangShan", 20)
person.greet()
ZhangShan is saying hello to you!
魔术方法:以下划线开头和结束的方法
除了__init__()方法,还有一个我们经常打交道的还有 call() ,当对象后接时,Python解释器会调用该对象的__call__() 方法,该对象被称为可调用对象,代码如下:
class CallableObject:
def __call__(self, *args, **kwargs):
print("Hello!")
callable_object = CallableObject()
callable_object()
Hello!
之前我们使用def定义一个函数,其实就是创建了一个可调用对象,±*/运算符也是函数(可调用对象)。
限定函数参数的类型
通常函数对输入的参数类型是有要求的,要限制参数类型,需要在声明函数时,在参数名的后面接一个“:(要求的类型)”,在表示函数内容后,接一个“->类型名”可以指定返回值的类型。
# 求三维空间中两个物体间的距离的函数
import math
class Object_new:
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
def distance(object1: Object_new, object2: Object_new)->float:
return math.sqrt(math.pow(object1.x - object2.x, 2) + math.pow(object1.y - object2.y, 2) + math.pow(object1.z - object2.z, 2))
player = Object_new(0,0,0)
enemy = Object_new(100,100,100)
print("The distance between two objects is {}".format(distance(player, enemy)))
The distance between two objects is 173.20508075688772
静态方法
静态方法可以不依赖于对象,直接使用类名的方式调用。
class DataUtil:
@staticmethod
def get_all_files(path: str) -> list:
all_files = []
for root, dirs, files in os.walk(path):
for file in files:
all_files.append(os.path.join(root, file))
return all_files
print(DataUtil.get_all_files("./data"))
包和模块
创建包和模块
python中,库是一个文件夹,至少包含一个空的__init__.py文件,模块是一个python源文件。
如果我们在A.py写了一个函数,想在B.py中使用,需要使用import语句。
# A.py
def add(a,b):
return a + b
# B.py
import A
print(A.add(1,2))
包:
- 文件夹A中需要包含__init__.py,向该文件中添加函数add。
- 与A文件夹同级创建一个main.py源文件,导入并使用模块名.的方式使用A包__init__中定义的函数add。
import A
print(A.add(1, 2))
import语句的本质:
当解释器遇到 import A语句,会在环境变量的路径中寻找A的含有__init__.py文件夹或者名为A.py的文件。找到时,执行一遍该文件,赋值给一个module类型的对象。
import matplotlib
print(type(matplotlib))
<class 'module'>
主函数:
因为导入模块就是把该模块运行一遍并赋值给一个对象,因此模块中的测试代码也会执行。这时可以使用主函数包裹测试代码:
if name == ‘main’:
这是因为当Python源文件被独立运行,该变量的值为__main__,这时if条件通过,执行测试代码;当Python源文件被当作模块导入时,该变量的值为模块名称。
所有的内建变量可以通过vars()获得。
当你以单个文件运行时,name__便是__main
当你以模块导入使用时,这个属性便是这个模块的名字。
在C/C++/Java中,main是程序执行的起点,Python中,也有类似的运行机制,但方式却截然不同:Python使用缩进对齐组织代码的执行,所有没有缩进的代码(非函数定义和类定义),都会在载入时自动执行,这些代码,可以认为是Python的main函数。
每个文件(模块)都可以任意写一些没有缩进的代码,并且在载入时自动执行,为了区分主执行文件还是被调用的文件,Python引入了一个变量__name__,当文件是被调用时,__name__的值为模块名,当文件被执行时,__name__为’main’。这个特性,为测试驱动开发提供了极好的支持,我们可以在每个模块中写上测试代码,这些测试代码仅当模块被Python直接执行时才会运行,代码和测试完美的结合在一起。
打包Python源代码
- 将Python小工具直接执行或者不具备Python环境情况下,可以使用PyInstaller库将Python源代码打包成.exe可执行文件。
# 安装PyInstaller
pip install pywin32
pip install wheel
pip install pyinstaller
- 打包Python脚本
pyinstaller -w -F plot.py
- 还可以使用Nuitka打包Python脚本,它把Python翻译成C++, 速度更快更保密,但需要安装C++编译器。