Python入门
1.4.2 类
Str,int等数据类型是Python内置的数据类型。此外,用户还可以自己来定义新的类,也就是自己撞见数据类型。
Python中使用class关键词来定义新的类,类要遵循以下格式:
class 类名:
def __init__(self,参数,…): #构建函数
…
def 方法名1(self,参数,…): #方法1
…
def 方法名2(self,参数,…): #方法2
…
__init__是进行初始化的方法,也成为构造函数(constructor),只在生成类的实例时被调用一次。构造函数中的self是Python中的一个特点,凡是带有前缀self.的东西,都可以在这个类下面一直被使用,且如果被改变过一次了,那么下次使用的时候将会是更改之后的版本。
类的例子:
class Man: #定义一个新类Man
def __init__(self, name): #初始化参数,并接受参数name
self.name = name #初始化参数name
print("Initialized!") #输出Initialized
def hello(self): #从构造函数中带入初始化的参数
print("Hello " + self.name + "!") #输出Hello+构造函数的参数+!
def goodbye(self): #从构造函数中传参
print("Good-bye " + self.name + "!") #输出Good-bye+构造函数的参数+!
m = Man("David") #向构造函数传入name的参数
m.hello() #调用函数hello
m.goodbye() #调用函数goodbye
运行结果:
Initialized!
Hello David!
Good-bye David!
1.5 NumPy
NumPy的数组类(numpy.array)——便捷计算数组和矩阵的方法。
1.5.1 导入NumPy
NumPy是外部库,要使用import关键词来导入:
>>> import numpy as np #将NumPy作为np导入,调用NumPy时可直接用“np”
1.5.2 生成NumPy数组
生成NumPy数组需要使用.array()方法。.array()会将Python列表接收为参数并生成NumPy数组(numpy.array):
运行结果:
1.5.3 NumPy的算术运算
运行结果:
这里要注意a数组和b数组都是个数为5的一维数组,所以才可以进行运算,如果是不同的,程序就会报错。
NumPy数组不仅可以进行element-wise(对应元素的)运算,也可以和单一的数值(标量)组合起来进行运算:
运行结果:
1.5.4 NumPy的N维数组
NumPy还可以生成多维数组(矩阵):
运行结果:
此外还可以通过.shape查看数组a的形状(几行几列);通过.dtype查看里面元素的数据类型。另外,NumPy生成的一维的算术运算同样适用于N维中:
运行结果:
1.5.5 广播
NumPy中对于行与列数量不同的数组也可以进行运算。比如图中的例子,当矩阵和标量10相乘的时系统自动将向量扩展成了2 × 2的形状,然后才进行的运算,这个功能称为广播(broadcast)
例子:
运行结果:
同样这个功能对加减除也有效。
1.5.6 访问元素
数组的索引是先取整个行然后再取行里面的元素:
运行结果:
还可以使用for循环访问元素:
运行结果:
以上例子都是先取行再取元素的,下面演示NumPy中直接访问各个元素:
运行结果:
运用.flatten()将数组转为一维数组之后还可以获取满足一定条件的元素:
运行结果:
第一行结果为布尔型,第二行取a>25索引是在第一行布尔值之上的(取出True对应的元素)
学会利用.flatten()还可以选择“按行”(.flatten(‘a’))或者“按列”(.flatten(‘f’))进行降维。
1.6 Matplotlib
Matplotlib是用于绘制图形的库,使用它可以轻松绘制图形以及将数据的可视化。
1.6.1 绘制简单图形
绘制图形要用到Matplotlib库的pyplot模块:
运行结果:
1.6.2 pyplot的功能
在sin函数图形中我们用pyplot功能追加一个cos函数,并尝试使用pyplot来添加标题,x轴标签名等功能:
运行结果:
1.6.3 显示图像
还可以利用pyplot的imshow()方法显示图像,显示出的图像会有尺寸的标注。读入图像可以用matplotlib.image模块的imread()方法:
运行结果:
感知机
感知机(perceptron)是神经网络(深度学习)的起源算法。学习感知机的构造就是学习通向神经网络和深度学习的一种重要思想。
2.1 感知机是什么
感知机是接受多个输入信号,输出一个信号的。这里的“信号”是指具备“流动性”的东西,比如电流,河流。感知机的信号会形成流,向前方输送信息。感知机的流只有“传递信号/不传递信号”两种取值。“传递信号”——“1”;“不传递信号”——“0”。
图中是接受两给个信号的感知机的例子。x1,x2是输入信号,y是输出信号,w1和w2(是weight的首字母)是权重(权重数值越大,该信号就越重要)。图中的○称为“神经元”或者“节点”。输入的信号在被送往神经元的时候会被分别乘以各自固定的权重(w1x1,w2x2)。随后神经元会计算传送过来的信号的总和,当这个值>某个界限值θ(阈值)时,就会输出1,也成为“神经元被激活”
将感知机的运行原理用数学式来表示,就是:
2.2 简单逻辑电路
2.2.1 与门
考虑用感知机来解决问题,首先要以逻辑电路为题材来思考一下与门(AND gate)。与门是有两个输入和一个输出的门电路,且仅在两个输入均为“1”时才会输出“1”,其他时候——“0”
用感知机来表示这个与门:需要做的只有选取确定能满足上图的真值表的w1,w2和θ的值即可。满足条件的参数有无数多个,比如(w1,w2,θ)=(0.5,0.5,0.7)时,(w1,w2,θ)=(0.8,0.8,1.0)。参数设置成这样,仅当x1和x2同时为1时,信号的加权总和才会超过给定的阈值θ。
2.2.2 与非门和或门
接着来考虑一下“与非门”(NAND gate)。NAND时Not AND的意思,与非门时颠倒了与门的输出,仅当x1和x2同时为1时输出0,其他时候则是1.
表示与非门,可以用(w1,w2,θ)=(-0.5,-0.5,-0.7)这类的组合实现。实际上只要把实验与门的参数值的符号取反就可以实现与非门了。
接着看一下“或门”。或门是凡是有一个输入信号是“1”,那么输出就是“1”
表示或门可以用(w1,w2,θ)=(0.5,0.5,0.3)这类组合实现。
综上所诉,与门,与非门,或门的感知机构造一是样的,只是权重和阈值不一样而已。也就是说相同构造的感知机可以通过调整参数值来“变身”为与门,与非门或或门。
2.3 感知机的实现
2.3.1 简单的实现
现在,用Python来实现一下刚才的逻辑电路。我们要写一个接受x1和x2的AND函数,然后来验证以下与门的真值表:
运行结果:
同样我们也可以实现非与门和或门,只要将w1,w2和theta值修改一下就可以了。
2.3.2 导入权重和偏置
考虑到以后的事情,我们要对之前感知机行为的数学式进行一些改变——要将原先的阈值改为偏置(-b)。改完之后的感知机行为的数学式:
式中表达的内容与之前完全相同,b——偏置,w1和w2——权重。如果信号与权重的乘积加上偏置>0,那么就输出1,反之则输出0:
运行结果:
2.3.3 使用权重和偏置的实现
接下来分别用def函数实现与门,与非门以及或门:
与门:
与非门:
或门:
当没有信号输入或者信号输入为0的时候,系统只会输出偏置的值。