以熟练使用Pytorch完成深度学习模型为目标,简单介绍Pytorch涉及到的Python基础(Python其它知识可以在遇到后再学习,先动手)。
这篇教程并不涉及Python的复杂方法,教程的结构如下:
1.Python实例
2.Python基础
- 2.1 Python数据类型
- 2.2 Python语法
3.Numpy
4.类
5.文件读写
6.错误分析
3.1Numpy中主要是数组array的计算,数组是一个包含同类型数据的对象,数组有点类似于之前所述的列表。
import numpy as np
# 生成数组,np.array(列表,dtype),这里的dtype表示数组的类型,是可选参数。
a = np.array([1,2])
print(a) # 输出[1,2]
# 多维数组以及数组的一些常见方法
a = np.array([[1,2,3],
[4,5,6],
[7,8,9],
[10,11,12]])
3.2 数组查询与切片是一个比较重要,且常用的方法
# case1 查询
print(a[0,1]) #输出2,表示第0行第1列
# case2 切片
print(a[0:2,1:3]) #输出[[2 3],[5 6]] 表示第0-1行中的1-2列
3.3 获取Numpy数组的属性
# case3 获取shape,类型等信息
print(a.shape) # 输出(3,3)
print(a.dtype) # 输出int32
3.4 维数操作
在深度学习中用到的tensor张量与numpy数组比较类似,会涉及到比较多维数上的操作,需要对维数有个比较深刻的认识,这里要注意增加维数与挤压维数比较常用。
如果数组的shape为(5,3,4,5)表示第一维有5个,第二维有3个,第三维有4个,第四维有5个。
# case4 重新调整shape,reshape
b = a.reshape(2,6)
print(b) # 输出[[ 1 2 3 4 5 6],[ 7 8 9 10 11 12]]
# 增加维数
c = np.array([1,2,3])
print(c.shape) # 输出(3,)
d = c[np.newaxis,:]
print(d) # 输出[[1 2 3]]
# 挤压维度,只能挤压维数为1的
print(d.shape) # 输出(1, 3)
c = np.squeeze(d)
print(c) # 输出 [1,2,3]
# 数组拼接
a = np.array([[1,2,3],
[4,5,6]])
b = np.array([[7,8,9],
[10,11,12]])
d1 = np.concatenate((a,b),axis=0)
print(d1) # 输出 [[ 1 2 3],[ 4 5 6],[ 7 8 9],[10 11 12]]
d2 = np.concatenate((a,b),axis=1)
print(d2) # 输出 [[ 1 2 3 7 8 9],[ 4 5 6 10 11 12]]
3.5 数组条件查询
在图像处理或numpy使用中比较常用的方法是对数组进行条件查询,并对满足条件的值修改。
3.5.1 对数组中满足条件的位置赋值,支持多条件查询
# 数组中元素小于5的设置为0
a = np.array([[1,2,3],
[4,5,6]])
a[a<5]=0
print(a) # 输出[[0 0 0],[0 5 6]]
3.5.1 查找满足条件的数组的位置,用np.where(),同样可以多条件查询.
# 找数组元素等于1的位置
a = np.array([[1,2,1],
[4,5,1]])
print(np.where(a==1)) # 输出(array([0, 0, 1], dtype=int64), array([0, 2, 2], dtype=int64))
这里np.where返回的是一个x,y坐标数组,如上图表示满足条件的位置在[0,0],[0,2],[1,2]三个点。
# 将上述查找到的元素赋值为255
a[np.where(a==1)]=255
print(a) # 输出[[255 2 255],[4 5 255]]
练习1.a = np.array([1,2,3.2],dtype=np.int),a等于什么?提示:数据类型与a中不太一样。
练习2. 有两个数组a,b,令a与b的元素中相同且为0的元素更改为255.
a = np.array([[1,0,3],[4,0,6]]), b = np.array([[0,2,3],[4,0,6]])
4.1类的创建与实例化
这里类可以理解为一个模板,比如人是一个类。实例化是用模板创建了一个具体的对象,比如“小明”就是类实例化的一个对象,且有了这个模板后我可以轻而易举的创建无数个实例对象,比如女娲以人类为模板创建了无数的具体的人。
# 类的创建 class 类名:
class Dog:
def hello(self):
print("hello dog")
# 实例化
a = Dog()
4.2初始化
创建了人类这个模板后,不能是空的,我希望他能有名字,有性别,有出生日期,所以需要再每次实例化一个人的时候赋予他这些属性,就有了初始化。
注意初始化是在每次实例化的时候都会运行的函数。函数名不能自定义,且self表示实例本身,比如实例化了xiaoming后,xiaoming这个对象里面self就表示xiaoming.
def init(self,参数1,参数2…):
# 初始化
class Person(object):
def __init__(self, name, gender, birth):
self.name = name
self.gender = gender
self.birth = birth
# 创建实例,同时,属性name, gender, birth绑定到了xiaoming上
xiaoming = Person('Xiao Ming', 'Male', '1991-1-1') # 这时候类中的self.name都表示'Xiao Ming'
xiaohong = Person('Xiao Hong', 'Female', '1992-2-2')
# 输出'Xiao Ming'
print(xiaoming.name)
4.3类的属性与实例属性
类的属性或者类的方法调用都是用英文句号“.”表示。
类的属性与实例属性的区别在于它们有没有self.如下图所示,num是类属性,name是实例属性。
类的属性在不实例化也可以调用,但是实例属性只能在实例化后给实例对象调用,因为实例属性在__init__函数中,只有实例化才会运行该函数。
# 类属性与实例属性
class Test:
num=100 # 类属性
def __init__(self, name):
self.name=name #实例属性
print(Test.num) # 打印 100
# print(Test.name) # 报错,Test没有属性name。
test1 = Test("Bob")
print(test1.num) # 打印 100
print(test1.name) # 打印 "Bob"
4.4类的方法
类的方法与属性一样,也有类方法与实例方法,一般用到的都是实例方法,所以这里只讲实例方法。
# 类方法
class ComplexNumber:
def __init__(self,real = 0,imag = 0):
self.real = real
self.imag = imag
def show(self):
print("{}+{}i".format(self.real,self.imag))
# 实例化
c1 = ComplexNumber(2,3)
c1.show() # 打印2+3i
4.5类的继承
有时候需要复用一个类A的大多数方法与属性,这时候就可以通过继承A来实现。
4.5.1 父类的定义与普通类的定义一致
# 类的继承
# 父类Person的定义
class Person:
def __init__(self, name):
self.name = name
def print_name(self):
print("name is " + self.name)
4.5.2 子类
(1)子类的定义与普通类的定义有所区别,class 子类名(父类名):
(2)在初始化时需要初始化父类的初始化函数。
(3)子类可以调用父类的方法与属性。
# 子类学生的定义
class Student(Person):
def __init__(self, name, score):
Person.__init__(self, name) # Person.__init__(self, name)是一样的效果
# 一定要用 super(Student, self).__init__(name) 去初始化父类,否则,继承自 Person 的 Student 将没有 name。
self.score = score # 学生的特有属性分数。
def print_score(self):
print("score is", self.score)
Bob = Student("Bob", 90)
Bob.print_name() # Student没有print_name方法也可以打印"name is Bob"
Bob.print_score() # 打印"score is" 90