if __name__ == '__main__': print("第一个解释器") print(1-2) print(3*2) print(3**2) lkl={'aini':520} print(lkl['aini']) hu=True if hu: print("刘坤龙") else: print("坤龙") for i in [1,2,3]: print(i) a = [1,2,3,4,5] print(a) print(a[0:3]) a[4]=99 print(a) def lkl(): print("好难啊") lkl() def lkl1(object): print(object+"好难啊"+"!") lkl1("计算机")’2.类运行
class lkl: def __init__(self,name,age): self.name=name self.age=age print("这个是初始函数!!") def lkl1(self): print("我叫"+self.name) def lkl2(self): print("年纪是"+self.age) lkl=lkl("刘坤龙","21") lkl.lkl1(); lkl.lkl2(); #### 注意:使用类时要在终端输入 python test.py #### 使用类时里面不管是数字还是汉字都要带引号3. NumPy数组
import numpy as np#numpy属于外界包 需要向外界导入,此时的需要 #此时将numpy作为np导入 x=np.array([1.0,2.0,3.0]) print(x) y=np.array([4.0,5.0,6.0]) print(x+y) x1=np.array([[1,2],[3,4]]) print(x1) print(x1.shape,x1.dtype) #shape表示矩阵的形状,矩阵的元素类型有dtype查看 print(x1*10) x1=x1.flatten() print(x1) #flatten是将此以一维数组输出4.matplotlib
import numpy as np import matplotlib.pyplot as plt x=np.arange(0,6,0.1)#以0.1为单位,生成0到6的数据 y=np.sin(x) plt.plot(x,y)#将x,y的数据传给plt.plot方法 plt.show()4.1 绘制图像
import numpy as np import matplotlib.pyplot as plt x=np.arange(0,6,0.1)#以0.1为单位,生成0到6的数据 y=np.sin(x) plt.plot(x,y,label="sin")#将x,y的数据传给plt.plot方法 n=np.cos(x) plt.plot(x,n,linestyle="--",label="cos")#用虚线绘制 plt.title('sin & cos') plt.xlabel('x') plt.ylabel('y') plt.legend() plt.show()4.2 图片
import matplotlib.pyplot as plt from matplotlib.image import imread #img=imread('E:python学习py.png')#读入图片 img=imread('E:/python学习/py.png')#两种都可以 plt.imshow(img) plt.show()
二.感知机 1. 理解
- 感知机接收多个输入信号,输出一个信号
- 输入信号都有各自固有的权重w,权重发挥控制各个信号的重要性作用,权重越大,重要性越高
- 与门:仅在两个输入均为1时输出1,其他为0.(3011)
- 与非门:仅当两个输入为1时输出0,其他为1.(3110)
- 或门:只要有一个输入为1,输出就为1.(3110)
- 异或门:仅当x1或x2中一方为1时,才会输出1.(2120)
三.神经网络 1.激活函数(必须使用非线性函数)
- sigmoid函数(exp(-x)表示e的-x次方)
- 用该函数进行信号的转换,转换后传送给下一个神经元
h ( x ) = 1 1 + e x p ( − x ) h(x)=frac{1}{1+exp(-x)} h(x)=1+exp(−x)1
- sigmoid函数实现
import numpy as np def sigmoid(x): return 1/(1+np.exp(-x)) x=np.array([-0.1,1.0,2.0]) print(sigmoid(x))2.跳跃函数
import numpy as np x=np.array([-1.0,1.0,2.0]) print(x) y=x>0 y1=y.astype(np.int)#转换数据类型 print(y) print(y1)
import numpy as np import matplotlib.pylab as plt def st_fu(x): return np.array(x>0,dtype=np.int) x = np.arange(-5.0,5.0,0.1)#在-5.0到5.0之间以0.1为单位生数组 y = st_fu(x) plt.plot(x,y) plt.ylim(-0.1,1.1)#指定y的范围 plt.show()3.ReLU函数
h ( x ) = { x ( x > 0 ) 0 ( x ≤ 0 ) h(x)=begin{cases}x(x>0)\0(xle0)end{cases} h(x)={x(x>0)0(x≤0)
- 函数实现
import matplotlib.pylab as plt import numpy as np def relu(x): return np.maximum(x,0)4.神经网络内积
import numpy as np x=np.array([1,2]) print(x.shape) y=np.array([[1,3,5],[2,4,6]]) print(y) print(y.shape) w=np.dot(x,y)#内积 print(w)5.小结1
- 回归问题可以使用恒等函数identity_function() {感觉没啥用,原样输出}
- 二元分类问题可以使用sigmoid函数
- 多元分类问题可以使用softmax函数
- 该函数会出现溢出的现象,由于进行指数函数,数会很大
- softmax函数的输出是0.0到1.0之间的实数,输出总和为1
y k = e x p ( a k ) ∑ i = 1 n exp ( α i ) y_k=cfrac{exp(a_k)}{sum_{i=1}^n{exp left(alpha _i right)}} yk=∑i=1nexp(αi)exp(ak)
5.1改进softmax函数y k = C e x p ( a k ) C ∑ i = 1 n exp ( α i ) y_k=cfrac{Cexp(a_k)}{Csum_{i=1}^n{exp left(alpha _i right)}} yk=C∑i=1nexp(αi)Cexp(ak)
y k = e x p ( a k + l o g C ) ∑ i = 1 n exp ( α i + l o g C ) y_k=cfrac{exp(a_k+logC)}{sum_{i=1}^n{exp left(alpha _i +logCright)}} yk=∑i=1nexp(αi+logC)exp(ak+logC)
y k = e x p ( a k + C ′ ) ∑ i = 1 n exp ( α i + C ′ ) y_k=cfrac{exp(a_k+C')}{sum_{i=1}^n{exp left(alpha _i +C'right)}} yk=∑i=1nexp(αi+C′)exp(ak+C′)
- 由于分子分母同时乘上C(为任意数),不改变数值大小
c=np.max(a) exp_a=np.exp(a-c)#溢出对策
- 为防止溢出,一般使用输入信号的最大值
- 神经网络中激活函数使用的是平滑变化的sigmoid函数和ReLU函数
- 使用NumPy多维数组,可以高效实现神经网络
- 机器学习大致分回归问题(恒等函数)和分类问题(softmax函数)
- (例如识别数字5)先从图像中提取特征量,在用机器学习技术学习这些特征量的模式。
- 特征量指可以从输入数据(输入图像)中准确提取本质数据(重要数据)的转换器
- 特征量通常为向量的形式(包括SIFT,SURF,HOG等)
- 使用特征量将图像数据转为向量,然后对向量使用机器学习中的SVM,KNN等进行分类
- 神经网络的学习通过某个指标表示现在的状态
- 神经中的所有指标称为损失函数(一般用均方误差和交叉熵误差)
- 公式
E = 1 2 ∑ k ( y k − t k ) 2 E=frac{1}{2}sum_k{(y_k-t_k)^2} E=21k∑(yk−tk)2
- yk表示神经网络的输出,tk表示监督数据,k表示数据的维数
- 代码实现
import numpy as np def mean_sq_err(y,t): return 0.5*np.sum((y-t)**2) t=[0,0,1,0,0,0,0,0,0,0] y=[0.1,0.05,0.6,0.0,0.05,0.1,0.0,0.1,0.0,0.0] print(mean_sq_err(np.array(y),np.array(t))) y=[0.1,0.05,0.1,0.0,0.05,0.1,0.0,0.6,0.0,0.0] print(mean_sq_err(np.array(y),np.array(t)))3.交叉熵误差
- 公式
E = − ∑ k t k l o g y k E=-sum_k{t_klogy_k} E=−k∑tklogyk
- yk表示网络神经的输出,tk是正确解标签
- tk中只有正确解标签的索引是1,其他均是0
- 代码实现
import numpy as np def cro_ent_err(y,t): delta=1e-7 return -np.sum(t*np.log(y+delta)) t=[0,0,1,0,0,0,0,0,0,0] y=[0.1,0.05,0.6,0.0,0.05,0.1,0.0,0.1,0.0,0.0] print(cro_ent_err(np.array(y),np.array(t))) y=[0.1,0.05,0.1,0.0,0.05,0.1,0.0,0.6,0.0,0.0] print(cro_ent_err(np.array(y),np.array(t)))4. mini-batch
-
之前是针对单个函数的损失函数,要对所有的训练数据的损失函数的总和,以交叉熵误差为例
-
E = − 1 N ∑ n ∑ k t n k l o g y n k E=-frac{1}{N}sum_nsum_kt_{nk}logy_{nk} E=−N1n∑k∑tnklogynk
-
Tnk表示第n个数据的第k个元素的值
-
Ynk是神经网络的输出,Tnk是监督数据
-
神经网络的学习就是从训练数据中选出一批数据(称为mini-batch,小批量),再对每个小批量进行学习
- 实现一个同时处理单个数据和多个数据两种情况的函数
def cro_ent_err(y,t): if y.ndim==1: t=reshape(1,t.size) y=reshape(1,y.size) batch_size=y.shape[0] return -np.sum(np.log(y[np.arange(batch_size),t]+1e-7))/batch_size6数值微分
- 导数
d f ( x ) d x = lim h − > 0 f ( x + h ) − f ( x ) h frac{df(x)}{dx}=lim_{h->0}frac{f(x+h)-f(x)}{h} dxdf(x)=h−>0limhf(x+h)−f(x)
-
import numpy as np def nnum_dif(f,x): h=1e-4#表示10的-4次方,大概是0.0001 return (f(x+h)-f(x))/h def func_1(x): return 0.01*x**2+0.1*x print(nnum_dif(func_1,5)) print(nnum_dif(func_1,10))
-
偏导数
f ( x 0 , x 1 ) = x 0 2 + x 1 2 f(x_0,x_1)=x_0^2+x_1^2 f(x0,x1)=x02+x12
import numpy as np#此时x0=3,x1=4 def nnum_dif(f,x): h=1e-4 return (f(x+h)-f(x))/h def func_tmp1(x0): return x0*x0+4.0**2 print(nnum_dif(func_tmp1,3.0))
- 梯度
import numpy as np def num_grad(f,x): h=1e-4 grad=np.zeros_like(x)#生成和x形状相同的数组 for idx in range(x.size): tmp_val=x[idx] # f(x+h)的计算 x[idx]=tmp_val+h fxh1 = f(x) # f(x-h)的计算 x[idx] = tmp_val - h fxh2 = f(x) grad[idx]=(fxh1-fxh2)/(2*h) x[idx]=tmp_val#还原值 return grad def func_2(x): return x[0]**2+x[1]**2#或者return np.sum(x**2) print(num_grad(func_2,np.array([3.0,4.0]))) #输出是[6. 8.]在输出NumPy数组时,数组会改成易读模式
- 梯度指示的方向时各点处的函数值减少最多的方向
- 神经网络必须在学习时找到最优参数(权重和偏置),最优参数指损失函数取最小值的参数
- 用梯度来找函数最小值(或尽可能小)就是梯度法
- 代码表示梯度下降法
import numpy as np def num_grad(f,x): h=1e-4 grad=np.zeros_like(x)#生成和x形状相同的数组 for idx in range(x.size): tmp_val=x[idx] # f(x+h)的计算 x[idx]=tmp_val+h fxh1 = f(x) # f(x-h)的计算 x[idx] = tmp_val - h fxh2 = f(x) grad[idx]=(fxh1-fxh2)/(2*h) x[idx]=tmp_val#还原值 return grad def grad_des(f,init_x,lr=0.01,step_num=100):#f是要优化的参数 x=init_x#init_x是初始值,lr是学习率,step_num是梯度重复次数 for i in range(step_num): grad=num_grad(f,x) x-=lr*grad return x def func_2(x): return x[0]**2+x[1]**2 init_x=np.array([-3.0,4.0]) print(grad_des(func_2,init_x=init_x,lr=0.1,step_num=100))
- 学习率过大会发散一个很大的值,太小会没怎么更新就结束了
- 神经网络里面的梯度是指损失函数关于权重参数的梯度
- 神经网络中有合适的权重和偏置,调整权重和偏置以便于拟合训练数据的过程称为学习。分以下四步
- 从训练数据中随机选择一部分数据。
- 计算损失函数关于各个权重参数的梯度,(误差反向传播法)
- 将权重参数沿梯度方向进行微小的更新。
- 重复步骤1 步骤2,步骤3
- 神经网络学习的目的是为了找到使损失函数的值尽可能小的参数。即寻找最优化参数的问题。
w ← w − η δ L δ W 需 要 更 新 的 权 重 参 数 记 为 W , 损 失 函 数 关 于 W 的 梯 度 记 为 δ L δ W η 表 示 学 习 率 wgets w-etafrac{delta L}{delta W} \需要更新的权重参数记为W,损失函数关于W的梯度记为frac{delta L}{delta W} \ eta表示学习率 w←w−ηδWδL需要更新的权重参数记为W,损失函数关于W的梯度记为δWδLη表示学习率
class SGD: def __init__(self,lr=0.01): self.lr=lr #lr表示学习率,这个会保存为实例变量 def update(self,params,grads): #params['w1'],grads['w1']分别保存了权重参数和他们梯度 for key in params.keys(): params[key]-=self.lr*grads[key]
- 缺点:如果函数的形状非均匀,比如呈延伸状,搜索路径会很低效。
- 原因:梯度方向没有指向最小值方向
-
参照小球在碗中的滚动的物理规则进行移动
-
w ← α w − η δ L δ W W ← W + v wgets alpha w-etafrac{delta L}{delta W} \ Wgets W+v w←αw−ηδWδLW←W+v
-
出现新的变量v,对应物理上的速度
class Momentum: """Momentum SGD""" def __init__(self, lr=0.01, momentum=0.9): self.lr = lr self.momentum = momentum self.v = None def update(self, params, grads): if self.v is None: self.v = {} for key, val in params.items(): self.v[key] = np.zeros_like(val) for key in params.keys(): self.v[key] = self.momentum*self.v[key] - self.lr*grads[key] params[key] += self.v[key]
-
为参数的每个元素适当的调整更新步伐
-
该会为参数的每个元素适当的调整学习率,与此同时进行学习。
-
h ← h + δ L δ W ⊙ δ L δ W ⊙ 表 示 对 应 矩 阵 运 算 的 乘 法 W ← W − η 1 h δ L δ W hgets h+frac{delta L}{delta W}odotfrac{delta L}{delta W} \ odot 表示对应矩阵运算的乘法 \ Wgets W-etafrac{1}{sqrt h}frac{delta L}{delta W} h←h+δWδL⊙δWδL⊙表示对应矩阵运算的乘法W←W−ηh 1δWδL
-
h保存了以前梯度值的平方和
-
class AdaGrad: """AdaGrad""" def __init__(self, lr=0.01): self.lr = lr self.h = None def update(self, params, grads): if self.h is None: self.h = {} for key, val in params.items(): self.h[key] = np.zeros_like(val) for key in params.keys(): self.h[key] += grads[key] * grads[key] params[key] -= self.lr * grads[key] / (np.sqrt(self.h[key]) + 1e-7)
-
在更新参数时,通过乘以1/根号h,就可以调整学习的尺度。
-
参数的元素中变动较大(被大幅更新)的元素的学习率将变小。
-
可以按参照的元素进行学习率衰减,使变动大的参数的学习率逐渐减少
- 2015年提出,将Momentum和AdaGrad结合,实现了参数空间的高效搜索。
- 也进行了超参数的“偏置校正”
Xavier初始值-----sigmoid,tanh
He初始值-----ReLU
- 书上说很重要,权重初始值非常重要。
思路:调整各层的激活值分布使其拥有适当的广度。为此,要向神经网络中插入对数据分布进行正规化的层。
- 可以使学习快速进行(可以增大学习率)
- 不那么依赖初始值(对于初始值不那么神经质)
- 抑制过拟合(降低Dropout等的必要性)
- 过拟合:指的使只能拟合训练数据,但不能很好的拟合不包含在训练数据中的其他数据的状态。
原因:
- 模型拥有大量参数,表现力强。
- 训练数据小
- 机器学习目标:就是提高泛化能力,即便是没有包含在训练数据里的未关测数据,也希望模型可以进行正确的识别。
- 权值衰减:用来被使用的一种抑制过拟合的方法,通过对大的权重进行惩罚,来抑制过拟合。
+权重的L2范数
- Dropout(网络模型复杂,权值衰减不行):在学习过程中随机删除神经元的方法。
- 超参数:指的是各层的神经元个数,batch大小,参数更新时的学习率或权值衰减等
- 超参数的验证:如果没有设置合适的值,模型的性能就会很差。
- 填充:在进行卷积处理时,有时要向输入数据的周围填入固定的数据。
- 步幅:应用滤波器的位置间隔称为步幅。
- 池化是缩小高,长方向上的空间的运算。
- 除了Max池化(从目标区域中取出最大值)之外,还有Average池化(计算目标区域的平均值)等。
- 特点:1.没有学习的参数。2.通道数不发生变化。3.对微小的位置变化具有鲁棒性(健壮)
import numpy as np x=np.random.rand(10,1,4,4)#随机生成数据 #生成10个高为4,长为4,通道数为1的数据 print(x.shape) print(x[0])4.基于im2col的展开
-
使用im2col函数可以高效实现卷积层和池化层
-
对3维的输入数据应用im2col后,数据转化为2维矩阵。(展开以适合滤波器)
-
使用im2col展开数据后,之后就只需将卷积层的滤波器(权重)纵向展开为1列,并计算2个矩阵的乘积即可。
- 展开输入数据
- 求各行的最大值
- 转换为合适的输出大小
- LeNet
- 与现有cnn不同,激活函数不同,采用的sigmoid函数,现有的是ReLU函数。
- 采用子采样(subsampling)缩小中间数据大小,现有的Max池化
- AlexNet
- 叠有很多个卷积层和池化层,最后由全连接层输出结果。
- 激活函数用ReLU
- 使用进行局部正规化的LRN(Local Response Normalization)层
- 使用Dropout(抑制过拟合)
- 基于3*3的小型滤波器的卷积层。
- 激活函数是ReLU
- 全连接层的后面使用Dropout层。
- 基于Adam的最优化
- 使用He初始值作为权重初始值
- VGG是由卷积层和池化层构成的基础的CNN。
- 特点在于将有权重的层(卷积层或全连接层)叠加至16层(或者19层),具有深度(根据深度也被称为VGG16或者VGG19)
- 基于3*3的小型滤波器的卷积层的运算是连续进行的。
- 特点:横向纵向上面都有深度。横向有“宽度”,称为“Inception结构”。
- 该结构使用了多个大小不同的滤波器(和池化),最后合并看结果。
- GoogLeNet特征就是将这个Inception结构用作一个构件(构成元素)。
- 很多地方使用了1*1的滤波器的卷积器,通过在通道方向上减小大小,有助于减少参数和实现高速化处理。
- 微软团队,特点:具有更深的结构。
- 太深也不好,会影响学习不能正常进行,导致性能不佳,所以导入“快捷结构(捷径,小路)”
- 快捷结构横跨(跳过)输入数据的卷积层,将输入x合计到输出。
- 通过以2个卷积层为间隔跳跃式的来连接加深层。
- AlexNet中conv是对应卷积层,pool对应池化层,fc对应全连接层,norm对应正规化层。
- GPU适合计算大规模的汇总好的数据。
- 通过基于im2col以大型矩阵的乘积的方式汇总计算,更适合GPU发挥。
- Google的TensorFlow,微软的CNTK在开发中高度重视分布式学习。
- FCN(Fully Convolutional Network)“全部由卷积层构成的网络”,通过一次forward处理,对所有像素进行分类。
- FCN的特征:在于最后导入了扩大空间大小的处理,基于这个处理,使变小的中间数据可以一下子扩大到和输入图像一样的大小。
- FCN最后的扩大处理是基于双线性插值法的扩大(双线性插值扩大),通过卷积(逆卷积运算)来实现的。
- NIC(Neural Image Caption)由深层的CNN和处理自然语言的RNN(Recurrent Neural Network)构成
- RNN是循环连接的网络,经常被用于自然语言,时间序列数据等连续性的数据上。
- NIC基于CNN从图片中提取特征,并将这个特征传给RNN。
- 图像风格变换:在学习过程中使网络的中间数据近似内容的中间数据。(风格矩阵)
- 图像的生成:基于DCGAN(Deep Convolutional Generative Adversarial Network),从零生成的图片。
- DCGAN:使用深度学习,技术要点是使用Generator(生成者)和Discriminator(识别者)这两个神经网络。
- 自动驾驶:基于CNN的神经网络SegNet,输入头像进行分割(像素水平分割)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)