python、pycharm小技巧
1. 要学会使用Debug pycharm Debug使用
Debug记得打断点! Pycharm debug技巧 在debug的时候python console可以直接敲变量显示。 在安装Pycharm的时候,问你是否要添加环境变量,如果勾选的话那下次直接在命令行输入Pycharm就可以直接启动了。 2. 查找某个变量——选中变量按ctrl+F,查看某个函数的定义——ctrl+鼠标左键点一下函数(变量也可以)。选中然后shift+table是统一往前移;选中然后table是统一往后移。ctrl+/是注释。在括号内ctrl+P会提示你写什么参数。 3.我可以自己写库函数,比如我在同一目录下写了task2这个py文件,里面定义了propagate这个函数,那么我在同一目录下别的py文件里想调用propagate这个函数就可以先写from task2 import propagate然后就可以调用函数了。的
在想print的东西后面直接输入.pr然后table补全就可以自动写出print函数。
4.在这个目录下可以看到环境中安装的所有包
5. 环境的概念大于python,一个环境里我可以进入python我也可以进入C++,所以在terminal里要敲python代码首先需要先进入python。
np.random用法
x = np.random.randint(0,255,(25, 25, 3)) 生成25x25x3的数组,每个元素是0~255的整数。 np.random用法
x = np.random.rand(25, 25, 3) 生成25x25x3的数组,每个元素是0~1的浮点数(每个数服从0~1均匀分布。)np.random系列函数用法
x = np.random.randn(d0,d1,d2……dn)每个元素服从标准正态分布,np.random.randn()函数 很清楚
- 标准正态分布曲线下面积分布规律是:在-1.96~+1.96范围内曲线下的面积等于0.9500(即取值在这个范围的概率为95%),在-2.58~+2.58范围内曲线下面积为0.9900(即取值在这个范围的概率为99%)。
- 因此:由np.random.randn()函数所产生的随机样本基本上取值主要在-1.96~+1.96之间,当然也不排除存在较大值的情形,只是概率较小而已。
np.random.permutation( ) 函数:用法1: a = np.random.permutation(m) #它会返回一个长度为m的随机数组,且里面的数是0到m-1,0到m-1这几个数是随机打乱的。
用法2:总体来说他是一个随机排列函数,就是将输入的数据进行随机排列,此函数只能针对一维数据随机排列,对于多维数据只能对第一维度的数据进行随机排列。简而言之:np.random.permutation函数的作用就是按照给定列表生成一个打乱后的随机列表。在处理数据集时,通常可以使用该函数进行打乱数据集内部顺序,并按照同样的顺序进行标签序列的打乱。np.random.permutation( ) 用法2、3在这里
plt.imshow( )显示图片用法 train_set_x_orig.shape (209, 64, 64, 3) 训练集的特征这里有209张图,64x64的3通道rgb图。plt.imshow(train_set_x_orig[25])表示画出第25张图片,plt.imshow默认是
,这样就可以正确显示。plt.imshow()的用法 plt.plot( )里面只能传入一维数组。
array.transpose( ) 用来把图片[H, W, C] 转换成[C, H, W],array.transpose(2, 0, 1),原来的第0个维度和第2个维度交换,原来的第1维度和第0维度交换,原来的第2维度和第1维度交换。
a = numpy.random.randn([32, 32, 3]) # HWC b = a.transpose([2, 0, 1]) # HWC to CHW c = b.transpose([1, 2, 0]) # CHW to HWC
Numpy中-1的作用 | Numpy中的广播机制 广播加减乘除的几个例子,清楚 |
Numpy中axis的理解,很清楚 | np.squeeze用法 np.squeeze()会删除数组中的单维度条目,即把shape中为1的维度去掉,但对非单维的维度不起作用。 它不会影响原数组,会另外复制一个然后删除单维度,返回。 如果原数组shape是(1, ),那么squeeze后的shape是( );如果原数组shape是(2, ),那么squeeze后还是(2, );如果原数组shape是( ),那么squeeze后还是( )。 |
classes数组是array([b'non-cat', b'cat'], dtype='|S7'),这串字符串以二进制的形式存储,classes[1].decode("utf-8")的意思是以utf8的格式解码。
python元组的用法 Python元组详解
元组就是不可改变的列表,功能和列表类似,同样可以进行切片、修改等操作。在Python中任意无符号的对象,以逗号隔开,默认为元组
Python提供了一种返回值的机制,即一个函数可以返回多个值,这在别的语言中是很少见的。如果函数return noisy_circles, noisy_moons, blobs, gaussian_quantiles, no_structure好多变量,说明return的是个元组。Python type() 函数 type() 函数
我发现一个小细节,如果只print一个单独的np数组是不会显示array的,如
;但如果把多个np数组放到列表或者元组里再print就会多个array,如
断言assert用法 使用断言来确保我要的数据是正确的 assert (w.shape == (dim, 1)) # w的维度是(dim,1) assert (isinstance(b, float) or isinstance(b, int)) # b的类型是float或者是int
isinstance用法
>>>a = 2 >>> isinstance (a,int) True >>> isinstance (a,str) False >>> isinstance (a,(str,int,list)) # 是元组中的一个返回 True True
np.dot( )函数使用方法 注意矩阵与向量乘法,和常识不一样。 矩阵和向量相乘时,比如向量是 (5, ) 的,那么它会先自动变为(5,1)的矩阵,然后再相乘,结果比如是(5,1),也会自动变成 (5, ) | |
np.mean( )函数 np.power( ) 次方函数 | 机器学习中为什么需要对数据进行归一化? |
Numpy只支持CPU,李沐在Numpy的基础上开发了Mxnet可以支持GPU,后来有了Pytorch既支持CPU也支持GPU,用GPU就需要用到CUDA。
学习率和迭代次数更改学习率和迭代次数,有可能会发现训练集的准确性可能会提高,但是测试集准确性会下降,这是由于过拟合造成的。可以试试看加验证集,然后提前终止训练。为了让渐变下降起作用,必须明智地选择学习速率。学习率 α 决定了更新参数的速度。如果学习率过高,我们可能会“超过”最优值。同样,如果它太小,将需要太多迭代才能收敛到最佳值。这就是为什么使用良好调整的学习率至关重要的原因。
if __name__ == "__main__": 和import的一些用法
Python中if __name__ == ‘__main__‘:的作用和原理
一个python文件通常有两种使用方法,第一是作为脚本直接执行,第二是 import 到其他的 python 脚本中被调用(模块重用)执行。因此 if __name__ == 'main': 的作用就是控制这两种情况执行代码的过程,在 if __name__ == 'main': 下的代码只有在第一种情况下(即文件作为脚本直接执行)才会被执行,而 import 到其他脚本中是不会被执行的。
我自己写了一个python file,然后我在另一个python file里import这个文件,那么被import的文件里的所有语句会被直接执行,而if __name__ == 'main': 下面的语句不会被执行,def自定义的函数也不会被执行,除非你在另一个程序中调用这个自定义的函数才会执行。举例:
我在test1.py中这么写 def printfunc(): print(123) 然后我在test2.py中导入test1.py这个文件 import test1 #这时会自动执行所有test1.py中的所有语句,但因为我只在里面自定义了个函数所以没被执行,需要手动调用它才会有效果。如果是其他可以直接产生效果的语句,那么import的时候就直接执行产生结果了 test1.printfunc()#我想使用test1.py里的函数我就得这么写 如果我导入的时候是这么写的 from planar_utils import printfunc printfunc() #这种导入方式直接写函数名字就能调用了 如果你不想导入的时候自动执行test1.py里面的所有语句, 那只需要把不想执行的语句写在if __name__ == ‘__main__‘:下面就可以
字典的用法(字典里可以value也可以再套一个字典)字典的用法
a = {} a['fw'] = {'ysy':1234,'dfas':654} a['ss'] = 365 print(a) #结果{'fw': {'ysy': 1234, 'dfas': 654}, 'ss': 365} print(a['fw']) #结果{'ysy': 1234, 'dfas': 654} print(a['fw']['ysy']) #结果1234
import 和 from xxx import xxx的区别
import 导入模块,每次使用模块中的函数都要指定是哪个模块。 模块.函数
将整个模块导入,格式为: import somemodule (as别名) 从某个模块中导入某个函数,格式为: from somemodule import somefunction (as别名) 从某个模块中导入多个函数,格式为: from somemodule import firstfunc, secondfunc, thirdfunc 将某个模块中的全部函数导入,格式为: from somemodule import * from…import * 导入模块,每次使用模块中的函数,直接使用函数就可以了;因为已经知道该函数是那个模块中的了。 直接使用函数名使用就可以了
![]()
import的时候会自动执行所有被import文件中的语句,如果里面全部都是在def定义函数那就不会有什么效果,用的时候再调用就行,如果里面有可以直接被执行的语句,那么import的时候就会被直接执行了。
sklearn库
库安装 pip install -U scikit-learn -i https://pypi.douban.com/simple
sklearn
全称scikit-learn
,这里scikit
表示SciPy Toolkit
,因为它依赖于SciPy
库。而learn
则表示机器学习。所以安装时如果没有scipy会自动安装依赖,也就是把scipy给自动装上。安装完成后名字不知道为啥又不叫全称了,显示叫sklearn了,所以调用是调用sklearn的。
在这个目录下可以看到环境中安装的所有包。
import sklearn diabetes = sklearn.datasets.load_diabetes()
这样是会报下面的错误,原因好像是sklearn
不会自动导入其子包,所以要手动导入一下。ttributeError: module 'sklearn' has no attribute 'datasets'
import sklearn.datasets diabetes = sklearn.datasets.load_diabetes()
sklearn之datasets模块常用功能介绍 sklearn之datasets模块常用功能详细介绍
def load_extra_datasets(): N = 200 noisy_circles = sklearn.datasets.make_circles(n_samples=N, factor=.5, noise=.3) # 返回的是有2个元素的元组,第一个元素是X,第二个是Y,下面同理 noisy_moons = sklearn.datasets.make_moons(n_samples=N, noise=.2) blobs = sklearn.datasets.make_blobs(n_samples=N, random_state=5, n_features=2, centers=6) gaussian_quantiles = sklearn.datasets.make_gaussian_quantiles(mean=None, cov=0.5, n_samples=N, n_features=2, n_classes=2, shuffle=True, random_state=None) no_structure = np.random.rand(N, 2), np.random.rand(N, 2) # 元组,里面是两个numpy数组 return noisy_circles, noisy_moons, blobs, gaussian_quantiles, no_structure
scipy库
可以使用scipy读图片并改变图片大小,但是scipy.ndimage.imread和scipy.misc.imresize这两个函数新版本scipy已经弃用了。 用scipy读图片并改变图片大小
吴恩达深度学习第四周编程作业,最后用自己的图片进行测试发现会报如下错误AttributeError: module 'scipy.ndimage' has no attribute 'imread',原因是scipy1.3.0开始imread,imresize被弃用。 解决方法一:用imageio和from PIL import Image
解决方法二:用matplotlib和from PIL import Image
data = sio.loadmat('datasets/data.mat') 的 sio.loadmat是用来读取matlab的mat数据文件数据的。loadmat()函数加载.mat数据文件 python读取 mat 文件
np.meshgrid( ) 感觉适合用来画网格点。配合plt.contourf( )使用。 np.meshgrid( )函数用法
np.square( )函数 返回一个新数组,该数组的元素值为源数组元素的平方,源阵列保持不变。np.sqrt( )函数 作用:对数组每个元素返回一个它的非负平方根 np.sqrt( )开根号函数 如果X所有元素都为实数(标量),则y中元素也全为实数(标量);注意:对于X中的负实数,在y中会显示为nan。如果X中存在至少一个元素为复数,则返回的数组y中元素全为复数(此时负实数的平方根也会计算出来;例如-9的平方根为0+3j)。
np.maximum( )函数 对两个参数进行逐元素比较,谁大就返回谁。np.maximum( )函数用法
a1 = [3,5,2,1,6] a2 = [7,1,2,4,2] np.maximum(a1,a2) Out[21]: array([7, 5, 2, 4, 6])
lambda匿名函数:lamda匿名函数用法
g=lambda x:x+1 print(g(1)) #结果为2
函数的输入可以是另一个函数,比如下面的,X,Y都是有内容的参数,第一个输入是输入了一个函数,这个函数会在最外面的函数中调用。
plot_decision_boundary(lambda x: clf.predict(x), X, Y) #绘制决策边界def plot_decision_boundary(model, X, y): Z = model(np.c_[xx.ravel(), yy.ravel()])
plt.contourf用来画出不同分类的边界线
plt.contourf( )绘制边界函数 讲的很清楚
在程序中绘制一条线,不能用在纸上的思想来画。在纸上画比如y=x^2,很容易将画出一条抛物线,但是在程序中画图的逻辑不一样,应该通过很多离散的点来画,判断这个点是不是在线上以及在上面还是下面,需要再多做一步运算。
np.c_[a1, b1])用法、x.ravel()用法、plt.contourf 与 plt.contour 区别
ravel函数将多维数组降为一维,仍返回array数组,元素以列排列。np.c_[a1, b1])用法、x.ravel()用法、plt.contourf 与 plt.contour 区别
ravel与flatten两者所要实现的功能是一致的(将多维数组降位一维),区别在于返回拷贝(copy)还是返回视图(view),numpy.flatten()返回一份拷贝,对拷贝所做的修改不会影响(reflects)原始矩阵,而numpy.ravel()返回的是视图(view),会影响(reflects)原始矩阵,相当于只是改变了排列方式里面的元素还是和原来的矩阵一一对应的有影响的关系的。
numpy的拷贝和视图
a = np.arange(12).reshape(3, 4) a array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) a.flatten()[1] = 2 #矩阵拉平之后修改第2个元素值,因为flatten是复制,所以并不会改变源矩阵a a array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) a.ravel()[1] = 2 #矩阵拉平之后修改第2个元素值,因为ravel返回的是视图,所以拉平后的元素和原来的 还是一一对应的,所以会改变源矩阵的值 a array([[ 0, 2, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) 所以 a.flatten()相当于a.ravel().copy() 复制的话会更加占用内存 视图在做运算的时候会自动复制,所以运算后并不会影响源矩阵 b = a #直接赋值互相有影响的 b = b + 2#运算是不会影响源矩阵的 b array([[ 2, 5, 4, 5], [ 6, 7, 8, 9], [10, 11, 12, 13]]) a array([[ 0, 3, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) b = a b += 2 #但是如果是这种写法的运算会影响源矩阵,因为这是源地操作,在原来的内存上操作的 b array([[ 2, 5, 4, 5], [ 6, 7, 8, 9], [10, 11, 12, 13]]) a array([[ 2, 5, 4, 5], [ 6, 7, 8, 9], [10, 11, 12, 13]])
reshape也不能改变原来的映射关系,原来互相能影响的reshape后还是会有影响的。
dZ = np.array([1,2,3], copy=True),np.array默认copy为true,就相当于( ).copy,返回一份拷贝,不影响原数组。
numpy中np.array( )与np.asarray( )的区别 array和asarray都可以将结构数据转化为ndarray,但主要区别是当数据源是ndarray时,array仍然会copy出一个副本,占用新的内存,但asarray不会。np.array()与np.asarray()的区别
Python面向对象编程
python中的类 python中的类 面向对象与面向过程的本质的区别 面向对象与面向过程的本质的区别
面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了;面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。
可以拿生活中的实例来理解面向过程与面向对象,例如五子棋,面向过程的设计思路就是首先分析问题的步骤:1、开始游戏,2、黑子先走,3、绘制画面,4、判断输赢,5、轮到白子,6、绘制画面,7、判断输赢,8、返回步骤2,9、输出最后结果。把上面每个步骤用不同的方法来实现。
如果是面向对象的设计思想来解决问题。面向对象的设计则是从另外的思路来解决问题。整个五子棋可以分为1、黑白双方,这两方的行为是一模一样的,2、棋盘系统,负责绘制画面,3、规则系统,负责判定诸如犯规、输赢等。第一类对象(玩家对象)负责接受用户输入,并告知第二类对象(棋盘对象)棋子布局的变化,棋盘对象接收到了棋子的变化就要负责在屏幕上面显示出这种变化,同时利用第三类对象(规则系统)来对棋局进行判定。
属性用来描述具体某个对象的特征。比如小志身高180M,体重70KG,这里身高、体重都是属性。
面向对象的思想就是把一切都看成对象,而对象一般都由属性+方法组成!属性属于对象静态的一面,用来形容对象的一些特性,方法属于对象动态的一面,咱们举一个例子,小明会跑,会说话,跑、说话这些行为就是对象的方法!所以为动态的一面, 我们把属性和方法称为这个对象的成员!
类:具有同种属性的对象称为类,是个抽象的概念。比如“人”就是一类,期中有一些人名,比如小明、小红、小玲等等这些都是对象,类就相当于一个模具,他定义了它所包含的全体对象的公共特征和功能,对象就是类的一个实例化,小明就是人的一个实例化!我们在做程序的时候,经常要将一个变量实例化,就是这个原理!我们一般在做程序的时候一般都不用类名的,比如我们在叫小明的时候,不会喊“人,你干嘛呢!”而是说的是“小明,你在干嘛呢!”
面向对象有三大特性,分别是封装性、继承性和多态性。
随机数种子 np.random.seed( )
np.random.seed() 的使用详解
import numpy as np i = 0 while (i < 4): if (i < 2): np.random.seed(0) #设置随机数种子0,种子0和种子1的区别在于生成的随机数序列不一样 print(np.random.randn(1, 5))#这两行语句被执行了两次,每次执行seed(0)就又指向随机数序列的起始位置了,所以两次打印是一样的,都是打印了前几个随机数 else: #设置种子,然后就会生成一串随机数序列,种子指向序列的起始位置,不管运行程序多少遍,这个序列是不会变的 print(np.random.randn(1, 5)) #这里没有再执行seed函数所以生成随机数就从序列中上次生成的随机数下面继续生成 i += 1 print('~~~~~~~~~~~~~~~~~~~~~~~~~~') i = 0 while (i < 4): if (i < 2): np.random.seed(1) #设置种子1,生成了另一个新的随机数序列 print(np.random.randn(1, 5)) else: print(np.random.randn(1, 5)) i += 1 print('~~~~~~~~~~~~~~~~~~~~~~~~~~') np.random.seed(1) #执行了seed(1),又指向了序列的起始位置 print(np.random.randn(1, 5)) print(np.random.randn(1, 5)) [[1.76405235 0.40015721 0.97873798 2.2408932 1.86755799]] [[1.76405235 0.40015721 0.97873798 2.2408932 1.86755799]] [[-0.97727788 0.95008842 -0.15135721 -0.10321885 0.4105985 ]] [[0.14404357 1.45427351 0.76103773 0.12167502 0.44386323]] ~~~~~~~~~~~~~~~~~~~~~~~~~~ [[ 1.62434536 -0.61175641 -0.52817175 -1.07296862 0.86540763]] [[ 1.62434536 -0.61175641 -0.52817175 -1.07296862 0.86540763]] [[-2.3015387 1.74481176 -0.7612069 0.3190391 -0.24937038]] [[ 1.46210794 -2.06014071 -0.3224172 -0.38405435 1.13376944]] ~~~~~~~~~~~~~~~~~~~~~~~~~~ [[ 1.62434536 -0.61175641 -0.52817175 -1.07296862 0.86540763]] [[-2.3015387 1.74481176 -0.7612069 0.3190391 -0.24937038]]
设置随机数种子会自动生成一个随机数序列,种子指向了序列的起始位置。不同的种子参数对应不同的随机数序列的起始位置。每次运行程序,只要设置了种子,随机数序列是不会改变的。
range( )函数 range( )函数用法
>>>range(10) # 从 0 开始到 9 >>> range(0, 10, 3) # 步长为 3[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] [0, 3, 6, 9] Python range函数 讲的很清楚
range( )返回的是一个可迭代对象(类型是对象),而不是列表类型, 所以打印的时候不会打印列表。
list( )函数是对象迭代器,可以把range()返回的可迭代对象转为一个列表,返回的变量类型为列表。
reverse和reversed函数用法与区别 reverse和reversed函数及使用
reverse( )是python列表的内置方法,用于列表中数据的反转。
a.reverse()会改变原列表。
reserved( )是python内置函数,对于给定的序列(包括列表、元组、字符串以及 range(n)区间)可以返回一个逆序序列的迭代器(用于遍历该逆序序列)。并不会修改原来序列中元素的顺序。
list( reversed(range(5)) #[4, 3, 2, 1, 0]
除法
我自己总结一下:对于加减法,整数和整数相加减,结果还是整数;浮点数和浮点数相加减,结果还是浮点数;整数和浮点数相加减,结果是浮点数。
对于除法,/ 这个除号返回的商始终是浮点数,无论两个数字是否为整数。
np.divide( ) 数组对应位置元素做除法,得到的是真实值。np.divide( )详解 np.true_divide( )得到的是真实值。
math.floor(x) 方法将 x 向下舍入到最接近的整数。math.ceil(x)方法将数字向上舍入到最接近的整数。
numpy数组除法 numpy数组除法 python除法 python各类除法 python 除法取整_Python中整数和浮点数 python除法 写的最清楚 Python中的除法运算符
np.size( )用法 .size会返回数组中元素个数,例如,Z = np.zeros([10,10]) Z.size 是 100 np.size用法
numpy元素类型dtype Numpy的dtype设置方法
float32和float64的本质区别(类型对深度学习影响以及python的使用) float32和float64的本质区别(类型对深度学习影响以及python的使用)float64存储方式、精度 float存储方式、精度
numpy中默认元素数据类型是float64。假如你的数据是整数而且在0-255之间那换成uint8可以节省内存,比如这个Y = np.zeros((m,1), dtype='uint8')
python强制类型转换 python强制类型转化
强制类型转换比如 float(a), int(b) 这些是不会影响被转换的数的,只是会返回一个转换后的数。感觉大部分函数都是有一个返回值而不是直接改变变量,包括reshape,并不会改变原数组,除非你自己给自己赋值。
对于只有一个元素的数组,可以直接强制类型转换float( )之类的,把数组变成一个正常的数。 想返回数组中的数还可以用item方法 numpy的item函数
np.mean, sum, max, min (keepdims=True)的理解 keepidms=True(结果保持其原来维数)
np.round( )函数 是对浮点数取整的一个函数。当整数部分是偶数,小数部分是0.5时,向下取整,最后结果为偶数;当整数部分是奇数,小数部分是0.5时,则向上取整,最后结果为偶数。这样得到的结果在统计学上更精确。简而言之就是小数部分正好是0.5时四舍五入为偶数。例如下面的代码,
a array([[0.3 , 0.32, 0.35], [0.5 , 0.51, 0.52], [0.6 , 0.65, 1.5 ]]) np.round(a) array([[0., 0., 0.], [0., 1., 1.], [1., 1., 2.]])
enumerate函数 用来遍历一个集合对象,在遍历的同时还可以得到当前元素的索引位置。enumerate函数 enumerate() 函数 菜鸟教程
>>> seq = ['one', 'two', 'three'] >>> for i, element in enumerate(seq): ... print i, element ... 0 one 1 two 2 three
matplotlib相关
plt.subplot( )函数 plt.subplot()函数解析 plt.figure( )函数的用法 plt.figure( )的用法
plt.tight_layout()函数 plt.tight_layout()
plt.savefig()的用法 plt.savefig()的用法
plt.imread(
"xxx.jpg"
)读取图片函数用法
plt.imread( )可以从图像文件读入数据,得到一个表示图像的NumPy数组。第一个参数是文件名或文件对象,Linux的路径记得把~换成/home/ysy,要么就是直接把图片放在和程序文件的同一目录下然后用 . /代替当前路径,这样写路径就直接,format参数指定图像类型,如果省略,就由文件的扩展名决定图像类型。 对于灰度图像,它返回一个形状为(M,N)的数组;对于彩色图像,返冋形状为(M,N,C)的数组。 其中,M为图像的高度,N为图像的宽度,C为3或4,表示图像的通道数。plt.imread( )plt.imshow( )显示图片用法 train_set_x_orig.shape (209, 64, 64, 3) 训练集的特征这里有209张图,64x64的3通道rgb图。plt.imshow(train_set_x_orig[25])表示画出第25张图片,plt.imshow默认是
,这样就可以正确显示。 plt.imshow( )用法 plt.plot( )里面只能传入一维数组。 plt.plot( ) 函数详解
plt.show( )函数用于显示所有图形。
plt.rcParams['figure.figsize'] = (40.0, 40.0) 我自己试了一下好像是设置画布大小 matplotlib.pyplot中的rcparams参数小结
plt.axis('off') # 打印图片的时候不显示坐标轴 plt.rcParams[]详解
plt.scatter( )绘制散点图函数解析plt.scatter()函数 cmap = plt.cm.Spectral的功能是给label为1的点一种颜色,给label为0的点另一种颜色,没有这个功能的话label为0的点是白色看不见的。plt.cm.Spectral
plt.scatter(X=横坐标,Y=纵坐标,c=label样本标签,s=点的大小,cmap=plt.cm.Spectral); #训练数据可视化
设置坐标轴范围 axes = plt.gca() #先获取坐标轴 axes.set_xlim([-1.5,2.5]) axes.set_ylim([-1,1.5])
路径中“./”、“../”、“/”代表的含义 路径相关知识点总结
. / 代表目前所在的目录; . . / 代表上一层目录; / 代表根目录。
在读取文件时,路径的写法有如下方式:
1、文件在当前目录(以图像文件为例,当前项目文件为中心)
"./1.jpg" 或 "1.jpg"
2、文件在上层目录
(1)在上层目录下
"../1.jpg"
(2)在上层目录下的一个Image文件夹下
"../Image/1.jpg"
(3)在上上层目录下
"../../1.jpg"
3、文件在下一层目录(Image1文件夹)
"./Image1/1.jpg"
4、根目录表示法,任何页面访问Image下的Image.jpg图片
"C:/Image/1.jpg" Linux里是这样 '/home/ysy/softwares/python_projects/吴恩达深度学习课后作业/第四周 - PA1&2 - 一步步搭建多层神经网络以及应用/datasets/'
函数传参问题
调用函数时
,关键字参数
必须跟随在位置参数
后面! 因为python函数
在解析参数时, 是按照顺序来的,位置参数
是必须先满足, 才能考虑其他可变参数。 传参问题定义函数时,如果有的形参有默认值,有的形参没有默认值,那么有默认值的形参要放在没有默认值的形参的后面。 函数传参问题总结
def func1(a, b, c): #位置参数和关键字参数的顺序问题 print(a, b, c) func1(10, 20, 30) # 正确 func1(c=30, a=10, b=20) # 正确 func1(10, 20, c=30) # 正确(注意关键字参数必须在位置参数的后面) func1(a = 10, 20, 30) # 错误,关键字参数必须在位置参数的后面,报positional argument follows keyword argument错 func1(10, 20, a = 30) #错误,位置参数严格按照顺序来,第一个就是对应a,而不会因为a用了关键字参数b和c往前移了一位,报unc1() got multiple values for argument 'a'错 def func2(a, b, c=0): #参数默认值的顺序问题 print(a, b, c) #这样定义是正确的 func2(100, 200, 300) #正确 func2(100, 200) #正确 func2(a=100, c=200, b=150) #正确 func2(b=110, a=220) #正确 def func3(a, b=0, c): #错误,没有默认值的参数不能放在有默认值的参数的后面,报non-default argument follows default argument错 print(a, b, c) def func4(a, b=0, c=1): print(a, b, c) func4(2) func4(2,2) func4(2,c=2)
对于吴恩达深度学习第3周神经网络作业中
plot_decision_boundary(lambda x: predict(parameters, x.T), X, Y)函数的理解
def plot_decision_boundary(model, X, y): x_min, x_max = X[0, :].min() - 1, X[0, :].max() + 1 y_min, y_max = X[1, :].min() - 1, X[1, :].max() + 1 h = 0.01 xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h)) # 生成网格坐标点 Z = model(np.c_[xx.ravel(), yy.ravel()]) # 预测出来的是01标签 Z = Z.reshape(xx.shape) # 和xx横坐标,yy纵坐标的矩阵规格相同,这样才是一一对应,代表了对应点的预测值 plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral) # 绘制分界线 plot_decision_boundary(lambda x: predict(parameters, x.T), X, Y) '''这里的写法感觉很巧妙,因为定义这个函数时是这么定义的def plot_decision_boundary(model, X, y), 所以第一个参数其实就是model = lambda x: predict(parameters, x.T),那么这就是一个匿名函数的写法, lambda x表示这个匿名函数只有x需要调用时传入,而parameters并不是形参,是确定的值。 调用model(x)函数时输入了x,然后x又被传入了predict函数,并且先转置了一下。 写成这种形式也是对的,plot_decision_boundary(model = lambda x: predict(parameters, x.T), X = X, y = Y) 至于为什么要传入一个函数我觉得是因为这个函数定义在别的文件里,那里可没有predict这个函数,所以在这个文件用的时候把predict作为输入传进来再用。 '''
训练神经网络出现loss变成nan 神经网络训练时出现NaN loss
我的理解是,如果只是loss变成nan,应该并不影响参数的梯度下降更新,只是loss变成nan了。loss变成nan有可能是sigmoid里面的指数运算太大了,导致sigmoid输出为0,然后loss运行里有log函数,log(0)就会出现nan。一种解决方法是在log里加入一个非常小的量防止溢出,我试了一下确实有用,加上了一个1e-323。或者调小学习率,因为如果学习率太大,那么梯度下降可能就有那种发散的感觉,参数变得很大,导致输出的结果很大或者很小,不太正常。学习率调大,一旦超过某个值就会出现极端恶劣的情况:左右徘徊,甚至直接变成发散的,没能收敛。 学习率太大导致输出也很大
学习率设置的太大有可能训练时报错nan。 nan的错误多源于学习率设置的太大或者batchsize设置的太大,可以10倍10倍的减小学习率直到nan错误不出现。其实要弄明白nan错误怎么出现的才能真正的解决这个错误。 神经网络训练时出现nan错误
这个错误是因为logits输出太大变成INF,对这个取log就会在求梯度就会变成nan,nan是not a number 的缩写,表示不是一个有理数。所以除了调小学习率这个解决方案,另一个解决方案还可以给loss加正则化项。
在某些涉及指数计算,可能最后算得值为INF(无穷)(比如不做其他处理的softmax中分子分母需要计算exp(x),值过大,最后可能为INF/INF,得到NaN,此时你要确认你使用的softmax中在计算exp(x)做了相关处理(比如减去最大值等等))
nan在数学表示上表示一个无法表示的数,一般表示一个非浮点数(比如无理数)。inf不同于nan,inf是一个超过浮点表示范围的浮点数,其本质仍然是一个数,只是他为无穷大。
在numpy数组中,这些计算会产生nan的结果:
深度学习的一些方法 深度学习的一些方法
神经网络中涉及的训练参数与超参数概念理解,可以修改哪些超参数? 卷积神经网络中涉及的训练参数与超参数概念理解 讲的比较清楚
1.网络超参数
创建整个神经网络模型前,首先要指定与网络结构相关的超参数,如输入图像大小、卷积层和池化层以及网络训练、优化相关超参数。
输入图像大小、卷积层超参数(卷积核尺寸、卷积核数量、卷积的步长)、池化层超参数(池化核尺寸、池化步长、池化方式)
2.网络训练、优化超参数
Epoch(将全部的训练集数据投入神经网络模型完成一次完整的训练,这个过程称为一个Epoch。简单理解epoch的值就是整个训练集数据被输入神经网络训练了几次。)
Batch
Batch_size(① 基本梯度下降(BGD)② 随机梯度下降( Stochastic Gradient Descent. SGD ) ③ 小批量梯度下降(Mini-Batch GD))
Iteration迭代(训练时,1个batch训练图像通过网络训练一次(一次前向传播+一次后向传播),每迭代一次权重更新一次;测试时,1个batch测试图像通过网络一次(一次前向传播)
iteration就是使用一个batch数据对模型进行一次参数更新的过程)学习率 Ir(学习率是神经网络优化时的重要超参数.在梯度下降法中,学习率的取值非常关键,学习率决定了参数移动到最优值的速度快慢,如果学习率过大,很可能会越过最优值导致函数无法收敛,甚至发散;反之,如果学习率过小,优化的效率可能过低,收敛速度太慢,也易使算法陷入局部最优。合适的学习率应该是在保证收敛的前提下,能尽快收敛。)
3.神经网络优化的改善方法
改善神经网络优化的目标是找到更好的局部最小值和提高优化效率,目前比较有效的经验性改善方法通常分为以下几点:
(1)使用更有效的优化算法,来提高梯度下降优化方法的效率和稳定性,此如动态学习率调整、梯度估计修正等。
(2)使用更好的参数初始化方法、数据预处理方法来提高优化效率。
(3)修改网络结构来得到更好的优化地形(Optimization Landscape),比如使用ReLU激活函数、残差连接、逐层归一化等。
优化地形:指在高维空间中损失函数的曲面形状,好的优化地形通常比较平滑。
(4)使用更好的超参数优化方法。和师兄聊天,师兄说一般不改backbone,主题网络结构参数不怎么改,一改就大概率变得很烂,只改一些batchsize、学习率之类的。
numpy.all( )函数 与 numpy.any( )函数 numpy.all()函数 与 numpy.any()函数
python中表示否定:None,False,0,空列表,空元组,空集合,空字典,空钱包。
numpy的布尔索引
布尔索引是通过相同数组上的True还是False来进行提取的。提取的条件可以有多个,那么如果有多个,可以使用&来代表且,用来代表或,如果有多个条件,那么每个条件要使用圆括号括起来。Numpy--布尔索引
将a1数组中所有小于10的数据全部都提取出来。那么可以使用以下方式实现:
a1 = np.arange(0,24).reshape((4,6)) a2 = a1 < 10 print(a1[a2]) # 这样就会在a1中把a2中为True的元素对应的位置的值提取出来
利用索引,也可以做一些值的替换。把满足条件的位置的值替换成其他的值 :
a1 = np.arange(0,24).reshape((4,6)) a1[a1 < 5] = 0 #将小于5的所有值全部都替换成0 print(a1)
还可以使用np.where( )函数来实现: np.where() 用法详解 清楚
用法1:np.where(condition, x, y) 满足条件(condition)的元素,等于x,不满足的等于y。
a1 = np.arange(0,24).reshape((4,6)) a2 = np.where(a1 < 10,1,0) #把a1中所有小于10的数全部变成1,其余的变成0 print(a2)
用法2: np.where(condition) 只有条件 (condition),没有x和y,则输出满足条件 (即非0) 元素的坐标。这里的坐标以元组tuple的形式给出,通常原数组有多少维,输出的tuple中就包含几个数组,分别对应符合条件元素的各维坐标。
a = np.array([[1,1],[1,2]]) b = np.where(a == 1) a=[[1 1] [1 2]] b=(array([0, 0, 1]), array([0, 1, 0])) #符合条件的坐标,左边的都是行坐标,右边的都是列坐标
np.unique( )函数 对于数组或者列表,np.unique() 函数 去除其中重复的元素 ,并按元素 由小到大 返回一个新的无元素重复的元组或者列表。
a array([[[ 1. , 1.5], [-0.3, 0.5]], [[ 1. , 0.9], [ 2.1, 2.1]]]) np.unique(a) array([-0.3, 0.5, 0.9, 1. , 1.5, 2.1]) # 返回一个元素不重复的一维数组
Python函数参数注解-> 元数据 Python 函数 元数据
由于Python是一门解释型语言,在Python中定义变量不需要指明类型,所以在编写函数时,可以为函数的参数添加一些额外的信息来指明变量类型,以方便其他人使用。因此,可以使用函数参数注解来提示使用者传入变量的类型。
def Test(a:int,b:float)->float: return a*b print(Test(1,2.7))
python函数中的参数*args和**kwargs的含义和用法*args、**kwargs用法
一个星号
*
的作用是把除了位置参数和关键字参数剩下的参数作为元组传入;两个星号**
的作用是把关键字参数作为字典传入。def this_fun(a,b,*args,**kwargs): print a print b print args print kwargs this_fun(0,1,2,3,index1=11,index2=22) 0 1 (2, 3) {'index2': 22, 'index1': 11}
第一种不定的参数形式把剩下的没有关键字的参数收起来形成一个tuple,而第二种把有关键字的收起来做成一个字典。
字符串的索引和切片
字符串类型数据、索引与切片
python文件操作 文件操作
编码技术:将内容翻译成二进制,以及如何将二进制翻译回可识别内容。
计算机中有许多可用编码:UTF-8(最常用)、GBK、Big5等。
操作文件大概可以分为三个步骤:打开文件,操作文件,关闭文件。
open( )打开文件函数、或者创建新文件(只是打开,不是读取)
open(name, mode, encoding)
name:是要打开的目标文件名的字符串(可以包含文件所在的具体路径);
mode:设置打开文件的模式(访问模式): 只读、写入、追加等;
encoding:编码格式(推荐使用UTF-8)。
f = open('python.txt', 'r', encoding = "UTF-8")
# 此时的 f 是open函数的文件对象,拥有属性和方法
mode常用的三种基础访问模式
模式 | 功能 |
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
w | 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,原有内容会被删除。如果该文件不存在,创建新文件。 |
a | 打开一个文件用于追加。如果该文件已存在,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
read( )方法
文件对象.read( num ) num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据。读到哪,光标就移动到哪。
readlines( )方法
文件对象.readlines( ) readlines可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素。会从光标的位置开始读取。
f = open('python.txt', 'r', encoding = "UTF-8") # encoding必须用关键字参数传进去
content = f.readlines()
print(content) # 结果为 ['FLIR_1_RGB\n', 'FLIR_2_RGB\n', 'FLIR_3_RGB\n']
f.close()
readline( )方法
一次读取一行,调用一次读取一行。 f.readlines( )
还可以用for循环来读取每一行
for line in f:
print(line) #用for循环来读取txt文件的每一行
close( ) 关闭文件对象
f.close( )如果不调用close,同时程序没有停止运行,那么这个文件将一直被Python程序占用,被占用就意味着不能对文件删除重命名这些操作。程序停止运行也会结束占用。
with open语法
可以在执行完with open里的语句后自动关闭close文件,避免忘记f.close()
with open("python.txt", "r") as f:
content = f.readlines()
# 通过在with open的语句块中对文件进行操作
# 可以在执行完with open里的语句后自动关闭close文件,避免忘记f.close()
write( )方法
注意:
直接调用write,内容并未真正写入磁盘,而是会积攒在程序的内存中,称之为缓冲区。当调用flush( )方法刷新的时候,内容会真正写入磁盘。或者close之后也会自动写入磁盘(close方法内置了flush方法),也就是说用with open或者程序停止运行了,内容也会自动写入磁盘。讲解
这样做是避免频繁的操作硬盘,导致效率下降(攒一堆,然后用flush一次性写进磁盘)。
with open("python.txt", "w") as f:
f.write("11111111")
注意用w打开首先会清空原来的内容。用a打开是追加写入,可以用\n换行追加写入。
iter( )函数的用法iter( ) 函数生成迭代器 | next( )函数用法next() 返回迭代器的下一个项目。 next() 函数要和生成迭代器的 iter() 函数一起使用。 |
python中下划线的用法
独立下划线,只有一个下划线。
代码中一个独立的下划线,表示这个变量不重要。
一个独立的下划线,它也是一个变量名;只不过它比较特殊,当你使用下划线作为变量名时,就代表你告诉大家,这个变量不重要,仅仅占个位置,可以忽略,后面不会再使用它。
当然了,这是一种约定俗成,你要是不遵守也是可以的,毕竟在后面还可以通过下划线来获取这个变量的值。
例如:
for i, _ in [(1, 2), (3, 4)]:
print(i)
上面的代码表示我们只需要列表内部元组的第一个,第二个其实赋值给了下划线,虽然后面你可以通过下滑线来取到值,但是强烈建议你不要这么做,这违反了约定。